Files
wine-staging/patches/vkd3d-latest/0007-Updated-vkd3d-to-d3f658d410c42d739bdb3513bfdbd3f4e78.patch
Alistair Leslie-Hughes bbcdf55b0a Updated vkd3d-latest patchset
2025-10-30 07:44:02 +11:00

1528 lines
68 KiB
Diff

From 65b2564bc2e373169e5de6198d42600dd8a44273 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
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, &param_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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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, "<unhandled register %#x>", 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