summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2022-03-14 09:52:35 +0200
committerMarge Bot <emma+marge@anholt.net>2022-03-24 10:49:07 +0000
commit1d250b7b959d2a206280e4f83db05780a83e0927 (patch)
tree0115e8156790e6127d793886b1f2db9d14030dd1
parenta4f502de3228ec37dfcaa38225077ec3709d74ea (diff)
anv: fix color write enable interaction with color mask
Color writes & color masks occupy the same fields in the BLEND_STATE structure. So we need to store color mask (which are not dynamic) on the pipeline to merge that information with color writes. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Fixes: b15bfe92f7f8 ("anv: implement VK_EXT_color_write_enable") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6111 Reviewed-by: Tapani Pälli <tapani.palli@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15310>
-rw-r--r--src/intel/vulkan/anv_pipeline.c29
-rw-r--r--src/intel/vulkan/anv_private.h21
-rw-r--r--src/intel/vulkan/genX_pipeline.c43
-rw-r--r--src/intel/vulkan/gfx7_cmd_buffer.c32
-rw-r--r--src/intel/vulkan/gfx8_cmd_buffer.c30
5 files changed, 99 insertions, 56 deletions
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index e7db9215d11..7c6c0d4419f 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -2058,6 +2058,16 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
return VK_SUCCESS;
}
+static bool
+anv_rendering_uses_color_attachment(const VkPipelineRenderingCreateInfo *rendering_info)
+{
+ for (unsigned i = 0; i < rendering_info->colorAttachmentCount; i++) {
+ if (rendering_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED)
+ return true;
+ }
+ return false;
+}
+
/**
* Copy pipeline state not marked as dynamic.
* Dynamic state is pipeline state which hasn't been provided at pipeline
@@ -2176,13 +2186,7 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
* disabled or if the subpass of the render pass the pipeline is
* created against does not use any color attachments.
*/
- bool uses_color_att = false;
- for (unsigned i = 0; i < rendering_info->colorAttachmentCount; i++) {
- if (rendering_info->pColorAttachmentFormats[i] != VK_FORMAT_UNDEFINED) {
- uses_color_att = true;
- break;
- }
- }
+ bool uses_color_att = anv_rendering_uses_color_attachment(rendering_info);
if (uses_color_att && !raster_discard) {
assert(pCreateInfo->pColorBlendState);
@@ -2555,6 +2559,17 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
pipeline->rasterization_samples =
ms_info ? ms_info->rasterizationSamples : 1;
+ /* Store the color write masks, to be merged with color write enable if
+ * dynamic.
+ */
+ if (raster_enabled && anv_rendering_uses_color_attachment(rendering_info)) {
+ for (unsigned i = 0; i < pCreateInfo->pColorBlendState->attachmentCount; i++) {
+ const VkPipelineColorBlendAttachmentState *a =
+ &pCreateInfo->pColorBlendState->pAttachments[i];
+ pipeline->color_comp_writes[i] = a->colorWriteMask;
+ }
+ }
+
return VK_SUCCESS;
}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 2d44d169db6..7e95f240635 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -3383,6 +3383,8 @@ struct anv_graphics_pipeline {
VkPolygonMode polygon_mode;
uint32_t rasterization_samples;
+ VkColorComponentFlags color_comp_writes[MAX_RTS];
+
struct anv_shader_bin * shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT];
VkShaderStageFlags active_stages;
@@ -3505,6 +3507,25 @@ anv_pipeline_is_mesh(const struct anv_graphics_pipeline *pipeline)
return anv_pipeline_has_stage(pipeline, MESA_SHADER_MESH);
}
+static inline bool
+anv_cmd_buffer_all_color_write_masked(const struct anv_cmd_buffer *cmd_buffer)
+{
+ const struct anv_cmd_graphics_state *state = &cmd_buffer->state.gfx;
+ uint8_t color_writes = state->dynamic.color_writes;
+
+ /* All writes disabled through vkCmdSetColorWriteEnableEXT */
+ if ((color_writes & ((1u << state->color_att_count) - 1)) == 0)
+ return true;
+
+ /* Or all write masks are empty */
+ for (uint32_t i = 0; i < state->color_att_count; i++) {
+ if (state->pipeline->color_comp_writes[i] != 0)
+ return false;
+ }
+
+ return true;
+}
+
#define ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(prefix, stage) \
static inline const struct brw_##prefix##_prog_data * \
get_##prefix##_prog_data(const struct anv_graphics_pipeline *pipeline) \
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index a1bccf9dc00..d2c707d4a7f 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -1406,8 +1406,6 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline,
.AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
#endif
.LogicOpEnable = info->logicOpEnable,
- .LogicOpFunction = dynamic_states & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP ?
- 0: genX(vk_to_intel_logic_op)[info->logicOp],
/* Vulkan specification 1.2.168, VkLogicOp:
*
@@ -1434,20 +1432,20 @@ emit_cb_state(struct anv_graphics_pipeline *pipeline,
.SourceAlphaBlendFactor = vk_to_intel_blend[a->srcAlphaBlendFactor],
.DestinationAlphaBlendFactor = vk_to_intel_blend[a->dstAlphaBlendFactor],
.AlphaBlendFunction = vk_to_intel_blend_op[a->alphaBlendOp],
- .WriteDisableAlpha =
- (dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) == 0 &&
- !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT),
- .WriteDisableRed =
- (dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) == 0 &&
- !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT),
- .WriteDisableGreen =
- (dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) == 0 &&
- !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT),
- .WriteDisableBlue =
- (dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) == 0 &&
- !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT),
};
+ /* Write logic op if not dynamic */
+ if (!(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP))
+ entry.LogicOpFunction = genX(vk_to_intel_logic_op)[info->logicOp];
+
+ /* Write blending color if not dynamic */
+ if (!(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE)) {
+ entry.WriteDisableAlpha = !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT);
+ entry.WriteDisableRed = !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT);
+ entry.WriteDisableGreen = !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT);
+ entry.WriteDisableBlue = !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT);
+ }
+
if (a->srcColorBlendFactor != a->srcAlphaBlendFactor ||
a->dstColorBlendFactor != a->dstAlphaBlendFactor ||
a->colorBlendOp != a->alphaBlendOp) {
@@ -2319,11 +2317,11 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline,
wm_prog_data->has_side_effects ||
wm_prog_data->uses_kill;
- if (pipeline->force_fragment_thread_dispatch ||
- !has_color_buffer_write_enabled(pipeline, blend)) {
- /* Only set this value in non dynamic mode. */
+ /* Only set this value in non dynamic mode. */
+ if (!(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE)) {
wm.ForceThreadDispatchEnable =
- !(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) ? ForceON : 0;
+ (pipeline->force_fragment_thread_dispatch ||
+ !has_color_buffer_write_enabled(pipeline, blend)) ? ForceON : 0;
}
#endif
@@ -2352,10 +2350,11 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline,
wm_prog_data->has_side_effects ||
wm.PixelShaderKillsPixel;
- if (pipeline->force_fragment_thread_dispatch ||
- has_color_buffer_write_enabled(pipeline, blend)) {
- /* Only set this value in non dynamic mode. */
- wm.ThreadDispatchEnable = !(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);
+ /* Only set this value in non dynamic mode. */
+ if (!(dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE)) {
+ wm.ThreadDispatchEnable =
+ pipeline->force_fragment_thread_dispatch ||
+ has_color_buffer_write_enabled(pipeline, blend);
}
if (multisample && multisample->rasterizationSamples > 1) {
diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c
index 285d14066c4..cf183429878 100644
--- a/src/intel/vulkan/gfx7_cmd_buffer.c
+++ b/src/intel/vulkan/gfx7_cmd_buffer.c
@@ -290,13 +290,12 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
primitive_topology);
- const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
uint32_t dwords[GENX(3DSTATE_WM_length)];
struct GENX(3DSTATE_WM) wm = {
GENX(3DSTATE_WM_header),
.ThreadDispatchEnable = pipeline->force_fragment_thread_dispatch ||
- color_writes,
+ !anv_cmd_buffer_all_color_write_masked(cmd_buffer),
.MultisampleRasterizationMode =
genX(ms_rasterization_mode)(pipeline,
dynamic_raster_mode),
@@ -317,8 +316,6 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)) {
const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
- bool dirty_color_blend =
- cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
uint32_t blend_dws[GENX(BLEND_STATE_length) +
MAX_RTS * GENX(BLEND_STATE_ENTRY_length)];
@@ -328,19 +325,24 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
/* Skip this part */
dws += GENX(BLEND_STATE_length);
- bool dirty_logic_op =
- cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
-
for (uint32_t i = 0; i < MAX_RTS; i++) {
- bool write_disabled = dirty_color_blend &&
- (color_writes & BITFIELD_BIT(i)) == 0;
+ /* Disable anything above the current number of color attachments. */
+ bool write_disabled = i >= cmd_buffer->state.gfx.color_att_count ||
+ (color_writes & BITFIELD_BIT(i)) == 0;
struct GENX(BLEND_STATE_ENTRY) entry = {
- .WriteDisableAlpha = write_disabled,
- .WriteDisableRed = write_disabled,
- .WriteDisableGreen = write_disabled,
- .WriteDisableBlue = write_disabled,
- .LogicOpFunction =
- dirty_logic_op ? genX(vk_to_intel_logic_op)[d->logic_op] : 0,
+ .WriteDisableAlpha = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_A_BIT) == 0,
+ .WriteDisableRed = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_R_BIT) == 0,
+ .WriteDisableGreen = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_G_BIT) == 0,
+ .WriteDisableBlue = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_B_BIT) == 0,
+ .LogicOpFunction = genX(vk_to_intel_logic_op)[d->logic_op],
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry);
dws += GENX(BLEND_STATE_ENTRY_length);
diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c
index 5e165102011..8f30e1253a2 100644
--- a/src/intel/vulkan/gfx8_cmd_buffer.c
+++ b/src/intel/vulkan/gfx8_cmd_buffer.c
@@ -642,7 +642,6 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)) {
const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
-
/* 3DSTATE_WM in the hope we can avoid spawning fragment shaders
* threads.
*/
@@ -651,7 +650,8 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
GENX(3DSTATE_WM_header),
.ForceThreadDispatchEnable = (pipeline->force_fragment_thread_dispatch ||
- !color_writes) ? ForceON : 0,
+ anv_cmd_buffer_all_color_write_masked(cmd_buffer)) ?
+ ForceON : 0,
};
GENX(3DSTATE_WM_pack)(NULL, wm_dwords, &wm);
@@ -677,18 +677,24 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
/* Skip this part */
dws += GENX(BLEND_STATE_length);
- bool dirty_logic_op =
- cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
-
for (uint32_t i = 0; i < MAX_RTS; i++) {
- bool write_disabled = (color_writes & BITFIELD_BIT(i)) == 0;
+ /* Disable anything above the current number of color attachments. */
+ bool write_disabled = i >= cmd_buffer->state.gfx.color_att_count ||
+ (color_writes & BITFIELD_BIT(i)) == 0;
struct GENX(BLEND_STATE_ENTRY) entry = {
- .WriteDisableAlpha = write_disabled,
- .WriteDisableRed = write_disabled,
- .WriteDisableGreen = write_disabled,
- .WriteDisableBlue = write_disabled,
- .LogicOpFunction =
- dirty_logic_op ? genX(vk_to_intel_logic_op)[d->logic_op] : 0,
+ .WriteDisableAlpha = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_A_BIT) == 0,
+ .WriteDisableRed = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_R_BIT) == 0,
+ .WriteDisableGreen = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_G_BIT) == 0,
+ .WriteDisableBlue = write_disabled ||
+ (pipeline->color_comp_writes[i] &
+ VK_COLOR_COMPONENT_B_BIT) == 0,
+ .LogicOpFunction = genX(vk_to_intel_logic_op)[d->logic_op],
};
GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry);
dws += GENX(BLEND_STATE_ENTRY_length);