From 71ebd9b9d71d21da510c2acfb12fb5e34f3278b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Briano?= Date: Thu, 25 May 2023 12:19:58 -0700 Subject: [PATCH] anv,hasvk: respect provoking vertex setting on geometry shaders We need to set the right value on ReorderMode based on the provoking vertex mode, or the order in which the vertices for tristrip[_adj] are delivered to the geometry shader doesn't match what Vulkan expects. Fixes dEQP-VK.transform_feedback.primitives_generated_query.concurrent.*triangle_strip_with_adjacency* Reviewed-by: Kenneth Graunke Part-of: --- .../drivers/zink/ci/zink-anv-tgl-fails.txt | 6 -- src/intel/vulkan/anv_private.h | 1 + src/intel/vulkan/genX_cmd_buffer.c | 37 +++++++++ src/intel/vulkan/genX_pipeline.c | 78 ++++++++++--------- src/intel/vulkan_hasvk/genX_pipeline.c | 19 ++++- 5 files changed, 95 insertions(+), 46 deletions(-) diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt index e14d7494f45..0eca4d6d945 100644 --- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt @@ -181,12 +181,6 @@ spec@!opengl 2.1@polygon-stipple-fs,Fail spec@!opengl 3.0@clearbuffer-depth-cs-probe,Fail -spec@!opengl 3.2@gl-3.2-adj-prims cull-back pv-first,Fail -spec@!opengl 3.2@gl-3.2-adj-prims cull-front pv-first,Fail -spec@!opengl 3.2@gl-3.2-adj-prims line cull-back pv-first,Fail -spec@!opengl 3.2@gl-3.2-adj-prims line cull-front pv-first,Fail -spec@!opengl 3.2@gl-3.2-adj-prims pv-first,Fail - spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index,Fail spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index2,Fail spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-non-const-uniform-index,Fail diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e341a04bef7..75775848afd 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3543,6 +3543,7 @@ struct anv_graphics_pipeline { uint32_t streamout_state[5]; uint32_t hs[9]; uint32_t ds[11]; + uint32_t gs[10]; } gfx8; }; diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index c8e882a5160..7c317848f58 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3364,6 +3364,38 @@ 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) { @@ -3495,6 +3527,11 @@ 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 & diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 563a7da9c26..45327573422 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -1400,53 +1400,57 @@ emit_3dstate_gs(struct anv_graphics_pipeline *pipeline) const struct brw_gs_prog_data *gs_prog_data = get_gs_prog_data(pipeline); - anv_batch_emit(batch, GENX(3DSTATE_GS), gs) { - gs.Enable = true; - gs.StatisticsEnable = true; - gs.KernelStartPointer = gs_bin->kernel.offset; - gs.DispatchMode = gs_prog_data->base.dispatch_mode; + struct GENX(3DSTATE_GS) gs = { + GENX(3DSTATE_GS_header), + }; - 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 = TRAILING; + 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); } static bool diff --git a/src/intel/vulkan_hasvk/genX_pipeline.c b/src/intel/vulkan_hasvk/genX_pipeline.c index 2e236f694c5..5681c8a9a78 100644 --- a/src/intel/vulkan_hasvk/genX_pipeline.c +++ b/src/intel/vulkan_hasvk/genX_pipeline.c @@ -1462,7 +1462,8 @@ emit_3dstate_hs_te_ds(struct anv_graphics_pipeline *pipeline, } static void -emit_3dstate_gs(struct anv_graphics_pipeline *pipeline) +emit_3dstate_gs(struct anv_graphics_pipeline *pipeline, + const struct vk_rasterization_state *rs) { const struct intel_device_info *devinfo = pipeline->base.device->info; const struct anv_shader_bin *gs_bin = @@ -1500,7 +1501,19 @@ emit_3dstate_gs(struct anv_graphics_pipeline *pipeline) 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 = TRAILING; + + switch (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"); + } #if GFX_VER >= 8 gs.ExpectedVertexCount = gs_prog_data->vertices_in; @@ -1844,7 +1857,7 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_3dstate_vs(pipeline); emit_3dstate_hs_te_ds(pipeline, state->ts); - emit_3dstate_gs(pipeline); + emit_3dstate_gs(pipeline, state->rs); emit_3dstate_vf_statistics(pipeline);