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 <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23243>
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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 &
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user