Files
wine-staging/patches/vkd3d-latest/0003-Updated-vkd3d-to-1569bb3fb8c745d895ad555da1de5e6a2a8.patch
Alistair Leslie-Hughes e97aabbb86 Updated vkd3d-latest patchset
2025-11-15 16:50:06 +11:00

644 lines
28 KiB
Diff

From 96fcc9490766c82944e09eb5d549386679236bd9 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 11 Nov 2025 08:00:39 +1100
Subject: [PATCH] Updated vkd3d to 1569bb3fb8c745d895ad555da1de5e6a2a846218.
---
libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 5 +-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 189 ++++++++----------
.../libs/vkd3d-shader/hlsl_constant_ops.c | 45 ++---
libs/vkd3d/libs/vkd3d-shader/ir.c | 11 +-
5 files changed, 115 insertions(+), 137 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index a14346a45d2..4848c531ced 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -1607,7 +1607,7 @@ static void write_fx_2_type_iter(const struct hlsl_type *type, const char *name,
}
buffer = &fx->unstructured;
- offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler));
+ offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler, HLSL_SAMPLER_DIM_GENERIC));
put_u32(buffer, get_fx_2_type_class(type));
*ctx->names++ = put_u32(buffer, 0);
*ctx->semantics++ = put_u32(buffer, 0);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 87cfaf83f76..0202d71cc23 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -1844,18 +1844,19 @@ 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);
+struct hlsl_ir_node *hlsl_fold_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block);
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);
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);
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type);
-D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler);
+D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type,
+ bool is_combined_sampler, enum hlsl_sampler_dim sampler_dim);
struct extern_resource
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 6fe29e5bfed..8bb23e0690d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -938,7 +938,8 @@ static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
if ((replacement = func(ctx, instr, &block)))
{
list_move_before(&instr->entry, &block.instrs);
- hlsl_replace_node(instr, replacement);
+ if (replacement != instr)
+ hlsl_replace_node(instr, replacement);
return true;
}
else
@@ -955,7 +956,10 @@ static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
*
* New instructions should be added to "block", and the replacement instruction
* should be returned. If the instruction should be left alone, NULL should be
- * returned instead. */
+ * returned instead.
+ *
+ * It is legal to return the same instruction from the replace function, in
+ * which case replace_ir() returns true but hlsl_replace_node() is skipped. */
static bool replace_ir(struct hlsl_ctx *ctx, PFN_replace_func func, struct hlsl_block *block)
{
return hlsl_transform_ir(ctx, call_replace_func, block, func);
@@ -4095,7 +4099,6 @@ static bool lower_conditional_block_stores(struct hlsl_ctx *ctx, struct hlsl_ir_
static bool lower_conditional_block_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
struct hlsl_ir_node *cond, bool is_then)
{
- struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
struct hlsl_ir_node *discard_cond, *new_cond = NULL;
struct hlsl_ir_jump *jump;
struct hlsl_block block;
@@ -4118,12 +4121,8 @@ static bool lower_conditional_block_discard_nz(struct hlsl_ctx *ctx, struct hlsl
cond = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, cond, &instr->loc);
discard_cond = hlsl_block_add_cast(ctx, &block, discard_cond, cond->data_type, &instr->loc);
- operands[0] = cond;
- operands[1] = discard_cond;
-
/* discard_nz (cond && discard_cond) */
- new_cond = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LOGIC_AND, operands,
- hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &jump->node.loc);
+ new_cond = hlsl_block_add_binary_expr(ctx, &block, HLSL_OP2_LOGIC_AND, cond, discard_cond);
list_move_before(&jump->node.entry, &block.instrs);
hlsl_src_remove(&jump->condition);
@@ -5250,49 +5249,37 @@ static struct hlsl_ir_node *lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_n
return hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc);
}
-static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *lower_resource_load_bias(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
- struct hlsl_ir_node *swizzle, *store;
+ struct hlsl_ir_node *swizzle, *tmp_load;
struct hlsl_ir_resource_load *load;
- struct hlsl_ir_load *tmp_load;
struct hlsl_ir_var *tmp_var;
- struct hlsl_deref deref;
if (instr->type != HLSL_IR_RESOURCE_LOAD)
- return false;
+ return NULL;
load = hlsl_ir_resource_load(instr);
if (load->load_type != HLSL_RESOURCE_SAMPLE_LOD
&& load->load_type != HLSL_RESOURCE_SAMPLE_LOD_BIAS)
- return false;
+ return NULL;
if (!load->lod.node)
- return false;
+ return NULL;
if (!(tmp_var = hlsl_new_synthetic_var(ctx, "coords-with-lod",
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), &instr->loc)))
- return false;
-
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), 4, load->lod.node, &load->lod.node->loc)))
- return false;
- list_add_before(&instr->entry, &swizzle->entry);
-
- if (!(store = hlsl_new_simple_store(ctx, tmp_var, swizzle)))
- return false;
- list_add_before(&instr->entry, &store->entry);
+ return NULL;
- hlsl_init_simple_deref_from_var(&deref, tmp_var);
- if (!(store = hlsl_new_store_index(ctx, &deref, NULL, load->coords.node, 0, &instr->loc)))
- return false;
- list_add_before(&instr->entry, &store->entry);
+ swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), 4, load->lod.node, &load->lod.node->loc);
+ hlsl_block_add_simple_store(ctx, block, tmp_var, swizzle);
+ hlsl_block_add_simple_store(ctx, block, tmp_var, load->coords.node);
- if (!(tmp_load = hlsl_new_var_load(ctx, tmp_var, &instr->loc)))
- return false;
- list_add_before(&instr->entry, &tmp_load->node.entry);
+ tmp_load = hlsl_block_add_simple_load(ctx, block, tmp_var, &instr->loc);
hlsl_src_remove(&load->coords);
- hlsl_src_from_node(&load->coords, &tmp_load->node);
+ hlsl_src_from_node(&load->coords, tmp_load);
hlsl_src_remove(&load->lod);
- return true;
+ return &load->node;
}
static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
@@ -5746,34 +5733,29 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
return true;
}
-static bool lower_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *lower_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *cond, *cond_cast, *abs, *neg;
struct hlsl_type *float_type;
struct hlsl_ir_jump *jump;
- struct hlsl_block block;
if (instr->type != HLSL_IR_JUMP)
- return false;
+ return NULL;
jump = hlsl_ir_jump(instr);
if (jump->type != HLSL_IR_JUMP_DISCARD_NZ)
- return false;
+ return NULL;
cond = jump->condition.node;
float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, cond->data_type->e.numeric.dimx);
- hlsl_block_init(&block);
-
- cond_cast = hlsl_block_add_cast(ctx, &block, cond, float_type, &instr->loc);
- abs = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_ABS, cond_cast, &instr->loc);
- neg = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_NEG, abs, &instr->loc);
+ cond_cast = hlsl_block_add_cast(ctx, block, cond, float_type, &instr->loc);
+ abs = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, cond_cast, &instr->loc);
+ neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, abs, &instr->loc);
- list_move_tail(&instr->entry, &block.instrs);
hlsl_src_remove(&jump->condition);
hlsl_src_from_node(&jump->condition, neg);
jump->type = HLSL_IR_JUMP_DISCARD_NEG;
-
- return true;
+ return &jump->node;
}
static bool cast_discard_neg_conditions_to_vec4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -8551,96 +8533,74 @@ static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op)
}
}
-static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *fold_unary_identities(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
- struct hlsl_ir_node *res = NULL;
struct hlsl_ir_expr *expr, *x;
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->operands[0].node)
- return false;
+ return NULL;
if (expr->operands[0].node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
x = hlsl_ir_expr(expr->operands[0].node);
switch (expr->op)
{
case HLSL_OP1_ABS:
+ /* ||x|| -> |x| */
if (x->op == HLSL_OP1_ABS)
- {
- /* ||x|| -> |x| */
- hlsl_replace_node(instr, &x->node);
- return true;
- }
+ return &x->node;
+ /* |-x| -> |x| */
if (x->op == HLSL_OP1_NEG)
{
- /* |-x| -> |x| */
hlsl_src_remove(&expr->operands[0]);
hlsl_src_from_node(&expr->operands[0], x->operands[0].node);
- return true;
+ return &expr->node;
}
break;
case HLSL_OP1_BIT_NOT:
+ /* ~(~x) -> x */
if (x->op == HLSL_OP1_BIT_NOT)
- {
- /* ~(~x) -> x */
- hlsl_replace_node(instr, x->operands[0].node);
- return true;
- }
+ return x->operands[0].node;
break;
case HLSL_OP1_CEIL:
case HLSL_OP1_FLOOR:
+ /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */
if (x->op == HLSL_OP1_CEIL || x->op == HLSL_OP1_FLOOR)
- {
- /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */
- hlsl_replace_node(instr, &x->node);
- return true;
- }
+ return &x->node;
break;
case HLSL_OP1_NEG:
+ /* -(-x) -> x */
if (x->op == HLSL_OP1_NEG)
- {
- /* -(-x) -> x */
- hlsl_replace_node(instr, x->operands[0].node);
- return true;
- }
+ return x->operands[0].node;
break;
case HLSL_OP1_LOGIC_NOT:
+ /* !!x -> x */
if (x->op == HLSL_OP1_LOGIC_NOT)
- {
- /* !!x -> x */
- hlsl_replace_node(instr, x->operands[0].node);
- return true;
- }
+ return x->operands[0].node;
if (hlsl_is_comparison_op(x->op)
&& hlsl_base_type_is_integer(x->operands[0].node->data_type->e.numeric.type)
&& hlsl_base_type_is_integer(x->operands[1].node->data_type->e.numeric.type))
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {x->operands[0].node, x->operands[1].node};
- struct hlsl_block block;
-
- hlsl_block_init(&block);
/* !(x == y) -> x != y, !(x < y) -> x >= y, etc. */
- res = hlsl_block_add_expr(ctx, &block, invert_comparison_op(x->op),
+ return hlsl_block_add_expr(ctx, block, invert_comparison_op(x->op),
operands, instr->data_type, &instr->loc);
-
- list_move_before(&instr->entry, &block.instrs);
- hlsl_replace_node(instr, res);
- return true;
}
break;
@@ -8649,7 +8609,7 @@ static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
break;
}
- return false;
+ return NULL;
}
static bool nodes_are_equivalent(const struct hlsl_ir_node *c1, const struct hlsl_ir_node *c2)
@@ -8784,8 +8744,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block)
do
{
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 |= replace_ir(ctx, hlsl_fold_binary_exprs, block);
+ progress |= replace_ir(ctx, fold_unary_identities, block);
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);
@@ -10053,7 +10013,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx,
else
writemask = (1u << deref->var->data_type->e.numeric.dimx) - 1;
- if (version.type == VKD3D_SHADER_TYPE_PIXEL && (!ascii_strcasecmp(semantic_name, "PSIZE")
+ if (version.type == VKD3D_SHADER_TYPE_VERTEX && (!ascii_strcasecmp(semantic_name, "PSIZE")
|| (!ascii_strcasecmp(semantic_name, "FOG") && version.major < 3)))
{
/* These are always 1-component, but for some reason are written
@@ -10525,7 +10485,8 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
vkd3d_unreachable();
}
-D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler)
+D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type,
+ bool is_combined_sampler, enum hlsl_sampler_dim sampler_dim)
{
enum hlsl_type_class class = type->class;
@@ -10564,7 +10525,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb
break;
case HLSL_CLASS_SAMPLER:
- switch (type->sampler_dim)
+ switch (sampler_dim)
{
case HLSL_SAMPLER_DIM_1D:
return D3DXPT_SAMPLER1D;
@@ -10602,7 +10563,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb
break;
case HLSL_CLASS_ARRAY:
- return hlsl_sm1_base_type(type->e.array.type, is_combined_sampler);
+ return hlsl_sm1_base_type(type->e.array.type, is_combined_sampler, sampler_dim);
case HLSL_CLASS_STRUCT:
return D3DXPT_VOID;
@@ -10640,15 +10601,19 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb
vkd3d_unreachable();
}
-static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
- struct hlsl_type *type, bool is_combined_sampler, unsigned int ctab_start)
+static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type,
+ bool is_combined_sampler, enum hlsl_sampler_dim sampler_dim, unsigned int ctab_start)
{
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
unsigned int array_size = hlsl_get_multiarray_size(type);
struct hlsl_struct_field *field;
size_t i;
- if (type->bytecode_offset)
+ /* Native deduplicates types, but emits the correct dimension for generic
+ * samplers. Apparently it deals with this by never deduplicating any
+ * sampler types. This is not very efficient, but we may as well do the
+ * same. */
+ if (type->bytecode_offset && array_type->class != HLSL_CLASS_SAMPLER)
return;
if (array_type->class == HLSL_CLASS_STRUCT)
@@ -10660,7 +10625,7 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
{
field = &array_type->e.record.fields[i];
field->name_bytecode_offset = put_string(buffer, field->name);
- write_sm1_type(buffer, field->type, false, ctab_start);
+ write_sm1_type(buffer, field->type, false, HLSL_SAMPLER_DIM_GENERIC, ctab_start);
}
fields_offset = bytecode_align(buffer) - ctab_start;
@@ -10680,9 +10645,11 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
else
{
type->bytecode_offset = put_u32(buffer,
- vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type, is_combined_sampler)));
+ vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type, is_combined_sampler, sampler_dim)));
if (hlsl_is_numeric_type(array_type))
put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx));
+ else if (is_combined_sampler)
+ put_u32(buffer, vkd3d_make_u32(1, 4));
else
put_u32(buffer, vkd3d_make_u32(1, 1));
put_u32(buffer, vkd3d_make_u32(array_size, 0));
@@ -10736,7 +10703,9 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
++uniform_count;
- if (var->is_param && var->is_uniform)
+ /* Not var->is_uniform. The $ prefix is only added if the variable
+ * is actually declared with a 'uniform' modifier. */
+ if (var->is_param && (var->storage_modifiers & HLSL_STORAGE_UNIFORM))
{
char *new_name;
@@ -10793,17 +10762,33 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
{
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
+ enum hlsl_sampler_dim sampler_dim = HLSL_SAMPLER_DIM_GENERIC;
size_t var_offset, name_offset;
if (var->semantic.name || !var->regs[r].allocated || !var->last_read)
continue;
+ /* Arrays can be used with multiple different dimensions.
+ * The dimension written into the CTAB is the dimension of the
+ * first usage, which is not really that sensible... */
+ if (r == HLSL_REGSET_SAMPLERS)
+ {
+ for (unsigned int i = 0; i < var->bind_count[r]; ++i)
+ {
+ if (var->objects_usage[r][i].sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
+ {
+ sampler_dim = var->objects_usage[r][i].sampler_dim;
+ break;
+ }
+ }
+ }
+
var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
name_offset = put_string(buffer, var->name);
set_u32(buffer, var_offset, name_offset - ctab_start);
- write_sm1_type(buffer, var->data_type, var->is_combined_sampler, ctab_start);
+ write_sm1_type(buffer, var->data_type, var->is_combined_sampler, sampler_dim, ctab_start);
set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
if (var->default_values)
@@ -15101,8 +15086,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
}
else
{
- hlsl_transform_ir(ctx, lower_discard_nz, body, NULL);
- hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL);
+ replace_ir(ctx, lower_discard_nz, body);
+ replace_ir(ctx, lower_resource_load_bias, body);
}
compute_liveness(ctx, body);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
index 1c44e5fa37a..627418165bc 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
@@ -1818,26 +1818,23 @@ static struct hlsl_ir_node *collect_exprs(struct hlsl_ctx *ctx, struct hlsl_bloc
return hlsl_block_add_expr(ctx, block, opl, operands, instr->data_type, &instr->loc);
}
-bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+struct hlsl_ir_node *hlsl_fold_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *tmp;
struct hlsl_ir_expr *expr;
enum hlsl_base_type type;
enum hlsl_ir_expr_op op;
- struct hlsl_block block;
bool progress = false;
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;
if (expr->operands[2].node)
- return false;
-
- hlsl_block_init(&block);
+ return NULL;
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
@@ -1845,15 +1842,11 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
op = expr->op;
if (!arg1 || !arg2)
- return false;
+ return NULL;
- if ((tmp = collect_exprs(ctx, &block, instr, op, arg1, arg2)))
- {
- /* (x OPL a) OPR (x OPL b) -> x OPL (a OPR b) */
- list_move_before(&instr->entry, &block.instrs);
- hlsl_replace_node(instr, tmp);
- return true;
- }
+ /* (x OPL a) OPR (x OPL b) -> x OPL (a OPR b) */
+ if ((tmp = collect_exprs(ctx, block, instr, op, arg1, arg2)))
+ return tmp;
if (is_op_commutative(op) && arg1->type == HLSL_IR_CONSTANT && arg2->type != HLSL_IR_CONSTANT)
{
@@ -1876,13 +1869,13 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
{
/* (x OP a) OP b -> x OP (a OP b) */
arg1 = e1->operands[0].node;
- arg2 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[1].node, arg2);
+ arg2 = hlsl_block_add_binary_expr(ctx, block, op, e1->operands[1].node, arg2);
progress = true;
}
else if (is_op_commutative(op))
{
/* (x OP a) OP y -> (x OP y) OP a */
- arg1 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[0].node, arg2);
+ arg1 = hlsl_block_add_binary_expr(ctx, block, op, e1->operands[0].node, arg2);
arg2 = e1->operands[1].node;
progress = true;
}
@@ -1892,13 +1885,13 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
&& e2->operands[0].node->type != HLSL_IR_CONSTANT && e2->operands[1].node->type == HLSL_IR_CONSTANT)
{
/* x OP (y OP a) -> (x OP y) OP a */
- arg1 = hlsl_block_add_binary_expr(ctx, &block, op, arg1, e2->operands[0].node);
+ arg1 = hlsl_block_add_binary_expr(ctx, block, op, arg1, e2->operands[0].node);
arg2 = e2->operands[1].node;
progress = true;
}
if (!progress && e1 && e1->op == op
- && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[1].node, arg2)))
+ && (tmp = collect_exprs(ctx, block, instr, op, e1->operands[1].node, arg2)))
{
/* (y OPR (x OPL a)) OPR (x OPL b) -> y OPR (x OPL (a OPR b)) */
arg1 = e1->operands[0].node;
@@ -1907,7 +1900,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
}
if (!progress && is_op_commutative(op) && e1 && e1->op == op
- && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[0].node, arg2)))
+ && (tmp = collect_exprs(ctx, block, instr, op, e1->operands[0].node, arg2)))
{
/* ((x OPL a) OPR y) OPR (x OPL b) -> (x OPL (a OPR b)) OPR y */
arg1 = tmp;
@@ -1916,7 +1909,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
}
if (!progress && e2 && e2->op == op
- && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[0].node)))
+ && (tmp = collect_exprs(ctx, block, instr, op, arg1, e2->operands[0].node)))
{
/* (x OPL a) OPR ((x OPL b) OPR y) -> (x OPL (a OPR b)) OPR y */
arg1 = tmp;
@@ -1925,7 +1918,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
}
if (!progress && is_op_commutative(op) && e2 && e2->op == op
- && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[1].node)))
+ && (tmp = collect_exprs(ctx, block, instr, op, arg1, e2->operands[1].node)))
{
/* (x OPL a) OPR (y OPR (x OPL b)) -> (x OPL (a OPR b)) OPR y */
arg1 = tmp;
@@ -1937,15 +1930,11 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
if (progress)
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2};
- struct hlsl_ir_node *res;
-
- res = hlsl_block_add_expr(ctx, &block, op, operands, instr->data_type, &instr->loc);
- list_move_before(&instr->entry, &block.instrs);
- hlsl_replace_node(instr, res);
+ return hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc);
}
- return progress;
+ return NULL;
}
struct hlsl_ir_node *hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx,
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 5b1d0449a64..6a1c5303eb4 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -3846,16 +3846,19 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
break;
case VKD3DSPR_RASTOUT:
+ /* Fog and point size are scalar, but fxc/d3dcompiler emits a full
+ * write mask when writing to them. */
+ if (reg->idx[0].offset > 0)
+ {
+ write_mask = VKD3DSP_WRITEMASK_0;
+ dst_param->write_mask = write_mask;
+ }
/* Leave point size as a system value for the backends to consume. */
if (reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
return true;
reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset;
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
- /* Fog and point size are scalar, but fxc/d3dcompiler emits a full
- * write mask when writing to them. */
- if (reg->idx[0].offset > 0)
- write_mask = VKD3DSP_WRITEMASK_0;
break;
default:
--
2.51.0