mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
microsoft/compiler: sink load_invocation_id in TCS split even for single-use
dxil_nir_split_tess_ctrl sinks load_invocation_id into per-use local loads before wrapping the pre-barrier region in a loop. That sinking was skipped when the load had only one use, on the assumption that duplication wasn't needed. The skip produces wrong code when the single use is on the opposite side of the barrier from the load — e.g. HLSL-style TCS with a post- barrier `if (InvocationId == 0)` patch-constant gate. The load gets wrapped into the loop but the use stays outside, and after SSA repair the use sees the counter's post-loop value (== tcs_vertices_out), making the gate fold to false. opt_dead_cf then strips the patch- constant stores inside the gate body, producing an empty PatchConstantFunc and zero tess factors at runtime. Dropping the list_is_singular skip moves the single-use load right before its use, letting the existing pre/post-barrier handling wrap each region correctly. Multi-use loads still get one local load per use as before. Assisted-by: Claude Opus 4.7 <noreply@anthropic.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41028>
This commit is contained in:
parent
b7f9974f3e
commit
1262600f0f
1 changed files with 6 additions and 5 deletions
|
|
@ -214,9 +214,11 @@ dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func)
|
|||
* will run sequentially. Then a loop is inserted so load_invocation_id will load the
|
||||
* loop counter. This loop continues until a barrier is reached, when the loop
|
||||
* is closed and the process begins again.
|
||||
*
|
||||
* First, sink load_invocation_id so that it's present on both sides of barriers.
|
||||
* Each use gets a unique load of the invocation ID.
|
||||
*
|
||||
* First, sink load_invocation_id so that each use has its own local load.
|
||||
* This ensures the load sits in the same pre/post-barrier region as its
|
||||
* use, which the loop-wrapping pass below relies on — even for single-use
|
||||
* loads whose use sits across a barrier.
|
||||
*/
|
||||
nir_builder b = nir_builder_create(patch_const_func_impl);
|
||||
nir_foreach_block(block, patch_const_func_impl) {
|
||||
|
|
@ -225,8 +227,7 @@ dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func)
|
|||
continue;
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_load_invocation_id ||
|
||||
list_is_empty(&intr->def.uses) ||
|
||||
list_is_singular(&intr->def.uses))
|
||||
list_is_empty(&intr->def.uses))
|
||||
continue;
|
||||
nir_foreach_use_including_if_safe(src, &intr->def) {
|
||||
b.cursor = nir_before_src(src);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue