anv: emit 3DSTATE_GS only once per pipeline
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 2 Aug 2023 06:30:05 +0000 (09:30 +0300)
committerMarge Bot <emma+marge@anholt.net>
Sat, 12 Aug 2023 13:49:31 +0000 (13:49 +0000)
Following 71ebd9b9d7, 3DSTATE_GS can be emitted as part of the
pipeline batch and as a dynamic state. Just do the latter.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 71ebd9b9d7 ("anv,hasvk: respect provoking vertex setting on geometry shaders")
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24632>

src/intel/vulkan/genX_cmd_buffer.c
src/intel/vulkan/genX_pipeline.c
src/intel/vulkan/gfx8_cmd_buffer.c

index eafc20d..916f5b8 100644 (file)
@@ -3373,38 +3373,6 @@ genX(emit_ds)(struct anv_cmd_buffer *cmd_buffer)
 }
 
 ALWAYS_INLINE static void
-genX(emit_gs)(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
-   if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY))
-      return;
-
-   uint32_t dwords[GENX(3DSTATE_GS_length)];
-   const struct vk_dynamic_graphics_state *dyn =
-      &cmd_buffer->vk.dynamic_graphics_state;
-
-   struct GENX(3DSTATE_GS) gs = {
-      GENX(3DSTATE_GS_header),
-   };
-
-   switch (dyn->rs.provoking_vertex) {
-   case VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT:
-      gs.ReorderMode = LEADING;
-      break;
-
-   case VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT:
-      gs.ReorderMode = TRAILING;
-      break;
-
-   default:
-      unreachable("Invalid provoking vertex mode");
-   }
-
-   GENX(3DSTATE_GS_pack)(NULL, dwords, &gs);
-   anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx8.gs);
-}
-
-ALWAYS_INLINE static void
 genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
@@ -3535,11 +3503,6 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
       genX(emit_hs)(cmd_buffer);
    }
 
