Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 64 ++++++++++++++++---------------- libs/vkd3d-shader/hlsl.h | 22 +++++------ libs/vkd3d-shader/hlsl.y | 50 ++++++++++++------------- libs/vkd3d-shader/hlsl_codegen.c | 59 +++++++++++++++-------------- 4 files changed, 97 insertions(+), 98 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 53b9db36..926e2746 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -418,28 +418,28 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
-struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, +struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) { - struct hlsl_ir_assignment *assign; + struct hlsl_ir_store *store;
if (!writemask && type_is_single_reg(rhs->data_type)) writemask = (1 << rhs->data_type->dimx) - 1;
- if (!(assign = vkd3d_malloc(sizeof(*assign)))) + if (!(store = vkd3d_malloc(sizeof(*store)))) return NULL;
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc); - assign->lhs.var = var; - hlsl_src_from_node(&assign->lhs.offset, offset); - hlsl_src_from_node(&assign->rhs, rhs); - assign->writemask = writemask; - return assign; + init_node(&store->node, HLSL_IR_STORE, NULL, loc); + store->lhs.var = var; + hlsl_src_from_node(&store->lhs.offset, offset); + hlsl_src_from_node(&store->rhs, rhs); + store->writemask = writemask; + return store; }
-struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) { - return hlsl_new_assignment(lhs, NULL, rhs, 0, rhs->loc); + return hlsl_new_store(lhs, NULL, rhs, 0, rhs->loc); }
struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, @@ -830,13 +830,13 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) { static const char * const names[] = { - "HLSL_IR_ASSIGNMENT", "HLSL_IR_CONSTANT", "HLSL_IR_EXPR", "HLSL_IR_IF", "HLSL_IR_LOAD", "HLSL_IR_LOOP", "HLSL_IR_JUMP", + "HLSL_IR_STORE", "HLSL_IR_SWIZZLE", };
@@ -909,14 +909,14 @@ static const char *debug_writemask(DWORD writemask) return vkd3d_dbg_sprintf(".%s", string); }
-static void dump_ir_assignment(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_assignment *assign) +static void dump_ir_assignment(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) { vkd3d_string_buffer_printf(buffer, "= ("); - dump_deref(buffer, &assign->lhs); - if (assign->writemask != VKD3DSP_WRITEMASK_ALL) - vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(assign->writemask)); + dump_deref(buffer, &store->lhs); + if (store->writemask != VKD3DSP_WRITEMASK_ALL) + vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(store->writemask)); vkd3d_string_buffer_printf(buffer, " "); - dump_src(buffer, &assign->rhs); + dump_src(buffer, &store->rhs); vkd3d_string_buffer_printf(buffer, ")"); }
@@ -1111,10 +1111,6 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_
switch (instr->type) { - case HLSL_IR_ASSIGNMENT: - dump_ir_assignment(buffer, hlsl_ir_assignment(instr)); - break; - case HLSL_IR_CONSTANT: dump_ir_constant(buffer, hlsl_ir_constant(instr)); break; @@ -1139,6 +1135,10 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_ dump_ir_loop(buffer, hlsl_ir_loop(instr)); break;
+ case HLSL_IR_STORE: + dump_ir_assignment(buffer, hlsl_ir_store(instr)); + break; + case HLSL_IR_SWIZZLE: dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr)); break; @@ -1198,13 +1198,6 @@ void hlsl_free_instr_list(struct list *list) vkd3d_free(list); }
-static void free_ir_assignment(struct hlsl_ir_assignment *assignment) -{ - hlsl_src_remove(&assignment->rhs); - hlsl_src_remove(&assignment->lhs.offset); - vkd3d_free(assignment); -} - static void free_ir_constant(struct hlsl_ir_constant *constant) { vkd3d_free(constant); @@ -1251,6 +1244,13 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) vkd3d_free(loop); }
+static void free_ir_store(struct hlsl_ir_store *store) +{ + hlsl_src_remove(&store->rhs); + hlsl_src_remove(&store->lhs.offset); + vkd3d_free(store); +} + static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) { hlsl_src_remove(&swizzle->val); @@ -1261,10 +1261,6 @@ void hlsl_free_instr(struct hlsl_ir_node *node) { switch (node->type) { - case HLSL_IR_ASSIGNMENT: - free_ir_assignment(hlsl_ir_assignment(node)); - break; - case HLSL_IR_CONSTANT: free_ir_constant(hlsl_ir_constant(node)); break; @@ -1289,6 +1285,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_loop(hlsl_ir_loop(node)); break;
+ case HLSL_IR_STORE: + free_ir_store(hlsl_ir_store(node)); + break; + case HLSL_IR_SWIZZLE: free_ir_swizzle(hlsl_ir_swizzle(node)); break; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index cf12f63f..c82cd4f5 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -139,13 +139,13 @@ struct hlsl_struct_field
enum hlsl_ir_node_type { - HLSL_IR_ASSIGNMENT = 0, HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_IF, HLSL_IR_LOAD, HLSL_IR_LOOP, HLSL_IR_JUMP, + HLSL_IR_STORE, HLSL_IR_SWIZZLE, };
@@ -352,7 +352,7 @@ struct hlsl_ir_load struct hlsl_deref src; };
-struct hlsl_ir_assignment +struct hlsl_ir_store { struct hlsl_ir_node node; struct hlsl_deref lhs; @@ -420,12 +420,6 @@ enum hlsl_error_level HLSL_LEVEL_NOTE, };
-static inline struct hlsl_ir_assignment *hlsl_ir_assignment(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_ASSIGNMENT); - return CONTAINING_RECORD(node, struct hlsl_ir_assignment, node); -} - static inline struct hlsl_ir_constant *hlsl_ir_constant(const struct hlsl_ir_node *node) { assert(node->type == HLSL_IR_CONSTANT); @@ -462,6 +456,12 @@ static inline struct hlsl_ir_loop *hlsl_ir_loop(const struct hlsl_ir_node *node) return CONTAINING_RECORD(node, struct hlsl_ir_loop, node); }
+static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node) +{ + assert(node->type == HLSL_IR_STORE); + return CONTAINING_RECORD(node, struct hlsl_ir_store, node); +} + static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node *node) { assert(node->type == HLSL_IR_SWIZZLE); @@ -520,8 +520,6 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) DEC
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN; -struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_ir_node *hlsl_new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) DECLSPEC_HIDDEN; struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type *type, @@ -534,8 +532,10 @@ struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_sha 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_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN; +struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN; struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields) DECLSPEC_HIDDEN; 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) DECLSPEC_HIDDEN; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ab7059d3..6216b100 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -499,14 +499,14 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs
if (return_value) { - struct hlsl_ir_assignment *assignment; + struct hlsl_ir_store *store;
if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, &loc))) return NULL;
- if (!(assignment = hlsl_new_simple_assignment(ctx->cur_function->return_var, return_value))) + if (!(store = hlsl_new_simple_store(ctx->cur_function->return_var, return_value))) return NULL; - list_add_after(&return_value->entry, &assignment->node.entry); + list_add_after(&return_value->entry, &store->node.entry); } else if (!hlsl_type_is_void(return_type)) { @@ -543,17 +543,17 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, } else { - struct hlsl_ir_assignment *assign; + struct hlsl_ir_store *store; char name[27];
sprintf(name, "<deref-%p>", var_node); if (!(var = hlsl_new_synthetic_var(ctx, name, var_node->data_type, var_node->loc))) return NULL;
- if (!(assign = hlsl_new_simple_assignment(var, var_node))) + if (!(store = hlsl_new_simple_store(var, var_node))) return NULL;
- list_add_tail(instrs, &assign->node.entry); + list_add_tail(instrs, &store->node.entry); }
if (!(load = hlsl_new_load(var, offset, data_type, loc))) @@ -900,7 +900,7 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type)); return 0;
- case HLSL_IR_ASSIGNMENT: + case HLSL_IR_STORE: default: WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type)); return 0; @@ -1216,7 +1216,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) { struct hlsl_type *lhs_type = lhs->data_type; - struct hlsl_ir_assignment *assign; + struct hlsl_ir_store *store; struct hlsl_ir_expr *copy; DWORD writemask = 0;
@@ -1239,7 +1239,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in return NULL; }
- if (!(assign = vkd3d_malloc(sizeof(*assign)))) + if (!(store = vkd3d_malloc(sizeof(*store)))) return NULL;
while (lhs->type != HLSL_IR_LOAD) @@ -1247,7 +1247,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_IR_UNOP_CAST) { FIXME("Cast on the lhs.\n"); - vkd3d_free(assign); + vkd3d_free(store); return NULL; } else if (lhs->type == HLSL_IR_SWIZZLE) @@ -1261,13 +1261,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in if (!invert_swizzle(&s, &writemask, &width)) { hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); - vkd3d_free(assign); + vkd3d_free(store); return NULL; }
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) { - vkd3d_free(assign); + vkd3d_free(store); return NULL; } list_add_tail(instrs, &new_swizzle->node.entry); @@ -1278,17 +1278,17 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in else { hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); - vkd3d_free(assign); + vkd3d_free(store); return NULL; } }
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, lhs->loc); - assign->writemask = writemask; - assign->lhs.var = hlsl_ir_load(lhs)->src.var; - hlsl_src_from_node(&assign->lhs.offset, hlsl_ir_load(lhs)->src.offset.node); - hlsl_src_from_node(&assign->rhs, rhs); - list_add_tail(instrs, &assign->node.entry); + init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc); + store->writemask = writemask; + store->lhs.var = hlsl_ir_load(lhs)->src.var; + hlsl_src_from_node(&store->lhs.offset, hlsl_ir_load(lhs)->src.offset.node); + hlsl_src_from_node(&store->rhs, rhs); + list_add_tail(instrs, &store->node.entry);
/* Don't use the instruction itself as a source, as this makes structure * splitting easier. Instead copy it here. Since we retrieve sources from @@ -1355,7 +1355,7 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) { struct hlsl_ir_node *node = initializer->args[i]; - struct hlsl_ir_assignment *assign; + struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
if (i++ >= initializer->args_count) @@ -1367,9 +1367,9 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru break; list_add_tail(list, &c->node.entry);
- if (!(assign = hlsl_new_assignment(var, &c->node, node, 0, node->loc))) + if (!(store = hlsl_new_store(var, &c->node, node, 0, node->loc))) break; - list_add_tail(list, &assign->node.entry); + list_add_tail(list, &store->node.entry); } else FIXME("Initializing with "mismatched" fields is not supported yet.\n"); @@ -2724,8 +2724,8 @@ postfix_expr: /* var_modifiers is necessary to avoid shift/reduce conflicts. */ | var_modifiers type '(' initializer_expr_list ')' { - struct hlsl_ir_assignment *assignment; unsigned int i, writemask_offset = 0; + struct hlsl_ir_store *store; static unsigned int counter; struct hlsl_ir_load *load; struct hlsl_ir_var *var; @@ -2788,11 +2788,11 @@ postfix_expr: ctx->builtin_types.vector[$2->base_type][width - 1], &arg->loc))) continue;
- if (!(assignment = hlsl_new_assignment(var, NULL, arg, + if (!(store = hlsl_new_store(var, NULL, arg, ((1 << width) - 1) << writemask_offset, arg->loc))) YYABORT; writemask_offset += width; - list_add_tail($4.instrs, &assignment->node.entry); + list_add_tail($4.instrs, &store->node.entry); } vkd3d_free($4.args); if (!(load = hlsl_new_var_load(var, @2))) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index dbd591af..0641aa0f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -27,8 +27,8 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) { struct vkd3d_string_buffer *name; - struct hlsl_ir_assignment *store; struct hlsl_ir_var *const_var; + struct hlsl_ir_store *store; struct hlsl_ir_load *load;
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers))) @@ -55,7 +55,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru } list_add_head(instrs, &load->node.entry);
- if (!(store = hlsl_new_simple_assignment(var, &load->node))) + if (!(store = hlsl_new_simple_store(var, &load->node))) { ctx->failed = true; return; @@ -67,8 +67,8 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_type *type, unsigned int field_offset, const char *semantic) { struct vkd3d_string_buffer *name; - struct hlsl_ir_assignment *store; struct hlsl_ir_constant *offset; + struct hlsl_ir_store *store; struct hlsl_ir_var *varying; struct hlsl_ir_load *load;
@@ -102,7 +102,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct } list_add_after(&load->node.entry, &offset->node.entry);
- if (!(store = hlsl_new_assignment(var, &offset->node, &load->node, 0, var->loc))) + if (!(store = hlsl_new_store(var, &offset->node, &load->node, 0, var->loc))) { ctx->failed = true; return; @@ -144,8 +144,8 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct struct hlsl_type *type, unsigned int field_offset, const char *semantic) { struct vkd3d_string_buffer *name; - struct hlsl_ir_assignment *store; struct hlsl_ir_constant *offset; + struct hlsl_ir_store *store; struct hlsl_ir_var *varying; struct hlsl_ir_load *load;
@@ -179,7 +179,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct } list_add_after(&offset->node.entry, &load->node.entry);
- if (!(store = hlsl_new_assignment(varying, NULL, &load->node, 0, var->loc))) + if (!(store = hlsl_new_store(varying, NULL, &load->node, 0, var->loc))) { ctx->failed = true; return; @@ -285,15 +285,15 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr { 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; + struct hlsl_ir_store *store;
- if (instr->type != HLSL_IR_ASSIGNMENT) + if (instr->type != HLSL_IR_STORE) return false;
- assign = hlsl_ir_assignment(instr); - rhs = assign->rhs.node; + store = hlsl_ir_store(instr); + rhs = store->rhs.node; type = rhs->data_type; if (type->type != HLSL_CLASS_STRUCT) return false; @@ -302,8 +302,8 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) { + struct hlsl_ir_store *field_store; struct hlsl_ir_node *offset, *add; - struct hlsl_ir_assignment *store; struct hlsl_ir_load *field_load; struct hlsl_ir_constant *c;
@@ -333,9 +333,9 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr list_add_before(&instr->entry, &field_load->node.entry);
offset = &c->node; - if (assign->lhs.offset.node) + if (store->lhs.offset.node) { - if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, assign->lhs.offset.node, &c->node))) + if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, store->lhs.offset.node, &c->node))) { ctx->failed = true; return false; @@ -344,20 +344,19 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr offset = add; }
- if (!(store = hlsl_new_assignment(assign->lhs.var, offset, &field_load->node, 0, instr->loc))) + if (!(field_store = hlsl_new_store(store->lhs.var, offset, &field_load->node, 0, instr->loc))) { ctx->failed = true; return false; } - list_add_before(&instr->entry, &store->node.entry); + list_add_before(&instr->entry, &field_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); + /* Remove the store instruction, so that we can split structs which contain + * other structs. Although assignments produce a value, we don't allow + * HLSL_IR_STORE to be used as a source. */ + list_remove(&store->node.entry); + hlsl_free_instr(&store->node); return true; }
@@ -440,10 +439,10 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) } break;
- case HLSL_IR_ASSIGNMENT: + case HLSL_IR_STORE: { - struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr); - struct hlsl_ir_var *var = assignment->lhs.var; + struct hlsl_ir_store *store = hlsl_ir_store(instr); + struct hlsl_ir_var *var = store->lhs.var;
if (var->last_read < instr->index) { @@ -517,16 +516,16 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs { switch (instr->type) { - case HLSL_IR_ASSIGNMENT: + case HLSL_IR_STORE: { - struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr); + struct hlsl_ir_store *store = hlsl_ir_store(instr);
- var = assignment->lhs.var; + var = store->lhs.var; if (!var->first_write) var->first_write = loop_first ? min(instr->index, loop_first) : instr->index; - assignment->rhs.node->last_read = instr->index; - if (assignment->lhs.offset.node) - assignment->lhs.offset.node->last_read = instr->index; + store->rhs.node->last_read = instr->index; + if (store->lhs.offset.node) + store->lhs.offset.node->last_read = instr->index; break; } case HLSL_IR_EXPR:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 4 +- libs/vkd3d-shader/hlsl.h | 9 ++ libs/vkd3d-shader/hlsl_codegen.c | 185 +++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 926e2746..3618f26e 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -890,7 +890,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der } }
-static const char *debug_writemask(DWORD writemask) +const char *debug_hlsl_writemask(unsigned int writemask) { static const char components[] = {'x', 'y', 'z', 'w'}; char string[5]; @@ -914,7 +914,7 @@ static void dump_ir_assignment(struct vkd3d_string_buffer *buffer, const struct vkd3d_string_buffer_printf(buffer, "= ("); dump_deref(buffer, &store->lhs); if (store->writemask != VKD3DSP_WRITEMASK_ALL) - vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(store->writemask)); + vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); vkd3d_string_buffer_printf(buffer, " "); dump_src(buffer, &store->rhs); vkd3d_string_buffer_printf(buffer, ")"); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c82cd4f5..e642fee1 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -137,6 +137,13 @@ struct hlsl_struct_field unsigned int reg_offset; };
+struct hlsl_reg +{ + uint32_t id; + unsigned char writemask; + bool allocated; +}; + enum hlsl_ir_node_type { HLSL_IR_CONSTANT, @@ -208,6 +215,7 @@ struct hlsl_ir_var struct list scope_entry, param_entry;
unsigned int first_write, last_read; + struct hlsl_reg reg;
uint32_t is_input_varying : 1; uint32_t is_output_varying : 1; @@ -493,6 +501,7 @@ static inline void hlsl_src_remove(struct hlsl_src *src) }
const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN; +const char *debug_hlsl_writemask(unsigned int writemask) DECLSPEC_HIDDEN;
struct vkd3d_string_buffer *hlsl_type_to_string(struct vkd3d_string_buffer_cache *string_buffers, const struct hlsl_type *type) DECLSPEC_HIDDEN; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0641aa0f..a7007886 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -611,6 +611,189 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl compute_liveness_recurse(entry_func->body, 0, 0); }
+struct liveness +{ + size_t size; + struct + { + /* 0 if not live yet. */ + unsigned int last_read; + } *regs; +}; + +static unsigned int get_available_writemask(struct liveness *liveness, + unsigned int first_write, unsigned int component_idx, unsigned int component_count) +{ + unsigned int i, writemask = 0, count = 0; + + for (i = 0; i < 4; ++i) + { + if (liveness->regs[component_idx + i].last_read <= first_write) + { + writemask |= 1u << i; + if (++count == component_count) + return writemask; + } + } + + return 0; +} + +static bool resize_liveness(struct liveness *liveness, size_t new_count) +{ + size_t old_capacity = liveness->size; + + if (!vkd3d_array_reserve((void **)&liveness->regs, &liveness->size, new_count, sizeof(*liveness->regs))) + return false; + + if (liveness->size > old_capacity) + memset(liveness->regs + old_capacity, 0, (liveness->size - old_capacity) * sizeof(*liveness->regs)); + return true; +} + +static struct hlsl_reg allocate_register(struct liveness *liveness, + unsigned int first_write, unsigned int last_read, unsigned int component_count) +{ + struct hlsl_reg ret = {.allocated = true}; + unsigned int component_idx, writemask, i; + + for (component_idx = 0; component_idx < liveness->size; component_idx += 4) + { + if ((writemask = get_available_writemask(liveness, first_write, component_idx, component_count))) + break; + } + if (component_idx == liveness->size) + { + if (!resize_liveness(liveness, component_idx + 4)) + return ret; + writemask = (1u << component_count) - 1; + } + for (i = 0; i < 4; ++i) + { + if (writemask & (1u << i)) + liveness->regs[component_idx + i].last_read = last_read; + } + ret.id = component_idx / 4; + ret.writemask = writemask; + return ret; +} + +static bool is_range_available(struct liveness *liveness, unsigned int first_write, + unsigned int component_idx, unsigned int component_count) +{ + unsigned int i; + + for (i = 0; i < component_count; i += 4) + { + if (!get_available_writemask(liveness, first_write, component_idx + i, 4)) + return false; + } + return true; +} + +static struct hlsl_reg allocate_range(struct liveness *liveness, + unsigned int first_write, unsigned int last_read, unsigned int reg_count) +{ + const unsigned int component_count = reg_count * 4; + struct hlsl_reg ret = {.allocated = true}; + unsigned int i, component_idx; + + for (component_idx = 0; component_idx < liveness->size; component_idx += 4) + { + if (is_range_available(liveness, first_write, component_idx, + min(component_count, liveness->size - component_idx))) + break; + } + if (!resize_liveness(liveness, component_idx + component_count)) + return ret; + + for (i = 0; i < component_count; ++i) + liveness->regs[component_idx + i].last_read = last_read; + ret.id = component_idx / 4; + return ret; +} + +static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) +{ + if (type->reg_size > 4) + return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, + reg.id + type->reg_size - 1); + return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); +} + +static void allocate_variable_temp_register(struct hlsl_ir_var *var, struct liveness *liveness) +{ + if (var->is_input_varying || var->is_output_varying || var->is_uniform) + return; + + if (!var->reg.allocated && var->last_read) + { + if (var->data_type->reg_size > 1) + var->reg = allocate_range(liveness, var->first_write, + var->last_read, var->data_type->reg_size); + else + var->reg = allocate_register(liveness, var->first_write, + var->last_read, var->data_type->dimx); + TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, + debug_register('r', var->reg, var->data_type), var->first_write, var->last_read); + } +} + +static void allocate_temp_registers_recurse(struct list *instrs, struct liveness *liveness) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + allocate_temp_registers_recurse(&iff->then_instrs, liveness); + allocate_temp_registers_recurse(&iff->else_instrs, liveness); + break; + } + + case HLSL_IR_LOAD: + { + struct hlsl_ir_load *load = hlsl_ir_load(instr); + /* We need to at least allocate a variable for undefs. + * FIXME: We should probably find a way to remove them instead. */ + allocate_variable_temp_register(load->src.var, liveness); + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + allocate_temp_registers_recurse(&loop->body, liveness); + break; + } + + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + allocate_variable_temp_register(store->lhs.var, liveness); + break; + } + + default: + break; + } + } +} + +/* Simple greedy temporary register allocation pass that just assigns a unique + * index to all (simultaneously live) variables or intermediate values. Agnostic + * as to how many registers are actually available for the current backend, and + * does not handle constants. */ +static void allocate_temp_registers(struct hlsl_ir_function_decl *entry_func) +{ + struct liveness liveness = {0}; + allocate_temp_registers_recurse(entry_func->body, &liveness); +} + int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { struct hlsl_ir_var *var; @@ -648,6 +831,8 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (TRACE_ON()) rb_for_each_entry(&ctx->functions, dump_function, NULL);
+ allocate_temp_registers(entry_func); + if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_NOT_IMPLEMENTED;
On Mon, Apr 5, 2021 at 6:32 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Sorry for the wait...
libs/vkd3d-shader/hlsl.c | 4 +- libs/vkd3d-shader/hlsl.h | 9 ++ libs/vkd3d-shader/hlsl_codegen.c | 185 +++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c82cd4f5..e642fee1 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -137,6 +137,13 @@ struct hlsl_struct_field unsigned int reg_offset; };
+struct hlsl_reg +{
- uint32_t id;
- unsigned char writemask;
- bool allocated;
+};
Is that unsigned char intentional?
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0641aa0f..a7007886 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c
+static struct hlsl_reg allocate_range(struct liveness *liveness,
unsigned int first_write, unsigned int last_read, unsigned int reg_count)
+{
- const unsigned int component_count = reg_count * 4;
- struct hlsl_reg ret = {.allocated = true};
- unsigned int i, component_idx;
- for (component_idx = 0; component_idx < liveness->size; component_idx += 4)
- {
if (is_range_available(liveness, first_write, component_idx,
min(component_count, liveness->size - component_idx)))
break;
- }
- if (!resize_liveness(liveness, component_idx + component_count))
return ret;
This is going to return ret.allocated = true, which seems problematic.
There's another similar case above.
On 4/8/21 2:29 PM, Matteo Bruni wrote:
On Mon, Apr 5, 2021 at 6:32 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Sorry for the wait...
libs/vkd3d-shader/hlsl.c | 4 +- libs/vkd3d-shader/hlsl.h | 9 ++ libs/vkd3d-shader/hlsl_codegen.c | 185 +++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c82cd4f5..e642fee1 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -137,6 +137,13 @@ struct hlsl_struct_field unsigned int reg_offset; };
+struct hlsl_reg +{
- uint32_t id;
- unsigned char writemask;
- bool allocated;
+};
Is that unsigned char intentional?
Probably some overzealous attempt at structure packing.
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0641aa0f..a7007886 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c
+static struct hlsl_reg allocate_range(struct liveness *liveness,
unsigned int first_write, unsigned int last_read, unsigned int reg_count)
+{
- const unsigned int component_count = reg_count * 4;
- struct hlsl_reg ret = {.allocated = true};
- unsigned int i, component_idx;
- for (component_idx = 0; component_idx < liveness->size; component_idx += 4)
- {
if (is_range_available(liveness, first_write, component_idx,
min(component_count, liveness->size - component_idx)))
break;
- }
- if (!resize_liveness(liveness, component_idx + component_count))
return ret;
This is going to return ret.allocated = true, which seems problematic.
There's another similar case above.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 12 ++++++++++++ 2 files changed, 13 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e642fee1..a1549304 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -171,6 +171,7 @@ struct hlsl_ir_node * true even for loops, since currently we can't have a reference to a * value generated in an earlier iteration of the loop. */ unsigned int index, last_read; + struct hlsl_reg reg; };
struct hlsl_src diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index a7007886..81f4f39f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -745,6 +745,18 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness
LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) { + if (!instr->reg.allocated && instr->last_read) + { + if (instr->data_type->reg_size > 1) + instr->reg = allocate_range(liveness, instr->index, + instr->last_read, instr->data_type->reg_size); + else + instr->reg = allocate_register(liveness, instr->index, + instr->last_read, instr->data_type->dimx); + TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, + debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); + } + switch (instr->type) { case HLSL_IR_IF:
On Mon, Apr 5, 2021 at 6:32 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 12 ++++++++++++ 2 files changed, 13 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e642fee1..a1549304 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -171,6 +171,7 @@ struct hlsl_ir_node * true even for loops, since currently we can't have a reference to a * value generated in an earlier iteration of the loop. */ unsigned int index, last_read;
- struct hlsl_reg reg;
};
struct hlsl_src diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index a7007886..81f4f39f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -745,6 +745,18 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness
LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) {
if (!instr->reg.allocated && instr->last_read)
{
if (instr->data_type->reg_size > 1)
instr->reg = allocate_range(liveness, instr->index,
instr->last_read, instr->data_type->reg_size);
else
instr->reg = allocate_register(liveness, instr->index,
instr->last_read, instr->data_type->dimx);
TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index,
debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read);
}
switch (instr->type) { case HLSL_IR_IF:
It's most likely never going to matter (and right now it doesn't make any difference for sure) but to go "in order" you would allocate the temporary registers for instructions after assigning them for the variables used by the instruction. ... I think you can safely ignore this one.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 18 +++++------------- libs/vkd3d-shader/hlsl.h | 13 +++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3618f26e..8023fc70 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1370,17 +1370,6 @@ void hlsl_add_function(struct rb_tree *funcs, char *name, struct hlsl_ir_functio rb_put(funcs, func->name, &func->entry); }
-struct hlsl_profile_info -{ - const char *name; - enum vkd3d_shader_type type; - DWORD sm_major; - DWORD sm_minor; - DWORD level_major; - DWORD level_minor; - bool sw; -}; - static const struct hlsl_profile_info *get_target_info(const char *target) { unsigned int i; @@ -1556,10 +1545,13 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } }
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_message_context *message_context) +static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct hlsl_profile_info *profile, + struct vkd3d_shader_message_context *message_context) { memset(ctx, 0, sizeof(*ctx));
+ ctx->profile = profile; + ctx->message_context = message_context;
if (!(ctx->source_files = vkd3d_malloc(sizeof(*ctx->source_files)))) @@ -1642,7 +1634,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
vkd3d_shader_dump_shader(profile->type, &compile_info->source);
- if (!hlsl_ctx_init(&ctx, message_context)) + if (!hlsl_ctx_init(&ctx, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY;
if (hlsl_lexer_compile(&ctx, hlsl) == 2) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a1549304..f3ad3666 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -390,8 +390,21 @@ struct hlsl_scope struct hlsl_scope *upper; };
+struct hlsl_profile_info +{ + const char *name; + enum vkd3d_shader_type type; + unsigned int major_version; + unsigned int minor_version; + unsigned int major_level; + unsigned int minor_level; + bool software; +}; + struct hlsl_ctx { + const struct hlsl_profile_info *profile; + const char **source_files; unsigned int source_files_count; struct vkd3d_shader_location location;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index f3ad3666..6ae96d10 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -380,6 +380,7 @@ struct hlsl_ir_constant double d[4]; bool b[4]; } value; + struct hlsl_reg reg; };
struct hlsl_scope diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 81f4f39f..990c9540 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -796,6 +796,55 @@ static void allocate_temp_registers_recurse(struct list *instrs, struct liveness } }
+static void allocate_const_registers_recurse(struct list *instrs, struct liveness *liveness) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_CONSTANT: + { + struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); + + if (instr->data_type->reg_size > 1) + constant->reg = allocate_range(liveness, 1, UINT_MAX, instr->data_type->reg_size); + else + constant->reg = allocate_register(liveness, 1, UINT_MAX, instr->data_type->dimx); + TRACE("Allocated constant @%u to %s.\n", instr->index, + debug_register('c', constant->reg, instr->data_type)); + break; + } + + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + allocate_const_registers_recurse(&iff->then_instrs, liveness); + allocate_const_registers_recurse(&iff->else_instrs, liveness); + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + allocate_const_registers_recurse(&loop->body, liveness); + break; + } + + default: + break; + } + } +} + +static void allocate_const_registers(struct hlsl_ir_function_decl *entry_func) +{ + struct liveness liveness = {0}; + + allocate_const_registers_recurse(entry_func->body, &liveness); +} + /* Simple greedy temporary register allocation pass that just assigns a unique * index to all (simultaneously live) variables or intermediate values. Agnostic * as to how many registers are actually available for the current backend, and @@ -844,6 +893,8 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun rb_for_each_entry(&ctx->functions, dump_function, NULL);
allocate_temp_registers(entry_func); + if (ctx->profile->major_version < 4) + allocate_const_registers(entry_func);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 990c9540..734fa027 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -838,9 +838,25 @@ static void allocate_const_registers_recurse(struct list *instrs, struct livenes } }
-static void allocate_const_registers(struct hlsl_ir_function_decl *entry_func) +static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { struct liveness liveness = {0}; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->is_uniform && var->last_read) + { + if (var->data_type->reg_size > 1) + var->reg = allocate_range(&liveness, 1, INT_MAX, var->data_type->reg_size); + else + { + var->reg = allocate_register(&liveness, 1, INT_MAX, 4); + var->reg.writemask = (1 << var->data_type->dimx) - 1; + } + TRACE("Allocated %s to %s.\n", var->name, debug_register('c', var->reg, var->data_type)); + } + }
allocate_const_registers_recurse(entry_func->body, &liveness); } @@ -894,7 +910,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
allocate_temp_registers(entry_func); if (ctx->profile->major_version < 4) - allocate_const_registers(entry_func); + allocate_const_registers(ctx, entry_func);
if (ctx->failed) return VKD3D_ERROR_INVALID_SHADER;
On Mon, Apr 5, 2021 at 6:32 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 990c9540..734fa027 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -838,9 +838,25 @@ static void allocate_const_registers_recurse(struct list *instrs, struct livenes } }
-static void allocate_const_registers(struct hlsl_ir_function_decl *entry_func) +static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { struct liveness liveness = {0};
- struct hlsl_ir_var *var;
- LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
- {
if (var->is_uniform && var->last_read)
{
if (var->data_type->reg_size > 1)
var->reg = allocate_range(&liveness, 1, INT_MAX, var->data_type->reg_size);
else
{
var->reg = allocate_register(&liveness, 1, INT_MAX, 4);
var->reg.writemask = (1 << var->data_type->dimx) - 1;
}
TRACE("Allocated %s to %s.\n", var->name, debug_register('c', var->reg, var->data_type));
}
- }
I just noticed that this uses INT_MAX, like the old version of patch 5/6. There's also the "1u" thing...
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Nice. A possible followup would be to rename lhs and rhs to something like dst and src or something like that.
Also, any reason why dump_ir_assignment() kept its name?
On 4/8/21 2:27 PM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Nice. A possible followup would be to rename lhs and rhs to something like dst and src or something like that.
Also, any reason why dump_ir_assignment() kept its name?
Nope, I just overlooked it. I'll send a follow-up patch.