vkd3d-shader/spirv: Use left-shifted writemasks for private variables for inputs.

One of the effects of I/O normalization, when it was introduced, was to shift
the writemask of all semantics to become 0-based—e.g., to convert .yz to .xy.
It did this by modifying the shader code, but did *not* modify the signature
masks.

The SPIR-V compiler, at the time, used both the write mask on the dcl_input
instruction and the signature masks. It also, due to the requirements of the
SPIR-V format, performed the same normalization, left-shifting each mask to
become zero-based. Despite this normalization now being performed earlier in
the aforementioned VSIR pass, the handling in the SPIR-V backend was never
removed.

When 66cb2815f0 was written, I either incorrectly
assumed that the signature mask was equal to the dcl_input write mask (at least,
in any well-formed shader), or (less likely) I noticed that the discrepancy
might exist but believed that the left-shifting normalization performed by the
spirv compiler covered all cases.

In either case it turns out there is one case where the difference was not
handled by the spirv compiler either. That is the case of a varying which has
a fixup function and therefore needs a private variable, which is currently true
for the SV_VertexID, SV_InstanceID, and SV_IsFrontFace varyings.

Thus, if one of those varyings has a signature mask other than .x, we currently
copy the SPIR-V builtin value to the relevant component of the private variable,
but subsequent code will load from the .x variable due to the normalization done
by shader_src_param_io_normalise().

This fixes a regression introduced by 66cb2815f0.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57433
This commit is contained in:
Elizabeth Figura
2025-07-17 19:17:28 -05:00
committed by Henri Verbeet
parent decc155cca
commit f0906e9c5c
Notes: Henri Verbeet 2025-07-22 17:20:01 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1628

View File

@@ -5718,15 +5718,15 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
{ {
component_type = builtin->component_type; component_type = builtin->component_type;
input_component_count = builtin->component_count; input_component_count = builtin->component_count;
component_idx = 0;
} }
else else
{ {
component_type = signature_element->component_type; component_type = signature_element->component_type;
input_component_count = vsir_write_mask_component_count(signature_element->mask); input_component_count = vsir_write_mask_component_count(signature_element->mask);
component_idx = vsir_write_mask_get_component_idx(signature_element->mask);
} }
component_idx = vsir_write_mask_get_component_idx(write_mask);
if (needs_private_io_variable(builtin)) if (needs_private_io_variable(builtin))
{ {
use_private_var = true; use_private_var = true;
@@ -5734,7 +5734,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
} }
else else
{ {
component_idx = vsir_write_mask_get_component_idx(write_mask);
reg_write_mask = write_mask >> component_idx; reg_write_mask = write_mask >> component_idx;
} }
@@ -5820,7 +5819,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
vkd3d_write_mask_from_component_count(input_component_count), vkd3d_write_mask_from_component_count(input_component_count),
VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx); VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx);
spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id); spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id);
} }
} }