tu: avoid incorrect pipeline draw state for disabled depth/stencil attachments
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Pipeline creation can generate draw state that will, depending on creation
state, assume enabled depth and stencil attachments. Later on, the pipeline
can be used in a render pass that disables those attachments, while the
draw state will still be emitting as if those attachments are present and
usable. Specifically, this affects pairings of depth attachments and
TU_DYNAMIC_STATE_RB_DEPTH_CNTL, and of stencil attachments and
TU_DYNAMIC_STATE_DS.

When a pipeline is bound, ignore its set depth/stencil state if that state
was enabled and the pipeline is either bound outside of a render pass or
inside a render pass that disables the relevant attachment. This way the
depth/stencil state will be treated as dynamic and will be recomputed and
emitted during the draw state emission, taking into account the available
attachments inside the render pass.

Fixes: dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil

Signed-off-by: Zan Dobersek <zdobersek@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39323>
This commit is contained in:
Zan Dobersek 2026-01-15 09:50:36 +01:00 committed by Marge Bot
parent 3cb4776ede
commit 5a3b0ce461
5 changed files with 26 additions and 12 deletions

View file

@ -300,7 +300,6 @@ dEQP-VK.renderpasses.dynamic_rendering.partial_secondary_cmd_buff.fragment_densi
dEQP-VK.renderpasses.dynamic_rendering.partial_secondary_cmd_buff.fragment_density_map.offset.oversized_fdm.vert_offset_negative,Fail
dEQP-VK.renderpasses.dynamic_rendering.partial_secondary_cmd_buff.fragment_density_map.offset.oversized_fdm.vert_offset_negative_suspend_resume_extra_large,Fail
dEQP-VK.renderpasses.dynamic_rendering.partial_secondary_cmd_buff.fragment_density_map.offset.oversized_fdm.vert_offset_negative_suspend_resume,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.fragment_density_map.offset.clamp_to_edge.hor_offset_negative,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.fragment_density_map.offset.clamp_to_edge.hor_offset_negative_multiview,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.fragment_density_map.offset.clamp_to_edge.hor_offset_negative_multiview_suspend_resume,Fail
@ -341,7 +340,6 @@ dEQP-VK.renderpasses.renderpass2.fragment_density_map.offset.oversized_fdm.hor_o
dEQP-VK.renderpasses.renderpass2.fragment_density_map.offset.oversized_fdm.vert_offset_negative_extra_large,Fail
dEQP-VK.renderpasses.renderpass2.fragment_density_map.offset.oversized_fdm.vert_offset_negative,Fail
dEQP-VK.tessellation.misc_draw.tess_factor_barrier_bug,Crash
bypass-dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
gmem-dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency_and_usage,Fail
gmem-dEQP-VK.renderpasses.dynamic_rendering.complete_secondary_cmd_buff.fragment_density_map.offset.clamp_to_edge.vert_offset_negative,Fail
gmem-dEQP-VK.renderpasses.dynamic_rendering.complete_secondary_cmd_buff.fragment_density_map.offset.oversized_fdm.vert_offset_negative_suspend_resume,Fail

View file

@ -47,10 +47,7 @@ nobin-dEQP-VK.transform_feedback.simple.draw_indirect_multiview_counter_offset_1
dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency_and_usage,Fail
dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency,Fail
dEQP-VK.pipeline.monolithic.misc.identically_defined_layout,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
dEQP-VK.tessellation.misc_draw.tess_factor_barrier_bug,Crash
bypass-dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
gmem-dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
gmem-dEQP-VK.transform_feedback.simple.draw_indirect_counter_offset_16,Fail
gmem-dEQP-VK.transform_feedback.simple.draw_indirect_multiview_counter_offset_508,Fail
gmem-dEQP-VK.transform_feedback.simple_fast_gpl.draw_indirect_counter_offset_244,Fail

View file

@ -32,7 +32,6 @@ dynamic-dEQP-VK.renderpass2.depth_stencil_resolve.image_2d_32_32.samples_2.d32_s
dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency_and_usage,Fail
dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency,Fail
dEQP-VK.pipeline.monolithic.misc.identically_defined_layout,Fail
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.basic.partial_binding_depth_stencil,Fail
gmem-dEQP-VK.binding_model.descriptor_buffer.traditional_buffer.capture_replay.sparse_buffer_descriptor_data_consistency_and_usage,Fail

View file

@ -5575,15 +5575,26 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
cmd->state.bandwidth = pipeline->bandwidth;
cmd->state.pipeline_bandwidth = pipeline->bandwidth.valid;
struct tu_cs *cs = &cmd->draw_cs;
/* Ignore pipeline's enabled depth/stencil state if render pass doesn't provide
* depth/stencil attachments, or if pipeline was bound outside of renderpass.
* That way the correct state can be computed based on the presence of the
* relevant attachments.
*/
uint32_t set_state_mask = pipeline->set_state_mask;
if (cmd->vk.dynamic_graphics_state.ds.depth.test_enable &&
(!cmd->state.pass || !(cmd->state.vk_rp.attachments & MESA_VK_RP_ATTACHMENT_DEPTH_BIT)))
set_state_mask &= ~(1u << TU_DYNAMIC_STATE_RB_DEPTH_CNTL);
if (cmd->vk.dynamic_graphics_state.ds.stencil.test_enable &&
(!cmd->state.pass || !(cmd->state.vk_rp.attachments & MESA_VK_RP_ATTACHMENT_STENCIL_BIT)))
set_state_mask &= ~(1u << TU_DYNAMIC_STATE_DS);
/* note: this also avoids emitting draw states before renderpass clears,
* which may use the 3D clear path (for MSAA cases)
*/
if (!(cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE)) {
uint32_t mask = pipeline->set_state_mask;
struct tu_cs *cs = &cmd->draw_cs;
tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (10 + util_bitcount(mask)));
tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (10 + util_bitcount(set_state_mask)));
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_CONFIG, pipeline->program.config_state);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS, pipeline->program.vs_state);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_BINNING, pipeline->program.vs_binning_state);
@ -5595,12 +5606,12 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VPC, pipeline->program.vpc_state);
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_GMEM, pipeline->prim_order.state_gmem);
u_foreach_bit(i, mask)
u_foreach_bit(i, set_state_mask)
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i, pipeline->dynamic_state[i]);
}
cmd->state.pipeline_draw_states = pipeline->set_state_mask;
u_foreach_bit(i, pipeline->set_state_mask)
cmd->state.pipeline_draw_states = set_state_mask;
u_foreach_bit(i, set_state_mask)
cmd->state.dynamic_state[i] = pipeline->dynamic_state[i];
if (pipeline->shaders[MESA_SHADER_FRAGMENT]->fs.has_fdm !=

View file

@ -4045,6 +4045,15 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder,
/* Vertex buffer state needs to know the max valid binding */
BITSET_SET(keep, MESA_VK_DYNAMIC_VI_BINDINGS_VALID);
/* We might re-emit TU_DYNAMIC_STATE_DS or TU_DYNAMIC_STATE_RB_DEPTH_CNTL
* depending on render pass attachments. Some of these overlap with the
* state needed by LRZ above.
*/
for (unsigned i = 0; i < ARRAY_SIZE(tu_ds_state); i++)
BITSET_SET(keep, tu_ds_state[i]);
for (unsigned i = 0; i < ARRAY_SIZE(tu_rb_depth_cntl_state); i++)
BITSET_SET(keep, tu_rb_depth_cntl_state[i]);
/* Remove state which has been emitted and we no longer need to set when
* binding the pipeline by making it "dynamic".
*/