Mesa (main): radv: implement dynamic primitive restart enable

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 6 21:11:08 UTC 2021


Module: Mesa
Branch: main
Commit: c40d7fadc3a5c190411c6a1852068b9854fc7618
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c40d7fadc3a5c190411c6a1852068b9854fc7618

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon Mar 15 18:51:28 2021 +0100

radv: implement dynamic primitive restart enable

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

---

 src/amd/vulkan/radv_cmd_buffer.c | 62 +++++++++++++++++++++++++++++-----------
 src/amd/vulkan/radv_meta.c       |  7 ++++-
 src/amd/vulkan/radv_meta.h       |  1 +
 src/amd/vulkan/radv_pipeline.c   | 12 ++++++--
 src/amd/vulkan/radv_private.h    |  5 ++--
 src/amd/vulkan/si_cmd_buffer.c   |  6 ++--
 6 files changed, 67 insertions(+), 26 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index bbd67c444f1..6a75cac8015 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -107,6 +107,7 @@ const struct radv_dynamic_state default_dynamic_state = {
                           VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR},
       },
    .depth_bias_enable = 0u,
+   .primitive_restart_enable = 0u,
 };
 
 static void
@@ -305,6 +306,13 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy
       }
    }
 
+   if (copy_mask & RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE) {
+      if (dest->primitive_restart_enable != src->primitive_restart_enable) {
+         dest->primitive_restart_enable = src->primitive_restart_enable;
+         dest_mask |= RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
+      }
+   }
+
    cmd_buffer->state.dirty |= dest_mask;
 }
 
@@ -1273,7 +1281,8 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
    if (!cmd_buffer->state.emitted_pipeline)
       cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
                                  RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
-                                 RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
+                                 RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |
+                                 RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
 
    if (!cmd_buffer->state.emitted_pipeline ||
        cmd_buffer->state.emitted_pipeline->graphics.db_depth_control !=
@@ -1584,6 +1593,20 @@ radv_emit_fragment_shading_rate(struct radv_cmd_buffer *cmd_buffer)
    radeon_set_context_reg(cmd_buffer->cs, R_028848_PA_CL_VRS_CNTL, pa_cl_vrs_cntl);
 }
 
+static void
+radv_emit_primitive_restart_enable(struct radv_cmd_buffer *cmd_buffer)
+{
+   struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+
+   if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
+      radeon_set_uconfig_reg(cmd_buffer->cs, R_03092C_VGT_MULTI_PRIM_IB_RESET_EN,
+                             d->primitive_restart_enable);
+   } else {
+      radeon_set_context_reg(cmd_buffer->cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN,
+                             d->primitive_restart_enable);
+   }
+}
+
 static void
 radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index,
                          struct radv_color_buffer_info *cb, struct radv_image_view *iview,
@@ -2581,6 +2604,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
    if (states & RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE)
       radv_emit_fragment_shading_rate(cmd_buffer);
 
+   if (states & RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)
+      radv_emit_primitive_restart_enable(cmd_buffer);
+
    cmd_buffer->state.dirty &= ~states;
 }
 
@@ -3070,12 +3096,13 @@ si_emit_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dr
    struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info;
    struct radv_cmd_state *state = &cmd_buffer->state;
    unsigned topology = state->dynamic.primitive_topology;
+   bool prim_restart_enable = state->dynamic.primitive_restart_enable;
    struct radeon_cmdbuf *cs = cmd_buffer->cs;
    unsigned ia_multi_vgt_param;
 
    ia_multi_vgt_param =
       si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw, indirect_draw, count_from_stream_output,
