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.
This commit is contained in:
Giovanni Mascellani 2025-01-21 12:01:13 +01:00 committed by Henri Verbeet
parent 4d18fb39b6
commit 343022cdc1
Notes: Henri Verbeet 2025-01-22 15:04:30 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1351
2 changed files with 57 additions and 2 deletions

View File

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

View File

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