hlsl_type_compare() implies a stable comparison function, as if to be passed to qsort().
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 8 ++++---- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 14 +++++++------- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 988f64dc..cb13e8fd 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -230,7 +230,7 @@ unsigned int hlsl_type_component_count(struct hlsl_type *type) return count; }
-bool hlsl_type_compare(const struct hlsl_type *t1, const struct hlsl_type *t2) +bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2) { if (t1 == t2) return true; @@ -259,7 +259,7 @@ bool hlsl_type_compare(const struct hlsl_type *t1, const struct hlsl_type *t2) { t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if (!hlsl_type_compare(t1field->type, t2field->type)) + if (!hlsl_types_are_equal(t1field->type, t2field->type)) return false; if (strcmp(t1field->name, t2field->name)) return false; @@ -271,7 +271,7 @@ bool hlsl_type_compare(const struct hlsl_type *t1, const struct hlsl_type *t2) } if (t1->type == HLSL_CLASS_ARRAY) return t1->e.array.elements_count == t2->e.array.elements_count - && hlsl_type_compare(t1->e.array.type, t2->e.array.type); + && hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
return true; } @@ -473,7 +473,7 @@ struct hlsl_ir_node *hlsl_new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_i { struct hlsl_ir_expr *expr;
- assert(hlsl_type_compare(arg1->data_type, arg2->data_type)); + assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
if (!(expr = vkd3d_calloc(1, sizeof(*expr)))) return NULL; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 92ac5270..c15a8d93 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -563,10 +563,10 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) DECLS
struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority) DECLSPEC_HIDDEN; -bool hlsl_type_compare(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN; unsigned int hlsl_type_component_count(struct hlsl_type *type) DECLSPEC_HIDDEN; bool hlsl_type_is_row_major(const struct hlsl_type *type) DECLSPEC_HIDDEN; bool hlsl_type_is_void(const struct hlsl_type *type) DECLSPEC_HIDDEN; +bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN;
int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 47694751..af6c3976 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -169,7 +169,7 @@ static bool compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
if (t1->type == HLSL_CLASS_ARRAY) { - if (hlsl_type_compare(t1->e.array.type, t2)) + if (hlsl_types_are_equal(t1->e.array.type, t2)) /* e.g. float4[3] to float4 is allowed */ return true;
@@ -226,7 +226,7 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ || (t1->type <= HLSL_CLASS_LAST_NUMERIC && t2->type == HLSL_CLASS_ARRAY)) { /* e.g. float4[3] to float4 is allowed */ - if (t1->type == HLSL_CLASS_ARRAY && hlsl_type_compare(t1->e.array.type, t2)) + if (t1->type == HLSL_CLASS_ARRAY && hlsl_types_are_equal(t1->e.array.type, t2)) return true; if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) return true; @@ -254,7 +254,7 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ }
if (t1->type == HLSL_CLASS_STRUCT && t2->type == HLSL_CLASS_STRUCT) - return hlsl_type_compare(t1, t2); + return hlsl_types_are_equal(t1, t2);
return false; } @@ -265,7 +265,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct struct hlsl_type *src_type = node->data_type; struct hlsl_ir_expr *cast;
- if (hlsl_type_compare(src_type, dst_type)) + if (hlsl_types_are_equal(src_type, dst_type)) return node;
if (!implicit_compatible_data_types(src_type, dst_type)) @@ -1046,7 +1046,7 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type return NULL; }
- if (hlsl_type_compare(t1, t2)) + if (hlsl_types_are_equal(t1, t2)) return t1;
if (!expr_compatible_data_types(t1, t2)) @@ -1158,7 +1158,7 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
if (!operands[i]) break; - if (hlsl_type_compare(operands[i]->data_type, type)) + if (hlsl_types_are_equal(operands[i]->data_type, type)) continue; if (operands[i]->data_type->dimx * operands[i]->data_type->dimy != 1 && operands[i]->data_type->dimx * operands[i]->data_type->dimy != type->dimx * type->dimy) @@ -1799,7 +1799,7 @@ hlsl_prog: hlsl_note(ctx, decl->loc, VKD3D_SHADER_LOG_ERROR, ""%s" was previously defined here.", $2.name); YYABORT; } - else if (!hlsl_type_compare(decl->return_type, $2.decl->return_type)) + else if (!hlsl_types_are_equal(decl->return_type, $2.decl->return_type)) { hlsl_error(ctx, $2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Function "%s" was already declared with a different return type.", $2.name); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 283a67e6..5b68a460 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -73,7 +73,7 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (expr->op != HLSL_IR_UNOP_CAST) return false;
- if (hlsl_type_compare(src_type, dst_type) + if (hlsl_types_are_equal(src_type, dst_type) || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) { replace_node(&expr->node, expr->operands[0].node);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 11 +++++++++-- libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 5 +---- 3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index cb13e8fd..85859ada 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -497,17 +497,24 @@ struct hlsl_ir_if *hlsl_new_if(struct hlsl_ir_node *condition, struct vkd3d_shad return iff; }
-struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ir_var *var, const struct vkd3d_shader_location loc) +struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_type *type, const struct vkd3d_shader_location loc) { struct hlsl_ir_load *load;
if (!(load = vkd3d_calloc(1, sizeof(*load)))) return NULL; - init_node(&load->node, HLSL_IR_LOAD, var->data_type, loc); + init_node(&load->node, HLSL_IR_LOAD, type, loc); load->src.var = var; + hlsl_src_from_node(&load->src.offset, offset); return load; }
+struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ir_var *var, const struct vkd3d_shader_location loc) +{ + return hlsl_new_load(var, NULL, var->data_type, loc); +} + struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, struct hlsl_ir_node *val, struct vkd3d_shader_location *loc) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c15a8d93..819b8826 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -530,6 +530,8 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl struct list *parameters, const char *semantic, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_if *hlsl_new_if(struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; +struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type, + struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_loop *hlsl_new_loop(struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index af6c3976..c12b4e9a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -610,11 +610,8 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, list_add_tail(instrs, &assign->node.entry); }
- if (!(load = vkd3d_malloc(sizeof(*load)))) + if (!(load = hlsl_new_load(var, offset, data_type, loc))) return NULL; - init_node(&load->node, HLSL_IR_LOAD, data_type, loc); - load->src.var = var; - hlsl_src_from_node(&load->src.offset, offset); list_add_tail(instrs, &load->node.entry); return load; }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 5b68a460..2382ffe9 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -84,6 +84,86 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst return false; }
+static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_struct_field *field; + const struct hlsl_ir_load *rhs_load; + struct hlsl_ir_assignment *assign; + const struct hlsl_ir_node *rhs; + const struct hlsl_type *type; + + if (instr->type != HLSL_IR_ASSIGNMENT) + return false; + + assign = hlsl_ir_assignment(instr); + rhs = assign->rhs.node; + type = rhs->data_type; + if (type->type != HLSL_CLASS_STRUCT) + return false; + + rhs_load = hlsl_ir_load(rhs); + + LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + { + struct hlsl_ir_node *offset, *add; + struct hlsl_ir_assignment *store; + struct hlsl_ir_load *field_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset * 4, instr->loc))) + { + ctx->failed = true; + return false; + } + list_add_before(&instr->entry, &c->node.entry); + + offset = &c->node; + if (rhs_load->src.offset.node) + { + if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, rhs_load->src.offset.node, &c->node))) + { + ctx->failed = true; + return false; + } + list_add_before(&instr->entry, &add->entry); + offset = add; + } + if (!(field_load = hlsl_new_load(rhs_load->src.var, offset, field->type, instr->loc))) + { + ctx->failed = true; + return false; + } + list_add_before(&instr->entry, &field_load->node.entry); + + offset = &c->node; + if (assign->lhs.offset.node) + { + if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, assign->lhs.offset.node, &c->node))) + { + ctx->failed = true; + return false; + } + list_add_before(&instr->entry, &add->entry); + offset = add; + } + + if (!(store = hlsl_new_assignment(assign->lhs.var, offset, &field_load->node, 0, instr->loc))) + { + ctx->failed = true; + return false; + } + list_add_before(&instr->entry, &store->node.entry); + } + + /* Remove the assignment instruction, so that we can split structs + * which contain other structs. Although assignment instructions + * produce a value, we don't allow HLSL_IR_ASSIGNMENT to be used as + * a source. */ + list_remove(&assign->node.entry); + hlsl_free_instr(&assign->node); + return true; +} + static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -317,6 +397,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun list_move_head(entry_func->body, &ctx->static_initializers);
while (transform_ir(ctx, fold_redundant_casts, entry_func->body, NULL)); + while (transform_ir(ctx, split_struct_copies, entry_func->body, NULL)); while (transform_ir(ctx, fold_constants, entry_func->body, NULL)); while (transform_ir(ctx, dce, entry_func->body, NULL));
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Otherwise we end up overwriting UINT_MAX last_read for output variables.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b6b9ded..b9f753a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -355,7 +355,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs struct hlsl_ir_load *load = hlsl_ir_load(instr);
var = load->src.var; - var->last_read = loop_last ? max(instr->index, loop_last) : instr->index; + var->last_read = max(var->last_read, loop_last ? max(instr->index, loop_last) : instr->index); if (load->src.offset.node) load->src.offset.node->last_read = instr->index; break;
On 3/21/21 3:40 PM, Matteo Bruni wrote:
Otherwise we end up overwriting UINT_MAX last_read for output variables.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b6b9ded..b9f753a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -355,7 +355,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs struct hlsl_ir_load *load = hlsl_ir_load(instr);
var = load->src.var;
var->last_read = loop_last ? max(instr->index, loop_last) : instr->index;
var->last_read = max(var->last_read, loop_last ? max(instr->index, loop_last) : instr->index); if (load->src.offset.node) load->src.offset.node->last_read = instr->index; break;
This works, though I guess the other option is to assign UINT_MAX after calling compute_liveness_recurse().
On Sun, 21 Mar 2021 at 21:54, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 3/21/21 3:40 PM, Matteo Bruni wrote: This works, though I guess the other option is to assign UINT_MAX after calling compute_liveness_recurse().
Is that a Signed-off-by?
On 3/22/21 7:07 AM, Henri Verbeet wrote:
On Sun, 21 Mar 2021 at 21:54, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 3/21/21 3:40 PM, Matteo Bruni wrote: This works, though I guess the other option is to assign UINT_MAX after calling compute_liveness_recurse().
Is that a Signed-off-by?
Yeah, sure :S
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
On Sun, Mar 21, 2021 at 9:54 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 3/21/21 3:40 PM, Matteo Bruni wrote:
Otherwise we end up overwriting UINT_MAX last_read for output variables.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index b6b9ded..b9f753a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -355,7 +355,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs struct hlsl_ir_load *load = hlsl_ir_load(instr);
var = load->src.var;
var->last_read = loop_last ? max(instr->index, loop_last) : instr->index;
var->last_read = max(var->last_read, loop_last ? max(instr->index, loop_last) : instr->index); if (load->src.offset.node) load->src.offset.node->last_read = instr->index; break;
This works, though I guess the other option is to assign UINT_MAX after calling compute_liveness_recurse().
Yeah, I'm not particularly attached to this specific fix. Feel free to change it however you see fit.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2382ffe9..b6b9ded8 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -244,6 +244,19 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) break;
case HLSL_IR_ASSIGNMENT: + { + struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr); + struct hlsl_ir_var *var = assignment->lhs.var; + + if (var->last_read < instr->index) + { + list_remove(&instr->entry); + hlsl_free_instr(instr); + return true; + } + break; + } + case HLSL_IR_IF: case HLSL_IR_JUMP: case HLSL_IR_LOOP: @@ -371,8 +384,18 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { + struct hlsl_scope *scope; struct hlsl_ir_var *var;
+ /* Index 0 means unused; index 1 means function entry, so start at 2. */ + index_instructions(entry_func->body, 2); + + LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + var->first_write = var->last_read = 0; + } + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { var->first_write = 1; @@ -399,16 +422,16 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun while (transform_ir(ctx, fold_redundant_casts, entry_func->body, NULL)); while (transform_ir(ctx, split_struct_copies, entry_func->body, NULL)); while (transform_ir(ctx, fold_constants, entry_func->body, NULL)); + + do + compute_liveness(ctx, entry_func); while (transform_ir(ctx, dce, entry_func->body, NULL));
- /* Index 0 means unused; index 1 means function entry, so start at 2. */ - index_instructions(entry_func->body, 2); + compute_liveness(ctx, entry_func);
if (TRACE_ON()) rb_for_each_entry(&ctx->functions, dump_function, NULL);
- compute_liveness(ctx, entry_func); - if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_NOT_IMPLEMENTED;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Unfortunately with the fix from "patch 3.5" this doesn't eliminate redundant assignments to output variables anymore. That would require some smarter value tracking.
On 3/21/21 3:40 PM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Unfortunately with the fix from "patch 3.5" this doesn't eliminate redundant assignments to output variables anymore. That would require some smarter value tracking.
I don't think this patch ever eliminated redundant assignments, only assignments to variables that were never subsequently read from.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 3 ++- tests/hlsl-invalid.shader_test | 7 +++++++ tests/hlsl-static-initializer.shader_test | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c12b4e9a..45767de9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1472,7 +1472,8 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t local = false; }
- if (type->modifiers & HLSL_MODIFIER_CONST && !(var->modifiers & HLSL_STORAGE_UNIFORM) && !v->initializer.args_count) + if ((type->modifiers & HLSL_MODIFIER_CONST) && !v->initializer.args_count + && !(var->modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_UNIFORM))) { hlsl_error(ctx, v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, "Const variable "%s" is missing an initializer.", var->name); diff --git a/tests/hlsl-invalid.shader_test b/tests/hlsl-invalid.shader_test index 16e75d0a..370d84d4 100644 --- a/tests/hlsl-invalid.shader_test +++ b/tests/hlsl-invalid.shader_test @@ -115,3 +115,10 @@ float4 main() : sv_target { return 0; } + +[pixel shader fail] +float4 main() : sv_target +{ + const float4 x; + return x; +} diff --git a/tests/hlsl-static-initializer.shader_test b/tests/hlsl-static-initializer.shader_test index 9b9d000f..9c486512 100644 --- a/tests/hlsl-static-initializer.shader_test +++ b/tests/hlsl-static-initializer.shader_test @@ -5,9 +5,10 @@ float myfunc() } static float a = myfunc() + 0.2; static float b; +static const float c; float4 main() : sv_target { - return float4(a, b, 0, 0); + return float4(a, b, c, 0); }
[test]
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com