From 343022cdc174b83b35c214580ae9bf052805c3d7 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Tue, 21 Jan 2025 12:01:13 +0100 Subject: [PATCH] vkd3d-shader/spirv: Interpret the write mask as a destination swizzle for double comparison operations. This fixes a failure on a shader in Wild hearts. --- libs/vkd3d-shader/spirv.c | 18 +++++++- .../hlsl/arithmetic-float-uniform.shader_test | 41 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 7bd59062..c8dc6de4 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -8193,6 +8193,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t src0_id, src1_id, type_id, result_id; + uint32_t write_mask = dst->write_mask; unsigned int component_count; SpvOp op; @@ -8223,8 +8224,21 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co component_count = vsir_write_mask_component_count(dst->write_mask); - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + switch (instruction->opcode) + { + case VKD3DSIH_DEQO: + case VKD3DSIH_DGEO: + case VKD3DSIH_DLT: + case VKD3DSIH_DNE: + write_mask = vkd3d_write_mask_from_component_count(component_count); + break; + + default: + break; + } + + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 4183642f..fad6323f 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -209,3 +209,44 @@ float4 main() : sv_target uniform 0 float4 0.2 0.3 9.1 3.2 draw quad probe (0, 0) rgba (0.4, 0.6, 18.2, 6.4) + +[rtv 0] +format r32g32b32a32-uint +size (2d, 640, 480) + +[pixel shader todo] +uniform double2 a, b, c, d; + +% Return bool4 to ensure that non-trivial destination swizzling happens on the +% DLT instruction, rather than on the instruction to convert the result. +bool4 main() : SV_TARGET +{ + bool2 first = a < b; + bool2 second = c < d; + return bool4(first.x, second.x, second.y, first.y); +} + +[test] +uniform 0 double2 1.0 3.0 +uniform 4 double2 2.0 4.0 +uniform 8 double2 5.0 7.0 +uniform 12 double2 6.0 8.0 +todo(sm<6) draw quad +if(sm<6) probe (0, 0) rgbaui(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff) +if(sm>=6) probe (0, 0) rgbaui(1, 1, 1, 1) + +uniform 0 double2 1.0 4.0 +uniform 4 double2 2.0 3.0 +uniform 8 double2 5.0 8.0 +uniform 12 double2 6.0 7.0 +todo(sm<6) draw quad +if(sm<6) probe (0, 0) rgbaui(0xffffffff, 0xffffffff, 0, 0) +if(sm>=6) probe (0, 0) rgbaui(1, 1, 0, 0) + +uniform 0 double2 1.0 4.0 +uniform 4 double2 2.0 3.0 +uniform 8 double2 6.0 7.0 +uniform 12 double2 5.0 8.0 +todo(sm<6) draw quad +if(sm<6) probe (0, 0) rgbaui(0xffffffff, 0, 0xffffffff, 0) +if(sm>=6) probe (0, 0) rgbaui(1, 0, 1, 0)