-   if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE ||
-       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX)) {
-      genX(emit_gs)(cmd_buffer);
-   }
-
    if (!cmd_buffer->state.gfx.dirty && !descriptors_dirty &&
        !any_dynamic_state_dirty &&
        ((cmd_buffer->state.push_constants_dirty &
index ece3ba5..d5c4045 100644 (file)
@@ -1383,67 +1383,63 @@ emit_3dstate_hs_ds(struct anv_graphics_pipeline *pipeline,
 static void
 emit_3dstate_gs(struct anv_graphics_pipeline *pipeline)
 {
-   struct anv_batch *batch = &pipeline->base.base.batch;
    const struct intel_device_info *devinfo = pipeline->base.base.device->info;
    const struct anv_shader_bin *gs_bin =
       pipeline->base.shaders[MESA_SHADER_GEOMETRY];
 
-   if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) {
-      anv_batch_emit(batch, GENX(3DSTATE_GS), gs);
-      return;
-   }
-
-   const struct brw_gs_prog_data *gs_prog_data = get_gs_prog_data(pipeline);
-
    struct GENX(3DSTATE_GS) gs = {
       GENX(3DSTATE_GS_header),
    };
 
-   gs.Enable                  = true;
-   gs.StatisticsEnable        = true;
-   gs.KernelStartPointer      = gs_bin->kernel.offset;
-   gs.DispatchMode            = gs_prog_data->base.dispatch_mode;
+   if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) {
+       const struct brw_gs_prog_data *gs_prog_data = get_gs_prog_data(pipeline);
 
-   gs.SingleProgramFlow       = false;
-   gs.VectorMaskEnable        = false;
-   /* Wa_1606682166 */
-   gs.SamplerCount            = GFX_VER == 11 ? 0 : get_sampler_count(gs_bin);
-   gs.BindingTableEntryCount  = gs_bin->bind_map.surface_count;
-   gs.IncludeVertexHandles    = gs_prog_data->base.include_vue_handles;
-   gs.IncludePrimitiveID      = gs_prog_data->include_primitive_id;
-
-   gs.MaximumNumberofThreads = devinfo->max_gs_threads - 1;
-
-   gs.OutputVertexSize        = gs_prog_data->output_vertex_size_hwords * 2 - 1;
-   gs.OutputTopology          = gs_prog_data->output_topology;
-   gs.ControlDataFormat       = gs_prog_data->control_data_format;
-   gs.ControlDataHeaderSize   = gs_prog_data->control_data_header_size_hwords;
-   gs.InstanceControl         = MAX2(gs_prog_data->invocations, 1) - 1;
-   gs.ReorderMode             = LEADING;
-
-   gs.ExpectedVertexCount     = gs_prog_data->vertices_in;
-   gs.StaticOutput            = gs_prog_data->static_vertex_count >= 0;
-   gs.StaticOutputVertexCount = gs_prog_data->static_vertex_count >= 0 ?
-      gs_prog_data->static_vertex_count : 0;
-
-   gs.VertexURBEntryReadOffset = 0;
-   gs.VertexURBEntryReadLength = gs_prog_data->base.urb_read_length;
-   gs.DispatchGRFStartRegisterForURBData =
-      gs_prog_data->base.base.dispatch_grf_start_reg;
-
-   gs.UserClipDistanceClipTestEnableBitmask =
-      gs_prog_data->base.clip_distance_mask;
-   gs.UserClipDistanceCullTestEnableBitmask =
-      gs_prog_data->base.cull_distance_mask;
+      gs.Enable                  = true;
+      gs.StatisticsEnable        = true;
+      gs.KernelStartPointer      = gs_bin->kernel.offset;
+      gs.DispatchMode            = gs_prog_data->base.dispatch_mode;
+
+      gs.SingleProgramFlow       = false;
+      gs.VectorMaskEnable        = false;
+      /* Wa_1606682166 */
+      gs.SamplerCount            = GFX_VER == 11 ? 0 : get_sampler_count(gs_bin);
+      gs.BindingTableEntryCount  = gs_bin->bind_map.surface_count;
+      gs.IncludeVertexHandles    = gs_prog_data->base.include_vue_handles;
+      gs.IncludePrimitiveID      = gs_prog_data->include_primitive_id;
+
+      gs.MaximumNumberofThreads = devinfo->max_gs_threads - 1;
+
+      gs.OutputVertexSize        = gs_prog_data->output_vertex_size_hwords * 2 - 1;
+      gs.OutputTopology          = gs_prog_data->output_topology;
+      gs.ControlDataFormat       = gs_prog_data->control_data_format;
+      gs.ControlDataHeaderSize   = gs_prog_data->control_data_header_size_hwords;
+      gs.InstanceControl         = MAX2(gs_prog_data->invocations, 1) - 1;
+      gs.ReorderMode             = LEADING;
+
+      gs.ExpectedVertexCount     = gs_prog_data->vertices_in;
+      gs.StaticOutput            = gs_prog_data->static_vertex_count >= 0;
+      gs.StaticOutputVertexCount = gs_prog_data->static_vertex_count >= 0 ?
+         gs_prog_data->static_vertex_count : 0;
+
+      gs.VertexURBEntryReadOffset = 0;
+      gs.VertexURBEntryReadLength = gs_prog_data->base.urb_read_length;
+      gs.DispatchGRFStartRegisterForURBData =
+         gs_prog_data->base.base.dispatch_grf_start_reg;
+
+      gs.UserClipDistanceClipTestEnableBitmask =
+         gs_prog_data->base.clip_distance_mask;
+      gs.UserClipDistanceCullTestEnableBitmask =
+         gs_prog_data->base.cull_distance_mask;
 
 #if GFX_VERx10 >= 125
-   gs.ScratchSpaceBuffer =
-      get_scratch_surf(&pipeline->base.base, MESA_SHADER_GEOMETRY, gs_bin);
+      gs.ScratchSpaceBuffer =
+         get_scratch_surf(&pipeline->base.base, MESA_SHADER_GEOMETRY, gs_bin);
 #else
-   gs.PerThreadScratchSpace   = get_scratch_space(gs_bin);
-   gs.ScratchSpaceBasePointer =
-      get_scratch_address(&pipeline->base.base, MESA_SHADER_GEOMETRY, gs_bin);
+      gs.PerThreadScratchSpace   = get_scratch_space(gs_bin);
+      gs.ScratchSpaceBasePointer =
+         get_scratch_address(&pipeline->base.base, MESA_SHADER_GEOMETRY, gs_bin);
 #endif
+   }
 
    GENX(3DSTATE_GS_pack)(&pipeline->base.base.batch, pipeline->gfx8.gs, &gs);
 }
index c4c4b32..0b46c37 100644 (file)
@@ -281,6 +281,40 @@ genX(cmd_emit_te)(struct anv_cmd_buffer *cmd_buffer)
 }
 
 static void
+genX(emit_gs)(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
+   if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) {
+      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_GS), gs);
+      return;
+   }
+
+   uint32_t dwords[GENX(3DSTATE_GS_length)];
+   const struct vk_dynamic_graphics_state *dyn =
+      &cmd_buffer->vk.dynamic_graphics_state;
+
+   struct GENX(3DSTATE_GS) gs = {
+      GENX(3DSTATE_GS_header),
+   };
+
+   switch (dyn->rs.provoking_vertex) {
+   case VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT:
+      gs.ReorderMode = LEADING;
+      break;
+
+   case VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT:
+      gs.ReorderMode = TRAILING;
+      break;
+
+   default:
+      unreachable("Invalid provoking vertex mode");
+   }
+
+   GENX(3DSTATE_GS_pack)(NULL, dwords, &gs);
+   anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx8.gs);
+}
+
+static void
 genX(cmd_emit_sample_mask)(struct anv_cmd_buffer *cmd_buffer)
 {
    const struct vk_dynamic_graphics_state *dyn =
@@ -453,6 +487,11 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
       genX(cmd_emit_te)(cmd_buffer);
    }
 
+   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
+       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX)) {
+      genX(emit_gs)(cmd_buffer);
+   }
+
 #if GFX_VER >= 11
    if (cmd_buffer->device->vk.enabled_extensions.KHR_fragment_shading_rate &&
        (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE ||