Commit Graph

415 Commits

Author SHA1 Message Date
Giovanni Mascellani
065430547c vkd3d-shader/dxil: Parse the gather offset as an int2.
Instead of an int3.

Gather operations expect an offset with only two components.
Currently the following field (which is the gather channel) is
parsed as a third component, which leads to wrong and invalid
results.

This fixes a crash on a shader from WRC Generations.
2025-11-12 15:08:42 +01:00
Henri Verbeet
9c6f8c8bd5 vkd3d-shader/dxil: Only add declared ICBs to the vsir program.
The input DXIL can sometimes contain constant arrays not referenced by the
resulting vsir program. It doesn't hurt much to generate ICBs for those
anyway, but it's a little pointless.
2025-10-29 13:27:33 +01:00
Francisco Casas
32b622d7a5 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.
2025-10-29 13:14:54 +01:00
Giovanni Mascellani
835044dd8e vkd3d-shader/ir: Introduce VSIR_OP_SATURATE to represent floating-point clamping to [0, 1]. 2025-10-14 15:53:26 +02:00
Henri Verbeet
c89fd93859 vkd3d-shader/ir: Require signed operands for IREM instructions. 2025-10-14 15:49:18 +02:00
Henri Verbeet
320bdd6759 vkd3d-shader/ir: Validate IDIV instructions. 2025-10-14 15:49:18 +02:00
Giovanni Mascellani
79736ae6ff vkd3d-shader/ir: Introduce VSIR_OP_NEG to represent floating-point negation. 2025-10-13 19:06:34 +02:00
Giovanni Mascellani
781bb10ed0 vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_emit_dcl_primitive_topology(). 2025-10-09 15:52:10 +02:00
Giovanni Mascellani
6a9147b66b vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_emit_dcl_count(). 2025-10-09 15:52:03 +02:00
Giovanni Mascellani
0a9fd13b25 vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in struct sm6_cmp_info. 2025-10-09 15:51:55 +02:00
Giovanni Mascellani
0a3d2f877d vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_emit_dx_dot(). 2025-10-09 15:51:48 +02:00
Giovanni Mascellani
00993b7fa9 vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_dcl_register_builtin(). 2025-10-09 15:51:40 +02:00
Giovanni Mascellani
ebb320346a vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_emit_dx_atomic_binop(). 2025-10-09 15:51:33 +02:00
Giovanni Mascellani
9779b62699 vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in instruction_init_with_resource(). 2025-10-09 15:51:25 +02:00
Giovanni Mascellani
39a9f0921c vkd3d-shader/dxil: Rename "handler_idx" to "opcode" in sm6_parser_emit_binop(). 2025-10-09 15:51:18 +02:00
Henri Verbeet
32a6967778 vkd3d-shader/dxil: Ignore ORDERING_SEQCST.
More recent versions of the Vulkan/SPIR-V validation layers have started
to complain about our usage of "SequentiallyConsistent" in our SPIR-V
output. Specifically, VUID-StandaloneSpirv-MemorySemantics-10866 "Memory
Semantics with SequentiallyConsistent memory order must not be used in
the Vulkan API".

The SPIR-V specification says: "If the declared memory model is Vulkan,
SequentiallyConsistent must not be used." However, we're using the
GLSL450 memory model with SPIR-V 1.3, and "Vulkan" is not available
before SPIR-V 1.5.

The Vulkan specification says "Sequentially consistent atomics and
barriers are not supported and SequentiallyConsistent is treated as
AcquireRelease. SequentiallyConsistent should not be used." in the
"Shader Memory Access Ordering" section.

Those don't quite add up to the "... must not be used in the Vulkan
API", from the validation layers, but it does seem clear that
SequentiallyConsistent isn't actually supported. On the DXIL side, when
targetting SPIR-V with dxc, the generated SPIR-V uses the
"None"/"Relaxed" memory semantics. I wasn't immediately able to find a
reference for what seq_cst is supposed to mean in the context of DXIL,
but "None"/"Relaxed" does seem consistent with how the HLSL
atomic/interlocked intrinsics are expected to behave, as well as with
our behaviour for tpf shaders.
2025-10-09 15:39:41 +02:00
Giovanni Mascellani
c0db7f7ff5 vkd3d-shader/dxil: Generate ABS instructions instead of using modifiers. 2025-10-08 13:30:17 +02:00
Conor McCarthy
2d508a2fa6 vkd3d-shader: Set the program block count to the maximum for any function.
The block count is intended to be used for allocation of block info.
2025-10-03 00:22:03 +02:00
Francisco Casas
da4d5ef339 vkd3d-shader/dxil: Get rid of sm6_parser_require_space().
It's not obvious what this last remaining use of
sm6_parser_require_space() is preallocating space for, and that's as
good of a reason as any to get rid of it.
2025-10-03 00:10:06 +02:00
Francisco Casas
03a58d74b9 vkd3d-shader/dxil: Don't preallocate instructions in sm6_function_emit_blocks(). 2025-10-02 23:53:32 +02:00
Francisco Casas
626ad24ffe vkd3d-shader/dxil: Don't preallocate instructions in sm6_parser_globals_init(). 2025-10-02 23:53:27 +02:00
Francisco Casas
f30141f086 vkd3d-shader/dxil: Propagate parser errors in sm6_parser_init(). 2025-10-02 23:52:19 +02:00
Francisco Casas
d774cde932 vkd3d-shader/dxil: Propagate the vkd3d_result of sm6_parser_declare_global(). 2025-10-02 23:49:28 +02:00
Francisco Casas
1512c6c809 vkd3d-shader/dxil: Set the parser status to VKD3D_ERROR_NOT_IMPLEMENTED on missing functionality. 2025-10-02 23:47:50 +02:00
Francisco Casas
aa943c51ea vkd3d-shader/dxil: Handle sm6_parser_add_instruction() returning NULL.
Only calls to sm6_parser_add_instruction() where we are using the
returned vkd3d_shader_instruction are checked for, since these return
values might cause NULL dereferences if unchecked.

Other calls to sm6_parser_add_instruction() can be left alone since the
error is still recorded via sm6->p.status.
2025-10-02 23:40:56 +02:00