anv: emit 3DSTATE_GS only once per pipeline

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>
This commit is contained in:
Lionel Landwerlin 2023-08-02 09:30:05 +03:00 committed by Marge Bot
parent 8689791e1f
commit cf5ee0a0f7
3 changed files with 78 additions and 80 deletions

View file

@ -3372,38 +3372,6 @@ genX(emit_ds)(struct anv_cmd_buffer *cmd_buffer)
#endif
}
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)
{
@ -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 &

View 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.Enable = true;
gs.StatisticsEnable = true;
gs.KernelStartPointer = gs_bin->kernel.offset;
gs.DispatchMode = gs_prog_data->base.dispatch_mode;
gs.MaximumNumberofThreads = devinfo->max_gs_threads - 1;
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.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.MaximumNumberofThreads = devinfo->max_gs_threads - 1;
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.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.VertexURBEntryReadOffset = 0;
gs.VertexURBEntryReadLength = gs_prog_data->base.urb_read_length;
gs.DispatchGRFStartRegisterForURBData =
gs_prog_data->base.base.dispatch_grf_start_reg;
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.UserClipDistanceClipTestEnableBitmask =
gs_prog_data->base.clip_distance_mask;
gs.UserClipDistanceCullTestEnableBitmask =
gs_prog_data->base.cull_distance_mask;
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);
}

View file

@ -280,6 +280,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)
{
@ -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 ||