-                                draw_vertex_count, topology);
+                                draw_vertex_count, topology, prim_restart_enable);
 
    if (state->last_ia_multi_vgt_param != ia_multi_vgt_param) {
       if (info->chip_class == GFX9) {
@@ -3096,7 +3123,6 @@ radv_emit_draw_registers(struct radv_cmd_buffer *cmd_buffer, const struct radv_d
    struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info;
    struct radv_cmd_state *state = &cmd_buffer->state;
    struct radeon_cmdbuf *cs = cmd_buffer->cs;
-   int32_t primitive_reset_en;
 
    /* Draw state. */
    if (info->chip_class < GFX10) {
@@ -3105,19 +3131,7 @@ radv_emit_draw_registers(struct radv_cmd_buffer *cmd_buffer, const struct radv_d
                                  draw_info->indirect ? 0 : draw_info->count);
    }
 
-   /* Primitive restart. */
-   primitive_reset_en = draw_info->indexed && state->pipeline->graphics.prim_restart_enable;
-
-   if (primitive_reset_en != state->last_primitive_reset_en) {
-      state->last_primitive_reset_en = primitive_reset_en;
-      if (info->chip_class >= GFX9) {
-         radeon_set_uconfig_reg(cs, R_03092C_VGT_MULTI_PRIM_IB_RESET_EN, primitive_reset_en);
-      } else {
-         radeon_set_context_reg(cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, primitive_reset_en);
-      }
-   }
-
-   if (primitive_reset_en) {
+   if (state->dynamic.primitive_restart_enable) {
       uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer);
 
       if (primitive_reset_index != state->last_primitive_reset_index) {
@@ -4762,6 +4776,20 @@ radv_CmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer, VkBool32 depthBiasE
    state->dirty |= RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
 }
 
+void
+radv_CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable)
+{
+   RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+   struct radv_cmd_state *state = &cmd_buffer->state;
+
+   if (state->dynamic.primitive_restart_enable == primitiveRestartEnable)
+      return;
+
+   state->dynamic.primitive_restart_enable = primitiveRestartEnable;
+
+   state->dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
+}
+
 void
 radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
                         const VkCommandBuffer *pCmdBuffers)
@@ -5373,7 +5401,7 @@ radv_need_late_scissor_emission(struct radv_cmd_buffer *cmd_buffer,
 
    uint32_t primitive_reset_index = radv_get_primitive_reset_index(cmd_buffer);
 
-   if (info->indexed && state->pipeline->graphics.prim_restart_enable &&
+   if (info->indexed && state->dynamic.primitive_restart_enable &&
        primitive_reset_index != state->last_primitive_reset_index)
       return true;
 
diff --git a/src/amd/vulkan/radv_meta.c b/src/amd/vulkan/radv_meta.c
index 094f9fa1af1..7bc6cd3c5eb 100644
--- a/src/amd/vulkan/radv_meta.c
+++ b/src/amd/vulkan/radv_meta.c
@@ -93,6 +93,8 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_
          cmd_buffer->state.dynamic.fragment_shading_rate.combiner_ops[1];
 
       state->depth_bias_enable = cmd_buffer->state.dynamic.depth_bias_enable;
+
+      state->primitive_restart_enable = cmd_buffer->state.dynamic.primitive_restart_enable;
    }
 
    if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
@@ -178,6 +180,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
 
       cmd_buffer->state.dynamic.depth_bias_enable = state->depth_bias_enable;
 
+      cmd_buffer->state.dynamic.primitive_restart_enable = state->primitive_restart_enable;
+
       cmd_buffer->state.dirty |=
          RADV_CMD_DIRTY_DYNAMIC_VIEWPORT | RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
          RADV_CMD_DIRTY_DYNAMIC_CULL_MODE | RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
@@ -185,7 +189,8 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf
          RADV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |
          RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE |
          RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP |
-         RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
+         RADV_CMD_DIRTY_DYNAMIC_FRAGMENT_SHADING_RATE | RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
+         RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
    }
 
    if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h
index 1aa7e895992..d6519231a2b 100644
--- a/src/amd/vulkan/radv_meta.h
+++ b/src/amd/vulkan/radv_meta.h
@@ -92,6 +92,7 @@ struct radv_meta_saved_state {
    } fragment_shading_rate;
 
    bool depth_bias_enable;
+   bool primitive_restart_enable;
 };
 
 VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index e282e1fa431..a14b8afd918 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -1382,10 +1382,12 @@ radv_pipeline_needed_dynamic_state(const VkGraphicsPipelineCreateInfo *pCreateIn
 
    /* If rasterization is disabled we do not care about any of the
     * dynamic states, since they are all rasterization related only,
-    * except primitive topology and vertex binding stride.
+    * except primitive topology, primitive restart enable and vertex
+    * binding stride.
     */
    if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable)
-      return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE;
+      return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY | RADV_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE |
+             RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
 
    if (!pCreateInfo->pRasterizationState->depthBiasEnable &&
        !radv_is_state_dynamic(pCreateInfo, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT))
@@ -1515,7 +1517,6 @@ radv_pipeline_init_input_assembly_state(struct radv_pipeline *pipeline,
    struct radv_shader_variant *tes = pipeline->shaders[MESA_SHADER_TESS_EVAL];
    struct radv_shader_variant *gs = pipeline->shaders[MESA_SHADER_GEOMETRY];
 
-   pipeline->graphics.prim_restart_enable = !!ia_state->primitiveRestartEnable;
    pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(ia_state->topology);
 
    if (radv_pipeline_has_gs(pipeline)) {
@@ -1735,6 +1736,11 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
       dynamic->depth_bias_enable = pCreateInfo->pRasterizationState->depthBiasEnable;
    }
 
+   if (states & RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE) {
+      dynamic->primitive_restart_enable =
+         !!pCreateInfo->pInputAssemblyState->primitiveRestartEnable;
+   }
+
    pipeline->dynamic_state.mask = states;
 }
 
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 7cd0493af11..87ede4c5781 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1214,6 +1214,7 @@ struct radv_dynamic_state {
    } fragment_shading_rate;
 
    bool depth_bias_enable;
+   bool primitive_restart_enable;
 };
 
 extern const struct radv_dynamic_state default_dynamic_state;
