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
644 lines
28 KiB
Diff
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
|
|
|