This works around an issue introduced by commit
66cb2815f0. SV_PRIMITIVE_ID inputs in
geometry shaders use VKD3DSPR_PRIMID registers, and we create the
corresponding SPIR-V inputs using spirv_compiler_emit_io_register().
Unfortunately we also have an input signature element for the same
input, and simply creating another PrimitiveId input would run into
VUID-StandaloneSpirv-OpEntryPoint-09658.
Before the commit mentioned above, we'd use DCL_INPUT instructions to
emit input declarations, and these would help to distinguish whether
VKD3DSPR_INPUT or VKD3DSPR_PRIMID registers were used for primitive ID
inputs. Note that we can't simply ignore input signature element with
SIGNATURE_TARGET_LOCATION_UNUSED; the DXIL parser emits SV_SAMPLE_INDEX
inputs with that target location, but does require them to use a
VKD3DSPR_INPUT register.
The HLSL compiler already did this; the TPF and DXIL parsers did not.
Previously spirv_compiler_emit_sample_info() was unable to correctly
handle VSIR_DATA_U32 destinations; the new version is arguably simpler
as well.
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