@@ -1490,7 +1491,8 @@ void si_write_scissors(struct radeon_cmdbuf *cs, int first, int count, const VkR
                        const VkViewport *viewports, bool can_use_guardband);
 uint32_t si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw,
                                    bool indirect_draw, bool count_from_stream_output,
-                                   uint32_t draw_vertex_count, unsigned topology);
+                                   uint32_t draw_vertex_count, unsigned topology,
+                                   bool prim_restart_enable);
 void si_cs_emit_write_event_eop(struct radeon_cmdbuf *cs, enum chip_class chip_class, bool is_mec,
                                 unsigned event, unsigned event_flags, unsigned dst_sel,
                                 unsigned data_sel, uint64_t va, uint32_t new_fence,
@@ -1706,7 +1708,6 @@ struct radv_pipeline {
          struct radv_binning_state binning;
          struct radv_vrs_state vrs;
          uint32_t spi_baryc_cntl;
-         bool prim_restart_enable;
          unsigned esgs_ring_size;
          unsigned gsvs_ring_size;
          uint32_t vtx_base_sgpr;
diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c
index 19dbc313adc..993f6c32861 100644
--- a/src/amd/vulkan/si_cmd_buffer.c
+++ b/src/amd/vulkan/si_cmd_buffer.c
@@ -792,7 +792,7 @@ static const struct radv_prim_vertex_count prim_size_table[] = {
 uint32_t
 si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_draw,
                           bool indirect_draw, bool count_from_stream_output,
-                          uint32_t draw_vertex_count, unsigned topology)
+                          uint32_t draw_vertex_count, unsigned topology, bool prim_restart_enable)
 {
    enum chip_class chip_class = cmd_buffer->device->physical_device->rad_info.chip_class;
    enum radeon_family family = cmd_buffer->device->physical_device->rad_info.family;
@@ -831,7 +831,7 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dra
       if (cmd_buffer->device->physical_device->rad_info.max_se < 4 ||
           topology == V_008958_DI_PT_POLYGON || topology == V_008958_DI_PT_LINELOOP ||
           topology == V_008958_DI_PT_TRIFAN || topology == V_008958_DI_PT_TRISTRIP_ADJ ||
-          (cmd_buffer->state.pipeline->graphics.prim_restart_enable &&
+          (prim_restart_enable &&
            (cmd_buffer->device->physical_device->rad_info.family < CHIP_POLARIS10 ||
             (topology != V_008958_DI_PT_POINTLIST && topology != V_008958_DI_PT_LINESTRIP))))
          wd_switch_on_eop = true;
@@ -899,7 +899,7 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer, bool instanced_dra
    /* Workaround for a VGT hang when strip primitive types are used with
     * primitive restart.
     */
-   if (cmd_buffer->state.pipeline->graphics.prim_restart_enable &&
+   if (prim_restart_enable &&
        (topology == V_008958_DI_PT_LINESTRIP || topology == V_008958_DI_PT_TRISTRIP ||
         topology == V_008958_DI_PT_LINESTRIP_ADJ || topology == V_008958_DI_PT_TRISTRIP_ADJ)) {
       partial_vs_wave = true;



More information about the mesa-commit mailing list