From 89641d3d421db60eb5c6091d31e268476457a8e3 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 2 Sep 2025 18:56:38 +0200 Subject: [PATCH] vkd3d-shader/ir: Require signed source operands for ITOF instructions. --- libs/vkd3d-shader/dxil.c | 43 +++++++++++------------ libs/vkd3d-shader/ir.c | 3 +- tests/hlsl/bitwise-assignment.shader_test | 2 +- tests/hlsl/cast-to-int.shader_test | 6 ++-- tests/hlsl/ceil.shader_test | 2 +- tests/hlsl/d3dcolor-to-ubyte4.shader_test | 4 +-- tests/hlsl/floor.shader_test | 2 +- tests/hlsl/function-cast.shader_test | 5 ++- tests/hlsl/ldexp.shader_test | 3 +- tests/hlsl/lerp.shader_test | 3 +- tests/hlsl/round.shader_test | 8 ++--- tests/hlsl/saturate.shader_test | 2 +- tests/hlsl/trunc.shader_test | 2 +- 13 files changed, 37 insertions(+), 48 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 5eaad54c5..44d2b8b11 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -6966,14 +6966,15 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); } -static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, - const struct sm6_type *to, struct sm6_parser *sm6) +static enum vkd3d_shader_opcode dxil_map_cast_op(uint64_t code, const struct sm6_type *from, + uint32_t *src_type_flags, const struct sm6_type *to, struct sm6_parser *dxil) { enum vkd3d_shader_opcode op = VSIR_OP_INVALID; bool from_int, to_int, from_fp, to_fp; unsigned int from_width, to_width; bool is_valid = false; + *src_type_flags = 0; from_int = sm6_type_is_integer(from); to_int = sm6_type_is_integer(to); from_fp = sm6_type_is_floating_point(from); @@ -6982,15 +6983,13 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ /* NOTE: DXIL currently doesn't use vectors here. */ if ((!from_int && !from_fp) || (!to_int && !to_fp)) { - FIXME("Unhandled cast of type class %u to type class %u.\n", from->class, to->class); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast of type class %u to type class %u is not implemented.", from->class, to->class); return VSIR_OP_INVALID; } if (to->u.width == 8 || from->u.width == 8) { - FIXME("Unhandled 8-bit value.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast to/from an 8-bit type is not implemented."); return VSIR_OP_INVALID; } @@ -7030,6 +7029,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ case CAST_SITOFP: op = VSIR_OP_ITOF; is_valid = from_int && to_fp; + *src_type_flags |= DXIL_TYPE_SIGNED; break; case CAST_FPTRUNC: @@ -7048,16 +7048,14 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ break; default: - FIXME("Unhandled cast op %"PRIu64".\n", code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast operation %"PRIu64" is unhandled.", code); return VSIR_OP_INVALID; } if (!is_valid) { - FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.", code, from->class, from->u.width, to->class, to->u.width); return VSIR_OP_INVALID; @@ -7080,22 +7078,23 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ return op; } -static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_record *record, +static void sm6_parser_emit_cast(struct sm6_parser *dxil, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { struct vkd3d_shader_src_param *src_param; - enum vkd3d_shader_opcode handler_idx; const struct sm6_value *value; + enum vkd3d_shader_opcode op; const struct sm6_type *type; + uint32_t src_type_flags; unsigned int i = 0; - if (!(value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) + if (!(value = sm6_parser_get_value_by_ref(dxil, record, NULL, &i))) return; - if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6)) + if (!dxil_record_validate_operand_count(record, i + 2, i + 2, dxil)) return; - if (!(type = sm6_parser_get_type(sm6, record->operands[i++]))) + if (!(type = sm6_parser_get_type(dxil, record->operands[i++]))) return; dst->type = type; @@ -7108,28 +7107,28 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor return; } - if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VSIR_OP_INVALID) + if ((op = dxil_map_cast_op(record->operands[i], value->type, &src_type_flags, type, dxil)) == VSIR_OP_INVALID) return; - vsir_instruction_init(ins, &sm6->p.location, handler_idx); + vsir_instruction_init(ins, &dxil->p.location, op); - if (handler_idx == VSIR_OP_NOP) + if (op == VSIR_OP_NOP) { *dst = *value; dst->type = type; return; } - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + if (!(src_param = instruction_src_params_alloc(ins, 1, dxil))) return; - src_param_init_from_value(src_param, value, 0, sm6); + src_param_init_from_value(src_param, value, src_type_flags, dxil); - instruction_dst_param_init_ssa_scalar(ins, 0, sm6); + instruction_dst_param_init_ssa_scalar(ins, 0, dxil); /* VSIR bitcasts are represented by source registers with types different * from the types they were written with, rather than with different types * for the MOV source and destination. */ - if (handler_idx == VSIR_OP_MOV) + if (op == VSIR_OP_MOV) src_param->reg.data_type = ins->dst[0].reg.data_type; } diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 2c826050d..dbce702e9 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -11775,8 +11775,7 @@ static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3 { [VSIR_DATA_BOOL] = true, [VSIR_DATA_I32] = true, - [VSIR_DATA_U32] = true, - [VSIR_DATA_U64] = true, + [VSIR_DATA_I64] = true, }; static const bool dst_types[VSIR_DATA_TYPE_COUNT] = { diff --git a/tests/hlsl/bitwise-assignment.shader_test b/tests/hlsl/bitwise-assignment.shader_test index 4ad1d931e..27290eb93 100644 --- a/tests/hlsl/bitwise-assignment.shader_test +++ b/tests/hlsl/bitwise-assignment.shader_test @@ -73,7 +73,7 @@ float4 main() : SV_TARGET [test] uniform 0 uint4 2 0 0 0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(20, -48, 20, -48) +probe (0, 0) f32(20, -48, 20, -48) [pixel shader fail] % Make sure that bitshifts DON'T work with floats diff --git a/tests/hlsl/cast-to-int.shader_test b/tests/hlsl/cast-to-int.shader_test index 7e2687a1e..2f8b7b3e7 100644 --- a/tests/hlsl/cast-to-int.shader_test +++ b/tests/hlsl/cast-to-int.shader_test @@ -11,8 +11,7 @@ float4 main() : sv_target [test] uniform 0 float4 10.3 -11.6 12.8 13.1 draw quad -todo(msl & sm>=6) probe (0, 0) f32(10, -11, 12, 0) - +probe (0, 0) f32(10, -11, 12, 0) [vertex shader] uniform float4 f; @@ -32,8 +31,7 @@ float4 main(float4 t1 : TEXCOORD1) : sv_target [test] uniform 0 float4 -0.4 -0.7 -12.8 14.8 draw quad -todo(msl & sm>=6) probe (0, 0) f32(0, 0, -12, 14) - +probe (0, 0) f32(0, 0, -12, 14) [pixel shader] uniform float f; diff --git a/tests/hlsl/ceil.shader_test b/tests/hlsl/ceil.shader_test index b898f6907..05c901f5e 100644 --- a/tests/hlsl/ceil.shader_test +++ b/tests/hlsl/ceil.shader_test @@ -52,4 +52,4 @@ float4 main() : sv_target if(sm<4) uniform 0 float4 -1 6 7 3 if(sm>=4) uniform 0 int4 -1 6 7 3 draw quad -todo(msl & sm>=6) probe (0, 0) f32(6.0, 7.0, -1.0, 3.0) 4 +probe (0, 0) f32(6.0, 7.0, -1.0, 3.0) 4 diff --git a/tests/hlsl/d3dcolor-to-ubyte4.shader_test b/tests/hlsl/d3dcolor-to-ubyte4.shader_test index aa4e9fc4a..dfcbc14ea 100644 --- a/tests/hlsl/d3dcolor-to-ubyte4.shader_test +++ b/tests/hlsl/d3dcolor-to-ubyte4.shader_test @@ -12,7 +12,7 @@ float4 main() : sv_target [test] uniform 0 float4 -0.5 6.5 7.5 3.4 draw quad -todo(msl & sm>=6) probe (0, 0) f32(1912.0, 1657.0, -127.0, 867.0) 1 +probe (0, 0) f32(1912.0, 1657.0, -127.0, 867.0) 1 [pixel shader] uniform float4 u; @@ -25,4 +25,4 @@ float4 main() : sv_target [test] uniform 0 float4 -0.5 6.5 7.5 3.4 draw quad -todo(msl & sm>=6) probe (0, 0) f32(-127.0, -127.0, -127.0, -127.0) 1 +probe (0, 0) f32(-127.0, -127.0, -127.0, -127.0) 1 diff --git a/tests/hlsl/floor.shader_test b/tests/hlsl/floor.shader_test index d61305ad3..81c66c627 100644 --- a/tests/hlsl/floor.shader_test +++ b/tests/hlsl/floor.shader_test @@ -53,4 +53,4 @@ float4 main() : sv_target if(sm<4) uniform 0 float4 -1 6 7 3 if(sm>=4) uniform 0 int4 -1 6 7 3 draw quad -todo(msl & sm>=6) probe (0, 0) f32(6.0, 7.0, -1.0, 3.0) 4 +probe (0, 0) f32(6.0, 7.0, -1.0, 3.0) 4 diff --git a/tests/hlsl/function-cast.shader_test b/tests/hlsl/function-cast.shader_test index a939d43aa..14721a78b 100644 --- a/tests/hlsl/function-cast.shader_test +++ b/tests/hlsl/function-cast.shader_test @@ -19,7 +19,7 @@ float4 main() : sv_target [test] uniform 0 float4 -1.9 -1.0 2.9 4.0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(-1.0, -1.0, 2.0, 4.0) +probe (0, 0) f32(-1.0, -1.0, 2.0, 4.0) % As above, but cast "x" to float4 first. % In SM 6 a cast seems to implicitly promote the type to const, @@ -89,8 +89,7 @@ float4 main() : sv_target if(sm<4) uniform 0 float4 -2 0 1 -3000000 if(sm>=4) uniform 0 int4 -2 0 1 -3000000 draw quad -todo(msl & sm>=6) probe (0, 0) f32(-1.0, 0.0, 1.0, -3000000.0) 4 - +probe (0, 0) f32(-1.0, 0.0, 1.0, -3000000.0) 4 % An explicit cast gets applied right before assignment, as if it was on the lhs. [pixel shader fail(sm>=6)] diff --git a/tests/hlsl/ldexp.shader_test b/tests/hlsl/ldexp.shader_test index 498c6e447..ceacb9687 100644 --- a/tests/hlsl/ldexp.shader_test +++ b/tests/hlsl/ldexp.shader_test @@ -29,8 +29,7 @@ if(sm<4) uniform 4 float4 0 -10 10 100 if(sm>=4) uniform 0 int4 2 3 4 5 if(sm>=4) uniform 4 int4 0 -10 10 100 draw quad -todo(msl & sm>=6) probe (0, 0) f32(2.0, 0.00292968750, 4096.0, 6.33825300e+030) 2 - +probe (0, 0) f32(2.0, 0.00292968750, 4096.0, 6.33825300e+030) 2 [pixel shader] float4 main() : sv_target diff --git a/tests/hlsl/lerp.shader_test b/tests/hlsl/lerp.shader_test index 8c6da6978..c7eaaed67 100644 --- a/tests/hlsl/lerp.shader_test +++ b/tests/hlsl/lerp.shader_test @@ -34,8 +34,7 @@ if(sm>=4) uniform 0 int4 2 3 4 0 if(sm>=4) uniform 4 int4 0 -10 10 1000000 if(sm>=4) uniform 8 int4 0 1 -1 1000000 draw quad -todo(msl & sm>=6) probe (0, 0) f32(2.0, -10.0, -2.0, 1e12) 4 - +probe (0, 0) f32(2.0, -10.0, -2.0, 1e12) 4 [pixel shader] float4 main() : sv_target diff --git a/tests/hlsl/round.shader_test b/tests/hlsl/round.shader_test index 785354da3..c23580836 100644 --- a/tests/hlsl/round.shader_test +++ b/tests/hlsl/round.shader_test @@ -11,8 +11,6 @@ uniform 0 float4 -0.4 -6.6 7.6 3.4 draw quad probe (0, 0) rgba (0.0, -7.0, 8.0, 3.0) 4 - - [pixel shader] uniform float4 u; @@ -27,9 +25,7 @@ float4 main() : sv_target [test] uniform 0 float4 -0.4 -6.6 7.6 3.4 draw quad -todo(msl & sm>=6) probe (0, 0) f32(-7.0, 8.0, 0.0, 3.0) 4 - - +probe (0, 0) f32(-7.0, 8.0, 0.0, 3.0) 4 [pixel shader] uniform float4 u; @@ -43,7 +39,7 @@ float4 main() : sv_target [test] uniform 0 float4 -1 0 2 10 draw quad -todo(msl & sm>=6) probe (0, 0) f32(-1.0, 0.0, 2.0, 10.0) 4 +probe (0, 0) f32(-1.0, 0.0, 2.0, 10.0) 4 [pixel shader] float4 main() : sv_target diff --git a/tests/hlsl/saturate.shader_test b/tests/hlsl/saturate.shader_test index 4e764ca2b..28d2a1922 100644 --- a/tests/hlsl/saturate.shader_test +++ b/tests/hlsl/saturate.shader_test @@ -23,7 +23,7 @@ float4 main() : sv_target [test] uniform 0 float4 -2 0 2 -1 draw quad -todo(msl & sm>=6) probe (0, 0) f32(0.0, 0.0, 1.0, 0.0) +probe (0, 0) f32(0.0, 0.0, 1.0, 0.0) [pixel shader] uniform float4 u; diff --git a/tests/hlsl/trunc.shader_test b/tests/hlsl/trunc.shader_test index abcbfeee1..90edf1cc1 100644 --- a/tests/hlsl/trunc.shader_test +++ b/tests/hlsl/trunc.shader_test @@ -46,4 +46,4 @@ float4 main() : sv_target if(sm<4) uniform 0 float4 -1 6 7 3 if(sm>=4) uniform 0 int4 -1 6 7 3 draw quad -todo(msl & sm>=6) probe (0, 0) f32(6.0, 7.0, -1.0, 3.0) +probe (0, 0) f32(6.0, 7.0, -1.0, 3.0)