From 32b622d7a5c8ac036416a05c92f826e172900f7b Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Fri, 17 Oct 2025 02:51:04 -0300 Subject: [PATCH] vkd3d-shader/dxil: Also map destination write masks for system values. Currently, on what we consider normalized vsir, destination write masks are not relative to the signature element's mask, even though source swizzles are. Also for most instructions, the source swizzles are masked by the destination write mask, as given by vsir_src_is_masked(). The DXIL parser however, is not derelativizing the destination write masks for system value signature elements, so we fix that to make it consistent with how other front-ends are handled. For instance, when the test introduced in commit ca5bc63e5e0e01fbf06979af788b82b0590fc6ba is compiled to DXIL using DXC, and then parsed using vkd3d-compiler, we get the following store instructions: vs_6_0 .input .param POSITION.xyzw, v0.xyzw, float .output .param SV_Position.xyzw, o0.xyzw, float, POS .param SV_CullDistance.x, o1.x, float, CULLDST .param SV_ClipDistance.y, o1.y, float, CLIPDST .descriptors .text label l1 ... mov o1.x , sr1 mov o2.x , sr2 // Note the .x write mask! ret whereas, when compiling using FXC and parsing the TPF using vkd3d-compiler we get: vs_4_0 .input .param POSITION.xyzw, v0.xyzw, float .output .param SV_POSITION.xyzw, o0.xyzw, float, POS .param SV_CULLDISTANCE.x, o1.x, float, CULLDST .param SV_CLIPDISTANCE.y, o1.y, float, CLIPDST .descriptors .text label l1 mov o0.xyzw , v0.xyzw mov o1.x , v0.x mov o2.y , v0.y // Note the .y write mask. ret This only really matters for cases where we have a system value semantic whose mask doesn't start at .x, which is very rare. For instance, it requires the clip/cull distance combo, which share registers, so one of them pushes the other to start on another component. According to the tests, the only thing relying on this behaviour is the handling of private variables for system value semantics on the SPIR-V backend, which expects destination write masks as if the element started at .x even though it might not. This is modified then. --- libs/vkd3d-shader/dxil.c | 3 +-- libs/vkd3d-shader/spirv.c | 7 ++----- tests/hlsl/clip-cull-distance.shader_test | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 7861efc16..4512a81cb 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -6299,8 +6299,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr return; } e = &signature->elements[row_index]; - if (!e->sysval_semantic) - column_index += vsir_write_mask_get_component_idx(e->mask); + column_index += vsir_write_mask_get_component_idx(e->mask); if (column_index >= VKD3D_VEC4_SIZE) { diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 490bbc612..2028c588d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5813,7 +5813,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element return; } - write_mask = e->mask >> vsir_write_mask_get_component_idx(e->mask); + write_mask = e->mask; *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); } @@ -6060,7 +6060,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, if (use_private_variable) { compiler->private_output_variable[element_idx] = var_id; - compiler->private_output_variable_write_mask[element_idx] |= write_mask >> component_idx; + compiler->private_output_variable_write_mask[element_idx] |= write_mask; if (!compiler->epilogue_function_id) compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder); } @@ -6112,9 +6112,6 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi use_mask |= element->used_mask; } } - index = vsir_write_mask_get_component_idx(output->mask); - dst_write_mask >>= index; - use_mask >>= index; write_mask &= dst_write_mask; if (!write_mask) diff --git a/tests/hlsl/clip-cull-distance.shader_test b/tests/hlsl/clip-cull-distance.shader_test index 9b33fe414..1254bab26 100644 --- a/tests/hlsl/clip-cull-distance.shader_test +++ b/tests/hlsl/clip-cull-distance.shader_test @@ -132,11 +132,11 @@ probe rtv 0 (160, 120) f32(0.0, 0.0, 0.0, 1.0) probe rtv 0 (160, 240) f32(0.0, 0.0, 0.0, 1.0) probe rtv 0 (160, 360) f32(0.0, 0.0, 0.0, 1.0) probe rtv 0 (320, 120) f32(1.0, 1.0, 1.0, 1.0) -todo(sm<6) probe rtv 0 (320, 240) f32(0.0, 0.0, 0.0, 1.0) -todo(sm<6) probe rtv 0 (320, 360) f32(0.0, 0.0, 0.0, 1.0) +probe rtv 0 (320, 240) f32(0.0, 0.0, 0.0, 1.0) +probe rtv 0 (320, 360) f32(0.0, 0.0, 0.0, 1.0) probe rtv 0 (480, 120) f32(1.0, 1.0, 1.0, 1.0) -todo(sm<6) probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0) -todo(sm<6) probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0) +probe rtv 0 (480, 240) f32(0.0, 0.0, 0.0, 1.0) +probe rtv 0 (480, 360) f32(0.0, 0.0, 0.0, 1.0) probe rtv 0 (320, 239) f32(1.0, 1.0, 1.0, 1.0) [require]