Module: Mesa Branch: main Commit: b71957635f1ef890cef954cf5b8493b7e62bf728 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b71957635f1ef890cef954cf5b8493b7e62bf728
Author: Iván Briano <[email protected]> Date: Thu Feb 23 14:41:54 2023 -0800 anv: stop tracking color blend state in the pipeline Now that all color blend bits are dynamic, emit_cb_state() is doing almost nothing and half of that is wrong. In the case that color write enable is dynamic, at the time the pipeline state is emitted, it sees all the color attachments as having write disabled and stores the WriteDisabled bit for each channel. When all dynamic state is flushed, we have the right values already but the values recorded into the command buffer get ORed with the ones stored in the pipeline, and so WriteDisabled tag along when they shouldn't. Since all disabled color attachments are handled already when dynamic state is flushed, there's no point in doing so at pipeline creation time too. And since the only other thing done by emit_cb_state() is writing three hardcoded values, they might as well be taken care of in the same place as everything else. Fixes CTS from the future: dEQP-VK.pipeline.*.extended_dynamic_state.*.color_blend_equation_*dynamic* dEQP-VK.pipeline.*.extended_dynamic_state.*.color_blend_all_* Fixes: fc3fd7c69e8 (anv: dynamic color write mask) Reviewed-by: Lionel Landwerlin <[email protected]> Reviewed-by: Tapani Pälli <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21509> --- src/intel/vulkan/anv_private.h | 1 - src/intel/vulkan/genX_pipeline.c | 72 -------------------------------------- src/intel/vulkan/gfx8_cmd_buffer.c | 39 +++++++++++++++------ 3 files changed, 28 insertions(+), 84 deletions(-) diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e4f260855a6..e1c885ad180 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3143,7 +3143,6 @@ struct anv_graphics_pipeline { uint32_t sf[4]; uint32_t raster[5]; uint32_t wm[2]; - uint32_t blend_state[1 + MAX_RTS * 2]; uint32_t streamout_state[5]; uint32_t hs[9]; } gfx8; diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 3974dabcb15..f51004f8904 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -842,77 +842,6 @@ const uint32_t genX(vk_to_intel_primitive_type)[] = { [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ, }; -static inline uint32_t * -write_disabled_blend(uint32_t *state) -{ - struct GENX(BLEND_STATE_ENTRY) entry = { - .WriteDisableAlpha = true, - .WriteDisableRed = true, - .WriteDisableGreen = true, - .WriteDisableBlue = true, - }; - GENX(BLEND_STATE_ENTRY_pack)(NULL, state, &entry); - return state + GENX(BLEND_STATE_ENTRY_length); -} - -static void -emit_cb_state(struct anv_graphics_pipeline *pipeline, - const struct vk_color_blend_state *cb, - const struct vk_multisample_state *ms) -{ - uint32_t surface_count = 0; - struct anv_pipeline_bind_map *map; - if (anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) { - map = &pipeline->shaders[MESA_SHADER_FRAGMENT]->bind_map; - surface_count = map->surface_count; - } - - uint32_t *state_pos = pipeline->gfx8.blend_state; - - state_pos += GENX(BLEND_STATE_length); - for (unsigned i = 0; i < surface_count; i++) { - struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i]; - - /* All color attachments are at the beginning of the binding table */ - if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) - break; - - /* We can have at most 8 attachments */ - assert(i < MAX_RTS); - - if (cb == NULL || binding->index >= cb->attachment_count) { - state_pos = write_disabled_blend(state_pos); - continue; - } - - struct GENX(BLEND_STATE_ENTRY) entry = { - /* Vulkan specification 1.2.168, VkLogicOp: - * - * "Logical operations are controlled by the logicOpEnable and - * logicOp members of VkPipelineColorBlendStateCreateInfo. If - * logicOpEnable is VK_TRUE, then a logical operation selected by - * logicOp is applied between each color attachment and the - * fragment’s corresponding output value, and blending of all - * attachments is treated as if it were disabled." - * - * From the Broadwell PRM Volume 2d: Command Reference: Structures: - * BLEND_STATE_ENTRY: - * - * "Enabling LogicOp and Color Buffer Blending at the same time is - * UNDEFINED" - * - * Above is handled during emit since these states are dynamic. - */ - .ColorClampRange = COLORCLAMP_RTFORMAT, - .PreBlendColorClampEnable = true, - .PostBlendColorClampEnable = true, - }; - - GENX(BLEND_STATE_ENTRY_pack)(NULL, state_pos, &entry); - state_pos += GENX(BLEND_STATE_ENTRY_length); - } -} - static void emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, const struct vk_input_assembly_state *ia, @@ -1872,7 +1801,6 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_rs_state(pipeline, state->ia, state->rs, state->ms, state->rp, urb_deref_block_size); emit_ms_state(pipeline, state->ms); - emit_cb_state(pipeline, state->cb, state->ms); compute_kill_pixel(pipeline, state->ms, state->rp); emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs); diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c index daf3783bbb7..a6fe63093e6 100644 --- a/src/intel/vulkan/gfx8_cmd_buffer.c +++ b/src/intel/vulkan/gfx8_cmd_buffer.c @@ -724,10 +724,14 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) && (color_writes & ((1u << state->color_att_count) - 1)) != 0; - uint32_t blend_dws[GENX(BLEND_STATE_length) + - MAX_RTS * GENX(BLEND_STATE_ENTRY_length)]; - uint32_t *dws = blend_dws; - memset(blend_dws, 0, sizeof(blend_dws)); + uint32_t num_dwords = GENX(BLEND_STATE_length) + + GENX(BLEND_STATE_ENTRY_length) * MAX_RTS; + struct anv_state blend_states = + anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, + num_dwords * 4, + 64); + + uint32_t *dws = blend_states.map; struct GENX(BLEND_STATE) blend_state = { .AlphaToCoverageEnable = dyn->ms.alpha_to_coverage_enable, @@ -756,10 +760,29 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) .WriteDisableBlue = write_disabled || (dyn->cb.attachments[i].write_mask & VK_COLOR_COMPONENT_B_BIT) == 0, + /* Vulkan specification 1.2.168, VkLogicOp: + * + * "Logical operations are controlled by the logicOpEnable and + * logicOp members of VkPipelineColorBlendStateCreateInfo. If + * logicOpEnable is VK_TRUE, then a logical operation selected + * by logicOp is applied between each color attachment and the + * fragment’s corresponding output value, and blending of all + * attachments is treated as if it were disabled." + * + * From the Broadwell PRM Volume 2d: Command Reference: + * Structures: BLEND_STATE_ENTRY: + * + * "Enabling LogicOp and Color Buffer Blending at the same time + * is UNDEFINED" + */ .LogicOpFunction = genX(vk_to_intel_logic_op)[dyn->cb.logic_op], .LogicOpEnable = dyn->cb.logic_op_enable, .ColorBufferBlendEnable = !dyn->cb.logic_op_enable && dyn->cb.attachments[i].blend_enable, + + .ColorClampRange = COLORCLAMP_RTFORMAT, + .PreBlendColorClampEnable = true, + .PostBlendColorClampEnable = true, }; /* Setup blend equation. */ @@ -827,7 +850,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) } /* Generate blend state after entries. */ - GENX(BLEND_STATE_pack)(NULL, blend_dws, &blend_state); + GENX(BLEND_STATE_pack)(NULL, blend_states.map, &blend_state); /* 3DSTATE_PS_BLEND to be consistent with the rest of the * BLEND_STATE_ENTRY. @@ -844,12 +867,6 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) blend.AlphaToCoverageEnable = dyn->ms.alpha_to_coverage_enable; } - uint32_t num_dwords = GENX(BLEND_STATE_length) + - GENX(BLEND_STATE_ENTRY_length) * MAX_RTS; - - struct anv_state blend_states = - anv_cmd_buffer_merge_dynamic(cmd_buffer, blend_dws, - pipeline->gfx8.blend_state, num_dwords, 64); anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) { bsp.BlendStatePointer = blend_states.offset; bsp.BlendStatePointerValid = true;
