From ada09d003d14f2684ee48e6d7d9ec15fdc8a9169 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Tue, 10 Jun 2025 19:32:54 +0200 Subject: [PATCH] vkd3d-shader/ir: Repurpose IDIV to compute plain signed division. It doesn't compute signed remainder any more. --- libs/vkd3d-shader/dxil.c | 2 +- libs/vkd3d-shader/ir.c | 1 - libs/vkd3d-shader/spirv.c | 12 +++++------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2b939ebc3..0ece32dd1 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -4638,7 +4638,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco dst->type = a->type; - if (handler_idx == VSIR_OP_UDIV || handler_idx == VSIR_OP_IDIV) + if (handler_idx == VSIR_OP_UDIV) { struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6); unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 23b3ac7dc..21633b656 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -8265,7 +8265,6 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh /* All of these instructions have fixed destinations—they can * in some cases be masked, but the destination cannot be * reallocated to a different set of components. */ - case VSIR_OP_IDIV: case VSIR_OP_IMUL: case VSIR_OP_SWAPC: case VSIR_OP_UDIV: diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 09b13b090..767f5d1e3 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -7534,6 +7534,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VSIR_OP_FREM, SpvOpFRem}, {VSIR_OP_FTOD, SpvOpFConvert}, {VSIR_OP_IADD, SpvOpIAdd}, + {VSIR_OP_IDIV, SpvOpSDiv}, {VSIR_OP_IMUL_LOW, SpvOpIMul}, {VSIR_OP_INEG, SpvOpSNegate}, {VSIR_OP_IREM, SpvOpSRem}, @@ -7670,6 +7671,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * so we have an explicit check. */ switch (instruction->opcode) { + case VSIR_OP_IDIV: case VSIR_OP_IREM: check_zero = true; break; @@ -8081,10 +8083,6 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; unsigned int component_count = 0; - SpvOp div_op, mod_op; - - div_op = instruction->opcode == VSIR_OP_IDIV ? SpvOpSDiv : SpvOpUDiv; - mod_op = instruction->opcode == VSIR_OP_IDIV ? SpvOpSRem : SpvOpUMod; if (dst[0].reg.type != VKD3DSPR_NULL) { @@ -8101,7 +8099,7 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, else uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpUDiv, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); @@ -8126,7 +8124,7 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); } - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpUMod, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); @@ -10680,6 +10678,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VSIR_OP_FREM: case VSIR_OP_FTOD: case VSIR_OP_IADD: + case VSIR_OP_IDIV: case VSIR_OP_IMUL_LOW: case VSIR_OP_INEG: case VSIR_OP_IREM: @@ -10749,7 +10748,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VSIR_OP_IMAD: spirv_compiler_emit_imad(compiler, instruction); break; - case VSIR_OP_IDIV: case VSIR_OP_UDIV: spirv_compiler_emit_int_div(compiler, instruction); break;