diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index b2679beff..dc109ad8f 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -426,9 +426,6 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd case VKD3DSPSM_NEG: vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); break; - case VKD3DSPSM_ABS: - vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); - break; case VKD3DSPSM_ABSNEG: vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); break; @@ -1485,6 +1482,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, switch (ins->opcode) { + case VSIR_OP_ABS: + shader_glsl_intrinsic(gen, ins, "abs"); + break; case VSIR_OP_ADD: case VSIR_OP_IADD: shader_glsl_binop(gen, ins, "+"); diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 670f6c31c..b0b6d2c5a 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -2039,6 +2039,52 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr return VKD3D_OK; } +static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *program, + struct vsir_transformation_context *ctx) +{ + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it; + struct vkd3d_shader_instruction *ins, *new_ins; + unsigned int i; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + for (i = 0; i < ins->src_count; ++i) + { + struct vkd3d_shader_src_param *src = &ins->src[i]; + + /* TODO: support other modifiers, including destination modifiers. */ + if (src->modifiers == VKD3DSPSM_ABS) + { + if (!(new_ins = vsir_program_iterator_insert_before(&it, &new_it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + ins = vsir_program_iterator_current(&it); + + if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, VSIR_OP_ABS, 1, 1)) + { + vkd3d_shader_instruction_make_nop(new_ins); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + new_ins->src[0] = *src; + new_ins->src[0].modifiers = VKD3DSPSM_NONE; + + dst_param_init_ssa(&new_ins->dst[0], program->ssa_count, src->reg.data_type, src->reg.dimension); + src_param_init_ssa(src, program->ssa_count, src->reg.data_type, src->reg.dimension); + + if (data_type_is_64_bit(src->reg.data_type)) + { + new_ins->dst[0].write_mask = vsir_write_mask_64_from_32(new_ins->dst[0].write_mask); + src->swizzle = vsir_swizzle_64_from_32(src->swizzle); + } + + ++program->ssa_count; + } + } + } + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -11482,6 +11528,18 @@ static void vsir_validate_float_elementwise_operation(struct validation_context vsir_validate_elementwise_operation(ctx, instruction, types); } +static void vsir_validate_float_or_double_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { @@ -12534,7 +12592,7 @@ struct vsir_validator_instruction_desc static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = { - [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ABS] = {1, 1, vsir_validate_float_or_double_elementwise_operation}, [VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation}, [VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation}, [VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation}, @@ -13388,6 +13446,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t struct vsir_transformation_context ctx; vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + vsir_transform(&ctx, vsir_program_lower_modifiers); vsir_transform(&ctx, vsir_program_lower_instructions); if (program->shader_version.major >= 6) diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 8a89dcabd..9b4969a9b 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -609,9 +609,6 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m case VKD3DSPSM_NEG: vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); break; - case VKD3DSPSM_ABS: - vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); - break; case VKD3DSPSM_ABSNEG: vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); break; @@ -1472,6 +1469,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d switch (ins->opcode) { + case VSIR_OP_ABS: + msl_intrinsic(gen, ins, "abs"); + break; case VSIR_OP_ACOS: msl_intrinsic(gen, ins, "acos"); break; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 754842808..391b209ed 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4884,8 +4884,6 @@ static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler break; case VKD3DSPSM_NEG: return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); - case VKD3DSPSM_ABS: - return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); case VKD3DSPSM_ABSNEG: val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id);