From 8eebc71c133ca641ad98248f8d2c5649b387ad22 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 2 Sep 2025 22:01:26 +0200 Subject: [PATCH] vkd3d-shader/ir: Require signed operands for IMAX instructions. --- libs/vkd3d-shader/dxil.c | 15 ++++++++++----- libs/vkd3d-shader/ir.c | 14 +++++++++++++- tests/hlsl/abs.shader_test | 4 ++-- tests/hlsl/arithmetic-int-uniform.shader_test | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index fbbcbbdac..c1b604491 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -4975,8 +4975,11 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o instruction_dst_param_init_ssa_scalar(ins, 0, sm6); } -static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, const struct sm6_type *type) +static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, + const struct sm6_type *type, uint32_t *type_flags) { + *type_flags = 0; + switch (op) { case DX_FMAX: @@ -4984,6 +4987,7 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co case DX_FMIN: return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN; case DX_IMAX: + *type_flags |= DXIL_TYPE_SIGNED; return VSIR_OP_IMAX; case DX_IMIN: return VSIR_OP_IMIN; @@ -5005,14 +5009,15 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ { struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_params; + uint32_t type_flags; - vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); + vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type, &type_flags)); if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], operands[0], 0, sm6); - src_param_init_from_value(&src_params[1], operands[1], 0, sm6); + src_param_init_from_value(&src_params[0], operands[0], type_flags, sm6); + src_param_init_from_value(&src_params[1], operands[1], type_flags, sm6); - instruction_dst_param_init_ssa_scalar(ins, 0, sm6); + instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6); } static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 73792684f..3764464fd 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -11307,6 +11307,18 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex vsir_validate_elementwise_operation(ctx, instruction, types); } +static void vsir_validate_signed_integer_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_I64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { @@ -12385,7 +12397,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ [VSIR_OP_IGE] = {1, 2, vsir_validate_signed_integer_comparison_operation}, [VSIR_OP_ILT] = {1, 2, vsir_validate_signed_integer_comparison_operation}, [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, - [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IMAX] = {1, 2, vsir_validate_signed_integer_elementwise_operation}, [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation}, [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, diff --git a/tests/hlsl/abs.shader_test b/tests/hlsl/abs.shader_test index 0618f3432..bde566795 100644 --- a/tests/hlsl/abs.shader_test +++ b/tests/hlsl/abs.shader_test @@ -26,10 +26,10 @@ float4 main() : sv_target [test] uniform 0 float 2.0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(2, 8, 3, 1) +probe (0, 0) f32(2, 8, 3, 1) uniform 0 float -1.0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(1, 8, 3, 1) +probe (0, 0) f32(1, 8, 3, 1) [pixel shader] uniform float4 u; diff --git a/tests/hlsl/arithmetic-int-uniform.shader_test b/tests/hlsl/arithmetic-int-uniform.shader_test index 4770f5468..a664356a6 100644 --- a/tests/hlsl/arithmetic-int-uniform.shader_test +++ b/tests/hlsl/arithmetic-int-uniform.shader_test @@ -99,7 +99,7 @@ float4 main() : SV_TARGET [test] uniform 0 float4 5.0 -7.0 0.0 -10.0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(5.0, 7.0, 0.0, 10.0) +probe (0, 0) f32(5.0, 7.0, 0.0, 10.0) [pixel shader] uniform float4 a;