From 31581b000261d9df942c1eb24819a66070f586f1 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Tue, 10 Jun 2025 17:11:31 +0200 Subject: [PATCH] vkd3d-shader/ir: Lower IMUL and UMUL to IMUL_LOW. --- libs/vkd3d-shader/glsl.c | 34 ---------------------------------- libs/vkd3d-shader/ir.c | 24 ++++++++++++++++++++++++ libs/vkd3d-shader/msl.c | 35 ++--------------------------------- libs/vkd3d-shader/spirv.c | 28 ---------------------------- 4 files changed, 26 insertions(+), 95 deletions(-) diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index bf47474f3..40865d842 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -1250,37 +1250,6 @@ static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3 glsl_dst_cleanup(&dst, &gen->string_buffers); } -static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) -{ - struct glsl_src src[2]; - struct glsl_dst dst; - uint32_t mask; - - if (ins->dst[0].reg.type != VKD3DSPR_NULL) - { - /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */ - mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); - shader_glsl_print_assignment(gen, &dst, ""); - glsl_dst_cleanup(&dst, &gen->string_buffers); - - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled 64-bit integer multiplication."); - } - - if (ins->dst[1].reg.type != VKD3DSPR_NULL) - { - mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]); - glsl_src_init(&src[0], gen, &ins->src[0], mask); - glsl_src_init(&src[1], gen, &ins->src[1], mask); - - shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); - - glsl_src_cleanup(&src[1], &gen->string_buffers); - glsl_src_cleanup(&src[0], &gen->string_buffers); - glsl_dst_cleanup(&dst, &gen->string_buffers); - } -} - static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) { @@ -1584,9 +1553,6 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VKD3DSIH_UMIN: shader_glsl_intrinsic(gen, ins, "min"); break; - case VKD3DSIH_IMUL: - shader_glsl_mul_extended(gen, ins); - break; case VKD3DSIH_IMUL_LOW: shader_glsl_binop(gen, ins, "*"); break; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 7d56c0c1e..503c4a604 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1146,6 +1146,24 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro return VKD3D_OK; } +static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, + struct vkd3d_shader_instruction *imul, struct vsir_transformation_context *ctx) +{ + if (imul->dst[0].reg.type != VKD3DSPR_NULL) + { + vkd3d_shader_error(ctx->message_context, &imul->location, + VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Extended multiplication is not implemented."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + imul->dst[0] = imul->dst[1]; + imul->dst_count = 1; + imul->opcode = VKD3DSIH_IMUL_LOW; + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, struct vkd3d_shader_instruction *sincos) { @@ -1526,6 +1544,12 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr vkd3d_shader_instruction_make_nop(ins); break; + case VKD3DSIH_IMUL: + case VKD3DSIH_UMUL: + if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) + return ret; + break; + case VKD3DSIH_SINCOS: if (ins->dst_count == 1) { diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index ac9f7412d..ad6c278a9 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -1191,37 +1191,6 @@ static void msl_movc(struct msl_generator *gen, const struct vkd3d_shader_instru msl_dst_cleanup(&dst, &gen->string_buffers); } -static void msl_mul64(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) -{ - struct msl_src src[2]; - struct msl_dst dst; - uint32_t mask; - - if (ins->dst[0].reg.type != VKD3DSPR_NULL) - { - /* TODO: mulhi(). */ - mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); - msl_print_assignment(gen, &dst, ""); - msl_dst_cleanup(&dst, &gen->string_buffers); - - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled 64-bit integer multiplication."); - } - - if (ins->dst[1].reg.type != VKD3DSPR_NULL) - { - mask = msl_dst_init(&dst, gen, ins, &ins->dst[1]); - msl_src_init(&src[0], gen, &ins->src[0], mask); - msl_src_init(&src[1], gen, &ins->src[1], mask); - - msl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); - - msl_src_cleanup(&src[1], &gen->string_buffers); - msl_src_cleanup(&src[0], &gen->string_buffers); - msl_dst_cleanup(&dst, &gen->string_buffers); - } -} - static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { msl_print_indent(gen->buffer, gen->indent); @@ -1337,8 +1306,8 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_MIN: msl_intrinsic(gen, ins, "min"); break; - case VKD3DSIH_IMUL: - msl_mul64(gen, ins); + case VKD3DSIH_IMUL_LOW: + msl_binop(gen, ins, "*"); break; case VKD3DSIH_INE: case VKD3DSIH_NEU: diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index dd4c9743d..7bcd43e24 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -8020,30 +8020,6 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void spirv_compiler_emit_imul(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) -{ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, val_id, src0_id, src1_id; - - if (dst[0].reg.type != VKD3DSPR_NULL) - FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended/SpvOpUMulExtended */ - - if (dst[1].reg.type == VKD3DSPR_NULL) - return; - - type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); - - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); - - val_id = vkd3d_spirv_build_op_imul(builder, type_id, src0_id, src1_id); - - spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); -} - static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -10737,10 +10713,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_RCP: spirv_compiler_emit_rcp(compiler, instruction); break; - case VKD3DSIH_IMUL: - case VKD3DSIH_UMUL: - spirv_compiler_emit_imul(compiler, instruction); - break; case VKD3DSIH_IMAD: spirv_compiler_emit_imad(compiler, instruction); break;