anv: move 3DSTATE_CLIP emission to dynamic path

This instruction has a bunch of fixed fields and the rest depends on
the shader stages enabled. With the pipeline object going away, we
can't keep this on the pipeline.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36665>
This commit is contained in:
Lionel Landwerlin
2025-03-31 13:58:18 +03:00
committed by Marge Bot
parent c8305dfe0e
commit 5a8e295a97
4 changed files with 54 additions and 72 deletions
-1
View File
@@ -562,7 +562,6 @@ anv_cmd_buffer_flush_pipeline_hw_state(struct anv_cmd_buffer *cmd_buffer,
diff_fix_state(HS, final.hs);
diff_fix_state(DS, final.ds);
diff_fix_state(CLIP, partial.clip);
diff_fix_state(WM, partial.wm);
diff_fix_state(STREAMOUT, partial.so);
diff_fix_state(GS, partial.gs);
+2 -1
View File
@@ -1659,6 +1659,8 @@ struct anv_gfx_dynamic_state {
uint32_t LineStripListProvokingVertexSelect;
uint32_t TriangleFanProvokingVertexSelect;
uint32_t TriangleStripOddProvokingVertexSelect;
bool ForceZeroRTAIndexEnable;
uint32_t NonPerspectiveBarycentricEnable;
} clip;
/* 3DSTATE_COARSE_PIXEL */
@@ -5204,7 +5206,6 @@ struct anv_graphics_pipeline {
* with dynamic state.
*/
struct {
struct anv_gfx_state_ptr clip;
struct anv_gfx_state_ptr ps_extra;
struct anv_gfx_state_ptr wm;
struct anv_gfx_state_ptr so;
+43 -2
View File
@@ -1470,6 +1470,29 @@ update_clip_raster(struct anv_gfx_dynamic_state *hw_state,
#endif
}
ALWAYS_INLINE static void
update_clip_preraster_stages(struct anv_gfx_dynamic_state *hw_state,
const struct anv_cmd_graphics_state *gfx)
{
const bool layer_written =
anv_gfx_has_stage(gfx, MESA_SHADER_MESH) ?
get_gfx_mesh_prog_data(gfx)->map.per_primitive_offsets[VARYING_SLOT_LAYER] >= 0 :
(get_gfx_last_vue_map(gfx)->slots_valid & VARYING_BIT_LAYER);
SET(CLIP, clip.ForceZeroRTAIndexEnable, !layer_written);
}
ALWAYS_INLINE static void
update_clip_non_perspective_barycentrics(struct anv_gfx_dynamic_state *hw_state,
const struct anv_cmd_graphics_state *gfx)
{
const struct brw_wm_prog_data *wm_prog_data = get_gfx_wm_prog_data(gfx);
SET(CLIP, clip.NonPerspectiveBarycentricEnable,
wm_prog_data ?
wm_prog_data->uses_nonperspective_interp_modes : 0);
}
ALWAYS_INLINE static void
update_multisample(struct anv_gfx_dynamic_state *hw_state,
const struct vk_dynamic_graphics_state *dyn)
@@ -2239,6 +2262,12 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_gfx_dynamic_state *hw_state,
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CONSERVATIVE_MODE))
update_clip_raster(hw_state, dyn, gfx);
if (gfx->dirty & ANV_CMD_DIRTY_PRERASTER_SHADERS)
update_clip_preraster_stages(hw_state, gfx);
if (gfx->dirty & ANV_CMD_DIRTY_PS)
update_clip_non_perspective_barycentrics(hw_state, gfx);
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES))
update_multisample(hw_state, dyn);
@@ -2844,8 +2873,18 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_CLIP)) {
anv_batch_emit_merge(&cmd_buffer->batch, GENX(3DSTATE_CLIP),
pipeline, partial.clip, clip) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CLIP), clip) {
clip.ClipEnable = true;
clip.StatisticsEnable = true;
clip.EarlyCullEnable = true;
clip.GuardbandClipTestEnable = true;
clip.VertexSubPixelPrecisionSelect = _8Bit;
clip.ClipMode = CLIPMODE_NORMAL;
clip.MinimumPointWidth = 0.125;
clip.MaximumPointWidth = 255.875;
SET(clip, clip, APIMode);
SET(clip, clip, ViewportXYClipTestEnable);
SET(clip, clip, TriangleStripListProvokingVertexSelect);
@@ -2855,6 +2894,8 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
SET(clip, clip, TriangleStripOddProvokingVertexSelect);
#endif
SET(clip, clip, MaximumVPIndex);
SET(clip, clip, ForceZeroRTAIndexEnable);
SET(clip, clip, NonPerspectiveBarycentricEnable);
}
}
+9 -68
View File
@@ -469,72 +469,6 @@ sbe_primitive_id_override(struct anv_graphics_pipeline *pipeline)
(fs_input_map->slots_valid & VARYING_BIT_PRIMITIVE_ID) == 0;
}
static void
emit_3dstate_clip(struct anv_graphics_pipeline *pipeline,
const struct vk_input_assembly_state *ia,
const struct vk_viewport_state *vp,
const struct vk_rasterization_state *rs)
{
const struct brw_wm_prog_data *wm_prog_data =
get_pipeline_wm_prog_data(pipeline);
(void) wm_prog_data;
anv_pipeline_emit(pipeline, partial.clip, GENX(3DSTATE_CLIP), clip) {
clip.ClipEnable = true;
clip.StatisticsEnable = true;
clip.EarlyCullEnable = true;
clip.GuardbandClipTestEnable = true;
clip.VertexSubPixelPrecisionSelect = _8Bit;
clip.ClipMode = CLIPMODE_NORMAL;
clip.MinimumPointWidth = 0.125;
clip.MaximumPointWidth = 255.875;
/* TODO(mesh): Multiview. */
if (anv_pipeline_is_primitive(pipeline)) {
const struct brw_vue_prog_data *last =
anv_pipeline_get_last_vue_prog_data(pipeline);
/* From the Vulkan 1.0.45 spec:
*
* "If the last active vertex processing stage shader entry point's
* interface does not include a variable decorated with Layer, then
* the first layer is used."
*/
clip.ForceZeroRTAIndexEnable =
!(last->vue_map.slots_valid & VARYING_BIT_LAYER);
} else if (anv_pipeline_is_mesh(pipeline)) {
const struct brw_mesh_prog_data *mesh_prog_data =
get_pipeline_mesh_prog_data(pipeline);
clip.ForceZeroRTAIndexEnable =
mesh_prog_data->map.per_primitive_offsets[VARYING_SLOT_LAYER] < 0;
}
clip.NonPerspectiveBarycentricEnable = wm_prog_data ?
wm_prog_data->uses_nonperspective_interp_modes : 0;
}
#if GFX_VERx10 >= 125
const struct anv_device *device = pipeline->base.base.device;
if (device->vk.enabled_extensions.EXT_mesh_shader) {
anv_pipeline_emit(pipeline, final.clip_mesh,
GENX(3DSTATE_CLIP_MESH), clip_mesh) {
if (!anv_pipeline_is_mesh(pipeline))
continue;
const struct brw_mesh_prog_data *mesh_prog_data =
get_pipeline_mesh_prog_data(pipeline);
clip_mesh.PrimitiveHeaderEnable = mesh_prog_data->map.has_per_primitive_header;
clip_mesh.UserClipDistanceClipTestEnableBitmask = mesh_prog_data->clip_distance_mask;
clip_mesh.UserClipDistanceCullTestEnableBitmask = mesh_prog_data->cull_distance_mask;
}
}
#endif
}
static void
emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline,
const struct vk_rasterization_state *rs)
@@ -1525,6 +1459,13 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline)
distrib.TaskDistributionBatchSize = devinfo->num_slices > 2 ? 4 : 9; /* 2^N thread groups */
distrib.MeshDistributionBatchSize = devinfo->num_slices > 2 ? 3 : 3; /* 2^N thread groups */
}
anv_pipeline_emit(pipeline, final.clip_mesh,
GENX(3DSTATE_CLIP_MESH), clip_mesh) {
clip_mesh.PrimitiveHeaderEnable = mesh_prog_data->map.has_per_primitive_header;
clip_mesh.UserClipDistanceClipTestEnableBitmask = mesh_prog_data->clip_distance_mask;
clip_mesh.UserClipDistanceCullTestEnableBitmask = mesh_prog_data->cull_distance_mask;
}
}
#endif
@@ -1534,8 +1475,6 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline,
{
compute_kill_pixel(pipeline, state->ms, state);
emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs);
#if GFX_VERx10 >= 125
bool needs_instance_granularity =
intel_needs_workaround(pipeline->base.base.device->info, 14019166699) &&
@@ -1594,6 +1533,8 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline,
GENX(3DSTATE_MESH_SHADER), zero);
anv_pipeline_emit(pipeline, final.mesh_distrib,
GENX(3DSTATE_MESH_DISTRIB), zero);
anv_pipeline_emit(pipeline, final.clip_mesh,
GENX(3DSTATE_CLIP_MESH), zero);
anv_pipeline_emit(pipeline, final.task_control,
GENX(3DSTATE_TASK_CONTROL), zero);
anv_pipeline_emit(pipeline, final.task_control_protected,