anv: stop tracking color blend state in the pipeline
authorIván Briano <ivan.briano@intel.com>
Thu, 23 Feb 2023 22:41:54 +0000 (14:41 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 24 Feb 2023 22:07:52 +0000 (22:07 +0000)
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 <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21509>

src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_pipeline.c
src/intel/vulkan/gfx8_cmd_buffer.c

index e4f2608..e1c885a 100644 (file)
@@ -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;
index 3974dab..f51004f 100644 (file)
@@ -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);
index daf3783..a6fe630 100644 (file)
@@ -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;