You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-12-15 08:03:15 -08:00
1528 lines
68 KiB
Diff
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, ¶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, "<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
|
|
|