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
ca5bc63e5e 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 <v4:f32>, sr1 <s:f32>
        mov o2.x <v4:f32>, sr2 <s:f32> // 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 <v4:f32>, v0.xyzw <v4:f32>
        mov o1.x <v4:f32>, v0.x <v4:f32>
        mov o2.y <v4:f32>, v0.y <v4:f32> // 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.
This commit is contained in:
Francisco Casas
2025-10-17 02:51:04 -03:00
committed by Henri Verbeet
parent bc63aaf52d
commit 32b622d7a5
Notes: Henri Verbeet 2025-10-29 13:43:34 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1801
3 changed files with 7 additions and 11 deletions

View File

@@ -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]