From: Francisco Casas <fcasas(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl.c | 50 ++++++++++++++++++++++++++++++++
libs/vkd3d-shader/hlsl.h | 17 +++++++++++
libs/vkd3d-shader/hlsl.y | 13 ++++-----
libs/vkd3d-shader/hlsl_codegen.c | 6 ++++
4 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 20213504e..730eecba7 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -1586,6 +1586,27 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx,
uint32_t s, unsigned
return &swizzle->node;
}
+struct hlsl_ir_node *hlsl_new_stateblock_constant(struct hlsl_ctx *ctx, const char
*name,
+ struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_stateblock_constant *constant;
+ struct hlsl_type *type = hlsl_get_scalar_type(ctx, HLSL_TYPE_INT);
+
+ if (!(constant = hlsl_alloc(ctx, sizeof(*constant))))
+ return NULL;
+
+ init_node(&constant->node, HLSL_IR_STATEBLOCK_CONSTANT, type, loc);
+
+ if (!(constant->name = hlsl_alloc(ctx, strlen(name) + 1)))
+ {
+ vkd3d_free(constant);
+ return NULL;
+ }
+ strcpy(constant->name, name);
+
+ return &constant->node;
+}
+
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index)
{
struct hlsl_type *type = index->val.node->data_type;
@@ -1906,6 +1927,12 @@ static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx,
struct clone_instr
return dst;
}
+static struct hlsl_ir_node *clone_stateblock_constant(struct hlsl_ctx *ctx,
+ struct clone_instr_map *map, struct hlsl_ir_stateblock_constant *constant)
+{
+ return hlsl_new_stateblock_constant(ctx, constant->name,
&constant->node.loc);
+}
+
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c)
{
hlsl_block_cleanup(&c->body);
@@ -2001,6 +2028,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
case HLSL_IR_SWIZZLE:
return clone_swizzle(ctx, map, hlsl_ir_swizzle(instr));
+
+ case HLSL_IR_STATEBLOCK_CONSTANT:
+ return clone_stateblock_constant(ctx, map,
hlsl_ir_stateblock_constant(instr));
}
vkd3d_unreachable();
@@ -2831,6 +2861,12 @@ static void dump_ir_index(struct vkd3d_string_buffer *buffer, const
struct hlsl_
vkd3d_string_buffer_printf(buffer, "]");
}
+static void dump_ir_stateblock_constant(struct vkd3d_string_buffer *buffer,
+ const struct hlsl_ir_stateblock_constant *constant)
+{
+ vkd3d_string_buffer_printf(buffer, "%s", constant->name);
+}
+
static void dump_ir_switch(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
const struct hlsl_ir_switch *s)
{
struct hlsl_ir_switch_case *c;
@@ -2919,6 +2955,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct
vkd3d_string_buffer *buffer,
case HLSL_IR_SWIZZLE:
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
break;
+
+ case HLSL_IR_STATEBLOCK_CONSTANT:
+ dump_ir_stateblock_constant(buffer, hlsl_ir_stateblock_constant(instr));
+ break;
}
}
@@ -3091,6 +3131,12 @@ static void free_ir_index(struct hlsl_ir_index *index)
vkd3d_free(index);
}
+static void free_ir_stateblock_constant(struct hlsl_ir_stateblock_constant *constant)
+{
+ vkd3d_free(constant->name);
+ vkd3d_free(constant);
+}
+
void hlsl_free_instr(struct hlsl_ir_node *node)
{
assert(list_empty(&node->uses));
@@ -3148,6 +3194,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
case HLSL_IR_SWITCH:
free_ir_switch(hlsl_ir_switch(node));
break;
+
+ case HLSL_IR_STATEBLOCK_CONSTANT:
+ free_ir_stateblock_constant(hlsl_ir_stateblock_constant(node));
+ break;
}
}
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 0f6f0102a..b79c754c9 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -298,6 +298,7 @@ enum hlsl_ir_node_type
HLSL_IR_STORE,
HLSL_IR_SWIZZLE,
HLSL_IR_SWITCH,
+ HLSL_IR_STATEBLOCK_CONSTANT,
};
/* Common data for every type of IR instruction node. */
@@ -789,6 +790,14 @@ struct hlsl_ir_constant
struct hlsl_reg reg;
};
+/* Stateblock constants are undeclared values found on state blocks or technique passes
descriptions,
+ * that do not concern regular pixel, vertex, or compute shaders, except for parsing.
*/
+struct hlsl_ir_stateblock_constant
+{
+ struct hlsl_ir_node node;
+ char *name;
+};
+
struct hlsl_scope
{
/* Item entry for hlsl_ctx.scopes. */
@@ -1051,6 +1060,12 @@ static inline struct hlsl_ir_switch *hlsl_ir_switch(const struct
hlsl_ir_node *n
return CONTAINING_RECORD(node, struct hlsl_ir_switch, node);
}
+static inline struct hlsl_ir_stateblock_constant *hlsl_ir_stateblock_constant(const
struct hlsl_ir_node *node)
+{
+ assert(node->type == HLSL_IR_STATEBLOCK_CONSTANT);
+ return CONTAINING_RECORD(node, struct hlsl_ir_stateblock_constant, node);
+}
+
static inline void hlsl_block_init(struct hlsl_block *block)
{
list_init(&block->instrs);
@@ -1324,6 +1339,8 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const
char *name,
struct hlsl_struct_field *fields, size_t field_count);
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int
components,
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
+struct hlsl_ir_node *hlsl_new_stateblock_constant(struct hlsl_ctx *ctx, const char
*name,
+ struct vkd3d_shader_location *loc);
struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *template,
struct hlsl_type *type, const struct vkd3d_shader_location *loc);
struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const char *name,
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 7f7dd6e41..1dc7d5d34 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1309,6 +1309,7 @@ static unsigned int evaluate_static_expression_as_uint(struct
hlsl_ctx *ctx, str
case HLSL_IR_RESOURCE_STORE:
case HLSL_IR_STORE:
case HLSL_IR_SWITCH:
+ case HLSL_IR_STATEBLOCK_CONSTANT:
hlsl_error(ctx, &node->loc,
VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
"Expected literal expression.");
}
@@ -7396,15 +7397,13 @@ primary_expr:
{
if (ctx->in_state_block)
{
- struct hlsl_ir_load *load;
- struct hlsl_ir_var *var;
+ struct hlsl_ir_node *constant;
- if (!(var = hlsl_new_synthetic_var(ctx, "state_block_expr",
- hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &@1)))
+ if (!(constant = hlsl_new_stateblock_constant(ctx, $1, &@1)))
YYABORT;
- if (!(load = hlsl_new_var_load(ctx, var, &@1)))
- YYABORT;
- if (!($$ = make_block(ctx, &load->node)))
+ vkd3d_free($1);
+
+ if (!($$ = make_block(ctx, constant)))
YYABORT;
}
else
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 5dcbaefa3..f08a6aea1 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -3757,6 +3757,9 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
void *context)
case HLSL_IR_RESOURCE_STORE:
case HLSL_IR_SWITCH:
break;
+ case HLSL_IR_STATEBLOCK_CONSTANT:
+ /* Stateblock constants should not appear in the shader program. */
+ vkd3d_unreachable();
}
return false;
@@ -3880,6 +3883,9 @@ static void compute_liveness_recurse(struct hlsl_block *block,
unsigned int loop
case HLSL_IR_CALL:
/* We should have inlined all calls before computing liveness. */
vkd3d_unreachable();
+ case HLSL_IR_STATEBLOCK_CONSTANT:
+ /* Stateblock constants should not appear in the shader program. */
+ vkd3d_unreachable();
case HLSL_IR_STORE:
{
--
GitLab
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/739