Module: vkd3d Branch: master Commit: 80320f61293d51ff0202b693612a0d119e8af2d2 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/80320f61293d51ff0202b693612a0d...
Author: Francisco Casas fcasas@codeweavers.com Date: Mon Mar 18 15:31:04 2024 -0300
vkd3d-shader/hlsl: Introduce hlsl_ir_stateblock_constant.
---
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 3b93c690..1ecb14d2 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; @@ -1909,6 +1930,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); @@ -2004,6 +2031,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(); @@ -2835,6 +2865,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; @@ -2923,6 +2959,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; } }
@@ -3095,6 +3135,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)); @@ -3152,6 +3198,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 b53bcbd7..b6309ac4 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. */ @@ -785,6 +786,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. */ @@ -1060,6 +1069,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); @@ -1334,6 +1349,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 28347b4a..5acbc3a3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1294,6 +1294,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."); } @@ -7365,15 +7366,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 13c923b4..eaa72836 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -3746,6 +3746,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; @@ -3869,6 +3872,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: {