From: Zebediah Figura [email protected]
Signed-off-by: Francisco Casas [email protected] --- v2: * No changes. --- libs/vkd3d-shader/hlsl.c | 123 +++++++++++++++---------------- libs/vkd3d-shader/hlsl.h | 10 ++- libs/vkd3d-shader/hlsl.y | 99 ++++++++++++++----------- libs/vkd3d-shader/hlsl_codegen.c | 18 +++-- libs/vkd3d-shader/hlsl_sm1.c | 13 +++- libs/vkd3d-shader/hlsl_sm4.c | 13 +++- 6 files changed, 150 insertions(+), 126 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 7239b183..b349eb15 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -175,13 +175,14 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
case HLSL_CLASS_STRUCT: { - struct hlsl_struct_field *field; + unsigned int i;
type->dimx = 0; type->reg_size = 0;
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + struct hlsl_struct_field *field = &type->e.record.fields[i]; unsigned int field_size = field->type->reg_size;
assert(field_size); @@ -282,10 +283,12 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ case HLSL_CLASS_STRUCT: { struct hlsl_struct_field *field; + unsigned int elem_comp_count, i;
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { - unsigned int elem_comp_count = hlsl_type_component_count(field->type); + field = &type->e.record.fields[i]; + elem_comp_count = hlsl_type_component_count(field->type);
if (idx < elem_comp_count) { @@ -331,7 +334,8 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba return type; }
-struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields) +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_type *type;
@@ -341,7 +345,8 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, s type->base_type = HLSL_TYPE_VOID; type->name = name; type->dimy = 1; - type->e.elements = fields; + type->e.record.fields = fields; + type->e.record.field_count = field_count; hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry); @@ -401,8 +406,7 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha
unsigned int hlsl_type_component_count(struct hlsl_type *type) { - struct hlsl_struct_field *field; - unsigned int count = 0; + unsigned int count = 0, i;
if (type->type <= HLSL_CLASS_LAST_NUMERIC) { @@ -418,10 +422,8 @@ unsigned int hlsl_type_component_count(struct hlsl_type *type) return 0; }
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - count += hlsl_type_component_count(field->type); - } + for (i = 0; i < type->e.record.field_count; ++i) + count += hlsl_type_component_count(type->e.record.fields[i].type); return count; }
@@ -451,24 +453,22 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 return false; if (t1->type == HLSL_CLASS_STRUCT) { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; + size_t i; + + if (t1->e.record.field_count != t2->e.record.field_count) + return false;
- t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) + for (i = 0; i < t1->e.record.field_count; ++i) { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if (!hlsl_types_are_equal(t1field->type, t2field->type)) + const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; + const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + + if (!hlsl_types_are_equal(field1->type, field2->type)) return false; - if (strcmp(t1field->name, t2field->name)) + + if (strcmp(field1->name, field2->name)) return false; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); } - if (t1cur != t2cur) - return false; } if (t1->type == HLSL_CLASS_ARRAY) return t1->e.array.elements_count == t2->e.array.elements_count @@ -480,7 +480,6 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers) { - struct hlsl_struct_field *old_field, *field; struct hlsl_type *type;
if (!(type = hlsl_alloc(ctx, sizeof(*type)))) @@ -512,37 +511,30 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
case HLSL_CLASS_STRUCT: { - if (!(type->e.elements = hlsl_alloc(ctx, sizeof(*type->e.elements)))) + size_t field_count = old->e.record.field_count, i; + + type->e.record.field_count = field_count; + + if (!(type->e.record.fields = hlsl_alloc(ctx, field_count * sizeof(*type->e.record.fields)))) { vkd3d_free((void *)type->name); vkd3d_free(type); return NULL; } - list_init(type->e.elements); - LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry) + + for (i = 0; i < field_count; ++i) { - if (!(field = hlsl_alloc(ctx, sizeof(*field)))) - { - LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry) - { - vkd3d_free((void *)field->semantic.name); - vkd3d_free((void *)field->name); - vkd3d_free(field); - } - vkd3d_free(type->e.elements); - vkd3d_free((void *)type->name); - vkd3d_free(type); - return NULL; - } - field->loc = old_field->loc; - field->type = hlsl_type_clone(ctx, old_field->type, default_majority, modifiers); - field->name = hlsl_strdup(ctx, old_field->name); - if (old_field->semantic.name) + const struct hlsl_struct_field *src_field = &old->e.record.fields[i]; + struct hlsl_struct_field *dst_field = &type->e.record.fields[i]; + + dst_field->loc = src_field->loc; + dst_field->type = hlsl_type_clone(ctx, src_field->type, default_majority, modifiers); + dst_field->name = hlsl_strdup(ctx, src_field->name); + if (src_field->semantic.name) { - field->semantic.name = hlsl_strdup(ctx, old_field->semantic.name); - field->semantic.index = old_field->semantic.index; + dst_field->semantic.name = hlsl_strdup(ctx, src_field->semantic.name); + dst_field->semantic.index = src_field->semantic.index; } - list_add_tail(type->e.elements, &field->entry); } break; } @@ -911,24 +903,22 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return r; if (t1->type == HLSL_CLASS_STRUCT) { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; + size_t i;
- t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) + if (t1->e.record.field_count != t2->e.record.field_count) + return t1->e.record.field_count - t2->e.record.field_count; + + for (i = 0; i < t1->e.record.field_count; ++i) { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if ((r = compare_param_hlsl_types(t1field->type, t2field->type))) + const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; + const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + + if ((r = compare_param_hlsl_types(field1->type, field2->type))) return r; - if ((r = strcmp(t1field->name, t2field->name))) + + if ((r = strcmp(field1->name, field2->name))) return r; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); } - if (t1cur != t2cur) - return t1cur ? 1 : -1; return 0; } if (t1->type == HLSL_CLASS_ARRAY) @@ -1519,17 +1509,20 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
void hlsl_free_type(struct hlsl_type *type) { - struct hlsl_struct_field *field, *next_field; + struct hlsl_struct_field *field; + size_t i;
vkd3d_free((void *)type->name); if (type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + field = &type->e.record.fields[i]; + vkd3d_free((void *)field->name); vkd3d_free((void *)field->semantic.name); - vkd3d_free(field); } + vkd3d_free((void *)type->e.record.fields); } vkd3d_free(type); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3c1dd08d..ce1f69df 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -126,7 +126,11 @@ struct hlsl_type unsigned int dimy; union { - struct list *elements; + struct + { + struct hlsl_struct_field *fields; + size_t field_count; + } record; struct { struct hlsl_type *type; @@ -147,7 +151,6 @@ struct hlsl_semantic
struct hlsl_struct_field { - struct list entry; struct vkd3d_shader_location loc; struct hlsl_type *type; const char *name; @@ -752,7 +755,8 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, 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_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields); +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_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 09a01c6d..f293b82e 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -28,6 +28,12 @@
#define HLSL_YYLTYPE struct vkd3d_shader_location
+struct parse_fields +{ + struct hlsl_struct_field *fields; + size_t count, capacity; +}; + struct parse_parameter { struct hlsl_type *type; @@ -799,14 +805,15 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls return !!add_load(ctx, instrs, array, index, data_type, loc); }
-static struct hlsl_struct_field *get_struct_field(struct list *fields, const char *name) +static const struct hlsl_struct_field *get_struct_field(const struct hlsl_struct_field *fields, + size_t count, const char *name) { - struct hlsl_struct_field *f; + size_t i;
- LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) + for (i = 0; i < count; ++i) { - if (!strcmp(f->name, name)) - return f; + if (!strcmp(fields[i].name, name)) + return &fields[i]; } return NULL; } @@ -857,31 +864,28 @@ static void free_parse_variable_def(struct parse_variable_def *v) vkd3d_free(v); }
-static struct list *gen_struct_fields(struct hlsl_ctx *ctx, - struct hlsl_type *type, unsigned int modifiers, struct list *fields) +static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, + struct hlsl_type *type, unsigned int modifiers, struct list *defs) { struct parse_variable_def *v, *v_next; - struct hlsl_struct_field *field; - struct list *list; + size_t i = 0;
if (type->type == HLSL_CLASS_MATRIX) assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
- if (!(list = make_empty_list(ctx))) - return NULL; - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry) - { - unsigned int i; + memset(fields, 0, sizeof(*fields)); + fields->count = list_count(defs); + if (!hlsl_array_reserve(ctx, (void **)&fields->fields, &fields->capacity, fields->count, sizeof(*fields->fields))) + return false;
- if (!(field = hlsl_alloc(ctx, sizeof(*field)))) - { - free_parse_variable_def(v); - continue; - } + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, defs, struct parse_variable_def, entry) + { + struct hlsl_struct_field *field = &fields->fields[i++]; + unsigned int j;
field->type = type; - for (i = 0; i < v->arrays.count; ++i) - field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[i]); + for (j = 0; j < v->arrays.count; ++j) + field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[j]); vkd3d_free(v->arrays.sizes); field->loc = v->loc; field->name = v->name; @@ -892,11 +896,10 @@ static struct list *gen_struct_fields(struct hlsl_ctx *ctx, hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); free_parse_initializer(&v->initializer); } - list_add_tail(list, &field->entry); vkd3d_free(v); } - vkd3d_free(fields); - return list; + vkd3d_free(defs); + return true; }
static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type *orig_type, struct list *list) @@ -2681,6 +2684,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl DWORD modifiers; struct hlsl_ir_node *instr; struct list *list; + struct parse_fields fields; struct parse_function function; struct parse_parameter parameter; struct parse_initializer initializer; @@ -2809,8 +2813,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl %type <list> equality_expr %type <list> expr %type <list> expr_statement -%type <list> field -%type <list> fields_list %type <list> initializer_expr %type <list> jump_statement %type <list> logicand_expr @@ -2847,6 +2849,9 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
%type <colon_attribute> colon_attribute
+%type <fields> field +%type <fields> fields_list + %type <function> func_declaration %type <function> func_prototype
@@ -3002,7 +3007,7 @@ named_struct_spec: { bool ret;
- $$ = hlsl_new_struct_type(ctx, $2, $4); + $$ = hlsl_new_struct_type(ctx, $2, $4.fields, $4.count);
if (hlsl_get_var(ctx->cur_scope, $2)) { @@ -3021,7 +3026,7 @@ named_struct_spec: unnamed_struct_spec: KW_STRUCT '{' fields_list '}' { - $$ = hlsl_new_struct_type(ctx, NULL, $3); + $$ = hlsl_new_struct_type(ctx, NULL, $3.fields, $3.count); }
any_identifier: @@ -3032,30 +3037,35 @@ any_identifier: fields_list: %empty { - if (!($$ = make_empty_list(ctx))) - YYABORT; + $$.fields = NULL; + $$.count = 0; + $$.capacity = 0; } | fields_list field { - struct hlsl_struct_field *field, *next, *existing; + size_t i;
- $$ = $1; - LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) + for (i = 0; i < $2.count; ++i) { - if ((existing = get_struct_field($$, field->name))) + const struct hlsl_struct_field *field = &$2.fields[i]; + const struct hlsl_struct_field *existing; + + if ((existing = get_struct_field($1.fields, $1.count, field->name))) { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Field "%s" is already defined.", field->name); hlsl_note(ctx, &existing->loc, VKD3D_SHADER_LOG_ERROR, "'%s' was previously defined here.", field->name); - vkd3d_free(field); - } - else - { - list_add_tail($$, &field->entry); } } - vkd3d_free($2); + + if (!hlsl_array_reserve(ctx, (void **)&$1.fields, &$1.capacity, $1.count + $2.count, sizeof(*$1.fields))) + YYABORT; + memcpy($1.fields + $1.count, $2.fields, $2.count * sizeof(*$2.fields)); + $1.count += $2.count; + vkd3d_free($2.fields); + + $$ = $1; }
field_type: @@ -3079,7 +3089,8 @@ field: "Modifiers '%s' are not allowed on struct fields.", string->buffer); hlsl_release_string_buffer(ctx, string); } - $$ = gen_struct_fields(ctx, type, modifiers, $3); + if (!gen_struct_fields(ctx, &$$, type, modifiers, $3)) + YYABORT; }
func_declaration: @@ -3936,9 +3947,9 @@ postfix_expr: if (node->data_type->type == HLSL_CLASS_STRUCT) { struct hlsl_type *type = node->data_type; - struct hlsl_struct_field *field; + const struct hlsl_struct_field *field;
- if (!(field = get_struct_field(type->e.elements, $3))) + if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) { hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field "%s" is not defined.", $3); YYABORT; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index bc7f0a62..484b415d 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -137,10 +137,12 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, struct hlsl_type *type, unsigned int field_offset) { - struct hlsl_struct_field *field; + size_t i;
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + if (field->type->type == HLSL_CLASS_STRUCT) prepend_input_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); else if (field->semantic.name) @@ -225,10 +227,12 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, struct hlsl_type *type, unsigned int field_offset) { - struct hlsl_struct_field *field; + size_t i;
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + if (field->type->type == HLSL_CLASS_STRUCT) append_output_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); else if (field->semantic.name) @@ -859,10 +863,10 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
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_node *rhs; const struct hlsl_type *type; struct hlsl_ir_store *store; + size_t i;
if (instr->type != HLSL_IR_STORE) return false; @@ -879,8 +883,10 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; }
- LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + if (!split_copy(ctx, store, hlsl_ir_load(rhs), field->reg_offset, field->type)) return false; } diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 0cdd3917..06313a42 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -243,28 +243,33 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ { const struct hlsl_type *array_type = get_array_type(type); unsigned int array_size = get_array_size(type); - struct hlsl_struct_field *field; unsigned int field_count = 0; size_t fields_offset = 0; + size_t i;
if (type->bytecode_offset) return;
if (array_type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + field_count = array_type->e.record.field_count; + + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + field->name_bytecode_offset = put_string(buffer, field->name); write_sm1_type(buffer, field->type, ctab_start); }
fields_offset = bytecode_get_size(buffer) - ctab_start;
- LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + put_u32(buffer, field->name_bytecode_offset - ctab_start); put_u32(buffer, field->type->bytecode_offset - ctab_start); - ++field_count; } }
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 79027169..7758555b 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -355,7 +355,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b const struct hlsl_profile_info *profile = ctx->profile; unsigned int field_count = 0, array_size = 0; size_t fields_offset = 0, name_offset = 0; - struct hlsl_struct_field *field; + size_t i;
if (type->bytecode_offset) return; @@ -368,20 +368,25 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
if (array_type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + field_count = array_type->e.record.field_count; + + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + field->name_bytecode_offset = put_string(buffer, field->name); write_sm4_type(ctx, buffer, field->type); }
fields_offset = bytecode_get_size(buffer);
- LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + put_u32(buffer, field->name_bytecode_offset); put_u32(buffer, field->type->bytecode_offset); put_u32(buffer, field->reg_offset); - ++field_count; } }
Signed-off-by: Francisco Casas [email protected] ---
v2: * New in v2.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b349eb15..eac58c69 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -505,7 +505,12 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, switch (old->type) { case HLSL_CLASS_ARRAY: - type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers); + if (!(type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers))) + { + vkd3d_free((void *)type->name); + vkd3d_free(type); + return NULL; + } type->e.array.elements_count = old->e.array.elements_count; break;
@@ -528,7 +533,13 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, struct hlsl_struct_field *dst_field = &type->e.record.fields[i];
dst_field->loc = src_field->loc; - dst_field->type = hlsl_type_clone(ctx, src_field->type, default_majority, modifiers); + if (!(dst_field->type = hlsl_type_clone(ctx, src_field->type, default_majority, modifiers))) + { + vkd3d_free(type->e.record.fields); + vkd3d_free((void *)type->name); + vkd3d_free(type); + return NULL; + } dst_field->name = hlsl_strdup(ctx, src_field->name); if (src_field->semantic.name) {
Signed-off-by: Zebediah Figura [email protected]
Signed-off-by: Henri Verbeet [email protected]
Signed-off-by: Francisco Casas [email protected] ---
v2: * Getting field index using pointer arithmetic.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.y | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f293b82e..bfafd981 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -669,10 +669,14 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, }
static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, - const struct hlsl_struct_field *field, const struct vkd3d_shader_location loc) + unsigned int idx, const struct vkd3d_shader_location loc) { + const struct hlsl_struct_field *field; struct hlsl_ir_constant *c;
+ assert(idx < record->data_type->e.record.field_count); + field = &record->data_type->e.record.fields[idx]; + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, &loc))) return false; list_add_tail(instrs, &c->node.entry); @@ -3948,6 +3952,7 @@ postfix_expr: { struct hlsl_type *type = node->data_type; const struct hlsl_struct_field *field; + unsigned int field_idx = 0;
if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) { @@ -3955,7 +3960,8 @@ postfix_expr: YYABORT; }
- if (!add_record_load(ctx, $1, node, field, @2)) + field_idx = field - type->e.record.fields; + if (!add_record_load(ctx, $1, node, field_idx, @2)) YYABORT; $$ = $1; }
Signed-off-by: Zebediah Figura [email protected]
Signed-off-by: Henri Verbeet [email protected]
Signed-off-by: Francisco Casas [email protected] ---
v2: * Renamed hlsl_free_deref() to cleanup_deref(). * Made function static.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index eac58c69..2925b4e5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -621,6 +621,11 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
+static void cleanup_deref(struct hlsl_deref *deref) +{ + hlsl_src_remove(&deref->offset); +} + struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) { @@ -1579,7 +1584,7 @@ static void free_ir_jump(struct hlsl_ir_jump *jump)
static void free_ir_load(struct hlsl_ir_load *load) { - hlsl_src_remove(&load->src.offset); + cleanup_deref(&load->src); vkd3d_free(load); }
@@ -1592,8 +1597,8 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { hlsl_src_remove(&load->coords); - hlsl_src_remove(&load->sampler.offset); - hlsl_src_remove(&load->resource.offset); + cleanup_deref(&load->sampler); + cleanup_deref(&load->resource); hlsl_src_remove(&load->texel_offset); vkd3d_free(load); } @@ -1601,7 +1606,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) static void free_ir_store(struct hlsl_ir_store *store) { hlsl_src_remove(&store->rhs); - hlsl_src_remove(&store->lhs.offset); + cleanup_deref(&store->lhs); vkd3d_free(store); }
Signed-off-by: Zebediah Figura [email protected]
Signed-off-by: Henri Verbeet [email protected]
Signed-off-by: Francisco Casas [email protected] ---
v2: * Use "const struct vkd3d_shader_location *" instead of "const struct vkd3d_shader_location". * Removed 'in hlsl.y' in the patch subject. * Use vkd3d_string_buffer for initializing the deref synthetic variable names. * Move common "load = hlsl_new_load" pattern out of the if..else branches.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.y | 98 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..f5c9f4ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -272,8 +272,8 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, - struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc); +static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, + unsigned int comp, const struct vkd3d_shader_location *loc);
static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) @@ -311,8 +311,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) { - struct hlsl_type *src_scalar_type, *dst_scalar_type; - unsigned int src_idx, src_offset, dst_offset; + struct hlsl_type *dst_scalar_type; + unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
@@ -335,13 +335,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, }
dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type); - src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type); - - if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry);
- if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc))) + if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL;
if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc))) @@ -668,6 +663,62 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, return load; }
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, + unsigned int comp, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *comp_type; + struct hlsl_ir_node *offset; + struct hlsl_ir_constant *c; + struct hlsl_ir_load *load; + unsigned int comp_offset; + struct hlsl_ir_var *var; + + comp_offset = hlsl_compute_component_offset(ctx, var_node->data_type, comp, &comp_type); + + if (!(c = hlsl_new_uint_constant(ctx, comp_offset, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + offset = &c->node; + + if (var_node->type == HLSL_IR_LOAD) + { + const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src; + struct hlsl_ir_node *add; + + var = src->var; + if (src->offset.node) + { + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, &c->node))) + return NULL; + list_add_tail(instrs, &add->entry); + offset = add; + } + } + else + { + struct vkd3d_string_buffer *name; + struct hlsl_ir_store *store; + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); + var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + if (!(store = hlsl_new_simple_store(ctx, var, var_node))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, offset, comp_type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return load; +} + static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location loc) { @@ -1766,22 +1817,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
for (k = 0; k < src_comp_count; ++k) { - struct hlsl_type *dst_comp_type, *src_comp_type; - unsigned int dst_reg_offset, src_reg_offset; + struct hlsl_type *dst_comp_type; + unsigned int dst_reg_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c; struct hlsl_ir_load *load; struct hlsl_ir_node *conv;
- dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type); - src_reg_offset = hlsl_compute_component_offset(ctx, src->data_type, k, &src_comp_type); - - if (!(c = hlsl_new_uint_constant(ctx, src_reg_offset, &src->loc))) + if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) return; - list_add_tail(instrs, &c->node.entry);
- if (!(load = add_load(ctx, instrs, src, &c->node, src_comp_type, src->loc))) - return; + dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type);
if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) return; @@ -2218,20 +2264,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, struct hlsl_ir_load *value1, *value2; struct hlsl_ir_node *mul;
- offset = hlsl_compute_component_offset(ctx, cast_type1, j * cast_type1->dimx + k, &scalar_type); - if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) - return false; - list_add_tail(params->instrs, &c->node.entry); - - if (!(value1 = add_load(ctx, params->instrs, cast1, &c->node, scalar_type, *loc))) - return false; - - offset = hlsl_compute_component_offset(ctx, cast_type2, k * cast_type2->dimx + i, &scalar_type); - if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + if (!(value1 = add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) return false; - list_add_tail(params->instrs, &c->node.entry);
- if (!(value2 = add_load(ctx, params->instrs, cast2, &c->node, scalar_type, *loc))) + if (!(value2 = add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) return false;
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc)))
Patch series looks mostly fine now, just going to throw some nitpicks in there, or things I didn't notice the first time...
On 7/14/22 20:23, Francisco Casas wrote:
- else
- {
struct vkd3d_string_buffer *name;
struct hlsl_ir_store *store;
name = vkd3d_string_buffer_get(&ctx->string_buffers);
vkd3d_string_buffer_printf(name, "<deref-%p>", var_node);
var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc);
vkd3d_string_buffer_release(&ctx->string_buffers, name);
hlsl_get_string_buffer() [which can fail due to memory exhaustion] and hlsl_release_string_buffer().
if (!var)
return NULL;
if (!(store = hlsl_new_simple_store(ctx, var, var_node)))
return NULL;
list_add_tail(instrs, &store->node.entry);
- }
- if (!(load = hlsl_new_load(ctx, var, offset, comp_type, *loc)))
return NULL;
- list_add_tail(instrs, &load->node.entry);
- return load;
+}
Signed-off-by: Giovanni Mascellani [email protected]
(after the changes suggested by Zeb)
Il 15/07/22 03:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v2:
- Use "const struct vkd3d_shader_location *" instead of "const struct vkd3d_shader_location".
- Removed 'in hlsl.y' in the patch subject.
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.y | 98 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..f5c9f4ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -272,8 +272,8 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc);
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc);
static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
@@ -311,8 +311,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) {
struct hlsl_type *src_scalar_type, *dst_scalar_type;
unsigned int src_idx, src_offset, dst_offset;
struct hlsl_type *dst_scalar_type;
unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
@@ -335,13 +335,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, }
dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type);
src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc)))
if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL; if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc)))
@@ -668,6 +663,62 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, return load; }
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc)
+{
- struct hlsl_type *comp_type;
- struct hlsl_ir_node *offset;
- struct hlsl_ir_constant *c;
- struct hlsl_ir_load *load;
- unsigned int comp_offset;
- struct hlsl_ir_var *var;
- comp_offset = hlsl_compute_component_offset(ctx, var_node->data_type, comp, &comp_type);
- if (!(c = hlsl_new_uint_constant(ctx, comp_offset, loc)))
return NULL;
- list_add_tail(instrs, &c->node.entry);
- offset = &c->node;
- if (var_node->type == HLSL_IR_LOAD)
- {
const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src;
struct hlsl_ir_node *add;
var = src->var;
if (src->offset.node)
{
if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, &c->node)))
return NULL;
list_add_tail(instrs, &add->entry);
offset = add;
}
- }
- else
- {
struct vkd3d_string_buffer *name;
struct hlsl_ir_store *store;
name = vkd3d_string_buffer_get(&ctx->string_buffers);
vkd3d_string_buffer_printf(name, "<deref-%p>", var_node);
var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc);
vkd3d_string_buffer_release(&ctx->string_buffers, name);
if (!var)
return NULL;
if (!(store = hlsl_new_simple_store(ctx, var, var_node)))
return NULL;
list_add_tail(instrs, &store->node.entry);
- }
- if (!(load = hlsl_new_load(ctx, var, offset, comp_type, *loc)))
return NULL;
- list_add_tail(instrs, &load->node.entry);
- return load;
+}
- static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location loc) {
@@ -1766,22 +1817,17 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
for (k = 0; k < src_comp_count; ++k) {
struct hlsl_type *dst_comp_type, *src_comp_type;
unsigned int dst_reg_offset, src_reg_offset;
struct hlsl_type *dst_comp_type;
unsigned int dst_reg_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c; struct hlsl_ir_load *load; struct hlsl_ir_node *conv;
dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type);
src_reg_offset = hlsl_compute_component_offset(ctx, src->data_type, k, &src_comp_type);
if (!(c = hlsl_new_uint_constant(ctx, src_reg_offset, &src->loc)))
if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) return;
list_add_tail(instrs, &c->node.entry);
if (!(load = add_load(ctx, instrs, src, &c->node, src_comp_type, src->loc)))
return;
dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type); if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) return;
@@ -2218,20 +2264,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, struct hlsl_ir_load *value1, *value2; struct hlsl_ir_node *mul;
offset = hlsl_compute_component_offset(ctx, cast_type1, j * cast_type1->dimx + k, &scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, offset, loc)))
return false;
list_add_tail(params->instrs, &c->node.entry);
if (!(value1 = add_load(ctx, params->instrs, cast1, &c->node, scalar_type, *loc)))
return false;
offset = hlsl_compute_component_offset(ctx, cast_type2, k * cast_type2->dimx + i, &scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, offset, loc)))
if (!(value1 = add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) return false;
list_add_tail(params->instrs, &c->node.entry);
if (!(value2 = add_load(ctx, params->instrs, cast2, &c->node, scalar_type, *loc)))
if (!(value2 = add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) return false; if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc)))
Okay, I guess I managed to read the patch series through. Sorry it took me way longer than I'd hoped, and I didn't even properly review the individual patches (e.g. apply them and check that the tests pass after each one).
In general the patch series seems okay to me and, as far as I'm concerned, if this goes in with no changes at all I would have no qualms.
That said, I do have a number of relatively minor comments that I'll send in reply to individual patches. For the earlier patches in the series (like this one) I'm going to reply to "v2" since that's where I had started to write them, but I don't think anything mentioned in those was affected by the changes in v3.
On Fri, Jul 15, 2022 at 3:24 AM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v2:
- Use "const struct vkd3d_shader_location *" instead of "const struct vkd3d_shader_location".
- Removed 'in hlsl.y' in the patch subject.
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.y | 98 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..f5c9f4ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -272,8 +272,8 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc);
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc);
static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) @@ -311,8 +311,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) {
struct hlsl_type *src_scalar_type, *dst_scalar_type;
unsigned int src_idx, src_offset, dst_offset;
struct hlsl_type *dst_scalar_type;
unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
@@ -335,13 +335,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, }
dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type);
src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc)))
if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL; if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc)))
@@ -668,6 +663,62 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, return load; }
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc)
I would avoid using any "node" variable name in new code.
On 28-07-22 16:44, Matteo Bruni wrote:
Okay, I guess I managed to read the patch series through. Sorry it took me way longer than I'd hoped, and I didn't even properly review the individual patches (e.g. apply them and check that the tests pass after each one).
In general the patch series seems okay to me and, as far as I'm concerned, if this goes in with no changes at all I would have no qualms.
That said, I do have a number of relatively minor comments that I'll send in reply to individual patches. For the earlier patches in the series (like this one) I'm going to reply to "v2" since that's where I had started to write them, but I don't think anything mentioned in those was affected by the changes in v3.
On Fri, Jul 15, 2022 at 3:24 AM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v2:
- Use "const struct vkd3d_shader_location *" instead of "const struct vkd3d_shader_location".
- Removed 'in hlsl.y' in the patch subject.
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.y | 98 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..f5c9f4ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -272,8 +272,8 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc);
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc);
static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
@@ -311,8 +311,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) {
struct hlsl_type *src_scalar_type, *dst_scalar_type;
unsigned int src_idx, src_offset, dst_offset;
struct hlsl_type *dst_scalar_type;
unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
@@ -335,13 +335,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, }
dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type);
src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc)))
if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL; if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc)))
@@ -668,6 +663,62 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, return load; }
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc)
I would avoid using any "node" variable name in new code.
Understood. However, in this particular case (and later, add_load_index()) I can't think of a better name for the node argument, besides "value".
On Wed, Aug 3, 2022 at 11:26 PM Francisco Casas [email protected] wrote:
On 28-07-22 16:44, Matteo Bruni wrote:
Okay, I guess I managed to read the patch series through. Sorry it took me way longer than I'd hoped, and I didn't even properly review the individual patches (e.g. apply them and check that the tests pass after each one).
In general the patch series seems okay to me and, as far as I'm concerned, if this goes in with no changes at all I would have no qualms.
That said, I do have a number of relatively minor comments that I'll send in reply to individual patches. For the earlier patches in the series (like this one) I'm going to reply to "v2" since that's where I had started to write them, but I don't think anything mentioned in those was affected by the changes in v3.
On Fri, Jul 15, 2022 at 3:24 AM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v2:
- Use "const struct vkd3d_shader_location *" instead of "const struct vkd3d_shader_location".
- Removed 'in hlsl.y' in the patch subject.
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.y | 98 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..f5c9f4ca 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -272,8 +272,8 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc);
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc);
static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
@@ -311,8 +311,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) {
struct hlsl_type *src_scalar_type, *dst_scalar_type;
unsigned int src_idx, src_offset, dst_offset;
struct hlsl_type *dst_scalar_type;
unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; struct hlsl_ir_constant *c;
@@ -335,13 +335,8 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, }
dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type);
src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type);
if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc)))
if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL; if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc)))
@@ -668,6 +663,62 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, return load; }
+static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
unsigned int comp, const struct vkd3d_shader_location *loc)
I would avoid using any "node" variable name in new code.
Understood. However, in this particular case (and later, add_load_index()) I can't think of a better name for the node argument, besides "value".
"Instr" should always work as a replacement. Node really isn't an appropriate name anymore, specifically since we flattened the IR a while back.
At this point add_load() is split into add_load_component() and add_load_index(); register offsets are hidden for these functions.
Signed-off-by: Francisco Casas [email protected] ---
v2: * Use "const struct vkd3d_shader_location *loc" instead of "const struct vkd3d_shader_location loc" * Use vkd3d_string_buffer for initializing the deref synthetic variable names. * Move common "load = hlsl_new_load" pattern out of the if..else branches. * Removed braces on simple switch cases in hlsl_new_offset_from_path_index(). I kept them in the HLSL_CLASS_MATRIX case, even though it doesn't have declarations, because its body seems complex enough.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 105 +++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 7 ++ libs/vkd3d-shader/hlsl.y | 134 ++++++++++++++------------------------- 3 files changed, 157 insertions(+), 89 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2925b4e5..e4e2ca17 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -117,7 +117,7 @@ void hlsl_free_var(struct hlsl_ir_var *decl) vkd3d_free(decl); }
-static bool hlsl_type_is_row_major(const struct hlsl_type *type) +bool hlsl_type_is_row_major(const struct hlsl_type *type) { /* Default to column-major if the majority isn't explicitly set, which can * happen for anonymous nodes. */ @@ -314,6 +314,109 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ return 0; }
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, + struct hlsl_ir_node *node) +{ + assert(node); + + if (type->type == HLSL_CLASS_VECTOR) + return hlsl_get_scalar_type(ctx, type->base_type); + + if (type->type == HLSL_CLASS_MATRIX) + { + if (hlsl_type_is_row_major(type)) + return hlsl_get_vector_type(ctx, type->base_type, type->dimx); + else + return hlsl_get_vector_type(ctx, type->base_type, type->dimy); + } + + if (type->type == HLSL_CLASS_ARRAY) + return type->e.array.type; + + if (type->type == HLSL_CLASS_STRUCT) + { + struct hlsl_ir_constant *c = hlsl_ir_constant(node); + + assert(c->value[0].u < type->e.record.field_count); + return type->e.record.fields[c->value[0].u].type; + } + + assert(0); + return NULL; +} + +struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *idx_offset = NULL; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + idx_offset = idx; + break; + + case HLSL_CLASS_MATRIX: + { + if (!(c = hlsl_new_uint_constant(ctx, 4, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type); + + if (!(c = hlsl_new_uint_constant(ctx, size, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_STRUCT: + { + unsigned int field_i = hlsl_ir_constant(idx)->value[0].u; + struct hlsl_struct_field *field = &type->e.record.fields[field_i]; + + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + idx_offset = &c->node; + + break; + } + + default: + assert(0); + return NULL; + } + + if (offset) + { + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + } + + return idx_offset; +} + struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ce1f69df..2a6402ce 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -729,6 +729,12 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive); struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name);
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, + struct hlsl_ir_node *node); +struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, + const struct vkd3d_shader_location *loc); + struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); @@ -792,6 +798,7 @@ unsigned int hlsl_type_component_count(struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); +bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f5c9f4ca..b4ca4631 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -622,44 +622,51 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs return jump; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, - struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc) +static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *add = NULL; + struct hlsl_type *elem_type; + struct hlsl_ir_node *offset; struct hlsl_ir_load *load; + struct hlsl_block block; struct hlsl_ir_var *var;
+ elem_type = hlsl_get_type_from_path_index(ctx, var_node->data_type, idx); + if (var_node->type == HLSL_IR_LOAD) { const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src;
var = src->var; - if (src->offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, offset))) - return NULL; - list_add_tail(instrs, &add->entry); - offset = add; - } + if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, src->offset.node, idx, loc))) + return NULL; + list_move_tail(instrs, &block.instrs); } else { + struct vkd3d_string_buffer *name; 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))) + if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, NULL, idx, loc))) return NULL; + list_move_tail(instrs, &block.instrs);
- if (!(store = hlsl_new_simple_store(ctx, var, var_node))) + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); + var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) return NULL;
+ if (!(store = hlsl_new_simple_store(ctx, var, var_node))) + return NULL; list_add_tail(instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, offset, data_type, loc))) + if (!(load = hlsl_new_load(ctx, var, offset, elem_type, *loc))) return NULL; list_add_tail(instrs, &load->node.entry); + return load; }
@@ -722,61 +729,21 @@ static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location loc) { - const struct hlsl_struct_field *field; struct hlsl_ir_constant *c;
assert(idx < record->data_type->e.record.field_count); - field = &record->data_type->e.record.fields[idx];
- if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, &loc))) + if (!(c = hlsl_new_uint_constant(ctx, idx, &loc))) return false; list_add_tail(instrs, &c->node.entry);
- return !!add_load(ctx, instrs, record, &c->node, field->type, loc); + return !!add_load_index(ctx, instrs, record, &c->node, &loc); }
static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc);
-static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct list *instrs, - struct hlsl_ir_node *matrix, struct hlsl_ir_node *x, struct hlsl_ir_node *y, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *major, *minor, *mul, *add; - struct hlsl_ir_constant *four; - struct hlsl_ir_load *load; - struct hlsl_type *type = matrix->data_type, *scalar_type; - - scalar_type = hlsl_get_scalar_type(ctx, type->base_type); - - if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) - { - minor = x; - major = y; - } - else - { - minor = y; - major = x; - } - - if (!(four = hlsl_new_uint_constant(ctx, 4, loc))) - return NULL; - list_add_tail(instrs, &four->node.entry); - - if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, &four->node, major, loc))) - return NULL; - - if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, mul, minor, loc))) - return NULL; - - if (!(load = add_load(ctx, instrs, matrix, add, scalar_type, *loc))) - return NULL; - - return &load->node; -} - static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *matrix, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) { @@ -787,6 +754,9 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var; unsigned int i;
+ if (hlsl_type_is_row_major(mat_type)) + return add_load_index(ctx, instrs, matrix, index, loc); + ret_type = hlsl_get_vector_type(ctx, mat_type->base_type, mat_type->dimx);
name = vkd3d_string_buffer_get(&ctx->string_buffers); @@ -798,18 +768,21 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs,
for (i = 0; i < mat_type->dimx; ++i) { + struct hlsl_ir_load *column, *value; struct hlsl_ir_store *store; - struct hlsl_ir_node *value; struct hlsl_ir_constant *c;
if (!(c = hlsl_new_uint_constant(ctx, i, loc))) return false; list_add_tail(instrs, &c->node.entry);
- if (!(value = add_matrix_scalar_load(ctx, instrs, matrix, &c->node, index, loc))) + if (!(column = add_load_index(ctx, instrs, matrix, &c->node, loc))) return false;
- if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) + if (!(value = add_load_index(ctx, instrs, &column->node, index, loc))) + return false; + + if (!(store = hlsl_new_store(ctx, var, &c->node, &value->node, 0, *loc))) return false; list_add_tail(instrs, &store->node.entry); } @@ -825,30 +798,11 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls struct hlsl_ir_node *index, const struct vkd3d_shader_location loc) { const struct hlsl_type *expr_type = array->data_type; - struct hlsl_type *data_type; - struct hlsl_ir_constant *c; - - if (expr_type->type == HLSL_CLASS_ARRAY) - { - data_type = expr_type->e.array.type;
- if (!(c = hlsl_new_uint_constant(ctx, hlsl_type_get_array_element_reg_size(data_type), &loc))) - return false; - list_add_tail(instrs, &c->node.entry); - - if (!(index = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, index, &c->node))) - return false; - list_add_tail(instrs, &index->entry); - } - else if (expr_type->type == HLSL_CLASS_MATRIX) - { + if (expr_type->type == HLSL_CLASS_MATRIX) return add_matrix_index(ctx, instrs, array, index, &loc); - } - else if (expr_type->type == HLSL_CLASS_VECTOR) - { - data_type = hlsl_get_scalar_type(ctx, expr_type->base_type); - } - else + + if (expr_type->type != HLSL_CLASS_ARRAY && expr_type->type != HLSL_CLASS_VECTOR) { if (expr_type->type == HLSL_CLASS_SCALAR) hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed."); @@ -857,7 +811,10 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls return false; }
- return !!add_load(ctx, instrs, array, index, data_type, loc); + if (!add_load_index(ctx, instrs, array, index, &loc)) + return false; + + return true; }
static const struct hlsl_struct_field *get_struct_field(const struct hlsl_struct_field *fields, @@ -1306,7 +1263,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_constant *c; unsigned int j;
- if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) + if (!(c = hlsl_new_uint_constant(ctx, i, loc))) return NULL; list_add_tail(instrs, &c->node.entry);
@@ -1314,12 +1271,9 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, { if (operands[j]) { - struct hlsl_type *vector_arg_type; struct hlsl_ir_load *load;
- vector_arg_type = hlsl_get_vector_type(ctx, operands[j]->data_type->base_type, minor_size(type)); - - if (!(load = add_load(ctx, instrs, operands[j], &c->node, vector_arg_type, *loc))) + if (!(load = add_load_index(ctx, instrs, operands[j], &c->node, loc))) return NULL; vector_operands[j] = &load->node; } @@ -1328,6 +1282,10 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) return NULL;
+ if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) return NULL; list_add_tail(instrs, &store->node.entry);
On 7/14/22 20:23, Francisco Casas wrote:
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type,
struct hlsl_ir_node *node)
+{
- assert(node);
- if (type->type == HLSL_CLASS_VECTOR)
return hlsl_get_scalar_type(ctx, type->base_type);
- if (type->type == HLSL_CLASS_MATRIX)
- {
if (hlsl_type_is_row_major(type))
return hlsl_get_vector_type(ctx, type->base_type, type->dimx);
else
return hlsl_get_vector_type(ctx, type->base_type, type->dimy);
- }
- if (type->type == HLSL_CLASS_ARRAY)
return type->e.array.type;
- if (type->type == HLSL_CLASS_STRUCT)
- {
struct hlsl_ir_constant *c = hlsl_ir_constant(node);
assert(c->value[0].u < type->e.record.field_count);
return type->e.record.fields[c->value[0].u].type;
- }
- assert(0);
- return NULL;
+}
This is pretty ripe for a switch statement.
Signed-off-by: Giovanni Mascellani [email protected]
(after the changes suggested by Zeb)
Il 15/07/22 03:23, Francisco Casas ha scritto:
At this point add_load() is split into add_load_component() and add_load_index(); register offsets are hidden for these functions.
Signed-off-by: Francisco Casas [email protected]
v2:
- Use "const struct vkd3d_shader_location *loc" instead of "const struct
vkd3d_shader_location loc"
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
- Removed braces on simple switch cases in hlsl_new_offset_from_path_index(). I kept them in the HLSL_CLASS_MATRIX case, even though it doesn't have declarations, because its body seems complex enough.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 105 +++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 7 ++ libs/vkd3d-shader/hlsl.y | 134 ++++++++++++++------------------------- 3 files changed, 157 insertions(+), 89 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2925b4e5..e4e2ca17 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -117,7 +117,7 @@ void hlsl_free_var(struct hlsl_ir_var *decl) vkd3d_free(decl); }
-static bool hlsl_type_is_row_major(const struct hlsl_type *type) +bool hlsl_type_is_row_major(const struct hlsl_type *type) { /* Default to column-major if the majority isn't explicitly set, which can * happen for anonymous nodes. */ @@ -314,6 +314,109 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ return 0; }
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type,
struct hlsl_ir_node *node)
+{
- assert(node);
- if (type->type == HLSL_CLASS_VECTOR)
return hlsl_get_scalar_type(ctx, type->base_type);
- if (type->type == HLSL_CLASS_MATRIX)
- {
if (hlsl_type_is_row_major(type))
return hlsl_get_vector_type(ctx, type->base_type, type->dimx);
else
return hlsl_get_vector_type(ctx, type->base_type, type->dimy);
- }
- if (type->type == HLSL_CLASS_ARRAY)
return type->e.array.type;
- if (type->type == HLSL_CLASS_STRUCT)
- {
struct hlsl_ir_constant *c = hlsl_ir_constant(node);
assert(c->value[0].u < type->e.record.field_count);
return type->e.record.fields[c->value[0].u].type;
- }
- assert(0);
- return NULL;
+}
+struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx,
const struct vkd3d_shader_location *loc)
+{
- struct hlsl_ir_node *idx_offset = NULL;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
idx_offset = idx;
break;
case HLSL_CLASS_MATRIX:
{
if (!(c = hlsl_new_uint_constant(ctx, 4, loc)))
return NULL;
list_add_tail(&block->instrs, &c->node.entry);
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx)))
return NULL;
list_add_tail(&block->instrs, &idx_offset->entry);
break;
}
case HLSL_CLASS_ARRAY:
{
unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type);
if (!(c = hlsl_new_uint_constant(ctx, size, loc)))
return NULL;
list_add_tail(&block->instrs, &c->node.entry);
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx)))
return NULL;
list_add_tail(&block->instrs, &idx_offset->entry);
break;
}
case HLSL_CLASS_STRUCT:
{
unsigned int field_i = hlsl_ir_constant(idx)->value[0].u;
struct hlsl_struct_field *field = &type->e.record.fields[field_i];
if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc)))
return NULL;
list_add_tail(&block->instrs, &c->node.entry);
idx_offset = &c->node;
break;
}
default:
assert(0);
return NULL;
- }
- if (offset)
- {
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset)))
return NULL;
list_add_tail(&block->instrs, &idx_offset->entry);
- }
- return idx_offset;
+}
- struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ce1f69df..2a6402ce 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -729,6 +729,12 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive); struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name);
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type,
struct hlsl_ir_node *node);
+struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx,
const struct vkd3d_shader_location *loc);
- struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2);
@@ -792,6 +798,7 @@ unsigned int hlsl_type_component_count(struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); +bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f5c9f4ca..b4ca4631 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -622,44 +622,51 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs return jump; }
-static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc)
+static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node,
{struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
- struct hlsl_ir_node *add = NULL;
struct hlsl_type *elem_type;
struct hlsl_ir_node *offset; struct hlsl_ir_load *load;
struct hlsl_block block; struct hlsl_ir_var *var;
elem_type = hlsl_get_type_from_path_index(ctx, var_node->data_type, idx);
if (var_node->type == HLSL_IR_LOAD) { const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src; var = src->var;
if (src->offset.node)
{
if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, offset)))
return NULL;
list_add_tail(instrs, &add->entry);
offset = add;
}
if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, src->offset.node, idx, loc)))
return NULL;
list_move_tail(instrs, &block.instrs); } else {
struct vkd3d_string_buffer *name; 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)))
if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, NULL, idx, loc))) return NULL;
list_move_tail(instrs, &block.instrs);
if (!(store = hlsl_new_simple_store(ctx, var, var_node)))
name = vkd3d_string_buffer_get(&ctx->string_buffers);
vkd3d_string_buffer_printf(name, "<deref-%p>", var_node);
var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc);
vkd3d_string_buffer_release(&ctx->string_buffers, name);
if (!var) return NULL;
if (!(store = hlsl_new_simple_store(ctx, var, var_node)))
return NULL; list_add_tail(instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, offset, data_type, loc)))
- if (!(load = hlsl_new_load(ctx, var, offset, elem_type, *loc))) return NULL; list_add_tail(instrs, &load->node.entry);
}return load;
@@ -722,61 +729,21 @@ static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location loc) {
const struct hlsl_struct_field *field; struct hlsl_ir_constant *c;
assert(idx < record->data_type->e.record.field_count);
field = &record->data_type->e.record.fields[idx];
if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, &loc)))
- if (!(c = hlsl_new_uint_constant(ctx, idx, &loc))) return false; list_add_tail(instrs, &c->node.entry);
- return !!add_load(ctx, instrs, record, &c->node, field->type, loc);
return !!add_load_index(ctx, instrs, record, &c->node, &loc); }
static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc);
-static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct list *instrs,
struct hlsl_ir_node *matrix, struct hlsl_ir_node *x, struct hlsl_ir_node *y,
const struct vkd3d_shader_location *loc)
-{
- struct hlsl_ir_node *major, *minor, *mul, *add;
- struct hlsl_ir_constant *four;
- struct hlsl_ir_load *load;
- struct hlsl_type *type = matrix->data_type, *scalar_type;
- scalar_type = hlsl_get_scalar_type(ctx, type->base_type);
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
- {
minor = x;
major = y;
- }
- else
- {
minor = y;
major = x;
- }
- if (!(four = hlsl_new_uint_constant(ctx, 4, loc)))
return NULL;
- list_add_tail(instrs, &four->node.entry);
- if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, &four->node, major, loc)))
return NULL;
- if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, mul, minor, loc)))
return NULL;
- if (!(load = add_load(ctx, instrs, matrix, add, scalar_type, *loc)))
return NULL;
- return &load->node;
-}
- static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *matrix, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) {
@@ -787,6 +754,9 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var; unsigned int i;
if (hlsl_type_is_row_major(mat_type))
return add_load_index(ctx, instrs, matrix, index, loc);
ret_type = hlsl_get_vector_type(ctx, mat_type->base_type, mat_type->dimx); name = vkd3d_string_buffer_get(&ctx->string_buffers);
@@ -798,18 +768,21 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs,
for (i = 0; i < mat_type->dimx; ++i) {
struct hlsl_ir_load *column, *value; struct hlsl_ir_store *store;
struct hlsl_ir_node *value; struct hlsl_ir_constant *c; if (!(c = hlsl_new_uint_constant(ctx, i, loc))) return false; list_add_tail(instrs, &c->node.entry);
if (!(value = add_matrix_scalar_load(ctx, instrs, matrix, &c->node, index, loc)))
if (!(column = add_load_index(ctx, instrs, matrix, &c->node, loc))) return false;
if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc)))
if (!(value = add_load_index(ctx, instrs, &column->node, index, loc)))
return false;
if (!(store = hlsl_new_store(ctx, var, &c->node, &value->node, 0, *loc))) return false; list_add_tail(instrs, &store->node.entry); }
@@ -825,30 +798,11 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls struct hlsl_ir_node *index, const struct vkd3d_shader_location loc) { const struct hlsl_type *expr_type = array->data_type;
struct hlsl_type *data_type;
struct hlsl_ir_constant *c;
if (expr_type->type == HLSL_CLASS_ARRAY)
{
data_type = expr_type->e.array.type;
if (!(c = hlsl_new_uint_constant(ctx, hlsl_type_get_array_element_reg_size(data_type), &loc)))
return false;
list_add_tail(instrs, &c->node.entry);
if (!(index = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, index, &c->node)))
return false;
list_add_tail(instrs, &index->entry);
}
else if (expr_type->type == HLSL_CLASS_MATRIX)
{
- if (expr_type->type == HLSL_CLASS_MATRIX) return add_matrix_index(ctx, instrs, array, index, &loc);
- }
- else if (expr_type->type == HLSL_CLASS_VECTOR)
- {
data_type = hlsl_get_scalar_type(ctx, expr_type->base_type);
- }
- else
- if (expr_type->type != HLSL_CLASS_ARRAY && expr_type->type != HLSL_CLASS_VECTOR) { if (expr_type->type == HLSL_CLASS_SCALAR) hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed.");
@@ -857,7 +811,10 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls return false; }
- return !!add_load(ctx, instrs, array, index, data_type, loc);
if (!add_load_index(ctx, instrs, array, index, &loc))
return false;
return true; }
static const struct hlsl_struct_field *get_struct_field(const struct hlsl_struct_field *fields,
@@ -1306,7 +1263,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_constant *c; unsigned int j;
if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc)))
if (!(c = hlsl_new_uint_constant(ctx, i, loc))) return NULL; list_add_tail(instrs, &c->node.entry);
@@ -1314,12 +1271,9 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, { if (operands[j]) {
struct hlsl_type *vector_arg_type; struct hlsl_ir_load *load;
vector_arg_type = hlsl_get_vector_type(ctx, operands[j]->data_type->base_type, minor_size(type));
if (!(load = add_load(ctx, instrs, operands[j], &c->node, vector_arg_type, *loc)))
if (!(load = add_load_index(ctx, instrs, operands[j], &c->node, loc))) return NULL; vector_operands[j] = &load->node; }
@@ -1328,6 +1282,10 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) return NULL;
if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) return NULL; list_add_tail(instrs, &store->node.entry);
On Fri, Jul 15, 2022 at 3:24 AM Francisco Casas [email protected] wrote:
At this point add_load() is split into add_load_component() and add_load_index(); register offsets are hidden for these functions.
Signed-off-by: Francisco Casas [email protected]
Nice patch. I guess this one is already pretty compelling evidence in support of this "index paths" idea for parse-time IR.
v2:
- Use "const struct vkd3d_shader_location *loc" instead of "const struct
vkd3d_shader_location loc"
- Use vkd3d_string_buffer for initializing the deref synthetic variable names.
- Move common "load = hlsl_new_load" pattern out of the if..else branches.
- Removed braces on simple switch cases in hlsl_new_offset_from_path_index(). I kept them in the HLSL_CLASS_MATRIX case, even though it doesn't have declarations, because its body seems complex enough.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 105 +++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 7 ++ libs/vkd3d-shader/hlsl.y | 134 ++++++++++++++------------------------- 3 files changed, 157 insertions(+), 89 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2925b4e5..e4e2ca17 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -117,7 +117,7 @@ void hlsl_free_var(struct hlsl_ir_var *decl) vkd3d_free(decl); }
-static bool hlsl_type_is_row_major(const struct hlsl_type *type) +bool hlsl_type_is_row_major(const struct hlsl_type *type) { /* Default to column-major if the majority isn't explicitly set, which can * happen for anonymous nodes. */ @@ -314,6 +314,109 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ return 0; }
+struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type,
struct hlsl_ir_node *node)
Maybe index, or field, or field_index? In the next function you have "idx", which also works. In any case, pick one and then use consistent naming throughout.
Also, I'm a bit confused by the function name: as far as I can see the function has nothing specific to path indices, it's more of a "tell me the type of the next inner component".
+{
- assert(node);
- if (type->type == HLSL_CLASS_VECTOR)
return hlsl_get_scalar_type(ctx, type->base_type);
- if (type->type == HLSL_CLASS_MATRIX)
- {
if (hlsl_type_is_row_major(type))
return hlsl_get_vector_type(ctx, type->base_type, type->dimx);
else
return hlsl_get_vector_type(ctx, type->base_type, type->dimy);
- }
- if (type->type == HLSL_CLASS_ARRAY)
return type->e.array.type;
- if (type->type == HLSL_CLASS_STRUCT)
- {
struct hlsl_ir_constant *c = hlsl_ir_constant(node);
assert(c->value[0].u < type->e.record.field_count);
return type->e.record.fields[c->value[0].u].type;
- }
- assert(0);
- return NULL;
+}
+struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx,
const struct vkd3d_shader_location *loc)
+{
- struct hlsl_ir_node *idx_offset = NULL;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
idx_offset = idx;
break;
case HLSL_CLASS_MATRIX:
{
if (!(c = hlsl_new_uint_constant(ctx, 4, loc)))
return NULL;
list_add_tail(&block->instrs, &c->node.entry);
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx)))
return NULL;
list_add_tail(&block->instrs, &idx_offset->entry);
break;
}
case HLSL_CLASS_ARRAY:
{
unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type);
if (!(c = hlsl_new_uint_constant(ctx, size, loc)))
return NULL;
list_add_tail(&block->instrs, &c->node.entry);
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx)))
return NULL;
list_add_tail(&block->instrs, &idx_offset->entry);
break;
}
case HLSL_CLASS_STRUCT:
{
unsigned int field_i = hlsl_ir_constant(idx)->value[0].u;
field_idx?
Signed-off-by: Francisco Casas [email protected] ---
v2: * No changes.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 16 ++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 20 ++------------------ libs/vkd3d-shader/hlsl_codegen.c | 28 ++++++---------------------- 4 files changed, 26 insertions(+), 40 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e4e2ca17..d3ceba35 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -124,6 +124,22 @@ bool hlsl_type_is_row_major(const struct hlsl_type *type) return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR); }
+unsigned int hlsl_type_minor_size(const struct hlsl_type *type) +{ + if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type)) + return type->dimx; + else + return type->dimy; +} + +unsigned int hlsl_type_major_size(const struct hlsl_type *type) +{ + if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type)) + return type->dimy; + else + return type->dimx; +} + static unsigned int get_array_size(const struct hlsl_type *type) { if (type->type == HLSL_CLASS_ARRAY) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2a6402ce..546c87f3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -799,6 +799,8 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); bool hlsl_type_is_row_major(const struct hlsl_type *type); +unsigned int hlsl_type_minor_size(const struct hlsl_type *type); +unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b4ca4631..a1d39140 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1216,22 +1216,6 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static unsigned int minor_size(const struct hlsl_type *type) -{ - if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) - return type->dimx; - else - return type->dimy; -} - -static unsigned int major_size(const struct hlsl_type *type) -{ - if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) - return type->dimy; - else - return type->dimx; -} - static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) @@ -1247,7 +1231,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *load; struct hlsl_ir_var *var;
- vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type));
name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++); @@ -1256,7 +1240,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!var) return NULL;
- for (i = 0; i < major_size(type); i++) + for (i = 0; i < hlsl_type_major_size(type); i++) { struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; struct hlsl_ir_store *store; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 484b415d..373439af 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,22 +21,6 @@ #include "hlsl.h" #include <stdio.h>
-static unsigned int minor_size(const struct hlsl_type *type) -{ - if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) - return type->dimx; - else - return type->dimy; -} - -static unsigned int major_size(const struct hlsl_type *type) -{ - if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) - return type->dimy; - else - return type->dimx; -} - /* Split uniforms into two variables representing the constant and temp * registers, and copy the former to the latter, so that writes to uniforms * work. */ @@ -86,11 +70,11 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
if (type->type == HLSL_CLASS_MATRIX) { - struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); struct hlsl_semantic vector_semantic = *semantic; unsigned int i;
- for (i = 0; i < major_size(type); ++i) + for (i = 0; i < hlsl_type_major_size(type); ++i) { prepend_input_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); ++vector_semantic.index; @@ -176,11 +160,11 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
if (type->type == HLSL_CLASS_MATRIX) { - struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); struct hlsl_semantic vector_semantic = *semantic; unsigned int i;
- for (i = 0; i < major_size(type); ++i) + for (i = 0; i < hlsl_type_major_size(type); ++i) { append_output_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); ++vector_semantic.index; @@ -915,7 +899,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr type = rhs->data_type; if (type->type != HLSL_CLASS_MATRIX) return false; - element_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + element_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type));
if (rhs->type != HLSL_IR_LOAD) { @@ -923,7 +907,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; }
- for (i = 0; i < major_size(type); ++i) + for (i = 0; i < hlsl_type_major_size(type); ++i) { if (!split_copy(ctx, store, hlsl_ir_load(rhs), 4 * i, element_type)) return false;
Signed-off-by: Giovanni Mascellani [email protected]
Il 15/07/22 03:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v2:
- No changes.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 16 ++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 20 ++------------------ libs/vkd3d-shader/hlsl_codegen.c | 28 ++++++---------------------- 4 files changed, 26 insertions(+), 40 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e4e2ca17..d3ceba35 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -124,6 +124,22 @@ bool hlsl_type_is_row_major(const struct hlsl_type *type) return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR); }
+unsigned int hlsl_type_minor_size(const struct hlsl_type *type) +{
- if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type))
return type->dimx;
- else
return type->dimy;
+}
+unsigned int hlsl_type_major_size(const struct hlsl_type *type) +{
- if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type))
return type->dimy;
- else
return type->dimx;
+}
- static unsigned int get_array_size(const struct hlsl_type *type) { if (type->type == HLSL_CLASS_ARRAY)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2a6402ce..546c87f3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -799,6 +799,8 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); bool hlsl_type_is_row_major(const struct hlsl_type *type); +unsigned int hlsl_type_minor_size(const struct hlsl_type *type); +unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b4ca4631..a1d39140 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1216,22 +1216,6 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static unsigned int minor_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimx;
- else
return type->dimy;
-}
-static unsigned int major_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimy;
- else
return type->dimx;
-}
- static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc)
@@ -1247,7 +1231,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *load; struct hlsl_ir_var *var;
vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type));
vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++);
@@ -1256,7 +1240,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!var) return NULL;
for (i = 0; i < major_size(type); i++)
for (i = 0; i < hlsl_type_major_size(type); i++) { struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; struct hlsl_ir_store *store;
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 484b415d..373439af 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,22 +21,6 @@ #include "hlsl.h" #include <stdio.h>
-static unsigned int minor_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimx;
- else
return type->dimy;
-}
-static unsigned int major_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimy;
- else
return type->dimx;
-}
- /* Split uniforms into two variables representing the constant and temp
- registers, and copy the former to the latter, so that writes to uniforms
- work. */
@@ -86,11 +70,11 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
if (type->type == HLSL_CLASS_MATRIX) {
struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type));
struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); struct hlsl_semantic vector_semantic = *semantic; unsigned int i;
for (i = 0; i < major_size(type); ++i)
for (i = 0; i < hlsl_type_major_size(type); ++i) { prepend_input_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); ++vector_semantic.index;
@@ -176,11 +160,11 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
if (type->type == HLSL_CLASS_MATRIX) {
struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type));
struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); struct hlsl_semantic vector_semantic = *semantic; unsigned int i;
for (i = 0; i < major_size(type); ++i)
for (i = 0; i < hlsl_type_major_size(type); ++i) { append_output_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); ++vector_semantic.index;
@@ -915,7 +899,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr type = rhs->data_type; if (type->type != HLSL_CLASS_MATRIX) return false;
- element_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type));
element_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type));
if (rhs->type != HLSL_IR_LOAD) {
@@ -923,7 +907,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; }
- for (i = 0; i < major_size(type); ++i)
- for (i = 0; i < hlsl_type_major_size(type); ++i) { if (!split_copy(ctx, store, hlsl_ir_load(rhs), 4 * i, element_type)) return false;
On Fri, Jul 15, 2022 at 3:24 AM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v2:
- No changes.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 16 ++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 20 ++------------------ libs/vkd3d-shader/hlsl_codegen.c | 28 ++++++---------------------- 4 files changed, 26 insertions(+), 40 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e4e2ca17..d3ceba35 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -124,6 +124,22 @@ bool hlsl_type_is_row_major(const struct hlsl_type *type) return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR); }
+unsigned int hlsl_type_minor_size(const struct hlsl_type *type) +{
- if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type))
return type->dimx;
- else
return type->dimy;
+}
+unsigned int hlsl_type_major_size(const struct hlsl_type *type) +{
- if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type))
return type->dimy;
- else
return type->dimx;
+}
static unsigned int get_array_size(const struct hlsl_type *type) { if (type->type == HLSL_CLASS_ARRAY) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 2a6402ce..546c87f3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -799,6 +799,8 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); bool hlsl_type_is_row_major(const struct hlsl_type *type); +unsigned int hlsl_type_minor_size(const struct hlsl_type *type); +unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b4ca4631..a1d39140 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1216,22 +1216,6 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static unsigned int minor_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimx;
- else
return type->dimy;
-}
-static unsigned int major_size(const struct hlsl_type *type) -{
- if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)
return type->dimy;
- else
return type->dimx;
-}
static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) @@ -1247,7 +1231,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *load; struct hlsl_ir_var *var;
vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type));
vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++);
@@ -1256,7 +1240,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!var) return NULL;
for (i = 0; i < major_size(type); i++)
for (i = 0; i < hlsl_type_major_size(type); i++)
Nitpick, while at it you could change i++ to ++i as well.
From: Zebediah Figura [email protected]
Signed-off-by: Francisco Casas [email protected] --- v2: * Added in v2. --- include/private/list.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/private/list.h b/include/private/list.h index b4d681fe..5e92cfb2 100644 --- a/include/private/list.h +++ b/include/private/list.h @@ -150,8 +150,8 @@ static inline unsigned int list_count( const struct list *list ) return count; }
-/* move all elements from src to the tail of dst */ -static inline void list_move_tail( struct list *dst, struct list *src ) +/* move all elements from src to before the specified element */ +static inline void list_move_before( struct list *dst, struct list *src ) { if (list_empty(src)) return;
@@ -162,8 +162,8 @@ static inline void list_move_tail( struct list *dst, struct list *src ) list_init(src); }
-/* move all elements from src to the head of dst */ -static inline void list_move_head( struct list *dst, struct list *src ) +/* move all elements from src to after the specified element */ +static inline void list_move_after( struct list *dst, struct list *src ) { if (list_empty(src)) return;
@@ -174,6 +174,18 @@ static inline void list_move_head( struct list *dst, struct list *src ) list_init(src); }
+/* move all elements from src to the head of dst */ +static inline void list_move_head( struct list *dst, struct list *src ) +{ + list_move_after( dst, src ); +} + +/* move all elements from src to the tail of dst */ +static inline void list_move_tail( struct list *dst, struct list *src ) +{ + list_move_before( dst, src ); +} + /* iterate through the list */ #define LIST_FOR_EACH(cursor,list) \ for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
Signed-off-by: Zebediah Figura [email protected]
Signed-off-by: Giovanni Mascellani [email protected]
Il 15/07/22 03:23, Francisco Casas ha scritto:
From: Zebediah Figura [email protected]
Signed-off-by: Francisco Casas [email protected]
v2:
- Added in v2.
include/private/list.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/private/list.h b/include/private/list.h index b4d681fe..5e92cfb2 100644 --- a/include/private/list.h +++ b/include/private/list.h @@ -150,8 +150,8 @@ static inline unsigned int list_count( const struct list *list ) return count; }
-/* move all elements from src to the tail of dst */ -static inline void list_move_tail( struct list *dst, struct list *src ) +/* move all elements from src to before the specified element */ +static inline void list_move_before( struct list *dst, struct list *src ) { if (list_empty(src)) return;
@@ -162,8 +162,8 @@ static inline void list_move_tail( struct list *dst, struct list *src ) list_init(src); }
-/* move all elements from src to the head of dst */ -static inline void list_move_head( struct list *dst, struct list *src ) +/* move all elements from src to after the specified element */ +static inline void list_move_after( struct list *dst, struct list *src ) { if (list_empty(src)) return;
@@ -174,6 +174,18 @@ static inline void list_move_head( struct list *dst, struct list *src ) list_init(src); }
+/* move all elements from src to the head of dst */ +static inline void list_move_head( struct list *dst, struct list *src ) +{
- list_move_after( dst, src );
+}
+/* move all elements from src to the tail of dst */ +static inline void list_move_tail( struct list *dst, struct list *src ) +{
- list_move_before( dst, src );
+}
- /* iterate through the list */ #define LIST_FOR_EACH(cursor,list) \ for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
The transform_deref_paths_into_offsets pass turns these index paths back into register offsets.
Signed-off-by: Francisco Casas [email protected] ---
The idea is that we can move the transform_deref_paths_into_offsets() pass forward as we translate more passes to work with index paths. This, until register offsets can be totally removed, after we implement the SMxIRs and their translations.
The aim is to have 3 ways of initializing load/store nodes when using index paths:
* One that initializes the node from a another's node deref and and optional index to be appended to that deref's path. * One that initializes the node from a deref and the index of a single basic component within it. This one also generates constant nodes for the required path, so it also initializes an instruction block whose instructions must be inserted in the instruction list. * One that initializes the node directly for a whole variable. These functions are already present: hlsl_new_var_load() and hlsl_new_simple_store().
The signatures of these functions were placed nearby in hlsl.h
It is worth noting that the use of index paths allows to remove the data type argument when initializing store/loads because it can now be deducted from the variable and the hlsl_deref.
Applying an index over a matrix derefence retrieves a vector. If the matrix is row_major, this corresponds to a row, otherwise, it corresponds to a column. So, the code should take matrix majority into account, at least until the split_matrix_copies pass.
The first index in a path after a loading a struct should be an hlsl_ir_constant, since the field that's being addressed is always known at parse-time.
hlsl_init_simple_deref_from_var() can be used to initialize a deref that can be passed by reference to the load and store initialization functions. This value shall not be modified after being created and does not require to call hlsl_cleanup_deref().
---
v2 (including changes in splits of this patch): * cleanup_deref() had to be made non-static in this commit because this is the commit where it is used outside hlsl.c. It also was renamed to hlsl_cleanup_deref() to follow the convention. * hlsl_new_load_index(), hlsl_new_load_component() and hlsl_new_store_index() now receive a "const struct vkd3d_shader_location *loc". * Removed braces from switch cases without declarations. * hlsl_compute_component_path() made static and no longer used to retrieve the componet type. The "hlsl_" prefix was removed. * Using Zeb's strategy for handling recursion in compute_component_path(); implemented in subtype_index_from_component_index(). * Added hlsl_type_get_component_type() to retrieve the component type. * Allocating at least 1 byte in compute_component_path(), to ensure that NULL is never returned on success. * Using 'assert(index < type->dimx)' instead of 'assert(index < type->dimx * type->dimy)' in HLSL_CLASS_VECTOR case in path function. * Restored 'assert(array_index < type->e.array.elements_count)'. * Added 'assert(!other->offset.node)' in deref_copy() because it is not indended to copy derefs that use nodes. Naturally, the assertion must be removed once we remove the offset field from hlsl_deref. * Using memset to initialize deref in deref_copy(). * Using path_len instead of 'i' for calling hlsl_src_from_node() in hlsl_new_load_index/hlsl_new_store_index 'if (idx)' bodies. * Removed double newline in hlsl_new_load_component(). * Using list_move_before() instead of iterating instruction list in replace_deref_path_with_offset(). * Renamed hlsl_get_direct_var_deref() to hlsl_init_simple_deref_from_var(), passing deref by pointer. * The introduction of hlsl_new_store_index() was moved to another patch. * The introduction of hlsl_new_store_component() mas moved to another patch. * The translation of hlsl_new_resource_load() to register offsets was split from this patch. * hlsl_new_offset_node_from_deref() was implemented in order to create new offsets in hlsl.y from derefs, in order to be used as input for stores and resource loads that will still require offsets (at least until the following patches). his function is also used in replace_deref_path_with_offset(), to make the implementation smaller. * Added assertions to hlsl_new_store_index() and hlsl_new_load_index() to ensure that they don't receive derefs with register offset instead of index paths.
---
Zeb:
Regarding the possibility of having a hlsl_deref_from_component_index() function, there are 2 inconveniences: 1. It is necessary to create constant nodes for the path, so, an instruction block pointer is required. 2. An additional hlsl_deref pointer is required for its use in hlsl_new_store_component(), since the lhs path needs to be prepend to the path to the component [1].
The signature of the function would end up like this:
static bool hlsl_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int index, struct hlsl_deref *path_prefix, const struct vkd3d_shader_location *loc)
So in the end I think it is not a good idea to have hlsl_deref_from_component_index() directly.
However, subtype_index_from_component_index() worked nicely; it allowed to create a simple implementation for hlsl_compute_component_path() and creating hlsl_type_get_component_type(). Furthermore, given that the latter function allows to obtain the component data type easily, hlsl_compute_component_path() is no longer required to retrieve the component type and can be static now.
I ended up replacing
struct hlsl_deref hlsl_get_direct_var_deref(struct hlsl_ir_var *var);
with:
void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var);
as you suggested, but adding the "init" to the name to avoid it being solely a noun phrase.
I decided not to include the cast in hlsl_new_store_component() because now it is only required in one place and it would be inconsistent with hlsl_new_store_index() that doesn't.
While I could separate hlsl_new_store_index() and hlsl_new_load_component(), hlsl_new_load_component() and hlsl_new_load_index() must both be introduced in the same patch because they both expect dereferences with path indexes instead of offsets (which come from from other loads). Converting from dereferences with offsets to index paths is hard and I don't think it is worth implementing just to split more this patch (unlike converting the other way around).
[1] There is also the alternative of introducing a hlsl_deref_concat() function that takes two derefs and retrieves a new one.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 305 ++++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 +++++------ libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 417 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d3ceba35..4b01cca5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,124 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ return 0; }
+static bool type_is_single_component(const struct hlsl_type *type) +{ + return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT; +} + +/* Given a type and a component index, retrieves next path index required to reach the component. + * *typep will be set to the subtype within the original type that contains the component. + * *indexp will be set to the index of the component within *typep. + */ +static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx, + struct hlsl_type **typep, unsigned int *indexp) +{ + struct hlsl_type *type = *typep; + unsigned int index = *indexp; + + assert(!type_is_single_component(type)); + assert(index < hlsl_type_component_count(type)); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + assert(index < type->dimx); + *typep = hlsl_get_scalar_type(ctx, type->base_type); + *indexp = 0; + return index; + + case HLSL_CLASS_MATRIX: + { + unsigned int y = index / type->dimx, x = index % type->dimx; + bool row_major = hlsl_type_is_row_major(type); + + assert(index < type->dimx * type->dimy); + *typep = hlsl_get_vector_type(ctx, type->base_type, row_major? type->dimx : type->dimy); + *indexp = row_major? x : y; + return row_major? y : x; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type); + unsigned int array_index; + + *typep = type->e.array.type; + *indexp = index % elem_comp_count; + array_index = index / elem_comp_count; + assert(array_index < type->e.array.elements_count); + return array_index; + } + + case HLSL_CLASS_STRUCT: + { + struct hlsl_struct_field *field; + unsigned int field_comp_count, i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + field = &type->e.record.fields[i]; + field_comp_count = hlsl_type_component_count(field->type); + if (index < field_comp_count) + { + *typep = field->type; + *indexp = index; + return i; + } + index -= field_comp_count; + } + assert(0); + return 0; + } + + default: + assert(0); + return 0; + } +} + +struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index) +{ + while (!type_is_single_component(type)) + subtype_index_from_component_index(ctx, &type, &index); + + return type; +} + +/* Returns the path of a given component within a type, given its index. + * *path_len will be set to the lenght of the path. + * Memory should be free afterwards. + */ +static unsigned int *compute_component_path(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index, unsigned int *path_len) +{ + struct hlsl_type *path_type; + unsigned int *path, path_index; + + *path_len = 0; + path_type = type; + path_index = index; + while (!type_is_single_component(path_type)) + { + subtype_index_from_component_index(ctx, &path_type, &path_index); + ++*path_len; + } + if (!(path = hlsl_alloc(ctx, *path_len * sizeof(unsigned int) + 1))) + return NULL; + + *path_len = 0; + path_type = type; + path_index = index; + while (!type_is_single_component(path_type)) + { + path[*path_len] = subtype_index_from_component_index(ctx, &path_type, &path_index); + ++*path_len; + } + + return path; +} + struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) { @@ -433,6 +551,37 @@ struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struc return idx_offset; }
+struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *offset = NULL; + struct hlsl_type *type; + unsigned int i; + + list_init(&block->instrs); + + if (deref->offset.node) + return deref->offset.node; + + assert(deref->var); + + type = deref->var->data_type; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_block idx_block; + + if (!(offset = hlsl_new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, loc))) + return NULL; + + list_move_tail(&block->instrs, &idx_block.instrs); + + type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node); + } + + return offset; +} + struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type; @@ -523,7 +672,7 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha return NULL; }
-unsigned int hlsl_type_component_count(struct hlsl_type *type) +unsigned int hlsl_type_component_count(const struct hlsl_type *type) { unsigned int count = 0, i;
@@ -740,8 +889,50 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
-static void cleanup_deref(struct hlsl_deref *deref) +static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, + unsigned int path_len) +{ + deref->var = var; + deref->path_len = path_len; + deref->offset.node = NULL; + + if (path_len == 0) + { + deref->path = NULL; + return true; + } + + if (!(deref->path = hlsl_alloc(ctx, sizeof(*deref->path) * deref->path_len))) + { + deref->var = NULL; + deref->path_len = 0; + return false; + } + + return true; +} + +static struct hlsl_type *get_type_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + struct hlsl_type *type = deref->var->data_type; + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node); + return type; +} + +void hlsl_cleanup_deref(struct hlsl_deref *deref) { + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + hlsl_src_remove(&deref->path[i]); + vkd3d_free(deref->path); + + deref->path = NULL; + deref->path_len = 0; + hlsl_src_remove(&deref->offset); }
@@ -757,13 +948,21 @@ struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *v return NULL;
init_node(&store->node, HLSL_IR_STORE, NULL, loc); - store->lhs.var = var; + init_deref(ctx, &store->lhs, var, 0); hlsl_src_from_node(&store->lhs.offset, offset); hlsl_src_from_node(&store->rhs, rhs); store->writemask = writemask; return store; }
+/* Initializes a simple variable derefence, so that a pointer to it can be passed to load/store + * functions. The deref shall not be modified afterwards. */ +void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) +{ + memset(deref, 0, sizeof(*deref)); + deref->var = var; +} + struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) { return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); @@ -860,15 +1059,101 @@ struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; init_node(&load->node, HLSL_IR_LOAD, type, loc); - load->src.var = var; + init_deref(ctx, &load->src, var, 0); hlsl_src_from_node(&load->src.offset, offset); return load; }
+struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_load *load; + struct hlsl_type *type; + unsigned int i; + + assert(!deref->offset.node); + + type = get_type_from_deref(ctx, deref); + if (idx) + type = hlsl_get_type_from_path_index(ctx, type, idx); + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + return NULL; + init_node(&load->node, HLSL_IR_LOAD, type, *loc); + + if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx)) + { + vkd3d_free(load); + return NULL; + } + for (i = 0; i < deref->path_len; ++i) + hlsl_src_from_node(&load->src.path[i], deref->path[i].node); + if (idx) + hlsl_src_from_node(&load->src.path[deref->path_len], idx); + + return load; +} + struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - const struct vkd3d_shader_location loc) + struct vkd3d_shader_location loc) { - return hlsl_new_load(ctx, var, NULL, var->data_type, loc); + struct hlsl_deref var_deref; + + hlsl_init_simple_deref_from_var(&var_deref, var); + return hlsl_new_load_index(ctx, &var_deref, NULL, &loc); +} + +struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type, *comp_type; + unsigned int *path, path_len, i; + struct hlsl_ir_constant *c; + struct hlsl_ir_load *load; + + list_init(&block->instrs); + + type = get_type_from_deref(ctx, deref); + path = compute_component_path(ctx, type, comp, &path_len); + if (!path) + return NULL; + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + { + vkd3d_free(path); + return NULL; + } + comp_type = hlsl_type_get_component_type(ctx, type, comp); + init_node(&load->node, HLSL_IR_LOAD, comp_type, *loc); + + if (!init_deref(ctx, &load->src, deref->var, deref->path_len + path_len)) + { + vkd3d_free(path); + vkd3d_free(load); + return NULL; + } + + for (i = 0; i < deref->path_len; ++i) + hlsl_src_from_node(&load->src.path[i], deref->path[i].node); + for (i = 0; i < path_len; ++i) + { + if (!(c = hlsl_new_uint_constant(ctx, path[i], loc))) + { + vkd3d_free(path); + hlsl_free_instr_list(&block->instrs); + hlsl_cleanup_deref(&load->src); + vkd3d_free(load); + return NULL; + } + list_add_tail(&block->instrs, &c->node.entry); + + hlsl_src_from_node(&load->src.path[deref->path_len + i], &c->node); + } + vkd3d_free(path); + + list_add_tail(&block->instrs, &load->node.entry); + + return load; }
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, @@ -1703,7 +1988,7 @@ static void free_ir_jump(struct hlsl_ir_jump *jump)
static void free_ir_load(struct hlsl_ir_load *load) { - cleanup_deref(&load->src); + hlsl_cleanup_deref(&load->src); vkd3d_free(load); }
@@ -1716,8 +2001,8 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { hlsl_src_remove(&load->coords); - cleanup_deref(&load->sampler); - cleanup_deref(&load->resource); + hlsl_cleanup_deref(&load->sampler); + hlsl_cleanup_deref(&load->resource); hlsl_src_remove(&load->texel_offset); vkd3d_free(load); } @@ -1725,7 +2010,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) static void free_ir_store(struct hlsl_ir_store *store) { hlsl_src_remove(&store->rhs); - cleanup_deref(&store->lhs); + hlsl_cleanup_deref(&store->lhs); vkd3d_free(store); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 546c87f3..3a6af2a3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -374,6 +374,10 @@ struct hlsl_ir_swizzle struct hlsl_deref { struct hlsl_ir_var *var; + + unsigned int path_len; + struct hlsl_src *path; + struct hlsl_src offset; };
@@ -717,6 +721,8 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
+void hlsl_cleanup_deref(struct hlsl_deref *deref); + void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
void hlsl_free_instr(struct hlsl_ir_node *node); @@ -751,14 +757,29 @@ struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condit struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, const struct vkd3d_shader_location *loc); struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc); -struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_type *type, struct vkd3d_shader_location loc); -struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); + +void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); + +struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + struct vkd3d_shader_location loc); +struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); +struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); + +struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); + +struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc); + struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); -struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); + +struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_type *type, struct vkd3d_shader_location loc); +struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, 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_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, @@ -775,8 +796,6 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, const struct hlsl_semantic *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation); -struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - const struct vkd3d_shader_location loc);
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); @@ -794,10 +813,12 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type);
struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers); -unsigned int hlsl_type_component_count(struct hlsl_type *type); +unsigned int hlsl_type_component_count(const struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); +struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index); bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a1d39140..3447ddd5 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -352,7 +352,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, list_add_tail(instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, NULL, dst_type, *loc))) + if (!(load = hlsl_new_var_load(ctx, var, *loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -625,31 +625,18 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { - struct hlsl_type *elem_type; - struct hlsl_ir_node *offset; + const struct hlsl_deref *src; struct hlsl_ir_load *load; - struct hlsl_block block; - struct hlsl_ir_var *var; - - elem_type = hlsl_get_type_from_path_index(ctx, var_node->data_type, idx);
if (var_node->type == HLSL_IR_LOAD) { - const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src; - - var = src->var; - if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, src->offset.node, idx, loc))) - return NULL; - list_move_tail(instrs, &block.instrs); + src = &hlsl_ir_load(var_node)->src; } else { struct vkd3d_string_buffer *name; struct hlsl_ir_store *store; - - if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, NULL, idx, loc))) - return NULL; - list_move_tail(instrs, &block.instrs); + struct hlsl_ir_var *var;
name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); @@ -661,9 +648,11 @@ static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *in if (!(store = hlsl_new_simple_store(ctx, var, var_node))) return NULL; list_add_tail(instrs, &store->node.entry); + + src = &store->lhs; }
- if (!(load = hlsl_new_load(ctx, var, offset, elem_type, *loc))) + if (!(load = hlsl_new_load_index(ctx, src, idx, loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -673,39 +662,19 @@ static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *in static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, unsigned int comp, const struct vkd3d_shader_location *loc) { - struct hlsl_type *comp_type; - struct hlsl_ir_node *offset; - struct hlsl_ir_constant *c; + const struct hlsl_deref *src; struct hlsl_ir_load *load; - unsigned int comp_offset; - struct hlsl_ir_var *var; - - comp_offset = hlsl_compute_component_offset(ctx, var_node->data_type, comp, &comp_type); - - if (!(c = hlsl_new_uint_constant(ctx, comp_offset, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - - offset = &c->node; + struct hlsl_block block;
if (var_node->type == HLSL_IR_LOAD) { - const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src; - struct hlsl_ir_node *add; - - var = src->var; - if (src->offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, &c->node))) - return NULL; - list_add_tail(instrs, &add->entry); - offset = add; - } + src = &hlsl_ir_load(var_node)->src; } else { struct vkd3d_string_buffer *name; struct hlsl_ir_store *store; + struct hlsl_ir_var *var;
name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); @@ -717,11 +686,13 @@ static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list if (!(store = hlsl_new_simple_store(ctx, var, var_node))) return NULL; list_add_tail(instrs, &store->node.entry); + + src = &store->lhs; }
- if (!(load = hlsl_new_load(ctx, var, offset, comp_type, *loc))) + if (!(load = hlsl_new_load_component(ctx, &block, src, comp, loc))) return NULL; - list_add_tail(instrs, &load->node.entry); + list_move_tail(instrs, &block.instrs);
return load; } @@ -1275,7 +1246,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, list_add_tail(instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, NULL, type, *loc))) + if (!(load = hlsl_new_var_load(ctx, var, *loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -1632,8 +1603,10 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { struct hlsl_type *lhs_type = lhs->data_type; struct hlsl_ir_store *store; + struct hlsl_ir_node *offset; struct hlsl_ir_expr *copy; unsigned int writemask = 0; + struct hlsl_block block;
if (assign_op == ASSIGN_OP_SUB) { @@ -1702,10 +1675,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in } }
+ offset = hlsl_new_offset_node_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc); + list_move_tail(instrs, &block.instrs); + 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->lhs.offset, offset); hlsl_src_from_node(&store->rhs, rhs); list_add_tail(instrs, &store->node.entry);
@@ -2236,7 +2212,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, list_add_tail(params->instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, NULL, matrix_type, *loc))) + if (!(load = hlsl_new_var_load(ctx, var, *loc))) return false; list_add_tail(params->instrs, &load->node.entry);
@@ -2445,8 +2421,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + struct hlsl_ir_node *object_load_offset; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *coords; + struct hlsl_block block;
if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) @@ -2471,8 +2449,11 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) return false;
+ object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); + list_move_tail(instrs, &block.instrs); + if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, - object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, NULL, loc))) + object_load->src.var, object_load_offset, NULL, NULL, coords, NULL, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; @@ -2482,11 +2463,13 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + struct hlsl_ir_node *object_load_offset, *sampler_load_offset; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *offset = NULL; struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords; + struct hlsl_block block;
if (params->args_count != 2 && params->args_count != 3) { @@ -2522,11 +2505,18 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
+ object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); + list_move_tail(instrs, &block.instrs); + + sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc); + list_move_tail(instrs, &block.instrs); + if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, - HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node, - sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) + HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load_offset, + sampler_load->src.var, sampler_load_offset, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); + return true; } else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") @@ -2537,6 +2527,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + struct hlsl_ir_node *object_load_offset, *sampler_load_offset; enum hlsl_resource_load_type load_type; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; @@ -2545,6 +2536,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct hlsl_type *result_type; struct hlsl_ir_node *coords; unsigned int read_channel; + struct hlsl_block block;
if (!strcmp(name, "GatherGreen")) { @@ -2626,9 +2618,15 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
+ object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); + list_move_tail(instrs, &block.instrs); + + sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc); + list_move_tail(instrs, &block.instrs); + if (!(load = hlsl_new_resource_load(ctx, result_type, - load_type, object_load->src.var, object_load->src.offset.node, - sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) + load_type, object_load->src.var, object_load_offset, + sampler_load->src.var, sampler_load_offset, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 373439af..0b577f54 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,6 +21,48 @@ #include "hlsl.h" #include <stdio.h>
+/* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ +static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + struct hlsl_ir_node *instr) +{ + struct hlsl_ir_node *offset; + struct hlsl_block block; + + if (!deref->var) + return; + + if (!(offset = hlsl_new_offset_node_from_deref(ctx, &block, deref, &instr->loc))) + return; + list_move_before(&instr->entry, &block.instrs); + + hlsl_cleanup_deref(deref); + hlsl_src_from_node(&deref->offset, offset); +} + +/* TODO: remove when no longer needed. */ +static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + switch(instr->type) + { + case HLSL_IR_LOAD: + replace_deref_path_with_offset(ctx, &hlsl_ir_load(instr)->src, instr); + return true; + + case HLSL_IR_STORE: + replace_deref_path_with_offset(ctx, &hlsl_ir_store(instr)->lhs, instr); + return true; + + case HLSL_IR_RESOURCE_LOAD: + replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->resource, instr); + replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); + return true; + + default: + return false; + } + return false; +} + /* Split uniforms into two variables representing the constant and temp * registers, and copy the former to the latter, so that writes to uniforms * work. */ @@ -1890,6 +1932,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
list_move_head(&body->instrs, &ctx->static_initializers);
+ transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */ + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { if (var->modifiers & HLSL_STORAGE_UNIFORM)
On 7/14/22 20:23, Francisco Casas wrote:
- The introduction of hlsl_new_store_index() was moved to another patch.
- The introduction of hlsl_new_store_component() mas moved to another patch.
- The translation of hlsl_new_resource_load() to register offsets was split from this patch.
Yeah, although I kind of meant moving them *before* this patch, along the principle of "abstract away the interface and then change the implementation". Probably not worth rewriting the series again at this point, though.
Regarding the possibility of having a hlsl_deref_from_component_index() function, there are 2 inconveniences:
- It is necessary to create constant nodes for the path, so, an instruction block pointer is required.
- An additional hlsl_deref pointer is required for its use in hlsl_new_store_component(), since the lhs path needs to be prepend to the path to the component [1].
The signature of the function would end up like this:
static bool hlsl_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int index, struct hlsl_deref *path_prefix, const struct vkd3d_shader_location *loc)
So in the end I think it is not a good idea to have hlsl_deref_from_component_index() directly.
[1] There is also the alternative of introducing a hlsl_deref_concat() function that takes two derefs and retrieves a new one.
I don't think we'd need to pass the var *and* deref, would we?
Also: why do we need to pass a deref pointer to hlsl_new_store_component() in the first place? From 13/17 we only use it with variables directly. I guess the answer might be "consistency with hlsl_new_store_index()", which isn't a bad answer.
But, that said, I don't think that either of these are prohibitive, or make things worse than the alternative.
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index)
+{
- while (!type_is_single_component(type))
subtype_index_from_component_index(ctx, &type, &index);
- return type;
+}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
+static unsigned int *compute_component_path(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index, unsigned int *path_len)
+{
- struct hlsl_type *path_type;
- unsigned int *path, path_index;
- *path_len = 0;
- path_type = type;
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++*path_len;
- }
- if (!(path = hlsl_alloc(ctx, *path_len * sizeof(unsigned int) + 1)))
return NULL;
- *path_len = 0;
- path_type = type;
- path_index = index;
- while (!type_is_single_component(path_type))
- {
path[*path_len] = subtype_index_from_component_index(ctx, &path_type, &path_index);
++*path_len;
- }
- return path;
+}
Could we return path_type from this function, since we've already calculated it, and throw out hlsl_type_get_component_type() entirely?
@@ -757,13 +948,21 @@ struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *v return NULL;
init_node(&store->node, HLSL_IR_STORE, NULL, loc);
- store->lhs.var = var;
- init_deref(ctx, &store->lhs, var, 0);
Or hlsl_init_simple_deref_from_var(), here and in hlsl_new_load()?
hlsl_src_from_node(&store->lhs.offset, offset); hlsl_src_from_node(&store->rhs, rhs); store->writemask = writemask; return store;
}
On 15-07-22 17:52, Zebediah Figura wrote:
On 7/14/22 20:23, Francisco Casas wrote:
- The introduction of hlsl_new_store_index() was moved to another patch.
- The introduction of hlsl_new_store_component() mas moved to another
patch.
- The translation of hlsl_new_resource_load() to register offsets was
split from this patch.
Yeah, although I kind of meant moving them *before* this patch, along the principle of "abstract away the interface and then change the implementation". Probably not worth rewriting the series again at this point, though.
I see, that sounds useful for reducing the number of diff chunks. Albeit, at the cost of having to add an intermediate implementation. I will try to keep that principle in mind.
Regarding the possibility of having a hlsl_deref_from_component_index() function, there are 2 inconveniences:
- It is necessary to create constant nodes for the path, so, an
instruction block pointer is required. 2. An additional hlsl_deref pointer is required for its use in hlsl_new_store_component(), since the lhs path needs to be prepend to the path to the component [1].
The signature of the function would end up like this:
static bool hlsl_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, Â Â Â Â Â Â Â Â struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int index, Â Â Â Â Â Â Â Â struct hlsl_deref *path_prefix, const struct vkd3d_shader_location *loc)
So in the end I think it is not a good idea to have hlsl_deref_from_component_index() directly.
[1] There is also the alternative of introducing a hlsl_deref_concat() function that takes two derefs and retrieves a new one.
I don't think we'd need to pass the var *and* deref, would we?
Ah yes, we can use the deref to get the var.
Also: why do we need to pass a deref pointer to hlsl_new_store_component() in the first place? From 13/17 we only use it with variables directly. I guess the answer might be "consistency with hlsl_new_store_index()", which isn't a bad answer.
Hmm, good point, yes, I don't have a better argument than that. It may be useful in translating the next passes but I can't think of any use case yet.
But, that said, I don't think that either of these are prohibitive, or make things worse than the alternative.
So, just to confirm, I should replace compute_component_path() with a hlsl_deref_from_component_index() in v3. Right?
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, +Â Â Â Â Â Â Â unsigned int index) +{ +Â Â Â while (!type_is_single_component(type)) +Â Â Â Â Â Â Â subtype_index_from_component_index(ctx, &type, &index);
+Â Â Â return type; +}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
+static unsigned int *compute_component_path(struct hlsl_ctx *ctx, struct hlsl_type *type, +Â Â Â Â Â Â Â unsigned int index, unsigned int *path_len) +{ +Â Â Â struct hlsl_type *path_type; +Â Â Â unsigned int *path, path_index;
+Â Â Â *path_len = 0; +Â Â Â path_type = type; +Â Â Â path_index = index; +Â Â Â while (!type_is_single_component(path_type)) +Â Â Â { +Â Â Â Â Â Â Â subtype_index_from_component_index(ctx, &path_type, &path_index); +Â Â Â Â Â Â Â ++*path_len; +Â Â Â } +Â Â Â if (!(path = hlsl_alloc(ctx, *path_len * sizeof(unsigned int) + 1))) +Â Â Â Â Â Â Â return NULL;
+Â Â Â *path_len = 0; +Â Â Â path_type = type; +Â Â Â path_index = index; +Â Â Â while (!type_is_single_component(path_type)) +Â Â Â { +Â Â Â Â Â Â Â path[*path_len] = subtype_index_from_component_index(ctx, &path_type, &path_index); +Â Â Â Â Â Â Â ++*path_len; +Â Â Â }
+Â Â Â return path; +}
Could we return path_type from this function, since we've already calculated it, and throw out hlsl_type_get_component_type() entirely?
We would be giving the caller the responsibility of freeing the returned path even if it is not used (which I think was a concern in v1). It also happens often that the path is required but not the component type.
So, given that the implementation of both functions is small and doesn't introduce too much overhead, I think that keeping them separate is better, but, as always, if you insist I will change it.
@@ -757,13 +948,21 @@ struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *v          return NULL;      init_node(&store->node, HLSL_IR_STORE, NULL, loc); -   store->lhs.var = var; +   init_deref(ctx, &store->lhs, var, 0);
Or hlsl_init_simple_deref_from_var(), here and in hlsl_new_load()?
hlsl_src_from_node(&store->lhs.offset, offset); Â Â Â Â Â hlsl_src_from_node(&store->rhs, rhs); Â Â Â Â Â store->writemask = writemask; Â Â Â Â Â return store; Â }
On 7/15/22 18:31, Francisco Casas wrote:
But, that said, I don't think that either of these are prohibitive, or make things worse than the alternative.
So, just to confirm, I should replace compute_component_path() with a hlsl_deref_from_component_index() in v3. Right?
Without having seen it, I think I'd be in favor of it. In a sense it's the same function anyway, mostly, just with a few differences.
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, +Â Â Â Â Â Â Â unsigned int index) +{ +Â Â Â while (!type_is_single_component(type)) +Â Â Â Â Â Â Â subtype_index_from_component_index(ctx, &type, &index);
+Â Â Â return type; +}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
+static unsigned int *compute_component_path(struct hlsl_ctx *ctx, struct hlsl_type *type, +Â Â Â Â Â Â Â unsigned int index, unsigned int *path_len) +{ +Â Â Â struct hlsl_type *path_type; +Â Â Â unsigned int *path, path_index;
+Â Â Â *path_len = 0; +Â Â Â path_type = type; +Â Â Â path_index = index; +Â Â Â while (!type_is_single_component(path_type)) +Â Â Â { +Â Â Â Â Â Â Â subtype_index_from_component_index(ctx, &path_type, &path_index); +Â Â Â Â Â Â Â ++*path_len; +Â Â Â } +Â Â Â if (!(path = hlsl_alloc(ctx, *path_len * sizeof(unsigned int) + 1))) +Â Â Â Â Â Â Â return NULL;
+Â Â Â *path_len = 0; +Â Â Â path_type = type; +Â Â Â path_index = index; +Â Â Â while (!type_is_single_component(path_type)) +Â Â Â { +Â Â Â Â Â Â Â path[*path_len] = subtype_index_from_component_index(ctx, &path_type, &path_index); +Â Â Â Â Â Â Â ++*path_len; +Â Â Â }
+Â Â Â return path; +}
Could we return path_type from this function, since we've already calculated it, and throw out hlsl_type_get_component_type() entirely?
We would be giving the caller the responsibility of freeing the returned path even if it is not used (which I think was a concern in v1). It also happens often that the path is required but not the component type.
So, given that the implementation of both functions is small and doesn't introduce too much overhead, I think that keeping them separate is better, but, as always, if you insist I will change it.
Oh, right, I forgot that add_cast() needed hlsl_type_get_component_type() but not this function. Never mind, then.
On 7/14/22 20:23, Francisco Casas wrote:
The transform_deref_paths_into_offsets pass turns these index paths back into register offsets.
Signed-off-by: Francisco Casas [email protected]
The idea is that we can move the transform_deref_paths_into_offsets() pass forward as we translate more passes to work with index paths. This, until register offsets can be totally removed, after we implement the SMxIRs and their translations.
The aim is to have 3 ways of initializing load/store nodes when using index paths:
- One that initializes the node from a another's node deref and and optional index to be appended to that deref's path.
- One that initializes the node from a deref and the index of a single basic component within it. This one also generates constant nodes for the required path, so it also initializes an instruction block whose instructions must be inserted in the instruction list.
- One that initializes the node directly for a whole variable. These functions are already present: hlsl_new_var_load() and hlsl_new_simple_store().
The signatures of these functions were placed nearby in hlsl.h
It is worth noting that the use of index paths allows to remove the data type argument when initializing store/loads because it can now be deducted from the variable and the hlsl_deref.
Applying an index over a matrix derefence retrieves a vector. If the matrix is row_major, this corresponds to a row, otherwise, it corresponds to a column. So, the code should take matrix majority into account, at least until the split_matrix_copies pass.
The first index in a path after a loading a struct should be an hlsl_ir_constant, since the field that's being addressed is always known at parse-time.
hlsl_init_simple_deref_from_var() can be used to initialize a deref that can be passed by reference to the load and store initialization functions. This value shall not be modified after being created and does not require to call hlsl_cleanup_deref().
v2 (including changes in splits of this patch):
- cleanup_deref() had to be made non-static in this commit because this is the commit where it is used outside hlsl.c. It also was renamed to hlsl_cleanup_deref() to follow the convention.
- hlsl_new_load_index(), hlsl_new_load_component() and hlsl_new_store_index() now receive a "const struct vkd3d_shader_location *loc".
- Removed braces from switch cases without declarations.
- hlsl_compute_component_path() made static and no longer used to retrieve the componet type. The "hlsl_" prefix was removed.
- Using Zeb's strategy for handling recursion in compute_component_path(); implemented in subtype_index_from_component_index().
- Added hlsl_type_get_component_type() to retrieve the component type.
- Allocating at least 1 byte in compute_component_path(), to ensure that NULL is never returned on success.
- Using 'assert(index < type->dimx)' instead of 'assert(index < type->dimx * type->dimy)' in HLSL_CLASS_VECTOR case in path function.
- Restored 'assert(array_index < type->e.array.elements_count)'.
- Added 'assert(!other->offset.node)' in deref_copy() because it is not indended to copy derefs that use nodes. Naturally, the assertion must be removed once we remove the offset field from hlsl_deref.
- Using memset to initialize deref in deref_copy().
- Using path_len instead of 'i' for calling hlsl_src_from_node() in hlsl_new_load_index/hlsl_new_store_index 'if (idx)' bodies.
- Removed double newline in hlsl_new_load_component().
- Using list_move_before() instead of iterating instruction list in replace_deref_path_with_offset().
- Renamed hlsl_get_direct_var_deref() to hlsl_init_simple_deref_from_var(), passing deref by pointer.
- The introduction of hlsl_new_store_index() was moved to another patch.
- The introduction of hlsl_new_store_component() mas moved to another patch.
- The translation of hlsl_new_resource_load() to register offsets was split from this patch.
- hlsl_new_offset_node_from_deref() was implemented in order to create new offsets in hlsl.y from derefs, in order to be used as input for stores and resource loads that will still require offsets (at least until the following patches). his function is also used in replace_deref_path_with_offset(), to make the implementation smaller.
- Added assertions to hlsl_new_store_index() and hlsl_new_load_index() to ensure that they don't receive derefs with register offset instead of index paths.
Zeb:
Regarding the possibility of having a hlsl_deref_from_component_index() function, there are 2 inconveniences:
- It is necessary to create constant nodes for the path, so, an instruction block pointer is required.
- An additional hlsl_deref pointer is required for its use in hlsl_new_store_component(), since the lhs path needs to be prepend to the path to the component [1].
The signature of the function would end up like this:
static bool hlsl_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int index, struct hlsl_deref *path_prefix, const struct vkd3d_shader_location *loc)
So in the end I think it is not a good idea to have hlsl_deref_from_component_index() directly.
However, subtype_index_from_component_index() worked nicely; it allowed to create a simple implementation for hlsl_compute_component_path() and creating hlsl_type_get_component_type(). Furthermore, given that the latter function allows to obtain the component data type easily, hlsl_compute_component_path() is no longer required to retrieve the component type and can be static now.
I ended up replacing
struct hlsl_deref hlsl_get_direct_var_deref(struct hlsl_ir_var *var);
with:
void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var);
as you suggested, but adding the "init" to the name to avoid it being solely a noun phrase.
I decided not to include the cast in hlsl_new_store_component() because now it is only required in one place and it would be inconsistent with hlsl_new_store_index() that doesn't.
While I could separate hlsl_new_store_index() and hlsl_new_load_component(), hlsl_new_load_component() and hlsl_new_load_index() must both be introduced in the same patch because they both expect dereferences with path indexes instead of offsets (which come from from other loads). Converting from dereferences with offsets to index paths is hard and I don't think it is worth implementing just to split more this patch (unlike converting the other way around).
[1] There is also the alternative of introducing a hlsl_deref_concat() function that takes two derefs and retrieves a new one.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 305 ++++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 +++++------ libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 417 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d3ceba35..4b01cca5 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,124 @@ unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_typ return 0; }
+static bool type_is_single_component(const struct hlsl_type *type) +{
- return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT;
+}
+/* Given a type and a component index, retrieves next path index required to reach the component.
- *typep will be set to the subtype within the original type that contains the component.
- *indexp will be set to the index of the component within *typep.
- */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **typep, unsigned int *indexp)
+{
- struct hlsl_type *type = *typep;
- unsigned int index = *indexp;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*typep = hlsl_get_scalar_type(ctx, type->base_type);
*indexp = 0;
return index;
case HLSL_CLASS_MATRIX:
{
unsigned int y = index / type->dimx, x = index % type->dimx;
bool row_major = hlsl_type_is_row_major(type);
assert(index < type->dimx * type->dimy);
*typep = hlsl_get_vector_type(ctx, type->base_type, row_major? type->dimx : type->dimy);
*indexp = row_major? x : y;
return row_major? y : x;
}
case HLSL_CLASS_ARRAY:
{
unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type);
unsigned int array_index;
*typep = type->e.array.type;
*indexp = index % elem_comp_count;
array_index = index / elem_comp_count;
assert(array_index < type->e.array.elements_count);
return array_index;
}
case HLSL_CLASS_STRUCT:
{
struct hlsl_struct_field *field;
unsigned int field_comp_count, i;
for (i = 0; i < type->e.record.field_count; ++i)
{
field = &type->e.record.fields[i];
field_comp_count = hlsl_type_component_count(field->type);
if (index < field_comp_count)
{
*typep = field->type;
*indexp = index;
return i;
}
index -= field_comp_count;
}
assert(0);
return 0;
}
default:
assert(0);
return 0;
- }
+}
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index)
+{
- while (!type_is_single_component(type))
subtype_index_from_component_index(ctx, &type, &index);
- return type;
+}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
+static unsigned int *compute_component_path(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index, unsigned int *path_len)
+{
- struct hlsl_type *path_type;
- unsigned int *path, path_index;
- *path_len = 0;
- path_type = type;
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++*path_len;
- }
- if (!(path = hlsl_alloc(ctx, *path_len * sizeof(unsigned int) + 1)))
return NULL;
- *path_len = 0;
- path_type = type;
- path_index = index;
- while (!type_is_single_component(path_type))
- {
path[*path_len] = subtype_index_from_component_index(ctx, &path_type, &path_index);
++*path_len;
- }
- return path;
+}
- struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) {
@@ -433,6 +551,37 @@ struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struc return idx_offset; }
+struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc)
+{
- struct hlsl_ir_node *offset = NULL;
- struct hlsl_type *type;
- unsigned int i;
- list_init(&block->instrs);
- if (deref->offset.node)
return deref->offset.node;
- assert(deref->var);
- type = deref->var->data_type;
- for (i = 0; i < deref->path_len; ++i)
- {
struct hlsl_block idx_block;
if (!(offset = hlsl_new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, loc)))
return NULL;
list_move_tail(&block->instrs, &idx_block.instrs);
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- }
- return offset;
+}
- struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type;
@@ -523,7 +672,7 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha return NULL; }
-unsigned int hlsl_type_component_count(struct hlsl_type *type) +unsigned int hlsl_type_component_count(const struct hlsl_type *type) { unsigned int count = 0, i;
@@ -740,8 +889,50 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
-static void cleanup_deref(struct hlsl_deref *deref) +static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var,
unsigned int path_len)
+{
- deref->var = var;
- deref->path_len = path_len;
- deref->offset.node = NULL;
- if (path_len == 0)
- {
deref->path = NULL;
return true;
- }
- if (!(deref->path = hlsl_alloc(ctx, sizeof(*deref->path) * deref->path_len)))
- {
deref->var = NULL;
deref->path_len = 0;
return false;
- }
- return true;
+}
+static struct hlsl_type *get_type_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{
- struct hlsl_type *type = deref->var->data_type;
- unsigned int i;
- for (i = 0; i < deref->path_len; ++i)
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- return type;
+}
+void hlsl_cleanup_deref(struct hlsl_deref *deref) {
- unsigned int i;
- for (i = 0; i < deref->path_len; ++i)
hlsl_src_remove(&deref->path[i]);
- vkd3d_free(deref->path);
- deref->path = NULL;
- deref->path_len = 0;
}hlsl_src_remove(&deref->offset);
@@ -757,13 +948,21 @@ struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *v return NULL;
init_node(&store->node, HLSL_IR_STORE, NULL, loc);
- store->lhs.var = var;
- init_deref(ctx, &store->lhs, var, 0); hlsl_src_from_node(&store->lhs.offset, offset); hlsl_src_from_node(&store->rhs, rhs); store->writemask = writemask; return store; }
+/* Initializes a simple variable derefence, so that a pointer to it can be passed to load/store
- functions. The deref shall not be modified afterwards. */
+void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) +{
- memset(deref, 0, sizeof(*deref));
- deref->var = var;
+}
- struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) { return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc);
@@ -860,15 +1059,101 @@ struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; init_node(&load->node, HLSL_IR_LOAD, type, loc);
- load->src.var = var;
- init_deref(ctx, &load->src, var, 0); hlsl_src_from_node(&load->src.offset, offset); return load; }
+struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
+{
- struct hlsl_ir_load *load;
- struct hlsl_type *type;
- unsigned int i;
- assert(!deref->offset.node);
- type = get_type_from_deref(ctx, deref);
- if (idx)
type = hlsl_get_type_from_path_index(ctx, type, idx);
- if (!(load = hlsl_alloc(ctx, sizeof(*load))))
return NULL;
- init_node(&load->node, HLSL_IR_LOAD, type, *loc);
- if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx))
- {
vkd3d_free(load);
return NULL;
- }
- for (i = 0; i < deref->path_len; ++i)
hlsl_src_from_node(&load->src.path[i], deref->path[i].node);
- if (idx)
hlsl_src_from_node(&load->src.path[deref->path_len], idx);
- return load;
+}
- struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
const struct vkd3d_shader_location loc)
{struct vkd3d_shader_location loc)
- return hlsl_new_load(ctx, var, NULL, var->data_type, loc);
- struct hlsl_deref var_deref;
- hlsl_init_simple_deref_from_var(&var_deref, var);
- return hlsl_new_load_index(ctx, &var_deref, NULL, &loc);
+}
+struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc)
+{
struct hlsl_type *type, *comp_type;
unsigned int *path, path_len, i;
struct hlsl_ir_constant *c;
struct hlsl_ir_load *load;
list_init(&block->instrs);
type = get_type_from_deref(ctx, deref);
path = compute_component_path(ctx, type, comp, &path_len);
if (!path)
return NULL;
if (!(load = hlsl_alloc(ctx, sizeof(*load))))
{
vkd3d_free(path);
return NULL;
}
comp_type = hlsl_type_get_component_type(ctx, type, comp);
init_node(&load->node, HLSL_IR_LOAD, comp_type, *loc);
if (!init_deref(ctx, &load->src, deref->var, deref->path_len + path_len))
{
vkd3d_free(path);
vkd3d_free(load);
return NULL;
}
for (i = 0; i < deref->path_len; ++i)
hlsl_src_from_node(&load->src.path[i], deref->path[i].node);
for (i = 0; i < path_len; ++i)
{
if (!(c = hlsl_new_uint_constant(ctx, path[i], loc)))
{
vkd3d_free(path);
hlsl_free_instr_list(&block->instrs);
hlsl_cleanup_deref(&load->src);
vkd3d_free(load);
return NULL;
}
list_add_tail(&block->instrs, &c->node.entry);
hlsl_src_from_node(&load->src.path[deref->path_len + i], &c->node);
}
vkd3d_free(path);
list_add_tail(&block->instrs, &load->node.entry);
return load; }
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type,
@@ -1703,7 +1988,7 @@ static void free_ir_jump(struct hlsl_ir_jump *jump)
static void free_ir_load(struct hlsl_ir_load *load) {
- cleanup_deref(&load->src);
- hlsl_cleanup_deref(&load->src); vkd3d_free(load); }
@@ -1716,8 +2001,8 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { hlsl_src_remove(&load->coords);
- cleanup_deref(&load->sampler);
- cleanup_deref(&load->resource);
- hlsl_cleanup_deref(&load->sampler);
- hlsl_cleanup_deref(&load->resource); hlsl_src_remove(&load->texel_offset); vkd3d_free(load); }
@@ -1725,7 +2010,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) static void free_ir_store(struct hlsl_ir_store *store) { hlsl_src_remove(&store->rhs);
- cleanup_deref(&store->lhs);
- hlsl_cleanup_deref(&store->lhs); vkd3d_free(store); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 546c87f3..3a6af2a3 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -374,6 +374,10 @@ struct hlsl_ir_swizzle struct hlsl_deref { struct hlsl_ir_var *var;
- unsigned int path_len;
- struct hlsl_src *path;
};struct hlsl_src offset;
@@ -717,6 +721,8 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
+void hlsl_cleanup_deref(struct hlsl_deref *deref);
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
void hlsl_free_instr(struct hlsl_ir_node *node);
@@ -751,14 +757,29 @@ struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condit struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, const struct vkd3d_shader_location *loc); struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc); -struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
struct hlsl_type *type, struct vkd3d_shader_location loc);
-struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc);
+void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var);
+struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
struct vkd3d_shader_location loc);
+struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc);
+struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc);
+struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs);
+struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc);
- struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc);
-struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs);
+struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
struct hlsl_type *type, struct vkd3d_shader_location loc);
+struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, 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_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, @@ -775,8 +796,6 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, const struct hlsl_semantic *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation); -struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
const struct vkd3d_shader_location loc);
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
@@ -794,10 +813,12 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type);
struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers); -unsigned int hlsl_type_component_count(struct hlsl_type *type); +unsigned int hlsl_type_component_count(const struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int idx, struct hlsl_type **comp_type); +struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type);unsigned int index);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a1d39140..3447ddd5 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -352,7 +352,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, list_add_tail(instrs, &store->node.entry); }
if (!(load = hlsl_new_load(ctx, var, NULL, dst_type, *loc)))
if (!(load = hlsl_new_var_load(ctx, var, *loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -625,31 +625,18 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) {
- struct hlsl_type *elem_type;
- struct hlsl_ir_node *offset;
- const struct hlsl_deref *src; struct hlsl_ir_load *load;
struct hlsl_block block;
struct hlsl_ir_var *var;
elem_type = hlsl_get_type_from_path_index(ctx, var_node->data_type, idx);
if (var_node->type == HLSL_IR_LOAD) {
const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src;
var = src->var;
if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, src->offset.node, idx, loc)))
return NULL;
list_move_tail(instrs, &block.instrs);
src = &hlsl_ir_load(var_node)->src; } else { struct vkd3d_string_buffer *name; struct hlsl_ir_store *store;
if (!(offset = hlsl_new_offset_from_path_index(ctx, &block, var_node->data_type, NULL, idx, loc)))
return NULL;
list_move_tail(instrs, &block.instrs);
struct hlsl_ir_var *var; name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<deref-%p>", var_node);
@@ -661,9 +648,11 @@ static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *in if (!(store = hlsl_new_simple_store(ctx, var, var_node))) return NULL; list_add_tail(instrs, &store->node.entry);
src = &store->lhs; }
- if (!(load = hlsl_new_load(ctx, var, offset, elem_type, *loc)))
- if (!(load = hlsl_new_load_index(ctx, src, idx, loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -673,39 +662,19 @@ static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *in static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, unsigned int comp, const struct vkd3d_shader_location *loc) {
- struct hlsl_type *comp_type;
- struct hlsl_ir_node *offset;
- struct hlsl_ir_constant *c;
- const struct hlsl_deref *src; struct hlsl_ir_load *load;
- unsigned int comp_offset;
- struct hlsl_ir_var *var;
- comp_offset = hlsl_compute_component_offset(ctx, var_node->data_type, comp, &comp_type);
- if (!(c = hlsl_new_uint_constant(ctx, comp_offset, loc)))
return NULL;
- list_add_tail(instrs, &c->node.entry);
- offset = &c->node;
struct hlsl_block block;
if (var_node->type == HLSL_IR_LOAD) {
const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src;
struct hlsl_ir_node *add;
var = src->var;
if (src->offset.node)
{
if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, &c->node)))
return NULL;
list_add_tail(instrs, &add->entry);
offset = add;
}
src = &hlsl_ir_load(var_node)->src; } else { struct vkd3d_string_buffer *name; struct hlsl_ir_store *store;
struct hlsl_ir_var *var; name = vkd3d_string_buffer_get(&ctx->string_buffers); vkd3d_string_buffer_printf(name, "<deref-%p>", var_node);
@@ -717,11 +686,13 @@ static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list if (!(store = hlsl_new_simple_store(ctx, var, var_node))) return NULL; list_add_tail(instrs, &store->node.entry);
src = &store->lhs; }
- if (!(load = hlsl_new_load(ctx, var, offset, comp_type, *loc)))
- if (!(load = hlsl_new_load_component(ctx, &block, src, comp, loc))) return NULL;
- list_add_tail(instrs, &load->node.entry);
list_move_tail(instrs, &block.instrs);
return load; }
@@ -1275,7 +1246,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, list_add_tail(instrs, &store->node.entry); }
if (!(load = hlsl_new_load(ctx, var, NULL, type, *loc)))
if (!(load = hlsl_new_var_load(ctx, var, *loc))) return NULL; list_add_tail(instrs, &load->node.entry);
@@ -1632,8 +1603,10 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { struct hlsl_type *lhs_type = lhs->data_type; struct hlsl_ir_store *store;
struct hlsl_ir_node *offset; struct hlsl_ir_expr *copy; unsigned int writemask = 0;
struct hlsl_block block;
if (assign_op == ASSIGN_OP_SUB) {
@@ -1702,10 +1675,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in } }
- offset = hlsl_new_offset_node_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc);
- list_move_tail(instrs, &block.instrs);
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->lhs.offset, offset); hlsl_src_from_node(&store->rhs, rhs); list_add_tail(instrs, &store->node.entry);
@@ -2236,7 +2212,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, list_add_tail(params->instrs, &store->node.entry); }
- if (!(load = hlsl_new_load(ctx, var, NULL, matrix_type, *loc)))
- if (!(load = hlsl_new_var_load(ctx, var, *loc))) return false; list_add_tail(params->instrs, &load->node.entry);
@@ -2445,8 +2421,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
struct hlsl_ir_node *object_load_offset; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *coords;
struct hlsl_block block; if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY)
@@ -2471,8 +2449,11 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) return false;
object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc);
list_move_tail(instrs, &block.instrs);
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD,
object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, NULL, loc)))
object_load->src.var, object_load_offset, NULL, NULL, coords, NULL, loc))) return false; list_add_tail(instrs, &load->node.entry); return true;
@@ -2482,11 +2463,13 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
struct hlsl_ir_node *object_load_offset, *sampler_load_offset; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *offset = NULL; struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords;
struct hlsl_block block; if (params->args_count != 2 && params->args_count != 3) {
@@ -2522,11 +2505,18 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc);
list_move_tail(instrs, &block.instrs);
sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc);
list_move_tail(instrs, &block.instrs);
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format,
HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node,
sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc)))
HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load_offset,
sampler_load->src.var, sampler_load_offset, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry);
return true; } else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue")
@@ -2537,6 +2527,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
struct hlsl_ir_node *object_load_offset, *sampler_load_offset; enum hlsl_resource_load_type load_type; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load;
@@ -2545,6 +2536,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct hlsl_type *result_type; struct hlsl_ir_node *coords; unsigned int read_channel;
struct hlsl_block block; if (!strcmp(name, "GatherGreen")) {
@@ -2626,9 +2618,15 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc);
list_move_tail(instrs, &block.instrs);
sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc);
list_move_tail(instrs, &block.instrs);
if (!(load = hlsl_new_resource_load(ctx, result_type,
load_type, object_load->src.var, object_load->src.offset.node,
sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc)))
load_type, object_load->src.var, object_load_offset,
sampler_load->src.var, sampler_load_offset, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true;
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 373439af..0b577f54 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,6 +21,48 @@ #include "hlsl.h" #include <stdio.h>
+/* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ +static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref,
struct hlsl_ir_node *instr)
+{
- struct hlsl_ir_node *offset;
- struct hlsl_block block;
- if (!deref->var)
return;
- if (!(offset = hlsl_new_offset_node_from_deref(ctx, &block, deref, &instr->loc)))
return;
- list_move_before(&instr->entry, &block.instrs);
- hlsl_cleanup_deref(deref);
- hlsl_src_from_node(&deref->offset, offset);
+}
+/* TODO: remove when no longer needed. */ +static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{
- switch(instr->type)
- {
case HLSL_IR_LOAD:
replace_deref_path_with_offset(ctx, &hlsl_ir_load(instr)->src, instr);
return true;
case HLSL_IR_STORE:
replace_deref_path_with_offset(ctx, &hlsl_ir_store(instr)->lhs, instr);
return true;
case HLSL_IR_RESOURCE_LOAD:
replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->resource, instr);
replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr);
return true;
default:
return false;
- }
- return false;
+}
- /* Split uniforms into two variables representing the constant and temp
- registers, and copy the former to the latter, so that writes to uniforms
- work. */
@@ -1890,6 +1932,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
list_move_head(&body->instrs, &ctx->static_initializers);
- transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { if (var->modifiers & HLSL_STORAGE_UNIFORM)
Sorry, please ignore this email, it was sent by accident and doesn't contain any response from me.
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
+/* Given a type and a component index, retrieves next path index required to reach the component.
- *typep will be set to the subtype within the original type that contains the component.
- *indexp will be set to the index of the component within *typep.
- */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **typep, unsigned int *indexp)
I guess that the "p"'s in "typep" and "indexp" are a sort of reverse Hungarian notation. It's a nitpick, but I am not really a fan of that, and I don't think we're using that anywhere in the HLSL compiler.
+{
- struct hlsl_type *type = *typep;
- unsigned int index = *indexp;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*typep = hlsl_get_scalar_type(ctx, type->base_type);
*indexp = 0;
return index;
case HLSL_CLASS_MATRIX:
{
unsigned int y = index / type->dimx, x = index % type->dimx;
bool row_major = hlsl_type_is_row_major(type);
assert(index < type->dimx * type->dimy);
*typep = hlsl_get_vector_type(ctx, type->base_type, row_major? type->dimx : type->dimy);
*indexp = row_major? x : y;
return row_major? y : x;
I think we leave a space before the operator "?", don't we?
}
case HLSL_CLASS_ARRAY:
{
unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type);
unsigned int array_index;
*typep = type->e.array.type;
*indexp = index % elem_comp_count;
array_index = index / elem_comp_count;
assert(array_index < type->e.array.elements_count);
return array_index;
}
case HLSL_CLASS_STRUCT:
{
struct hlsl_struct_field *field;
unsigned int field_comp_count, i;
for (i = 0; i < type->e.record.field_count; ++i)
{
field = &type->e.record.fields[i];
field_comp_count = hlsl_type_component_count(field->type);
if (index < field_comp_count)
{
*typep = field->type;
*indexp = index;
return i;
}
index -= field_comp_count;
}
assert(0);
return 0;
}
default:
assert(0);
return 0;
- }
+}
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index)
+{
- while (!type_is_single_component(type))
subtype_index_from_component_index(ctx, &type, &index);
- return type;
+}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
I find the verbal tenses rather confusing: here we have a present tense, a future tense with "will" and a "should". Combined with the typo in "free" (I guess that was "freed"?), it makes the whole lot rather hard to understand if you don't already know what it means.
I would suggest to describe what this function does using consistently either an imperative form or a present tense, and to describe expectations from the caller by clearly marking them as such.
For example: "Return the path of a given component within a type, given its index, and set *path_len to the length of the path. The caller is responsible for freeing the returned pointer with hlsl_free()".
(Many technical writing indications suggest to avoid passive voices to make phrasing clearer; I am not sure that should be a general rule, but it can be a point to keep in mind)
BTW, the same suggestion applies to the comment before subtype_index_from_component_index(), though in that case the potential for confusion is smaller.
+/* Initializes a simple variable derefence, so that a pointer to it can be passed to load/store
- functions. The deref shall not be modified afterwards. */
Maybe I am missing something, but why this deref shouldn't be modified? Or, maybe, why is it particulatly important to specify that here? Maybe the comment could be make more explicit on what is special with this function.
+void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) +{
- memset(deref, 0, sizeof(*deref));
- deref->var = var;
+}
Thanks, Giovanni.
Hello,
On 19-07-22 05:11, Giovanni Mascellani wrote:
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
+/* Given a type and a component index, retrieves next path index required to reach the component.
- *typep will be set to the subtype within the original type that
contains the component.
- *indexp will be set to the index of the component within *typep.
- */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx, +Â Â Â Â Â Â Â struct hlsl_type **typep, unsigned int *indexp)
I guess that the "p"'s in "typep" and "indexp" are a sort of reverse Hungarian notation. It's a nitpick, but I am not really a fan of that, and I don't think we're using that anywhere in the HLSL compiler.
I didn't think on Hungarian notation, but I indeed added the 'p' to indicate that this is a "pointer to" the actual value.
Because the referenced values (*typep and *indexp) have to be used several times, and typep is a double pointer, I assigned these values to local variables:
struct hlsl_type *type = *typep; unsigned int index = *indexp;
Which is my opinion makes it far more readable that constantly using the dereference operator.
The problem is that I had to pick a different name for the local variables an the function arguments.
But, unless there is another suggestion, in v3 I am renaming the pointers "typep" and "indexp" to "type" and "index" respectively, and the values from "type" and "index" to "type_val" and "index_val" respectively.
+{ +Â Â Â struct hlsl_type *type = *typep; +Â Â Â unsigned int index = *indexp;
+Â Â Â assert(!type_is_single_component(type)); +Â Â Â assert(index < hlsl_type_component_count(type));
+Â Â Â switch (type->type) +Â Â Â { +Â Â Â Â Â Â Â case HLSL_CLASS_VECTOR: +Â Â Â Â Â Â Â Â Â Â Â assert(index < type->dimx); +Â Â Â Â Â Â Â Â Â Â Â *typep = hlsl_get_scalar_type(ctx, type->base_type); +Â Â Â Â Â Â Â Â Â Â Â *indexp = 0; +Â Â Â Â Â Â Â Â Â Â Â return index;
+Â Â Â Â Â Â Â case HLSL_CLASS_MATRIX: +Â Â Â Â Â Â Â { +Â Â Â Â Â Â Â Â Â Â Â unsigned int y = index / type->dimx, x = index % type->dimx; +Â Â Â Â Â Â Â Â Â Â Â bool row_major = hlsl_type_is_row_major(type);
+Â Â Â Â Â Â Â Â Â Â Â assert(index < type->dimx * type->dimy); +Â Â Â Â Â Â Â Â Â Â Â *typep = hlsl_get_vector_type(ctx, type->base_type, row_major? type->dimx : type->dimy); +Â Â Â Â Â Â Â Â Â Â Â *indexp = row_major? x : y; +Â Â Â Â Â Â Â Â Â Â Â return row_major? y : x;
I think we leave a space before the operator "?", don't we?
I see; changed.
+Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â case HLSL_CLASS_ARRAY: +Â Â Â Â Â Â Â { +Â Â Â Â Â Â Â Â Â Â Â unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type); +Â Â Â Â Â Â Â Â Â Â Â unsigned int array_index;
+Â Â Â Â Â Â Â Â Â Â Â *typep = type->e.array.type; +Â Â Â Â Â Â Â Â Â Â Â *indexp = index % elem_comp_count; +Â Â Â Â Â Â Â Â Â Â Â array_index = index / elem_comp_count; +Â Â Â Â Â Â Â Â Â Â Â assert(array_index < type->e.array.elements_count); +Â Â Â Â Â Â Â Â Â Â Â return array_index; +Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â case HLSL_CLASS_STRUCT: +Â Â Â Â Â Â Â { +Â Â Â Â Â Â Â Â Â Â Â struct hlsl_struct_field *field; +Â Â Â Â Â Â Â Â Â Â Â unsigned int field_comp_count, i;
+Â Â Â Â Â Â Â Â Â Â Â for (i = 0; i < type->e.record.field_count; ++i) +Â Â Â Â Â Â Â Â Â Â Â { +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â field = &type->e.record.fields[i]; +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â field_comp_count = hlsl_type_component_count(field->type); +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (index < field_comp_count) +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â { +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *typep = field->type; +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *indexp = index; +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â return i; +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â index -= field_comp_count; +Â Â Â Â Â Â Â Â Â Â Â } +Â Â Â Â Â Â Â Â Â Â Â assert(0); +Â Â Â Â Â Â Â Â Â Â Â return 0; +Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â default: +Â Â Â Â Â Â Â Â Â Â Â assert(0); +Â Â Â Â Â Â Â Â Â Â Â return 0; +Â Â Â } +}
+struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, +Â Â Â Â Â Â Â unsigned int index) +{ +Â Â Â while (!type_is_single_component(type)) +Â Â Â Â Â Â Â subtype_index_from_component_index(ctx, &type, &index);
+Â Â Â return type; +}
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
I find the verbal tenses rather confusing: here we have a present tense, a future tense with "will" and a "should". Combined with the typo in "free" (I guess that was "freed"?), it makes the whole lot rather hard to understand if you don't already know what it means.
I would suggest to describe what this function does using consistently either an imperative form or a present tense, and to describe expectations from the caller by clearly marking them as such.
For example: "Return the path of a given component within a type, given its index, and set *path_len to the length of the path. The caller is responsible for freeing the returned pointer with hlsl_free()".
(Many technical writing indications suggest to avoid passive voices to make phrasing clearer; I am not sure that should be a general rule, but it can be a point to keep in mind)
BTW, the same suggestion applies to the comment before subtype_index_from_component_index(), though in that case the potential for confusion is smaller.
Understood, I will prefer present sense and active voice from now on.
The function compute_component_path() will be removed in v3, but I am writing the comment in subtype_index_from_component_index() as:
/* Given a type and a component index, this function returns the next * path index required to reach the component within the type. * It sets *type to the subtype within the original type that contains * the component. * It sets *index to the index of the component within *type. */
+/* Initializes a simple variable derefence, so that a pointer to it can be passed to load/store
- functions. The deref shall not be modified afterwards. */
Maybe I am missing something, but why this deref shouldn't be modified? Or, maybe, why is it particulatly important to specify that here? Maybe the comment could be make more explicit on what is special with this function.
The point is that the derefs retrieved by this function in particular do not need to be passed to hlsl_cleanup_deref() afterwards because they don't point to allocated memory in the heap. However, if this deref is modified, this assumption no longer holds true (unless only the pointer to the variable is modified, but in that case it makes more sense to create another deref).
Is is better to say "There is no reason for modifying this deref." or, even better, to say nothing at all. So I am removing that part of the comment. It probably made more sense in the previous version of the patch where the deref was retrieved as return value.
+void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) +{ +Â Â Â memset(deref, 0, sizeof(*deref)); +Â Â Â deref->var = var; +}
Thanks, Giovanni.
Thanks, Francisco
On 7/19/22 15:21, Francisco Casas wrote:
Hello,
On 19-07-22 05:11, Giovanni Mascellani wrote:
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
+/* Given a type and a component index, retrieves next path index required to reach the component.
- *typep will be set to the subtype within the original type that
contains the component.
- *indexp will be set to the index of the component within *typep.
- */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx, +Â Â Â Â Â Â Â struct hlsl_type **typep, unsigned int *indexp)
I guess that the "p"'s in "typep" and "indexp" are a sort of reverse Hungarian notation. It's a nitpick, but I am not really a fan of that, and I don't think we're using that anywhere in the HLSL compiler.
I didn't think on Hungarian notation, but I indeed added the 'p' to indicate that this is a "pointer to" the actual value.
Because the referenced values (*typep and *indexp) have to be used several times, and typep is a double pointer, I assigned these values to local variables:
struct hlsl_type *type = *typep; unsigned int index = *indexp;
Which is my opinion makes it far more readable that constantly using the dereference operator.
The problem is that I had to pick a different name for the local variables an the function arguments.
But, unless there is another suggestion, in v3 I am renaming the pointers "typep" and "indexp" to "type" and "index" respectively, and the values from "type" and "index" to "type_val" and "index_val" respectively.
Personally I prefer the former, and don't particularly mind the -p suffix. Perhaps "type_ptr" would be more palatable.
+/* Returns the path of a given component within a type, given its index.
- *path_len will be set to the lenght of the path.
- Memory should be free afterwards.
- */
I find the verbal tenses rather confusing: here we have a present tense, a future tense with "will" and a "should". Combined with the typo in "free" (I guess that was "freed"?), it makes the whole lot rather hard to understand if you don't already know what it means.
I would suggest to describe what this function does using consistently either an imperative form or a present tense, and to describe expectations from the caller by clearly marking them as such.
For example: "Return the path of a given component within a type, given its index, and set *path_len to the length of the path. The caller is responsible for freeing the returned pointer with hlsl_free()".
(Many technical writing indications suggest to avoid passive voices to make phrasing clearer; I am not sure that should be a general rule, but it can be a point to keep in mind)
BTW, the same suggestion applies to the comment before subtype_index_from_component_index(), though in that case the potential for confusion is smaller.
Understood, I will prefer present sense and active voice from now on.
The function compute_component_path() will be removed in v3, but I am writing the comment in subtype_index_from_component_index() as:
/* Given a type and a component index, this function returns the next
- path index required to reach the component within the type.
- It sets *type to the subtype within the original type that contains
- the component.
- It sets *index to the index of the component within *type. */
FWIW, I don't see any problem with using future tense and passive voice in comments. For external facing documentation it's probably better to be consistent, but I don't think we should worry excessively about tense and grammar internally.
On Wed, Jul 20, 2022 at 12:03 AM Zebediah Figura [email protected] wrote:
On 7/19/22 15:21, Francisco Casas wrote:
Hello,
On 19-07-22 05:11, Giovanni Mascellani wrote:
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
+/* Given a type and a component index, retrieves next path index required to reach the component.
- *typep will be set to the subtype within the original type that
contains the component.
- *indexp will be set to the index of the component within *typep.
- */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **typep, unsigned int *indexp)
I guess that the "p"'s in "typep" and "indexp" are a sort of reverse Hungarian notation. It's a nitpick, but I am not really a fan of that, and I don't think we're using that anywhere in the HLSL compiler.
I didn't think on Hungarian notation, but I indeed added the 'p' to indicate that this is a "pointer to" the actual value.
Because the referenced values (*typep and *indexp) have to be used several times, and typep is a double pointer, I assigned these values to local variables:
struct hlsl_type *type = *typep; unsigned int index = *indexp;
Which is my opinion makes it far more readable that constantly using the dereference operator.
The problem is that I had to pick a different name for the local variables an the function arguments.
But, unless there is another suggestion, in v3 I am renaming the pointers "typep" and "indexp" to "type" and "index" respectively, and the values from "type" and "index" to "type_val" and "index_val" respectively.
Personally I prefer the former, and don't particularly mind the -p suffix. Perhaps "type_ptr" would be more palatable.
From a general naming viewpoint, yes I think it would be. "typep"
looks pretty ugly to me...
Signed-off-by: Francisco Casas [email protected] --- v2: * No changes. --- libs/vkd3d-shader/hlsl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 4b01cca5..d44c103e 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1595,10 +1595,23 @@ static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer
static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref) { + unsigned int i; + if (deref->var) { vkd3d_string_buffer_printf(buffer, "%s", deref->var->name); - if (deref->offset.node) + if (deref->path_len) + { + vkd3d_string_buffer_printf(buffer, "["); + for (i = 0; i < deref->path_len; ++i) + { + vkd3d_string_buffer_printf(buffer, "["); + dump_src(buffer, &deref->path[i]); + vkd3d_string_buffer_printf(buffer, "]"); + } + vkd3d_string_buffer_printf(buffer, "]"); + } + else if (deref->offset.node) { vkd3d_string_buffer_printf(buffer, "["); dump_src(buffer, &deref->offset);
Signed-off-by: Giovanni Mascellani [email protected]
Il 15/07/22 03:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v2:
- No changes.
libs/vkd3d-shader/hlsl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 4b01cca5..d44c103e 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1595,10 +1595,23 @@ static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer
static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref) {
- unsigned int i;
if (deref->var) { vkd3d_string_buffer_printf(buffer, "%s", deref->var->name);
if (deref->offset.node)
if (deref->path_len)
{
vkd3d_string_buffer_printf(buffer, "[");
for (i = 0; i < deref->path_len; ++i)
{
vkd3d_string_buffer_printf(buffer, "[");
dump_src(buffer, &deref->path[i]);
vkd3d_string_buffer_printf(buffer, "]");
}
vkd3d_string_buffer_printf(buffer, "]");
}
else if (deref->offset.node) { vkd3d_string_buffer_printf(buffer, "["); dump_src(buffer, &deref->offset);
Signed-off-by: Francisco Casas [email protected] --- v2: * Split from a previous patch. --- libs/vkd3d-shader/hlsl.c | 57 ++++++++++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 40 ++++++++++++++-------------- 3 files changed, 78 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index d44c103e..2d7d33fa 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -968,6 +968,63 @@ struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); }
+struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs) +{ + unsigned int *path, path_len, i; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_type *type; + + list_init(&block->instrs); + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_STORE, NULL, rhs->loc); + + type = get_type_from_deref(ctx, lhs); + path = compute_component_path(ctx, type, comp, &path_len); + if (!path) + { + vkd3d_free(store); + return NULL; + } + + if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + path_len)) + { + vkd3d_free(path); + vkd3d_free(store); + return NULL; + } + + for (i = 0; i < lhs->path_len; ++i) + hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node); + for (i = 0; i < path_len; ++i) + { + if (!(c = hlsl_new_uint_constant(ctx, path[i], &rhs->loc))) + { + vkd3d_free(path); + hlsl_free_instr_list(&block->instrs); + hlsl_cleanup_deref(&store->lhs); + vkd3d_free(store); + return NULL; + } + list_add_tail(&block->instrs, &c->node.entry); + + hlsl_src_from_node(&store->lhs.path[lhs->path_len + i], &c->node); + } + vkd3d_free(path); + + hlsl_src_from_node(&store->rhs, rhs); + + if (type_is_single_reg(rhs->data_type)) + store->writemask = (1 << rhs->data_type->dimx) - 1; + + list_add_tail(&block->instrs, &store->node.entry); + + return store; +} + struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, const struct vkd3d_shader_location *loc) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3a6af2a3..c8820711 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -768,6 +768,8 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc);
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); +struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 3447ddd5..8e5b8323 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -289,6 +289,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, { struct vkd3d_string_buffer *name; static unsigned int counter = 0; + struct hlsl_deref var_deref; struct hlsl_ir_load *load; struct hlsl_ir_var *var; unsigned int dst_idx; @@ -308,13 +309,14 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, vkd3d_string_buffer_release(&ctx->string_buffers, name); if (!var) return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var);
for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) { struct hlsl_type *dst_scalar_type; - unsigned int src_idx, dst_offset; struct hlsl_ir_store *store; - struct hlsl_ir_constant *c; + struct hlsl_block block; + unsigned int src_idx;
if (broadcast) { @@ -334,7 +336,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, } }
- dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type); + dst_scalar_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx);
if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) return NULL; @@ -343,13 +345,9 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, return NULL; list_add_tail(instrs, &cast->node.entry);
- if (!(c = hlsl_new_uint_constant(ctx, dst_offset, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - - if (!(store = hlsl_new_store(ctx, var, &c->node, &cast->node, 0, *loc))) + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, &cast->node))) return NULL; - list_add_tail(instrs, &store->node.entry); + list_move_tail(instrs, &block.instrs); }
if (!(load = hlsl_new_var_load(ctx, var, *loc))) @@ -721,6 +719,7 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_type *mat_type = matrix->data_type, *ret_type; struct vkd3d_string_buffer *name; static unsigned int counter = 0; + struct hlsl_deref var_deref; struct hlsl_ir_load *load; struct hlsl_ir_var *var; unsigned int i; @@ -736,12 +735,14 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, vkd3d_string_buffer_release(&ctx->string_buffers, name); if (!var) return false; + hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < mat_type->dimx; ++i) { struct hlsl_ir_load *column, *value; struct hlsl_ir_store *store; struct hlsl_ir_constant *c; + struct hlsl_block block;
if (!(c = hlsl_new_uint_constant(ctx, i, loc))) return false; @@ -753,9 +754,9 @@ static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, if (!(value = add_load_index(ctx, instrs, &column->node, index, loc))) return false;
- if (!(store = hlsl_new_store(ctx, var, &c->node, &value->node, 0, *loc))) + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, i, &value->node))) return false; - list_add_tail(instrs, &store->node.entry); + list_move_tail(instrs, &block.instrs); }
if (!(load = hlsl_new_var_load(ctx, var, *loc))) @@ -2121,6 +2122,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, unsigned int i, j, k, vect_count = 0; struct vkd3d_string_buffer *name; static unsigned int counter = 0; + struct hlsl_deref var_deref; struct hlsl_ir_load *load; struct hlsl_ir_var *var;
@@ -2167,15 +2169,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, vkd3d_string_buffer_release(&ctx->string_buffers, name); if (!var) return false; + hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < matrix_type->dimx; ++i) + { for (j = 0; j < matrix_type->dimy; ++j) { struct hlsl_ir_node *node = NULL; - struct hlsl_type *scalar_type; struct hlsl_ir_store *store; - struct hlsl_ir_constant *c; - unsigned int offset; + struct hlsl_block block;
for (k = 0; k < cast_type1->dimx && k < cast_type2->dimy; ++k) { @@ -2202,15 +2204,11 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, } }
- offset = hlsl_compute_component_offset(ctx, matrix_type, j * matrix_type->dimx + i, &scalar_type); - if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, j * matrix_type->dimx + i, node))) return false; - list_add_tail(params->instrs, &c->node.entry); - - if (!(store = hlsl_new_store(ctx, var, &c->node, node, 0, *loc))) - return false; - list_add_tail(params->instrs, &store->node.entry); + list_move_tail(params->instrs, &block.instrs); } + }
if (!(load = hlsl_new_var_load(ctx, var, *loc))) return false;
Signed-off-by: Francisco Casas [email protected] --- v2: * Split from a previous patch. --- libs/vkd3d-shader/hlsl.c | 115 +++++++++++---------------------------- libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d-shader/hlsl.y | 43 ++++----------- 3 files changed, 47 insertions(+), 115 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2d7d33fa..0cd88ba6 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -249,87 +249,6 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e return type; }
-/* Returns the register offset of a given component within a type, given its index. - * *comp_type will be set to the type of the component. */ -unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, - unsigned int idx, struct hlsl_type **comp_type) -{ - switch (type->type) - { - case HLSL_CLASS_SCALAR: - case HLSL_CLASS_VECTOR: - { - assert(idx < type->dimx * type->dimy); - *comp_type = hlsl_get_scalar_type(ctx, type->base_type); - return idx; - } - case HLSL_CLASS_MATRIX: - { - unsigned int minor, major, x = idx % type->dimx, y = idx / type->dimx; - - assert(idx < type->dimx * type->dimy); - - if (hlsl_type_is_row_major(type)) - { - minor = x; - major = y; - } - else - { - minor = y; - major = x; - } - - *comp_type = hlsl_get_scalar_type(ctx, type->base_type); - return 4 * major + minor; - } - - case HLSL_CLASS_ARRAY: - { - unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type); - unsigned int array_idx = idx / elem_comp_count; - unsigned int idx_in_elem = idx % elem_comp_count; - - assert(array_idx < type->e.array.elements_count); - - return array_idx * hlsl_type_get_array_element_reg_size(type->e.array.type) + - hlsl_compute_component_offset(ctx, type->e.array.type, idx_in_elem, comp_type); - } - - case HLSL_CLASS_STRUCT: - { - struct hlsl_struct_field *field; - unsigned int elem_comp_count, i; - - for (i = 0; i < type->e.record.field_count; ++i) - { - field = &type->e.record.fields[i]; - elem_comp_count = hlsl_type_component_count(field->type); - - if (idx < elem_comp_count) - { - return field->reg_offset + - hlsl_compute_component_offset(ctx, field->type, idx, comp_type); - } - idx -= elem_comp_count; - } - - assert(0); - return 0; - } - - case HLSL_CLASS_OBJECT: - { - assert(idx == 0); - *comp_type = type; - return 0; - } - } - - assert(0); - return 0; -} - static bool type_is_single_component(const struct hlsl_type *type) { return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT; @@ -965,7 +884,39 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) { - return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); + struct hlsl_deref lhs_deref; + + hlsl_init_simple_deref_from_var(&lhs_deref, lhs); + return hlsl_new_store_index(ctx, &lhs_deref, NULL, rhs, 0, &rhs->loc); +} + +struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, + struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_store *store; + unsigned int i; + + assert(lhs); + assert(!lhs->offset.node); + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_STORE, NULL, *loc); + + if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx)) + return NULL; + for (i = 0; i < lhs->path_len; ++i) + hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node); + if (idx) + hlsl_src_from_node(&store->lhs.path[lhs->path_len], idx); + + hlsl_src_from_node(&store->rhs, rhs); + + if (!writemask && type_is_single_reg(rhs->data_type)) + writemask = (1 << rhs->data_type->dimx) - 1; + store->writemask = writemask; + + return store; }
struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c8820711..72e7fab2 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -768,6 +768,8 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc);
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); +struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, + struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc); struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
@@ -817,8 +819,6 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers); unsigned int hlsl_type_component_count(const struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); -unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, - unsigned int idx, struct hlsl_type **comp_type); struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index); bool hlsl_type_is_row_major(const struct hlsl_type *type); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8e5b8323..b824ccef 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1200,6 +1200,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct vkd3d_string_buffer *name; static unsigned int counter = 0; struct hlsl_type *vector_type; + struct hlsl_deref var_deref; struct hlsl_ir_load *load; struct hlsl_ir_var *var;
@@ -1211,6 +1212,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, vkd3d_string_buffer_release(&ctx->string_buffers, name); if (!var) return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < hlsl_type_major_size(type); i++) { @@ -1238,11 +1240,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) return NULL;
- if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - - if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) + if (!(store = hlsl_new_store_index(ctx, &var_deref, &c->node, value, 0, loc))) return NULL; list_add_tail(instrs, &store->node.entry); } @@ -1604,10 +1602,8 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { struct hlsl_type *lhs_type = lhs->data_type; struct hlsl_ir_store *store; - struct hlsl_ir_node *offset; struct hlsl_ir_expr *copy; unsigned int writemask = 0; - struct hlsl_block block;
if (assign_op == ASSIGN_OP_SUB) { @@ -1632,15 +1628,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in return NULL; }
- if (!(store = hlsl_alloc(ctx, sizeof(*store)))) - return NULL; - while (lhs->type != HLSL_IR_LOAD) { if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) { hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS."); - vkd3d_free(store); return NULL; } else if (lhs->type == HLSL_IR_SWIZZLE) @@ -1654,13 +1646,11 @@ 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(store); return NULL; }
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) { - vkd3d_free(store); return NULL; } list_add_tail(instrs, &new_swizzle->node.entry); @@ -1671,19 +1661,12 @@ 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(store); return NULL; } }
- offset = hlsl_new_offset_node_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc); - list_move_tail(instrs, &block.instrs); - - 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, offset); - hlsl_src_from_node(&store->rhs, rhs); + if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc))) + return NULL; list_add_tail(instrs, &store->node.entry);
/* Don't use the instruction itself as a source, as this makes structure @@ -1732,32 +1715,30 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src) { unsigned int src_comp_count = hlsl_type_component_count(src->data_type); + struct hlsl_deref dst_deref; unsigned int k;
+ hlsl_init_simple_deref_from_var(&dst_deref, dst); + for (k = 0; k < src_comp_count; ++k) { struct hlsl_type *dst_comp_type; - unsigned int dst_reg_offset; struct hlsl_ir_store *store; - struct hlsl_ir_constant *c; struct hlsl_ir_load *load; struct hlsl_ir_node *conv; + struct hlsl_block block;
if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) return;
- dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type); + dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) return;
- if (!(c = hlsl_new_uint_constant(ctx, dst_reg_offset, &src->loc))) + if (!(store = hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv))) return; - list_add_tail(instrs, &c->node.entry); - - if (!(store = hlsl_new_store(ctx, dst, &c->node, conv, 0, src->loc))) - return; - list_add_tail(instrs, &store->node.entry); + list_move_tail(instrs, &block.instrs);
++*store_index; }
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
@@ -1732,32 +1715,30 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src) { unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
struct hlsl_deref dst_deref; unsigned int k;
hlsl_init_simple_deref_from_var(&dst_deref, dst);
for (k = 0; k < src_comp_count; ++k) { struct hlsl_type *dst_comp_type;
unsigned int dst_reg_offset; struct hlsl_ir_store *store;
struct hlsl_ir_constant *c; struct hlsl_ir_load *load; struct hlsl_ir_node *conv;
struct hlsl_block block; if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) return;
dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type);
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) return;
if (!(c = hlsl_new_uint_constant(ctx, dst_reg_offset, &src->loc)))
if (!(store = hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv))) return;
list_add_tail(instrs, &c->node.entry);
if (!(store = hlsl_new_store(ctx, dst, &c->node, conv, 0, src->loc)))
return;
list_add_tail(instrs, &store->node.entry);
list_move_tail(instrs, &block.instrs); ++*store_index; }
Here you are using hlsl_new_store_component(), which makes sense, so maybe these changes should belong to 11/17? Maybe I am blind, but I can't see how they depend on the changes in this patch.
Giovanni.
Yep, you are totally right, I should have left this change in the previous commit when I split the patch. Good catch!
On 19-07-22 05:25, Giovanni Mascellani wrote:
Hi,
Il 15/07/22 03:23, Francisco Casas ha scritto:
@@ -1732,32 +1715,30 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs, Â Â Â Â Â Â Â Â Â struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src) Â { Â Â Â Â Â unsigned int src_comp_count = hlsl_type_component_count(src->data_type); +Â Â Â struct hlsl_deref dst_deref; Â Â Â Â Â unsigned int k; +Â Â Â hlsl_init_simple_deref_from_var(&dst_deref, dst);
for (k = 0; k < src_comp_count; ++k) Â Â Â Â Â { Â Â Â Â Â Â Â Â Â struct hlsl_type *dst_comp_type; -Â Â Â Â Â Â Â unsigned int dst_reg_offset; Â Â Â Â Â Â Â Â Â struct hlsl_ir_store *store; -Â Â Â Â Â Â Â struct hlsl_ir_constant *c; Â Â Â Â Â Â Â Â Â struct hlsl_ir_load *load; Â Â Â Â Â Â Â Â Â struct hlsl_ir_node *conv; +Â Â Â Â Â Â Â struct hlsl_block block; Â Â Â Â Â Â Â Â Â if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) Â Â Â Â Â Â Â Â Â Â Â Â Â return; -Â Â Â Â Â Â Â dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type); +Â Â Â Â Â Â Â dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); Â Â Â Â Â Â Â Â Â if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) Â Â Â Â Â Â Â Â Â Â Â Â Â return; -Â Â Â Â Â Â Â if (!(c = hlsl_new_uint_constant(ctx, dst_reg_offset, &src->loc))) +Â Â Â Â Â Â Â if (!(store = hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv))) Â Â Â Â Â Â Â Â Â Â Â Â Â return; -Â Â Â Â Â Â Â list_add_tail(instrs, &c->node.entry);
-Â Â Â Â Â Â Â if (!(store = hlsl_new_store(ctx, dst, &c->node, conv, 0, src->loc))) -Â Â Â Â Â Â Â Â Â Â Â return; -Â Â Â Â Â Â Â list_add_tail(instrs, &store->node.entry); +Â Â Â Â Â Â Â list_move_tail(instrs, &block.instrs); Â Â Â Â Â Â Â Â Â ++*store_index; Â Â Â Â Â }
Here you are using hlsl_new_store_component(), which makes sense, so maybe these changes should belong to 11/17? Maybe I am blind, but I can't see how they depend on the changes in this patch.
Giovanni.
At this point, the parse code is free of offsets; it only uses index paths.
--- v2: * Split from a previous patch.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 33 +++++++++++++++++++++++++------- libs/vkd3d-shader/hlsl.h | 5 ++--- libs/vkd3d-shader/hlsl.y | 31 ++++-------------------------- libs/vkd3d-shader/hlsl_codegen.c | 3 +++ 4 files changed, 35 insertions(+), 37 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 0cd88ba6..6f2c3198 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -831,6 +831,28 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl return true; }
+static bool deref_copy(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_deref *other) +{ + unsigned int i; + + memset(deref, 0, sizeof(*deref)); + + if (!other) + return true; + + assert(!other->offset.node); + + if (!init_deref(ctx, deref, other->var, other->path_len)) + return false; + + for (i = 0; i < deref->path_len; ++i) + hlsl_src_from_node(&deref->path[i], other->path[i].node); + + hlsl_src_from_node(&deref->offset, other->offset.node); + + return true; +} + static struct hlsl_type *get_type_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) { struct hlsl_type *type = deref->var->data_type; @@ -1165,9 +1187,8 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b }
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, - struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc) + enum hlsl_resource_load_type type, struct hlsl_deref *resource, struct hlsl_deref *sampler, + struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load;
@@ -1175,10 +1196,8 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc return NULL; init_node(&load->node, HLSL_IR_RESOURCE_LOAD, data_type, *loc); load->load_type = type; - load->resource.var = resource; - hlsl_src_from_node(&load->resource.offset, resource_offset); - load->sampler.var = sampler; - hlsl_src_from_node(&load->sampler.offset, sampler_offset); + deref_copy(ctx, &load->resource, resource); + deref_copy(ctx, &load->sampler, sampler); hlsl_src_from_node(&load->coords, coords); hlsl_src_from_node(&load->texel_offset, texel_offset); return load; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 72e7fab2..f54b7cb7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -777,9 +777,8 @@ struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struc const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc);
struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, - struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); + enum hlsl_resource_load_type type, struct hlsl_deref *resource, struct hlsl_deref *sampler, + struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc);
struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type, struct vkd3d_shader_location loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b824ccef..ca1924a6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2400,10 +2400,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - struct hlsl_ir_node *object_load_offset; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *coords; - struct hlsl_block block;
if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) @@ -2428,11 +2426,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) return false;
- object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); - list_move_tail(instrs, &block.instrs); - if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, - object_load->src.var, object_load_offset, NULL, NULL, coords, NULL, loc))) + &object_load->src, NULL, coords, NULL, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; @@ -2442,13 +2437,11 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - struct hlsl_ir_node *object_load_offset, *sampler_load_offset; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; struct hlsl_ir_node *offset = NULL; struct hlsl_ir_load *sampler_load; struct hlsl_ir_node *coords; - struct hlsl_block block;
if (params->args_count != 2 && params->args_count != 3) { @@ -2484,15 +2477,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl return false; }
- object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); - list_move_tail(instrs, &block.instrs); - - sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc); - list_move_tail(instrs, &block.instrs); - if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, - HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load_offset, - sampler_load->src.var, sampler_load_offset, coords, offset, loc))) + HLSL_RESOURCE_SAMPLE, &object_load->src, &sampler_load->src, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry);
@@ -2506,7 +2492,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) { const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - struct hlsl_ir_node *object_load_offset, *sampler_load_offset; enum hlsl_resource_load_type load_type; const struct hlsl_type *sampler_type; struct hlsl_ir_resource_load *load; @@ -2515,7 +2500,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct hlsl_type *result_type; struct hlsl_ir_node *coords; unsigned int read_channel; - struct hlsl_block block;
if (!strcmp(name, "GatherGreen")) { @@ -2597,15 +2581,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
- object_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &object_load->src, loc); - list_move_tail(instrs, &block.instrs); - - sampler_load_offset = hlsl_new_offset_node_from_deref(ctx, &block, &sampler_load->src, loc); - list_move_tail(instrs, &block.instrs); - - if (!(load = hlsl_new_resource_load(ctx, result_type, - load_type, object_load->src.var, object_load_offset, - sampler_load->src.var, sampler_load_offset, coords, offset, loc))) + if (!(load = hlsl_new_resource_load(ctx, result_type, load_type, &object_load->src, + &sampler_load->src, coords, offset, loc))) return false; list_add_tail(instrs, &load->node.entry); return true; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0b577f54..483ee9e1 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -31,6 +31,9 @@ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der if (!deref->var) return;
+ /* register offsets shouldn't be used before this point is reached. */ + assert(!deref->offset.node); + if (!(offset = hlsl_new_offset_node_from_deref(ctx, &block, deref, &instr->loc))) return; list_move_before(&instr->entry, &block.instrs);
This can be done now, to ensure that register offsets are no longer used in hlsl.c and hlsl.h.
Signed-off-by: Francisco Casas [email protected] --- v2: * Removed "hlsl_" prefix in the function name after move. * Moving the new hlsl_new_offset_node_from_deref() too. --- libs/vkd3d-shader/hlsl.c | 103 ------------------------------- libs/vkd3d-shader/hlsl.h | 6 -- libs/vkd3d-shader/hlsl_codegen.c | 103 ++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 110 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6f2c3198..aee3cc2a 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -398,109 +398,6 @@ struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const stru return NULL; }
-struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *idx_offset = NULL; - struct hlsl_ir_constant *c; - - list_init(&block->instrs); - - switch (type->type) - { - case HLSL_CLASS_VECTOR: - idx_offset = idx; - break; - - case HLSL_CLASS_MATRIX: - { - if (!(c = hlsl_new_uint_constant(ctx, 4, loc))) - return NULL; - list_add_tail(&block->instrs, &c->node.entry); - - if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) - return NULL; - list_add_tail(&block->instrs, &idx_offset->entry); - - break; - } - - case HLSL_CLASS_ARRAY: - { - unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type); - - if (!(c = hlsl_new_uint_constant(ctx, size, loc))) - return NULL; - list_add_tail(&block->instrs, &c->node.entry); - - if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) - return NULL; - list_add_tail(&block->instrs, &idx_offset->entry); - - break; - } - - case HLSL_CLASS_STRUCT: - { - unsigned int field_i = hlsl_ir_constant(idx)->value[0].u; - struct hlsl_struct_field *field = &type->e.record.fields[field_i]; - - if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc))) - return NULL; - list_add_tail(&block->instrs, &c->node.entry); - - idx_offset = &c->node; - - break; - } - - default: - assert(0); - return NULL; - } - - if (offset) - { - if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset))) - return NULL; - list_add_tail(&block->instrs, &idx_offset->entry); - } - - return idx_offset; -} - -struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *offset = NULL; - struct hlsl_type *type; - unsigned int i; - - list_init(&block->instrs); - - if (deref->offset.node) - return deref->offset.node; - - assert(deref->var); - - type = deref->var->data_type; - - for (i = 0; i < deref->path_len; ++i) - { - struct hlsl_block idx_block; - - if (!(offset = hlsl_new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, loc))) - return NULL; - - list_move_tail(&block->instrs, &idx_block.instrs); - - type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node); - } - - return offset; -} - struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index f54b7cb7..e1ddd0cf 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -737,9 +737,6 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name);
struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node); -struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, - const struct vkd3d_shader_location *loc);
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, @@ -773,9 +770,6 @@ struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hl struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
-struct hlsl_ir_node *hlsl_new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc); - struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, enum hlsl_resource_load_type type, struct hlsl_deref *resource, struct hlsl_deref *sampler, struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 483ee9e1..e10377cb 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -21,6 +21,107 @@ #include "hlsl.h" #include <stdio.h>
+/* TODO: remove when no longer needed, only used for new_offset_node_from_deref() */ +static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *idx_offset = NULL; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + idx_offset = idx; + break; + + case HLSL_CLASS_MATRIX: + { + if (!(c = hlsl_new_uint_constant(ctx, 4, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type); + + if (!(c = hlsl_new_uint_constant(ctx, size, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_STRUCT: + { + unsigned int field_i = hlsl_ir_constant(idx)->value[0].u; + struct hlsl_struct_field *field = &type->e.record.fields[field_i]; + + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + idx_offset = &c->node; + + break; + } + + default: + assert(0); + return NULL; + } + + if (offset) + { + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + } + + return idx_offset; +} + +/* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ +static struct hlsl_ir_node *new_offset_node_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *offset = NULL; + struct hlsl_type *type; + unsigned int i; + + list_init(&block->instrs); + + assert(deref->var); + type = deref->var->data_type; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_block idx_block; + + if (!(offset = new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, loc))) + return NULL; + + list_move_tail(&block->instrs, &idx_block.instrs); + + type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node); + } + + return offset; +} + /* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *instr) @@ -34,7 +135,7 @@ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der /* register offsets shouldn't be used before this point is reached. */ assert(!deref->offset.node);
- if (!(offset = hlsl_new_offset_node_from_deref(ctx, &block, deref, &instr->loc))) + if (!(offset = new_offset_node_from_deref(ctx, &block, deref, &instr->loc))) return; list_move_before(&instr->entry, &block.instrs);
Signed-off-by: Francisco Casas [email protected] ---
v2: * Renamed add_extern_var() -> add_semantic_var()
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl_codegen.c | 81 +++++++++++++++----------------- 1 file changed, 37 insertions(+), 44 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e10377cb..d32bd11c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -204,11 +204,44 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru list_add_after(&load->node.entry, &store->node.entry); }
+static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + struct hlsl_type *type, unsigned int modifiers, const struct hlsl_semantic *semantic, bool output) +{ + struct hlsl_semantic new_semantic; + struct vkd3d_string_buffer *name; + struct hlsl_ir_var *ext_var; + + if (!(name = hlsl_get_string_buffer(ctx))) + return NULL; + vkd3d_string_buffer_printf(name, "<%s-%s%u>", output? "output" : "input", semantic->name, semantic->index); + if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) + { + hlsl_release_string_buffer(ctx, name); + return NULL; + } + new_semantic.index = semantic->index; + if (!(ext_var = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), + type, var->loc, &new_semantic, modifiers, NULL))) + { + hlsl_release_string_buffer(ctx, name); + vkd3d_free((void *)new_semantic.name); + return NULL; + } + hlsl_release_string_buffer(ctx, name); + if (output) + ext_var->is_output_semantic = 1; + else + ext_var->is_input_semantic = 1; + ext_var->is_param = var->is_param; + list_add_before(&var->scope_entry, &ext_var->scope_entry); + list_add_tail(&ctx->extern_vars, &ext_var->extern_entry); + + return ext_var; +} + static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, struct hlsl_type *type, unsigned int field_offset, unsigned int modifiers, const struct hlsl_semantic *semantic) { - struct vkd3d_string_buffer *name; - struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; struct hlsl_ir_load *load; @@ -229,27 +262,8 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; }
- if (!(name = hlsl_get_string_buffer(ctx))) + if (!(input = add_semantic_var(ctx, var, type, modifiers, semantic, false))) return; - vkd3d_string_buffer_printf(name, "<input-%s%u>", semantic->name, semantic->index); - if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) - { - hlsl_release_string_buffer(ctx, name); - return; - } - new_semantic.index = semantic->index; - if (!(input = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), - type, var->loc, &new_semantic, modifiers, NULL))) - { - hlsl_release_string_buffer(ctx, name); - vkd3d_free((void *)new_semantic.name); - return; - } - hlsl_release_string_buffer(ctx, name); - input->is_input_semantic = 1; - input->is_param = var->is_param; - list_add_before(&var->scope_entry, &input->scope_entry); - list_add_tail(&ctx->extern_vars, &input->extern_entry);
if (!(load = hlsl_new_var_load(ctx, input, var->loc))) return; @@ -297,8 +311,6 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, struct hlsl_type *type, unsigned int field_offset, unsigned int modifiers, const struct hlsl_semantic *semantic) { - struct vkd3d_string_buffer *name; - struct hlsl_semantic new_semantic; struct hlsl_ir_constant *offset; struct hlsl_ir_store *store; struct hlsl_ir_var *output; @@ -319,27 +331,8 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct return; }
- if (!(name = hlsl_get_string_buffer(ctx))) + if (!(output = add_semantic_var(ctx, var, type, modifiers, semantic, true))) return; - vkd3d_string_buffer_printf(name, "<output-%s%u>", semantic->name, semantic->index); - if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) - { - hlsl_release_string_buffer(ctx, name); - return; - } - new_semantic.index = semantic->index; - if (!(output = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), - type, var->loc, &new_semantic, modifiers, NULL))) - { - vkd3d_free((void *)new_semantic.name); - hlsl_release_string_buffer(ctx, name); - return; - } - hlsl_release_string_buffer(ctx, name); - output->is_output_semantic = 1; - output->is_param = var->is_param; - list_add_before(&var->scope_entry, &output->scope_entry); - list_add_tail(&ctx->extern_vars, &output->extern_entry);
if (!(offset = hlsl_new_uint_constant(ctx, field_offset, &var->loc))) return;
Signed-off-by: Zebediah Figura [email protected]
Signed-off-by: Francisco Casas [email protected] ---
v2: * Calling add_extern_var() with the new name "add_semantic_var". * Adding assert(i == 0) in prepend_input_copy() and append_output_copy().
The recursive structure of prepend_input_var_copy() and append_output_var_copy() could be preserved creating additional loads to complete the paths. Otherwise we would be requiring passing whole paths as arguments.
These additional loads should be handled by DCE.
Still, matrix vectors are copied iteratively instead of recursively now, to avoid the boilerplate of creating new loads in this last step.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl_codegen.c | 188 +++++++++++++++++++------------ 1 file changed, 116 insertions(+), 72 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index d32bd11c..e5747e0e 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -239,59 +239,75 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir return ext_var; }
-static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, unsigned int modifiers, const struct hlsl_semantic *semantic) +static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *lhs, + struct hlsl_type *type, unsigned int modifiers, const struct hlsl_semantic *semantic) { - struct hlsl_ir_constant *offset; - struct hlsl_ir_store *store; - struct hlsl_ir_load *load; - struct hlsl_ir_var *input; + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + struct hlsl_ir_var *var = lhs->src.var; + unsigned int i;
- if (type->type == HLSL_CLASS_MATRIX) + for (i = 0; i < hlsl_type_major_size(type); ++i) { - struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); - struct hlsl_semantic vector_semantic = *semantic; - unsigned int i; + struct hlsl_semantic semantic_copy = *semantic; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_ir_var *input; + struct hlsl_ir_load *load;
- for (i = 0; i < hlsl_type_major_size(type); ++i) - { - prepend_input_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); - ++vector_semantic.index; - } + semantic_copy.index = semantic->index + i;
- return; - } + if (!(input = add_semantic_var(ctx, var, vector_type, modifiers, &semantic_copy, false))) + return;
- if (!(input = add_semantic_var(ctx, var, type, modifiers, semantic, false))) - return; + if (!(load = hlsl_new_var_load(ctx, input, var->loc))) + return; + list_add_after(&lhs->node.entry, &load->node.entry);
- if (!(load = hlsl_new_var_load(ctx, input, var->loc))) - return; - list_add_head(instrs, &load->node.entry); + if (type->type == HLSL_CLASS_MATRIX) + { + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_after(&load->node.entry, &c->node.entry);
- if (!(offset = hlsl_new_uint_constant(ctx, field_offset, &var->loc))) - return; - list_add_after(&load->node.entry, &offset->node.entry); + if (!(store = hlsl_new_store_index(ctx, &lhs->src, &c->node, &load->node, 0, &var->loc))) + return; + list_add_after(&c->node.entry, &store->node.entry); + } + else + { + assert(i == 0);
- if (!(store = hlsl_new_store(ctx, var, &offset->node, &load->node, 0, var->loc))) - return; - list_add_after(&offset->node.entry, &store->node.entry); + if (!(store = hlsl_new_store_index(ctx, &lhs->src, NULL, &load->node, 0, &var->loc))) + return; + list_add_after(&load->node.entry, &store->node.entry); + } + } }
-static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset) +static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *lhs, + struct hlsl_type *type) { + struct hlsl_ir_var *var = lhs->src.var; size_t i;
for (i = 0; i < type->e.record.field_count; ++i) { const struct hlsl_struct_field *field = &type->e.record.fields[i]; + struct hlsl_ir_load *field_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_after(&lhs->node.entry, &c->node.entry); + + if (!(field_load = hlsl_new_load_index(ctx, &lhs->src, &c->node, &var->loc))) + return; + list_add_after(&c->node.entry, &field_load->node.entry);
if (field->type->type == HLSL_CLASS_STRUCT) - prepend_input_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); + prepend_input_struct_copy(ctx, instrs, field_load, field->type); else if (field->semantic.name) - prepend_input_copy(ctx, instrs, var, field->type, - field_offset + field->reg_offset, field->modifiers, &field->semantic); + prepend_input_copy(ctx, instrs, field_load, field->type, field->modifiers, &field->semantic); else hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); @@ -302,65 +318,87 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, * and copy the former to the latter, so that writes to input variables work. */ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) { + struct hlsl_ir_load *load; + + if (!(load = hlsl_new_var_load(ctx, var, var->loc))) + return; + list_add_head(instrs, &load->node.entry); + if (var->data_type->type == HLSL_CLASS_STRUCT) - prepend_input_struct_copy(ctx, instrs, var, var->data_type, 0); + prepend_input_struct_copy(ctx, instrs, load, var->data_type); else if (var->semantic.name) - prepend_input_copy(ctx, instrs, var, var->data_type, 0, var->modifiers, &var->semantic); + prepend_input_copy(ctx, instrs, load, var->data_type, var->modifiers, &var->semantic); }
-static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, unsigned int modifiers, const struct hlsl_semantic *semantic) +static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *rhs, + struct hlsl_type *type, unsigned int modifiers, const struct hlsl_semantic *semantic) { - struct hlsl_ir_constant *offset; - struct hlsl_ir_store *store; - struct hlsl_ir_var *output; - struct hlsl_ir_load *load; + struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + struct hlsl_ir_var *var = rhs->src.var; + unsigned int i;
- if (type->type == HLSL_CLASS_MATRIX) + for (i = 0; i < hlsl_type_major_size(type); ++i) { - struct hlsl_type *vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); - struct hlsl_semantic vector_semantic = *semantic; - unsigned int i; + struct hlsl_semantic semantic_copy = *semantic; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_ir_var *output; + struct hlsl_ir_load *load;
- for (i = 0; i < hlsl_type_major_size(type); ++i) - { - append_output_copy(ctx, instrs, var, vector_type, 4 * i, modifiers, &vector_semantic); - ++vector_semantic.index; - } + semantic_copy.index = semantic->index + i;
- return; - } + if (!(output = add_semantic_var(ctx, var, vector_type, modifiers, &semantic_copy, true))) + return;
- if (!(output = add_semantic_var(ctx, var, type, modifiers, semantic, true))) - return; + if (type->type == HLSL_CLASS_MATRIX) + { + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_tail(instrs, &c->node.entry);
- if (!(offset = hlsl_new_uint_constant(ctx, field_offset, &var->loc))) - return; - list_add_tail(instrs, &offset->node.entry); + if (!(load = hlsl_new_load_index(ctx, &rhs->src, &c->node, &var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + } + else + { + assert(i == 0);
- if (!(load = hlsl_new_load(ctx, var, &offset->node, type, var->loc))) - return; - list_add_after(&offset->node.entry, &load->node.entry); + if (!(load = hlsl_new_load_index(ctx, &rhs->src, NULL, &var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + }
- if (!(store = hlsl_new_store(ctx, output, NULL, &load->node, 0, var->loc))) - return; - list_add_after(&load->node.entry, &store->node.entry); + if (!(store = hlsl_new_simple_store(ctx, output, &load->node))) + return; + list_add_tail(instrs, &store->node.entry); + } }
-static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset) +static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *rhs, + struct hlsl_type *type) { + struct hlsl_ir_var *var = rhs->src.var; size_t i;
for (i = 0; i < type->e.record.field_count; ++i) { const struct hlsl_struct_field *field = &type->e.record.fields[i]; + struct hlsl_ir_load *field_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_tail(instrs, &c->node.entry); + + if (!(field_load = hlsl_new_load_index(ctx, &rhs->src, &c->node, &var->loc))) + return; + list_add_tail(instrs, &field_load->node.entry);
if (field->type->type == HLSL_CLASS_STRUCT) - append_output_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); + append_output_struct_copy(ctx, instrs, field_load, field->type); else if (field->semantic.name) - append_output_copy(ctx, instrs, var, field->type, - field_offset + field->reg_offset, field->modifiers, &field->semantic); + append_output_copy(ctx, instrs, field_load, field->type, field->modifiers, &field->semantic); else hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Field '%s' is missing a semantic.", field->name); @@ -372,10 +410,16 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, * variables work. */ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) { + struct hlsl_ir_load *load; + + if (!(load = hlsl_new_var_load(ctx, var, var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + if (var->data_type->type == HLSL_CLASS_STRUCT) - append_output_struct_copy(ctx, instrs, var, var->data_type, 0); + append_output_struct_copy(ctx, instrs, load, var->data_type); else if (var->semantic.name) - append_output_copy(ctx, instrs, var, var->data_type, 0, var->modifiers, &var->semantic); + append_output_copy(ctx, instrs, load, var->data_type, var->modifiers, &var->semantic); }
static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -2029,8 +2073,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
list_move_head(&body->instrs, &ctx->static_initializers);
- transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */ - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { if (var->modifiers & HLSL_STORAGE_UNIFORM) @@ -2064,6 +2106,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry append_output_var_copy(ctx, &body->instrs, entry_func->return_var); }
+ transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */ + transform_ir(ctx, lower_broadcasts, body, NULL); while (transform_ir(ctx, fold_redundant_casts, body, NULL)); do
hlsl_new_store() and hlsl_new_load() are deleted, so now there are no more direct ways to create derefs with offsets in hlsl.c and hlsl.h.
Signed-off-by: Francisco Casas [email protected] ---
v2: * No changes.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 32 ------------------------- libs/vkd3d-shader/hlsl.h | 4 ---- libs/vkd3d-shader/hlsl_codegen.c | 40 +++++++++----------------------- 3 files changed, 11 insertions(+), 65 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index aee3cc2a..c1a9e9ac 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -774,25 +774,6 @@ void hlsl_cleanup_deref(struct hlsl_deref *deref) hlsl_src_remove(&deref->offset); }
-struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, 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_store *store; - - if (!writemask && type_is_single_reg(rhs->data_type)) - writemask = (1 << rhs->data_type->dimx) - 1; - - if (!(store = hlsl_alloc(ctx, sizeof(*store)))) - return NULL; - - init_node(&store->node, HLSL_IR_STORE, NULL, loc); - init_deref(ctx, &store->lhs, var, 0); - hlsl_src_from_node(&store->lhs.offset, offset); - hlsl_src_from_node(&store->rhs, rhs); - store->writemask = writemask; - return store; -} - /* Initializes a simple variable derefence, so that a pointer to it can be passed to load/store * functions. The deref shall not be modified afterwards. */ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) @@ -978,19 +959,6 @@ struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condit return iff; }
-struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, 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 = hlsl_alloc(ctx, sizeof(*load)))) - return NULL; - init_node(&load->node, HLSL_IR_LOAD, type, loc); - init_deref(ctx, &load->src, var, 0); - hlsl_src_from_node(&load->src.offset, offset); - return load; -} - struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e1ddd0cf..77005407 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -774,11 +774,7 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struc enum hlsl_resource_load_type type, struct hlsl_deref *resource, struct hlsl_deref *sampler, struct hlsl_ir_node *coords, struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc);
-struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_type *type, struct vkd3d_shader_location loc); struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); -struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, 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_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct hlsl_struct_field *fields, size_t field_count); struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e5747e0e..fcb6aa33 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -950,39 +950,21 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst * split_matrix_copies(). Inserts new instructions right before * "store". */ static bool split_copy(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, - const struct hlsl_ir_load *load, const unsigned int offset, struct hlsl_type *type) + const struct hlsl_ir_load *load, const unsigned int indx, struct hlsl_type *type) { - struct hlsl_ir_node *offset_instr, *add; struct hlsl_ir_store *split_store; struct hlsl_ir_load *split_load; struct hlsl_ir_constant *c;
- if (!(c = hlsl_new_uint_constant(ctx, offset, &store->node.loc))) + if (!(c = hlsl_new_uint_constant(ctx, indx, &store->node.loc))) return false; list_add_before(&store->node.entry, &c->node.entry);
- offset_instr = &c->node; - if (load->src.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, load->src.offset.node, &c->node))) - return false; - list_add_before(&store->node.entry, &add->entry); - offset_instr = add; - } - if (!(split_load = hlsl_new_load(ctx, load->src.var, offset_instr, type, store->node.loc))) + if (!(split_load = hlsl_new_load_index(ctx, &load->src, &c->node, &store->node.loc))) return false; list_add_before(&store->node.entry, &split_load->node.entry);
- offset_instr = &c->node; - if (store->lhs.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, store->lhs.offset.node, &c->node))) - return false; - list_add_before(&store->node.entry, &add->entry); - offset_instr = add; - } - - if (!(split_store = hlsl_new_store(ctx, store->lhs.var, offset_instr, &split_load->node, 0, store->node.loc))) + if (!(split_store = hlsl_new_store_index(ctx, &store->lhs, &c->node, &split_load->node, 0, &store->node.loc))) return false; list_add_before(&store->node.entry, &split_store->node.entry);
@@ -994,8 +976,8 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, const struct hlsl_ir_node *rhs; struct hlsl_type *element_type; const struct hlsl_type *type; - unsigned int element_size, i; struct hlsl_ir_store *store; + unsigned int i;
if (instr->type != HLSL_IR_STORE) return false; @@ -1006,7 +988,6 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (type->type != HLSL_CLASS_ARRAY) return false; element_type = type->e.array.type; - element_size = hlsl_type_get_array_element_reg_size(element_type);
if (rhs->type != HLSL_IR_LOAD) { @@ -1016,7 +997,7 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
for (i = 0; i < type->e.array.elements_count; ++i) { - if (!split_copy(ctx, store, hlsl_ir_load(rhs), i * element_size, element_type)) + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) return false; }
@@ -1054,7 +1035,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr { const struct hlsl_struct_field *field = &type->e.record.fields[i];
- if (!split_copy(ctx, store, hlsl_ir_load(rhs), field->reg_offset, field->type)) + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, field->type)) return false; }
@@ -1092,7 +1073,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
for (i = 0; i < hlsl_type_major_size(type); ++i) { - if (!split_copy(ctx, store, hlsl_ir_load(rhs), 4 * i, element_type)) + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) return false; }
@@ -2106,8 +2087,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry append_output_var_copy(ctx, &body->instrs, entry_func->return_var); }
- transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */ - transform_ir(ctx, lower_broadcasts, body, NULL); while (transform_ir(ctx, fold_redundant_casts, body, NULL)); do @@ -2117,6 +2096,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry } while (progress); transform_ir(ctx, split_matrix_copies, body, NULL); + + transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); /* TODO: move forward, remove when no longer needed */ + transform_ir(ctx, lower_narrowing_casts, body, NULL); transform_ir(ctx, lower_casts_to_bool, body, NULL); do
On Fri, 15 Jul 2022 at 03:24, Francisco Casas [email protected] wrote:
@@ -911,24 +903,22 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return r; if (t1->type == HLSL_CLASS_STRUCT) {
struct list *t1cur, *t2cur;
struct hlsl_struct_field *t1field, *t2field;
size_t i;
t1cur = list_head(t1->e.elements);
t2cur = list_head(t2->e.elements);
while (t1cur && t2cur)
if (t1->e.record.field_count != t2->e.record.field_count)
return t1->e.record.field_count - t2->e.record.field_count;
This is perhaps unlikely to be an issue with any field counts seen in practice, but we shouldn't use (modular) subtraction as comparison function; see also commit 790ab754d5ac4fb1a723e16b22dbeea1a52a12b8. Ideally we'd use a variant of vkd3d_u32_compare() here.