From: Francisco Casas fcasas@codeweavers.com
---
We would want to add values to known_identifiers[] as we identify them.
I don't know how to handle unknown identifiers. Should we set them to zero with a respective warning ? --- libs/vkd3d-shader/hlsl.c | 2 ++ libs/vkd3d-shader/hlsl.h | 3 ++ libs/vkd3d-shader/hlsl.y | 1 + libs/vkd3d-shader/hlsl_codegen.c | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index dc07f4164..66948decc 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -160,6 +160,8 @@ void hlsl_free_var(struct hlsl_ir_var *decl) hlsl_free_state_block(decl->state_block); decl->state_block = NULL; } + if (decl->state_block_identifier) + vkd3d_free((void *)decl->state_block_identifier); vkd3d_free(decl); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index cab5331ba..5f8daca2e 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -415,6 +415,9 @@ struct hlsl_ir_var
/* The state_block on the variable's declaration, if it has one. */ struct hlsl_state_block *state_block; + /* If the variable appeared as a NEW_IDENTIFIER token in a rhs of a state block, this stores + * the name of the identifier. */ + const char *state_block_identifier;
/* Indexes of the IR instructions where the variable is first written and last read (liveness * range). The IR instructions are numerated starting from 2, because 0 means unused, and 1 diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 87b1034e6..7cc29650a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -7113,6 +7113,7 @@ primary_expr: if (!(var = hlsl_new_synthetic_var(ctx, "state_block_expr", hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &@1))) YYABORT; + var->state_block_identifier = $1; if (!(load = hlsl_new_var_load(ctx, var, &@1))) YYABORT; if (!($$ = make_block(ctx, &load->node))) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 383a32f55..e0338a5e4 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -5160,10 +5160,57 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry } }
+static bool lower_state_block_identifier_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const char *identifier = NULL; + struct hlsl_ir_load *load; + int i; + + static const struct + { + const char *name; + union hlsl_constant_value_component value; + } + known_identifiers[] = + { + /* We must fill this table as we start discovering the values of the identifiers. */ + {"EXAMPLE", {.u = 25}}, + }; + + if (instr->type != HLSL_IR_LOAD) + return false; + load = hlsl_ir_load(instr); + + if (!(identifier = load->src.var->state_block_identifier)) + return false; + + for (i = 0; i < ARRAY_SIZE(known_identifiers); ++i) + { + if (!strcmp(identifier, known_identifiers[i].name)) + { + struct hlsl_constant_value value = {0}; + struct hlsl_ir_node *c; + + value.u[0] = known_identifiers[i].value; + + if (!(c = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc))) + return false; + hlsl_replace_node(instr, c); + return true; + } + } + + FIXME("Unkown value of identifier '%s'\n", identifier); + return false; +} + void hlsl_static_constant_folding(struct hlsl_ctx *ctx, struct hlsl_block *expr) { bool progress;
+ if (ctx->in_state_block) + hlsl_transform_ir(ctx, lower_state_block_identifier_loads, expr, NULL); + do { progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, expr, NULL);