From 65b2564bc2e373169e5de6198d42600dd8a44273 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 30 Oct 2025 06:55:00 +1100 Subject: [PATCH] Updated vkd3d to d3f658d410c42d739bdb3513bfdbd3f4e787c528. --- libs/vkd3d/include/vkd3d_shader.h | 77 ++++++ libs/vkd3d/libs/vkd3d-shader/glsl.c | 1 + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 6 + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 11 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 25 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 172 ++++---------- .../libs/vkd3d-shader/hlsl_constant_ops.c | 66 ++---- libs/vkd3d/libs/vkd3d-shader/ir.c | 223 ++++++++++++++++-- libs/vkd3d/libs/vkd3d-shader/msl.c | 216 ++++++----------- libs/vkd3d/libs/vkd3d-shader/spirv.c | 9 +- .../libs/vkd3d-shader/vkd3d_shader_main.c | 2 - .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 12 files changed, 451 insertions(+), 358 deletions(-) diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index df1f5d5250d..50bcf6b292b 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -961,6 +961,83 @@ enum vkd3d_shader_parameter_name * \since 1.15 */ VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE, + /** + * Bump-mapping matrix. This parameter is used in the evaluation of the + * Shader Model 1.x instructions BEM, TEXBEM, and TEXBEML. + * + * This parameter specifies a 2x2 matrix, packed into a vector in the order + * [00, 01, 10, 11], where "01" specifies the component at column 0 and row + * 1. These coordinates correspond to the Direct3D notation. + * + * To use this parameter to implement Direct3D bump mapping, pass the values + * of the texture stage states D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, + * D3DTSS_BUMPENVMAT10, and D3DTSS_BUMPENVMAT11, in that order. + * + * These enum values are contiguous and arithmetic may safely be performed + * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_[n] is + * VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 plus n. + * + * The data type for each parameter must be + * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4. + * + * The default value for each parameter is the zero matrix [0, 0; 0, 0]. + * + * \since 1.18 + */ + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0, + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_1, + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_2, + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_3, + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_4, + VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_5, + /** + * Bump-mapping luminance scale factor. This parameter is used in the + * evaluation of the Shader Model 1.x instruction TEXBEML. + * + * To use this parameter to implement Direct3D bump mapping, pass the value + * of the texture stage state D3DTSS_BUMPENVLSCALE. + * + * These enum values are contiguous and arithmetic may safely be performed + * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_[n] is + * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 plus n. + * + * The data type for each parameter must be + * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. + * + * The default value for each parameter is 0.0. + * + * \since 1.18 + */ + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_1, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_2, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_3, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_4, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_5, + /** + * Bump-mapping luminance offset. This parameter is used in the + * evaluation of the Shader Model 1.x instruction TEXBEML. + * + * To use this parameter to implement Direct3D bump mapping, pass the value + * of the texture stage state D3DTSS_BUMPENVLOFFSET. + * + * These enum values are contiguous and arithmetic may safely be performed + * on them. That is, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_[n] is + * VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 plus n. + * + * The data type for each parameter must be + * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32. + * + * The default value for each parameter is 0.0. + * + * \since 1.18 + */ + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_1, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_2, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_3, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_4, + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_5, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), }; diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index 073282db129..4d7505d8740 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -2482,6 +2482,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); VKD3D_ASSERT(program->has_descriptor_info); + VKD3D_ASSERT(program->has_no_modifiers); vkd3d_glsl_generator_init(&generator, program, compile_info, combined_sampler_info, message_context); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 3b0a7acb52a..1de17e2b551 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -1737,6 +1737,12 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t return &c->node; } +struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_constant(ctx, type, value, loc)); +} + struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) { struct hlsl_constant_value value; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 829fcba0aab..75027f83e33 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -1579,6 +1579,8 @@ struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hls enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); struct hlsl_ir_node *hlsl_block_add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *arg, struct hlsl_type *type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); @@ -1833,10 +1835,13 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block); -bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); -bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block); +struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block); bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); -bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block); bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), struct hlsl_block *block, void *context); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 759dadf8a58..8ec963c8656 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -3038,10 +3038,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, if (!param->default_values[j].string) { value.u[0] = param->default_values[j].number; - if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) - return NULL; - hlsl_block_add_instr(args->instrs, comp); - + comp = hlsl_block_add_constant(ctx, args->instrs, type, &value, loc); hlsl_block_add_store_component(ctx, args->instrs, ¶m_deref, j, comp); } } @@ -3956,7 +3953,6 @@ static bool intrinsic_firstbithigh(struct hlsl_ctx *ctx, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; struct hlsl_type *type = params->args[0]->data_type; struct hlsl_ir_node *c, *clz, *eq, *xor; - struct hlsl_constant_value v; if (hlsl_version_lt(ctx, 4, 0)) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, @@ -3978,20 +3974,14 @@ static bool intrinsic_firstbithigh(struct hlsl_ctx *ctx, if (hlsl_version_lt(ctx, 5, 0)) return add_expr(ctx, params->instrs, HLSL_OP1_FIND_MSB, operands, type, loc); - v.u[0].u = 0x1f; - if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) - return false; - hlsl_block_add_instr(params->instrs, c); + c = hlsl_block_add_uint_constant(ctx, params->instrs, 0x1f, loc); if (!(clz = add_expr(ctx, params->instrs, HLSL_OP1_CLZ, operands, type, loc))) return false; if (!(xor = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_BIT_XOR, c, clz, loc))) return false; - v.u[0].i = -1; - if (!(c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &v, loc))) - return false; - hlsl_block_add_instr(params->instrs, c); + c = hlsl_block_add_uint_constant(ctx, params->instrs, ~0u, loc); if (!(eq = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_EQUAL, clz, c, loc))) return false; @@ -4043,9 +4033,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) return false; - if (!(zero = hlsl_new_constant(ctx, div->data_type, &zero_value, loc))) - return false; - hlsl_block_add_instr(params->instrs, zero); + zero = hlsl_block_add_constant(ctx, params->instrs, div->data_type, &zero_value, loc); if (!(abs = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, div, loc))) return false; @@ -4641,9 +4629,8 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, struct hlsl_type *int_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_INT, arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy); - if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc))) - return false; - hlsl_block_add_instr(params->instrs, zero); + zero = hlsl_block_add_constant(ctx, params->instrs, + hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc); /* Check if 0 < arg, cast bool to int */ diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 8f4e4cda73f..9048214923b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -4058,9 +4058,7 @@ static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx value.u[1].u = 1; value.u[2].u = 2; value.u[3].u = 3; - if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, c); + c = hlsl_block_add_constant(ctx, block, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc); operands[0] = swizzle; operands[1] = c; @@ -4172,10 +4170,7 @@ static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx, if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc))) return NULL; - if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, zero); - + zero = hlsl_block_add_constant(ctx, block, instr->data_type, &zero_value, &instr->loc); hlsl_block_add_simple_store(ctx, block, var, zero); TRACE("Lowering non-constant %s load on variable '%s'.\n", row_major ? "row_major" : "array", deref->var->name); @@ -4540,17 +4535,13 @@ static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_nod struct hlsl_constant_value zero_value, one_value; memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, zero); + zero = hlsl_block_add_constant(ctx, block, arg->data_type, &zero_value, &instr->loc); one_value.u[0].f = 1.0; one_value.u[1].f = 1.0; one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); + one = hlsl_block_add_constant(ctx, block, arg->data_type, &one_value, &instr->loc); fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); @@ -4745,9 +4736,7 @@ static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_nod component_count = hlsl_type_component_count(type); for (i = 0; i < component_count; ++i) half_value.u[i].f = 0.5f; - if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) - return NULL; - hlsl_block_add_instr(block, half); + half = hlsl_block_add_constant(ctx, block, type, &half_value, &expr->node.loc); sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); @@ -4828,15 +4817,10 @@ static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node neg_pi_value.u[i].f = -M_PI; } - if (!(half = hlsl_new_constant(ctx, type, &half_value, &instr->loc)) - || !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc)) - || !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc)) - || !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, half); - hlsl_block_add_instr(block, two_pi); - hlsl_block_add_instr(block, reciprocal_two_pi); - hlsl_block_add_instr(block, neg_pi); + half = hlsl_block_add_constant(ctx, block, type, &half_value, &instr->loc); + two_pi = hlsl_block_add_constant(ctx, block, type, &two_pi_value, &instr->loc); + reciprocal_two_pi = hlsl_block_add_constant(ctx, block, type, &reciprocal_two_pi_value, &instr->loc); + neg_pi = hlsl_block_add_constant(ctx, block, type, &neg_pi_value, &instr->loc); if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) return NULL; @@ -4905,10 +4889,7 @@ static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir one_value.u[1].f = 1.0; one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); - + one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); memset(operands, 0, sizeof(operands)); @@ -5069,10 +5050,7 @@ static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, str one_value.u[1].f = 1.0; one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); - + one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, slt_neg); } @@ -5119,17 +5097,13 @@ static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg); memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, zero); + zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); one_value.u[0].f = 1.0; one_value.u[1].f = 1.0; one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); + one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one))) return NULL; @@ -5168,17 +5142,13 @@ static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node } memset(&zero_value, 0, sizeof(zero_value)); - if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, zero); + zero = hlsl_block_add_constant(ctx, block, float_type, &zero_value, &instr->loc); one_value.u[0].f = 1.0; one_value.u[1].f = 1.0; one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; - if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); + one = hlsl_block_add_constant(ctx, block, float_type, &one_value, &instr->loc); slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[2], slt); @@ -5210,11 +5180,7 @@ static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx, /* Narrowing casts should have already been lowered. */ VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx); - zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); - if (!zero) - return NULL; - hlsl_block_add_instr(block, zero); - + zero = hlsl_block_add_constant(ctx, block, arg_type, &zero_value, &instr->loc); neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); neq->data_type = expr->node.data_type; return neq; @@ -5267,10 +5233,7 @@ static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx, for (i = 0; i < type->e.numeric.dimx; ++i) high_bit_value.u[i].u = 0x80000000; - if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, high_bit); - + high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); @@ -5306,10 +5269,7 @@ static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx, for (i = 0; i < type->e.numeric.dimx; ++i) high_bit_value.u[i].u = 0x80000000; - if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, high_bit); - + high_bit = hlsl_block_add_constant(ctx, block, type, &high_bit_value, &instr->loc); and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); @@ -5418,10 +5378,7 @@ static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx, for (i = 0; i < type->e.numeric.dimx; ++i) one_value.u[i].f = 1.0f; - if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, one); - + one = hlsl_block_add_constant(ctx, block, type, &one_value, &instr->loc); div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); @@ -5447,9 +5404,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, hlsl_block_init(&block); arg_type = jump->condition.node->data_type; - if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc))) - return false; - hlsl_block_add_instr(&block, zero); + zero = hlsl_block_add_constant(ctx, &block, arg_type, &zero_value, &instr->loc); operands[0] = jump->condition.node; operands[1] = zero; @@ -5457,9 +5412,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, arg_type->e.numeric.dimx, arg_type->e.numeric.dimy); cmp = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LESS, operands, cmp_type, &instr->loc); - if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) - return false; - hlsl_block_add_instr(&block, bool_false); + bool_false = hlsl_block_add_constant(ctx, &block, + hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc); or = bool_false; @@ -8417,22 +8371,21 @@ static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, return NULL; } -static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static struct hlsl_ir_node *fold_conditional_identities(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; - struct hlsl_ir_node *res = NULL; struct hlsl_ir_expr *expr, *ec; - struct hlsl_block block; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; if (instr->data_type->class > HLSL_CLASS_VECTOR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP3_TERNARY) - return false; + return NULL; c = expr->operands[0].node; x = expr->operands[1].node; @@ -8440,74 +8393,45 @@ static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_nod VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); + /* c ? x : x -> x */ if (nodes_are_equivalent(x, y)) - { - /* c ? x : x -> x */ - hlsl_replace_node(instr, x); - return true; - } + return x; if (c->type == HLSL_IR_CONSTANT) { + /* false ? x : y -> y */ if (hlsl_constant_is_zero(hlsl_ir_constant(c))) - { - /* false ? x : y -> y */ - hlsl_replace_node(instr, y); - return true; - } + return y; + /* true ? x : y -> x */ if (hlsl_constant_is_one(hlsl_ir_constant(c))) - { - /* true ? x : y -> x */ - hlsl_replace_node(instr, x); - return true; - } + return x; } - hlsl_block_init(&block); - if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT && hlsl_types_are_equal(c->data_type, x->data_type) && hlsl_types_are_equal(c->data_type, y->data_type)) { + /* c ? true : false -> c */ if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) - { - /* c ? true : false -> c */ - res = c; - goto done; - } + return c; + /* c ? false : true -> !c */ if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) - { - /* c ? false : true -> !c */ - res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); - goto done; - } + return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); } + /* !c ? x : y -> c ? y : x */ ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; if (ec && ec->op == HLSL_OP1_LOGIC_NOT) - { - /* !c ? x : y -> c ? y : x */ - res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); - goto done; - } + return hlsl_add_conditional(ctx, block, ec->operands[0].node, y, x); - res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); - res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); + res_x = evaluate_conditionals_recurse(ctx, block, c, true, x, &instr->loc); + res_y = evaluate_conditionals_recurse(ctx, block, c, false, y, &instr->loc); if (res_x || res_y) - res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); + return hlsl_add_conditional(ctx, block, c, res_x ? res_x : x, res_y ? res_y : y); -done: - if (res) - { - list_move_before(&instr->entry, &block.instrs); - hlsl_replace_node(instr, res); - return true; - } - - hlsl_block_cleanup(&block); - return false; + return NULL; } static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) @@ -8516,12 +8440,12 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) do { - progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); + progress = replace_ir(ctx, hlsl_fold_constant_exprs, block); progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); + progress |= replace_ir(ctx, fold_conditional_identities, block); + progress |= replace_ir(ctx, hlsl_fold_constant_identities, block); + progress |= replace_ir(ctx, hlsl_fold_constant_swizzles, block); any_progress |= progress; } while (progress); @@ -14895,7 +14819,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v replace_ir(ctx, lower_int_modulus_sm1, body); replace_ir(ctx, lower_division, body); /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ - hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); + replace_ir(ctx, hlsl_fold_constant_exprs, body); replace_ir(ctx, lower_casts_to_bool, body); replace_ir(ctx, lower_casts_to_int, body); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c index 7b3b0470d5d..1c44e5fa37a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -1434,11 +1434,11 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c return true; } -bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +struct hlsl_ir_node *hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; struct hlsl_constant_value res = {0}; - struct hlsl_ir_node *res_node; struct hlsl_ir_expr *expr; unsigned int i; bool success; @@ -1638,36 +1638,32 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, } if (success) - { - if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &res, &instr->loc))) - return false; - list_add_before(&expr->node.entry, &res_node->entry); - hlsl_replace_node(&expr->node, res_node); - } - return success; + return hlsl_block_add_constant(ctx, block, instr->data_type, &res, &instr->loc); + + return NULL; } -bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +struct hlsl_ir_node *hlsl_fold_constant_identities(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { static const struct hlsl_constant_value zero; struct hlsl_ir_constant *const_arg = NULL; struct hlsl_ir_node *mut_arg = NULL; - struct hlsl_ir_node *res_node; struct hlsl_ir_expr *expr; unsigned int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (instr->data_type->class > HLSL_CLASS_VECTOR) - return false; + return NULL; /* Verify that the expression has two operands. */ for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) { if (!!expr->operands[i].node != (i < 2)) - return false; + return NULL; } if (expr->operands[0].node->type == HLSL_IR_CONSTANT) @@ -1682,34 +1678,33 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in } else { - return false; + return NULL; } - res_node = NULL; switch (expr->op) { case HLSL_OP2_ADD: if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; + return mut_arg; break; case HLSL_OP2_MUL: if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; + return mut_arg; break; case HLSL_OP2_LOGIC_AND: if (hlsl_constant_is_zero(const_arg)) - res_node = &const_arg->node; + return &const_arg->node; else if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; + return mut_arg; break; case HLSL_OP2_LOGIC_OR: if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; + return mut_arg; else if (hlsl_constant_is_one(const_arg)) - res_node = &const_arg->node; + return &const_arg->node; break; case HLSL_OP2_LESS: @@ -1718,21 +1713,13 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in || expr->operands[1].node->type != HLSL_IR_CONSTANT || !hlsl_constant_is_zero(hlsl_ir_constant(expr->operands[1].node))) break; - if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &zero, &instr->loc))) - break; - list_add_before(&expr->node.entry, &res_node->entry); - break; + return hlsl_block_add_constant(ctx, block, instr->data_type, &zero, &instr->loc); default: break; } - if (res_node) - { - hlsl_replace_node(&expr->node, res_node); - return true; - } - return false; + return NULL; } static bool is_op_associative(enum hlsl_ir_expr_op op, enum hlsl_base_type type) @@ -1961,28 +1948,23 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst return progress; } -bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_constant_value value; struct hlsl_ir_swizzle *swizzle; struct hlsl_ir_constant *src; - struct hlsl_ir_node *dst; unsigned int i; if (instr->type != HLSL_IR_SWIZZLE) - return false; + return NULL; swizzle = hlsl_ir_swizzle(instr); if (swizzle->val.node->type != HLSL_IR_CONSTANT) - return false; + return NULL; src = hlsl_ir_constant(swizzle->val.node); for (i = 0; i < swizzle->node.data_type->e.numeric.dimx; ++i) value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->u.vector, i)]; - if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc))) - return false; - - list_add_before(&swizzle->node.entry, &dst->entry); - hlsl_replace_node(&swizzle->node, dst); - return true; + return hlsl_block_add_constant(ctx, block, instr->data_type, &value, &instr->loc); } diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 000c78aeed3..a566d65d8cd 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -1987,7 +1987,7 @@ static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *progra unsigned int idx = ins->dst[0].reg.idx[0].offset; struct vkd3d_shader_src_param *srcs; - /* texcoord t# -> mov_sat t#, t# + /* texcoord t# -> saturate t#, t# * Note that the t# destination will subsequently be turned into a temp. */ /* We run before I/O normalization. */ @@ -2001,15 +2001,180 @@ static enum vkd3d_result vsir_program_lower_texcoord(struct vsir_program *progra srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ins->dst[0].modifiers |= VKD3DSPDM_SATURATE; - - ins->opcode = VSIR_OP_MOV; + ins->opcode = VSIR_OP_SATURATE; ins->src = srcs; ins->src_count = 1; return VKD3D_OK; } +static struct vkd3d_shader_instruction *generate_bump_coords(struct vsir_program *program, + struct vsir_program_iterator *it, uint32_t idx, const struct vkd3d_shader_src_param *coords, + const struct vkd3d_shader_src_param *perturbation, const struct vkd3d_shader_location *loc) +{ + struct vkd3d_shader_instruction *ins; + uint32_t ssa_temp, ssa_coords; + + /* We generate the following code: + * + * mad srTMP.xy, PERTURBATION.xx, BUMP_MATRIX#.xy, COORDS.xy + * mad srCOORDS.xy, PERTURBATION.yy, BUMP_MATRIX#.zw, srTMP.xy + */ + + ssa_temp = program->ssa_count++; + ssa_coords = program->ssa_count++; + + ins = vsir_program_iterator_current(it); + if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) + return false; + dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; + ins->src[0] = *perturbation; + ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(X, X, X, X)); + src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); + ins->src[2] = *coords; + + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAD, 1, 3)) + return false; + dst_param_init_ssa_float4(&ins->dst[0], ssa_coords); + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; + ins->src[0] = *perturbation; + ins->src[0].swizzle = vsir_combine_swizzles(perturbation->swizzle, VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y)); + src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_BUMP_MATRIX_0 + idx, VSIR_DATA_F32); + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(Z, W, W, W); + src_param_init_ssa_float4(&ins->src[2], ssa_temp); + ins->src[2].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); + + return ins; +} + +static enum vkd3d_result vsir_program_lower_bem(struct vsir_program *program, struct vsir_program_iterator *it) +{ + struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); + const struct vkd3d_shader_location location = ins->location; + const struct vkd3d_shader_src_param *src = ins->src; + const struct vkd3d_shader_dst_param *dst = ins->dst; + + /* bem DST.xy, SRC0, SRC1 + * -> + * mad srTMP.xy, SRC1.xx, BUMP_MATRIX#.xy, SRC0.xy + * mad DST.xy, SRC1.yy, BUMP_MATRIX#.zw, srTMP.xy */ + + if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + if (!(ins = generate_bump_coords(program, it, dst[0].reg.idx[0].offset, &src[0], &src[1], &location))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->dst[0] = dst[0]; + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, + struct vsir_program_iterator *it, struct vkd3d_shader_message_context *message_context) +{ + struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); + const struct vkd3d_shader_location location = ins->location; + const struct vkd3d_shader_descriptor_info1 *descriptor; + const struct vkd3d_shader_src_param *src = ins->src; + bool is_texbeml = (ins->opcode == VSIR_OP_TEXBEML); + unsigned int idx = ins->dst[0].reg.idx[0].offset; + uint32_t ssa_coords, ssa_luminance, ssa_sample; + struct vkd3d_shader_src_param orig_coords; + + /* texbem t#, SRC + * -> + * bem srCOORDS.xy, t#, SRC + * texld t#, srCOORDS + * -> + * mad srTMP.xy, SRC.xx, BUMP_MATRIX#.xy, t#.xy + * mad srCOORDS.xy, SRC.yy, BUMP_MATRIX#.zw, srTMP.xy + * sample t#, srCOORDS, resource#, sampler# + * + * Luminance then adds: + * + * mad srLUM.x, SRC.z, BUMP_LUMINANCE_SCALE#, BUMP_LUMINANCE_OFFSET# + * mul t#, t#, srLUM.xxxx + * + * Note that the t# destination will subsequently be turned into a temp. */ + + descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); + if (descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { + vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unhandled TEXBEM(L) with a comparison sampler."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, idx); + if (descriptor->resource_type != VKD3D_SHADER_RESOURCE_TEXTURE_2D) + { + vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unhandled TEXBEM(L) with resource dimension %#x.", descriptor->resource_type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + if (!vsir_program_iterator_insert_after(it, is_texbeml ? 4 : 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_src_param_init(&orig_coords, VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); + orig_coords.reg.idx[0].offset = idx; + orig_coords.reg.dimension = VSIR_DIMENSION_VEC4; + orig_coords.swizzle = VKD3D_SHADER_NO_SWIZZLE; + + if (!(ins = generate_bump_coords(program, it, idx, &orig_coords, &src[0], &location))) + return VKD3D_ERROR_OUT_OF_MEMORY; + ssa_coords = ins->dst[0].reg.idx[0].offset; + + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_SAMPLE, 1, 3)) + return VKD3D_ERROR_OUT_OF_MEMORY; + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = idx; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + src_param_init_ssa_float4(&ins->src[0], ssa_coords); + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, Y, Y, Y); + vsir_src_param_init_resource(&ins->src[1], idx, idx); + vsir_src_param_init_sampler(&ins->src[2], idx, idx); + + if (is_texbeml) + { + enum vkd3d_shader_swizzle_component z = vsir_swizzle_get_component(src[0].swizzle, 2); + + ssa_sample = program->ssa_count++; + ssa_luminance = program->ssa_count++; + + /* Replace t# destination of the SAMPLE instruction with an SSA value. */ + dst_param_init_ssa_float4(&ins->dst[0], ssa_sample); + + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MAD, 1, 3)) + return VKD3D_ERROR_OUT_OF_MEMORY; + dst_param_init_ssa_float4(&ins->dst[0], ssa_luminance); + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; + ins->src[0] = src[0]; + ins->src[0].swizzle = vkd3d_shader_create_swizzle(z, z, z, z); + src_param_init_parameter(&ins->src[1], + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_SCALE_0 + idx, VSIR_DATA_F32); + src_param_init_parameter(&ins->src[2], + VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_0 + idx, VSIR_DATA_F32); + + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_MUL, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = idx; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + src_param_init_ssa_float4(&ins->src[0], ssa_sample); + src_param_init_ssa_float4(&ins->src[1], ssa_luminance); + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + } + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) { @@ -2094,6 +2259,10 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr switch (ins->opcode) { + case VSIR_OP_BEM: + ret = vsir_program_lower_bem(program, &it); + break; + case VSIR_OP_IFC: ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); break; @@ -2102,6 +2271,11 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr ret = vsir_program_lower_sm1_sincos(program, &it); break; + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + ret = vsir_program_lower_texbem(program, &it, message_context); + break; + case VSIR_OP_TEXCOORD: if ((ret = vsir_program_lower_texcoord(program, ins)) < 0) return ret; @@ -2136,8 +2310,6 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr ret = vsir_program_lower_texldl(program, ins); break; - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: case VSIR_OP_TEXDEPTH: case VSIR_OP_TEXDP3: case VSIR_OP_TEXDP3TEX: @@ -2281,6 +2453,8 @@ static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *progr } } + program->has_no_modifiers = true; + return ret; } @@ -2445,13 +2619,16 @@ static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program * struct vkd3d_shader_instruction *ins; struct vkd3d_shader_location loc; + /* Note we run before I/O normalization. */ + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM4); + if (!(ins = vsir_program_iterator_tail(&it))) return VKD3D_OK; loc = ins->location; if (!(ins = vsir_program_append(program))) return VKD3D_ERROR_OUT_OF_MEMORY; - if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) + if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1)) { vsir_instruction_init(ins, &loc, VSIR_OP_NOP); return VKD3D_ERROR_OUT_OF_MEMORY; @@ -2459,12 +2636,10 @@ static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program * src_param_init_temp_float4(&ins->src[0], 0); ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - /* Note we run before I/O normalization. */ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = 0; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; return VKD3D_OK; } @@ -8344,9 +8519,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * * neg sr0, vFOG.x * add sr1, FOG_END, sr0 - * mul_sat srFACTOR, sr1, FOG_SCALE + * mul srFACTOR, sr1, FOG_SCALE */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; @@ -8368,7 +8543,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp2); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ins = vsir_program_iterator_next(it); @@ -8380,9 +8554,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * * mul sr0, FOG_SCALE, vFOG.x * neg sr1, sr0 - * exp_sat srFACTOR, sr1 + * exp srFACTOR, sr1 */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; @@ -8404,7 +8578,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp2); ins = vsir_program_iterator_next(it); break; @@ -8415,9 +8588,9 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * mul sr0, FOG_SCALE, vFOG.x * mul sr1, sr0, sr0 * neg sr2, sr1 - * exp_sat srFACTOR, sr2 + * exp srFACTOR, sr2 */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 8))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; @@ -8446,7 +8619,6 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp3); ins = vsir_program_iterator_next(it); break; @@ -8459,10 +8631,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * * neg sr0, FOG_COLOUR * add sr1, FRAG_COLOUR, sr0 - * mad oC0, sr1, srFACTOR, FOG_COLOUR + * saturate sr2, srFACTOR + * mad oC0, sr1, sr2, FOG_COLOUR */ ssa_temp = program->ssa_count++; ssa_temp2 = program->ssa_count++; + ssa_temp3 = program->ssa_count++; vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); @@ -8475,11 +8649,16 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro src_param_init_ssa_float4(&ins->src[1], ssa_temp); ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_SATURATE, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); + src_param_init_ssa_float(&ins->src[0], ssa_factor); + ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, program->output_signature.elements[colour_signature_idx].mask); src_param_init_ssa_float4(&ins->src[0], ssa_temp2); - src_param_init_ssa_float(&ins->src[1], ssa_factor); + src_param_init_ssa_float(&ins->src[1], ssa_temp3); src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ins = vsir_program_iterator_next(it); @@ -10869,7 +11048,7 @@ static void vsir_validate_dst_param(struct validation_context *ctx, break; } - if (dst->modifiers & ~VKD3DSPDM_MASK) + if (dst->modifiers & ~VKD3DSPDM_MASK || (ctx->program->has_no_modifiers && dst->modifiers)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", dst->modifiers); @@ -11050,7 +11229,7 @@ static void vsir_validate_src_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Immediate constant source has invalid swizzle %#x.", src->swizzle); - if (src->modifiers >= VKD3DSPSM_COUNT) + if (src->modifiers >= VKD3DSPSM_COUNT || (ctx->program->has_no_modifiers && src->modifiers)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", src->modifiers); diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index 3e7bf831e48..7b4804e8036 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -209,20 +209,20 @@ static bool msl_check_shader_visibility(const struct msl_generator *gen, } } -static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx) +static bool msl_get_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, + enum vkd3d_shader_descriptor_type type, enum vkd3d_shader_binding_flag flags, unsigned int *idx) { const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; unsigned int i; if (!interface_info) - return NULL; + return false; for (i = 0; i < interface_info->binding_count; ++i) { const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) + if (binding->type != type) continue; if (binding->register_space != register_space) continue; @@ -230,111 +230,43 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s continue; if (!msl_check_shader_visibility(gen, binding->shader_visibility)) continue; - if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) + if ((binding->flags & flags) != flags) continue; - return &binding->binding; + *idx = binding->binding.binding; + return true; } - return NULL; + return false; } -static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx) +static bool msl_get_cbv_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx, unsigned int *idx) { - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - const struct vkd3d_shader_resource_binding *binding; - unsigned int i; - - if (!interface_info) - return NULL; - - for (i = 0; i < interface_info->binding_count; ++i) - { - binding = &interface_info->bindings[i]; - - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) - continue; - if (binding->register_space != register_space) - continue; - if (binding->register_index != register_idx) - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; - - return &binding->binding; - } - - return NULL; + return msl_get_binding(gen, register_space, register_idx, + VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, VKD3D_SHADER_BINDING_FLAG_BUFFER, idx); } -static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) +static bool msl_get_sampler_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx, unsigned int *idx) { - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - enum vkd3d_shader_binding_flag resource_type_flag; - unsigned int i; - - if (!interface_info) - return NULL; - - resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER - ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; - - for (i = 0; i < interface_info->binding_count; ++i) - { - const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; - - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) - continue; - if (binding->register_space != register_space) - continue; - if (binding->register_index != register_idx) - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; - if (!(binding->flags & resource_type_flag)) - continue; - - return &binding->binding; - } - - return NULL; + return msl_get_binding(gen, register_space, register_idx, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, 0, idx); } -static const struct vkd3d_shader_descriptor_binding *msl_get_uav_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) +static bool msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, + unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) { - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - const struct vkd3d_shader_resource_binding *binding; - enum vkd3d_shader_binding_flag resource_type_flag; - unsigned int i; - - if (!interface_info) - return NULL; - - resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER - ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; - - for (i = 0; i < interface_info->binding_count; ++i) - { - binding = &interface_info->bindings[i]; - - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) - continue; - if (binding->register_space != register_space) - continue; - if (binding->register_index != register_idx) - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; - if (!(binding->flags & resource_type_flag)) - continue; - - return &binding->binding; - } + return msl_get_binding(gen, register_space, register_idx, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER + ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); +} - return NULL; +static bool msl_get_uav_binding(const struct msl_generator *gen, unsigned int register_space, + unsigned int register_idx, enum vkd3d_shader_resource_type resource_type, unsigned int *idx) +{ + return msl_get_binding(gen, register_space, register_idx, + VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, resource_type == VKD3D_SHADER_RESOURCE_BUFFER + ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE, idx); } static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) @@ -370,6 +302,9 @@ static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_ge static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg) { + const struct vkd3d_shader_descriptor_info1 *descriptor; + unsigned int binding, cbv_id, cbv_idx; + switch (reg->type) { case VKD3DSPR_TEMP: @@ -441,38 +376,47 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu } case VKD3DSPR_CONSTBUFFER: + if (reg->idx_count != 3) { - const struct vkd3d_shader_descriptor_binding *binding; + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register index count %u.", + reg->idx_count); + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } - if (reg->idx_count != 3) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register index count %u.", - reg->idx_count); - vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } - if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } - /* FIXME: This should use vkd3d_shader_find_descriptor() to - * find the resource index/space from the resource ID. */ - if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for CBV %u.", reg->idx[0].offset); - vkd3d_string_buffer_printf(buffer, "", reg->type); - return MSL_DATA_UNION; - } - msl_print_cbv_name(buffer, binding->binding); - msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); + if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } + + cbv_id = reg->idx[0].offset; + cbv_idx = reg->idx[1].offset; + + if (!(descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cbv_id))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared CBV descriptor %u.", cbv_id); + vkd3d_string_buffer_printf(buffer, "", reg->type); return MSL_DATA_UNION; } + if (!msl_get_cbv_binding(gen, descriptor->register_space, cbv_idx, &binding)) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for CBV %u.", cbv_id); + vkd3d_string_buffer_printf(buffer, "", reg->type); + return MSL_DATA_UNION; + } + + msl_print_cbv_name(buffer, binding); + msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); + return MSL_DATA_UNION; + case VKD3DSPR_IDXTEMP: vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset); msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); @@ -923,7 +867,6 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct unsigned int resource_id, resource_idx, resource_space, sample_count; const struct msl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_info1 *descriptor; - const struct vkd3d_shader_descriptor_binding *binding; enum vkd3d_shader_resource_type resource_type; uint32_t coord_mask, write_mask_size; struct vkd3d_string_buffer *read; @@ -985,11 +928,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct } coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) - { - srv_binding = binding->binding; - } - else + if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, "No descriptor binding specified for SRV %u (index %u, space %u).", @@ -1042,7 +981,6 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst const struct msl_resource_type_info *resource_type_info; const struct vkd3d_shader_src_param *resource, *sampler; unsigned int resource_id, resource_idx, resource_space; - const struct vkd3d_shader_descriptor_binding *binding; unsigned int sampler_id, sampler_idx, sampler_space; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; @@ -1114,11 +1052,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst } coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) - { - srv_binding = binding->binding; - } - else + if (!msl_get_srv_binding(gen, resource_space, resource_idx, resource_type, &srv_binding)) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, "No descriptor binding specified for SRV %u (index %u, space %u).", @@ -1154,11 +1088,7 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst sampler_space = 0; } - if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) - { - sampler_binding = binding->binding; - } - else + if (!msl_get_sampler_binding(gen, sampler_space, sampler_idx, &sampler_binding)) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, "No descriptor binding specified for sampler %u (index %u, space %u).", @@ -1256,7 +1186,6 @@ static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_inst static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct msl_resource_type_info *resource_type_info; - const struct vkd3d_shader_descriptor_binding *binding; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; @@ -1300,11 +1229,7 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh } coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); - if ((binding = msl_get_uav_binding(gen, uav_space, uav_idx, resource_type))) - { - uav_binding = binding->binding; - } - else + if (!msl_get_uav_binding(gen, uav_space, uav_idx, resource_type, &uav_binding)) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, "No descriptor binding specified for UAV %u (index %u, space %u).", @@ -2334,6 +2259,7 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); VKD3D_ASSERT(program->has_descriptor_info); + VKD3D_ASSERT(program->has_no_modifiers); if ((ret = msl_generator_init(&generator, program, compile_info, message_context)) < 0) return ret; diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 0f5df228121..aae5f6b5534 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -4752,8 +4752,14 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, else if (reg->type == VKD3DSPR_UNDEF) return spirv_compiler_emit_load_undef(compiler, reg, write_mask); else if (reg->type == VKD3DSPR_PARAMETER) - return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, + { + val_id = spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, reg->data_type, reg->dimension == VSIR_DIMENSION_VEC4 ? 4 : 1); + if (reg->dimension != VSIR_DIMENSION_VEC4) + return val_id; + return spirv_compiler_emit_swizzle(compiler, val_id, + VKD3DSP_WRITEMASK_ALL, reg->data_type, swizzle, write_mask); + } component_count = vsir_write_mask_component_count(write_mask); @@ -11060,6 +11066,7 @@ int spirv_compile(struct vsir_program *program, uint64_t config_flags, VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); VKD3D_ASSERT(program->has_descriptor_info); + VKD3D_ASSERT(program->has_no_modifiers); if (!(spirv_compiler = spirv_compiler_create(program, compile_info, message_context, config_flags))) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 821c639ee16..c0faa30f14a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1503,8 +1503,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte if (context->cf_info_count) context->cf_info[context->cf_info_count - 1].inside_block = false; break; - case VSIR_OP_TEXBEM: - case VSIR_OP_TEXBEML: case VSIR_OP_TEXDP3TEX: case VSIR_OP_TEXM3x2TEX: case VSIR_OP_TEXM3x3SPEC: diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 346c74ff698..404e7cec6ea 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1610,6 +1610,7 @@ struct vsir_program uint8_t diffuse_written_mask; enum vsir_control_flow_type cf_type; enum vsir_normalisation_level normalisation_level; + bool has_no_modifiers; enum vkd3d_tessellator_domain tess_domain; enum vkd3d_shader_tessellator_partitioning tess_partitioning; enum vkd3d_shader_tessellator_output_primitive tess_output_primitive; -- 2.51.0