radv: make sure to emit BREAK_BATCH when color write enable is dynamic
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 25 Aug 2022 06:50:37 +0000 (08:50 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 29 Aug 2022 19:21:12 +0000 (19:21 +0000)
Color write enable can change CB_TARGET_MASK and emitting a BREAK_BATCH
seems needed for binning. Though, this was broken if this enable bit
changed dynamically for the same pipeline. Split the function to not
increase CPU overhead.

Found by inspection.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18233>

src/amd/vulkan/radv_cmd_buffer.c

index 09b0699..cf1bd26 100644 (file)
@@ -1396,32 +1396,10 @@ radv_emit_rbplus_state(struct radv_cmd_buffer *cmd_buffer)
 }
 
 static void
-radv_emit_batch_break_on_new_ps(struct radv_cmd_buffer *cmd_buffer)
-{
-   if (!cmd_buffer->device->pbb_allowed)
-      return;
-
-   struct radv_binning_settings *settings = &cmd_buffer->device->physical_device->binning_settings;
-   bool break_for_new_ps =
-      (!cmd_buffer->state.emitted_graphics_pipeline ||
-       cmd_buffer->state.emitted_graphics_pipeline->base.shaders[MESA_SHADER_FRAGMENT] !=
-          cmd_buffer->state.graphics_pipeline->base.shaders[MESA_SHADER_FRAGMENT]) &&
-      (settings->context_states_per_bin > 1 || settings->persistent_states_per_bin > 1);
-   bool break_for_new_cb_target_mask =
-      (cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE) &&
-      settings->context_states_per_bin > 1;
-
-   if (!break_for_new_ps && !break_for_new_cb_target_mask)
-      return;
-
-   radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
-   radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0));
-}
-
-static void
 radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
 {
    struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline;
+   const struct radv_device *device = cmd_buffer->device;
 
    if (cmd_buffer->state.emitted_graphics_pipeline == pipeline)
       return;
@@ -1497,7 +1475,18 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
       cmd_buffer->state.context_roll_without_scissor_emitted = true;
    }
 
-   radv_emit_batch_break_on_new_ps(cmd_buffer);
+   if (device->pbb_allowed) {
+      struct radv_binning_settings *settings = &device->physical_device->binning_settings;
+
+      if ((!cmd_buffer->state.emitted_graphics_pipeline ||
+           cmd_buffer->state.emitted_graphics_pipeline->base.shaders[MESA_SHADER_FRAGMENT] !=
+           cmd_buffer->state.graphics_pipeline->base.shaders[MESA_SHADER_FRAGMENT]) &&
+          (settings->context_states_per_bin > 1 || settings->persistent_states_per_bin > 1)) {
+         /* Break the batch on PS changes. */
+         radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+         radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0));
+      }
+   }
 
    radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.slab_bo);
 
@@ -7448,6 +7437,7 @@ static void
 radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct radv_draw_info *info,
                               bool pipeline_is_dirty)
 {
+   const struct radv_device *device = cmd_buffer->device;
    bool late_scissor_emission;
 
    if ((cmd_buffer->state.dirty & RADV_CMD_DIRTY_FRAMEBUFFER) ||
@@ -7500,6 +7490,17 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, const struct r
       }
    }
 
+   if (device->pbb_allowed) {
+      struct radv_binning_settings *settings = &device->physical_device->binning_settings;
+
+      if ((cmd_buffer->state.dirty & RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE) &&
+          settings->context_states_per_bin > 1) {
+         /* Break the batch on CB_TARGET_MASK changes. */
+         radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
+         radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0));
+      }
+   }
+
    radv_cmd_buffer_flush_dynamic_state(cmd_buffer, pipeline_is_dirty);
 
    radv_emit_draw_registers(cmd_buffer, info);