Signed-off-by: Francisco Casas [email protected] Signed-off-by: Giovanni Mascellani [email protected] ---
v3: * Using hlsl_get_string_buffer() and hlsl_release_string_buffer().
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.y | 99 +++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bfafd981..3b3d3582 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,63 @@ 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; + + if (!(name = hlsl_get_string_buffer(ctx))) + return NULL; + vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); + var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc); + hlsl_release_string_buffer(ctx, 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 +1818,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 +2265,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)))
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] Signed-off-by: Giovanni Mascellani [email protected] ---
v3: * Using hlsl_get_string_buffer() and hlsl_release_string_buffer(). * Use switch statement in hlsl_get_type_from_path_index().
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 107 ++++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 7 ++ libs/vkd3d-shader/hlsl.y | 135 ++++++++++++++------------------------- 3 files changed, 160 insertions(+), 89 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2925b4e5..6bd27781 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,111 @@ 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); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + return hlsl_get_scalar_type(ctx, type->base_type); + + case 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); + + case HLSL_CLASS_ARRAY: + return type->e.array.type; + + case 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; + } + + default: + 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 3b3d3582..aa351548 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -622,44 +622,52 @@ 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))) + if (!(name = hlsl_get_string_buffer(ctx))) + return NULL; + vkd3d_string_buffer_printf(name, "<deref-%p>", var_node); + var = hlsl_new_synthetic_var(ctx, name->buffer, var_node->data_type, var_node->loc); + hlsl_release_string_buffer(ctx, 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; }
@@ -723,61 +731,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) { @@ -788,6 +756,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); @@ -799,18 +770,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); } @@ -826,30 +800,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."); @@ -858,7 +813,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, @@ -1307,7 +1265,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);
@@ -1315,12 +1273,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; } @@ -1329,6 +1284,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);
Signed-off-by: Francisco Casas [email protected] Signed-off-by: Giovanni Mascellani [email protected] ---
v3: * 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 6bd27781..66acce23 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 aa351548..5cdd6418 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1218,22 +1218,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) @@ -1249,7 +1233,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++); @@ -1258,7 +1242,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;
From: Zebediah Figura [email protected]
Signed-off-by: Francisco Casas [email protected] Signed-off-by: Zebediah Figura [email protected] Signed-off-by: Giovanni Mascellani [email protected] ---
v3: * No changes.
Signed-off-by: Francisco Casas [email protected] --- 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 are to be placed nearby in hlsl.h as they are introduced in the following patches.
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(). The deref obtained with this function, can also be passed be passed as prefix to deref_from_component_index().
---
v3: * Replaced compute_component_path() with deref_from_component_index(). * Wrote implementation of init_deref() and get_type_from_deref() further up in the file. * Made hlsl_new_load_component() use deref_from_component_index() instead of the removed compute_component_path(). * Rewrote hlsl.c function comments in present and active voice. * Renamed typep -> type_ptr indexp -> index_ptr in subtype_index_from_component_index(). * Added space before '?' in ternary operators.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 298 +++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 ++++++----- libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 410 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 66acce23..535433ee 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,176 @@ 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, 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. */ +static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx, + struct hlsl_type **type_ptr, unsigned int *index_ptr) +{ + struct hlsl_type *type = *type_ptr; + unsigned int index = *index_ptr; + + assert(!type_is_single_component(type)); + assert(index < hlsl_type_component_count(type)); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + assert(index < type->dimx); + *type_ptr = hlsl_get_scalar_type(ctx, type->base_type); + *index_ptr = 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); + *type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy); + *index_ptr = 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; + + *type_ptr = type->e.array.type; + *index_ptr = 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) + { + *type_ptr = field->type; + *index_ptr = 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; +} + +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; + unsigned int i; + + assert(deref); + assert(!deref->offset.node); + + type = deref->var->data_type; + for (i = 0; i < deref->path_len; ++i) + type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node); + return type; +} + +/* Initializes a deref from another deref (prefix) and a component index. */ +static bool deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index, + const struct vkd3d_shader_location *loc) +{ + unsigned int path_len, path_index, deref_path_len, i; + struct hlsl_type *path_type; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + path_len = 0; + path_type = get_type_from_deref(ctx, prefix); + path_index = index; + while (!type_is_single_component(path_type)) + { + subtype_index_from_component_index(ctx, &path_type, &path_index); + ++path_len; + } + + if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len)) + return false; + + deref_path_len = 0; + for (i = 0; i < prefix->path_len; ++i) + hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node); + + path_type = get_type_from_deref(ctx, prefix); + path_index = index; + while (!type_is_single_component(path_type)) + { + unsigned int next_index = subtype_index_from_component_index(ctx, &path_type, &path_index); + + if (!(c = hlsl_new_uint_constant(ctx, next_index, loc))) + { + hlsl_free_instr_list(&block->instrs); + return false; + } + list_add_tail(&block->instrs, &c->node.entry); + + hlsl_src_from_node(&deref->path[deref_path_len++], &c->node); + } + + assert(deref_path_len == deref->path_len); + + return true; +} + struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) { @@ -435,6 +605,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; @@ -525,7 +726,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;
@@ -742,8 +943,17 @@ 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) +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); }
@@ -759,13 +969,20 @@ 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 it can be passed to load/store functions. */ +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); @@ -862,15 +1079,76 @@ 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) +{ + 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) { - return hlsl_new_load(ctx, var, NULL, var->data_type, loc); + struct hlsl_type *type, *comp_type; + struct hlsl_block comp_path_block; + struct hlsl_ir_load *load; + + list_init(&block->instrs); + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + return NULL; + + type = get_type_from_deref(ctx, deref); + comp_type = hlsl_type_get_component_type(ctx, type, comp); + init_node(&load->node, HLSL_IR_LOAD, comp_type, *loc); + + if (!deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc)) + { + vkd3d_free(load); + return NULL; + } + list_move_tail(&block->instrs, &comp_path_block.instrs); + + 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, @@ -1705,7 +1983,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); }
@@ -1718,8 +1996,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); } @@ -1727,7 +2005,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 5cdd6418..710d5748 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;
if (!(name = hlsl_get_string_buffer(ctx))) return NULL; @@ -662,9 +649,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);
@@ -674,39 +663,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;
if (!(name = hlsl_get_string_buffer(ctx))) return NULL; @@ -719,11 +688,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; } @@ -1277,7 +1248,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);
@@ -1634,8 +1605,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) { @@ -1704,10 +1677,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);
@@ -2238,7 +2214,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);
@@ -2447,8 +2423,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) @@ -2473,8 +2451,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; @@ -2484,11 +2465,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) { @@ -2524,11 +2507,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") @@ -2539,6 +2529,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; @@ -2547,6 +2538,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")) { @@ -2628,9 +2620,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)
Signed-off-by: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
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 are to be placed nearby in hlsl.h as they are introduced in the following patches.
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(). The deref obtained with this function, can also be passed be passed as prefix to deref_from_component_index().
v3:
- Replaced compute_component_path() with deref_from_component_index().
- Wrote implementation of init_deref() and get_type_from_deref() further up in the file.
- Made hlsl_new_load_component() use deref_from_component_index() instead of the removed compute_component_path().
- Rewrote hlsl.c function comments in present and active voice.
- Renamed typep -> type_ptr indexp -> index_ptr in subtype_index_from_component_index().
- Added space before '?' in ternary operators.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 298 +++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 ++++++----- libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 410 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 66acce23..535433ee 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,176 @@ 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, 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. */
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **type_ptr, unsigned int *index_ptr)
+{
- struct hlsl_type *type = *type_ptr;
- unsigned int index = *index_ptr;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*type_ptr = hlsl_get_scalar_type(ctx, type->base_type);
*index_ptr = 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);
*type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy);
*index_ptr = 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;
*type_ptr = type->e.array.type;
*index_ptr = 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)
{
*type_ptr = field->type;
*index_ptr = 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;
+}
+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;
- unsigned int i;
- assert(deref);
- assert(!deref->offset.node);
- type = deref->var->data_type;
- for (i = 0; i < deref->path_len; ++i)
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- return type;
+}
+/* Initializes a deref from another deref (prefix) and a component index. */ +static bool deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index,
const struct vkd3d_shader_location *loc)
+{
- unsigned int path_len, path_index, deref_path_len, i;
- struct hlsl_type *path_type;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- path_len = 0;
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++path_len;
- }
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
return false;
- deref_path_len = 0;
- for (i = 0; i < prefix->path_len; ++i)
hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node);
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
unsigned int next_index = subtype_index_from_component_index(ctx, &path_type, &path_index);
if (!(c = hlsl_new_uint_constant(ctx, next_index, loc)))
{
hlsl_free_instr_list(&block->instrs);
return false;
}
list_add_tail(&block->instrs, &c->node.entry);
hlsl_src_from_node(&deref->path[deref_path_len++], &c->node);
- }
- assert(deref_path_len == deref->path_len);
- return true;
+}
- struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) {
@@ -435,6 +605,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;
@@ -525,7 +726,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;
@@ -742,8 +943,17 @@ 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) +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);
@@ -759,13 +969,20 @@ 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 it can be passed to load/store functions. */ +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);
@@ -862,15 +1079,76 @@ 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)
+{
- 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)
- return hlsl_new_load(ctx, var, NULL, var->data_type, loc);
struct hlsl_type *type, *comp_type;
struct hlsl_block comp_path_block;
struct hlsl_ir_load *load;
list_init(&block->instrs);
if (!(load = hlsl_alloc(ctx, sizeof(*load))))
return NULL;
type = get_type_from_deref(ctx, deref);
comp_type = hlsl_type_get_component_type(ctx, type, comp);
init_node(&load->node, HLSL_IR_LOAD, comp_type, *loc);
if (!deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc))
{
vkd3d_free(load);
return NULL;
}
list_move_tail(&block->instrs, &comp_path_block.instrs);
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,
@@ -1705,7 +1983,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); }
@@ -1718,8 +1996,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); }
@@ -1727,7 +2005,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 5cdd6418..710d5748 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; if (!(name = hlsl_get_string_buffer(ctx))) return NULL;
@@ -662,9 +649,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);
@@ -674,39 +663,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; if (!(name = hlsl_get_string_buffer(ctx))) return NULL;
@@ -719,11 +688,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; }
@@ -1277,7 +1248,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);
@@ -1634,8 +1605,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) {
@@ -1704,10 +1677,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);
@@ -2238,7 +2214,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);
@@ -2447,8 +2423,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)
@@ -2473,8 +2451,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;
@@ -2484,11 +2465,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) {
@@ -2524,11 +2507,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")
@@ -2539,6 +2529,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;
@@ -2547,6 +2538,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")) {
@@ -2628,9 +2620,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 Wed, Jul 20, 2022 at 3:23 PM Francisco Casas [email protected] 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 are to be placed nearby in hlsl.h as they are introduced in the following patches.
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(). The deref obtained with this function, can also be passed be passed as prefix to deref_from_component_index().
v3:
- Replaced compute_component_path() with deref_from_component_index().
- Wrote implementation of init_deref() and get_type_from_deref() further up in the file.
- Made hlsl_new_load_component() use deref_from_component_index() instead of the removed compute_component_path().
- Rewrote hlsl.c function comments in present and active voice.
- Renamed typep -> type_ptr indexp -> index_ptr in subtype_index_from_component_index().
- Added space before '?' in ternary operators.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 298 +++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 ++++++----- libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 410 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 66acce23..535433ee 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,176 @@ 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, 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. */
Now *type_ptr and *index_ptr respectively, right?
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **type_ptr, unsigned int *index_ptr)
After rereading the patch a number of times, I think the prototype is okay (not sure about the name, it sounds like a "get" but it does change the two parameters, not that I have better suggestions) but that comment above needs some clarification. What this function does is to move one step through the "path", or component index I guess, returning the "index" to be taken for the outer data type and updating type_ptr and index_ptr (which are two in/out parameters btw, their types do make it somewhat expected but I wouldn't say it's super obvious at a first glance) with the next inner type and index. Which I guess is what the comment is trying to convey, but dunno, it really didn't work for me. It might be enough to tweak it with more details (e.g. next -> outer?) or maybe it deserves some more substantial rewriting.
+{
- struct hlsl_type *type = *type_ptr;
- unsigned int index = *index_ptr;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*type_ptr = hlsl_get_scalar_type(ctx, type->base_type);
*index_ptr = 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);
*type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy);
*index_ptr = 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;
*type_ptr = type->e.array.type;
*index_ptr = 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)
{
*type_ptr = field->type;
*index_ptr = 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;
+}
+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;
- unsigned int i;
- assert(deref);
- assert(!deref->offset.node);
- type = deref->var->data_type;
- for (i = 0; i < deref->path_len; ++i)
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- return type;
+}
+/* Initializes a deref from another deref (prefix) and a component index. */ +static bool deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index,
const struct vkd3d_shader_location *loc)
It might come as a shock but I don't like this function's name. Originally these x_from_y() kind of functions were always "conversion" functions, i.e. take object y and return something from it as type x. Which I guess is technically what this function is, but I don't feel like that is the best way to represent it.
For one, this function effectively has 2 out parameters (block and deref), in that it also generates instructions and adds them to the block list. I guess it's not any different from a few other functions you're introducing in the patchset but, as it is, the comment feels somewhat partial. I would mention "block" as another byproduct of the function in the comment at the top.
In regard to the name, maybe just adding a new_ (or create_? generate_? init_?) in front would be enough. I don't have great suggestions, as usual.
Somewhat minor, and probably more controversial, but maybe still worth mentioning: instead of returning a bool, the function could return a pointer to the deref. It should return NULL in the codepaths currently returning "false", to maintain the current semantics (which are fine). While it's unlikely that the return value is going to be super useful, making this function resemble the other similar ones introduced in this patch and previously has value in my mind. Also, of course, that doesn't mean you can drop the "deref" parameter.
+{
- unsigned int path_len, path_index, deref_path_len, i;
- struct hlsl_type *path_type;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- path_len = 0;
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++path_len;
- }
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
return false;
- deref_path_len = 0;
- for (i = 0; i < prefix->path_len; ++i)
hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node);
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
unsigned int next_index = subtype_index_from_component_index(ctx, &path_type, &path_index);
if (!(c = hlsl_new_uint_constant(ctx, next_index, loc)))
{
hlsl_free_instr_list(&block->instrs);
return false;
}
list_add_tail(&block->instrs, &c->node.entry);
hlsl_src_from_node(&deref->path[deref_path_len++], &c->node);
- }
- assert(deref_path_len == deref->path_len);
- return true;
+}
struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) { @@ -435,6 +605,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)
For reference, I find the naming of this one okay (aside from node -> instr or something), probably just because of the new_ prefix.
Hi,
On 28-07-22 16:59, Matteo Bruni wrote:
On Wed, Jul 20, 2022 at 3:23 PM Francisco Casas [email protected] 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 are to be placed nearby in hlsl.h as they are introduced in the following patches.
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(). The deref obtained with this function, can also be passed be passed as prefix to deref_from_component_index().
v3:
- Replaced compute_component_path() with deref_from_component_index().
- Wrote implementation of init_deref() and get_type_from_deref() further up in the file.
- Made hlsl_new_load_component() use deref_from_component_index() instead of the removed compute_component_path().
- Rewrote hlsl.c function comments in present and active voice.
- Renamed typep -> type_ptr indexp -> index_ptr in subtype_index_from_component_index().
- Added space before '?' in ternary operators.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 298 +++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 ++++++----- libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 410 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 66acce23..535433ee 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,176 @@ 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, 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. */
Now *type_ptr and *index_ptr respectively, right?
Yep.
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **type_ptr, unsigned int *index_ptr)
After rereading the patch a number of times, I think the prototype is okay (not sure about the name, it sounds like a "get" but it does change the two parameters, not that I have better suggestions) but that comment above needs some clarification. What this function does is to move one step through the "path", or component index I guess, returning the "index" to be taken for the outer data type and updating type_ptr and index_ptr (which are two in/out parameters btw, their types do make it somewhat expected but I wouldn't say it's super obvious at a first glance) with the next inner type and index. Which I guess is what the comment is trying to convey, but dunno, it really didn't work for me. It might be enough to tweak it with more details (e.g. next -> outer?) or maybe it deserves some more substantial rewriting.
Okay, how about:
/* Given a type and a component index, this function moves one step through the path required to * reach that component within the type. * It returns the first index of this path. * It sets *type_ptr to the (outermost) type within the original type that contains the component. * It sets *index_ptr to the index of the component within *type_ptr. * So, this function can be called several times in sequence to obtain all the path's indexes until * the component is finally reached. */
?
BTW, an alternative name for the function could be 'traverse_path_from_component_index', but I am not totally sure.
+{
- struct hlsl_type *type = *type_ptr;
- unsigned int index = *index_ptr;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*type_ptr = hlsl_get_scalar_type(ctx, type->base_type);
*index_ptr = 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);
*type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy);
*index_ptr = 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;
*type_ptr = type->e.array.type;
*index_ptr = 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)
{
*type_ptr = field->type;
*index_ptr = 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;
+}
+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;
- unsigned int i;
- assert(deref);
- assert(!deref->offset.node);
- type = deref->var->data_type;
- for (i = 0; i < deref->path_len; ++i)
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- return type;
+}
+/* Initializes a deref from another deref (prefix) and a component index. */ +static bool deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index,
const struct vkd3d_shader_location *loc)
It might come as a shock but I don't like this function's name. Originally these x_from_y() kind of functions were always "conversion" functions, i.e. take object y and return something from it as type x. Which I guess is technically what this function is, but I don't feel like that is the best way to represent it.
For one, this function effectively has 2 out parameters (block and deref), in that it also generates instructions and adds them to the block list. I guess it's not any different from a few other functions you're introducing in the patchset but, as it is, the comment feels somewhat partial. I would mention "block" as another byproduct of the function in the comment at the top.
Okay, I will write it as:
/* Initializes a deref from another deref (prefix) and a component index. * *block is initialized to contain the new constant node instructions used by the deref's path. */
In regard to the name, maybe just adding a new_ (or create_? generate_? init_?) in front would be enough. I don't have great suggestions, as usual.
I am for the "init_" prefix.
Somewhat minor, and probably more controversial, but maybe still worth mentioning: instead of returning a bool, the function could return a pointer to the deref. It should return NULL in the codepaths currently returning "false", to maintain the current semantics (which are fine). While it's unlikely that the return value is going to be super useful, making this function resemble the other similar ones introduced in this patch and previously has value in my mind. Also, of course, that doesn't mean you can drop the "deref" parameter.
Hmm, while the other functions return pointers to nodes (or to a specific type of node) we never return derefs.
Personally, when I see an initialization function that returns a pointer, my first inclination is to think that said function allocates memory, which isn't the case for derefs, which are most of time contained in other structs (hlsl_ir_store, hlsl_ir_load, or hlsl_ir_resource_load) and are never allocated separately.
+{
- unsigned int path_len, path_index, deref_path_len, i;
- struct hlsl_type *path_type;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- path_len = 0;
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++path_len;
- }
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
return false;
- deref_path_len = 0;
- for (i = 0; i < prefix->path_len; ++i)
hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node);
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
unsigned int next_index = subtype_index_from_component_index(ctx, &path_type, &path_index);
if (!(c = hlsl_new_uint_constant(ctx, next_index, loc)))
{
hlsl_free_instr_list(&block->instrs);
return false;
}
list_add_tail(&block->instrs, &c->node.entry);
hlsl_src_from_node(&deref->path[deref_path_len++], &c->node);
- }
- assert(deref_path_len == deref->path_len);
- return true;
+}
- struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) {
@@ -435,6 +605,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)
For reference, I find the naming of this one okay (aside from node -> instr or something), probably just because of the new_ prefix.
It makes sense to me to keep a distinction between 'new_' and 'init_' when the new value's memory is allocated in the function or not.
Ok, I will rename it to 'hlsl_new_offset_instr_from_deref'.
On Tue, Aug 2, 2022 at 9:19 PM Francisco Casas [email protected] wrote:
Hi,
Hi Francisco,
big thumb up from me. I left a couple little replies in-line.
On 28-07-22 16:59, Matteo Bruni wrote:
On Wed, Jul 20, 2022 at 3:23 PM Francisco Casas [email protected] 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 are to be placed nearby in hlsl.h as they are introduced in the following patches.
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(). The deref obtained with this function, can also be passed be passed as prefix to deref_from_component_index().
v3:
- Replaced compute_component_path() with deref_from_component_index().
- Wrote implementation of init_deref() and get_type_from_deref() further up in the file.
- Made hlsl_new_load_component() use deref_from_component_index() instead of the removed compute_component_path().
- Rewrote hlsl.c function comments in present and active voice.
- Renamed typep -> type_ptr indexp -> index_ptr in subtype_index_from_component_index().
- Added space before '?' in ternary operators.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 298 +++++++++++++++++++++++++++++-- libs/vkd3d-shader/hlsl.h | 35 +++- libs/vkd3d-shader/hlsl.y | 102 ++++++----- libs/vkd3d-shader/hlsl_codegen.c | 44 +++++ 4 files changed, 410 insertions(+), 69 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 66acce23..535433ee 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -330,6 +330,176 @@ 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, 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. */
Now *type_ptr and *index_ptr respectively, right?
Yep.
+static unsigned int subtype_index_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type **type_ptr, unsigned int *index_ptr)
After rereading the patch a number of times, I think the prototype is okay (not sure about the name, it sounds like a "get" but it does change the two parameters, not that I have better suggestions) but that comment above needs some clarification. What this function does is to move one step through the "path", or component index I guess, returning the "index" to be taken for the outer data type and updating type_ptr and index_ptr (which are two in/out parameters btw, their types do make it somewhat expected but I wouldn't say it's super obvious at a first glance) with the next inner type and index. Which I guess is what the comment is trying to convey, but dunno, it really didn't work for me. It might be enough to tweak it with more details (e.g. next -> outer?) or maybe it deserves some more substantial rewriting.
Okay, how about:
/* Given a type and a component index, this function moves one step through the path required to
- reach that component within the type.
- It returns the first index of this path.
- It sets *type_ptr to the (outermost) type within the original type
that contains the component.
- It sets *index_ptr to the index of the component within *type_ptr.
- So, this function can be called several times in sequence to obtain
all the path's indexes until
- the component is finally reached. */
?
I like it.
BTW, an alternative name for the function could be 'traverse_path_from_component_index', but I am not totally sure.
Also good, it feels like an improvement to me.
I wonder what Zeb and Giovanni think about this (if anything) :)
+{
- struct hlsl_type *type = *type_ptr;
- unsigned int index = *index_ptr;
- assert(!type_is_single_component(type));
- assert(index < hlsl_type_component_count(type));
- switch (type->type)
- {
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
*type_ptr = hlsl_get_scalar_type(ctx, type->base_type);
*index_ptr = 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);
*type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy);
*index_ptr = 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;
*type_ptr = type->e.array.type;
*index_ptr = 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)
{
*type_ptr = field->type;
*index_ptr = 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;
+}
+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;
- unsigned int i;
- assert(deref);
- assert(!deref->offset.node);
- type = deref->var->data_type;
- for (i = 0; i < deref->path_len; ++i)
type = hlsl_get_type_from_path_index(ctx, type, deref->path[i].node);
- return type;
+}
+/* Initializes a deref from another deref (prefix) and a component index. */ +static bool deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index,
const struct vkd3d_shader_location *loc)
It might come as a shock but I don't like this function's name. Originally these x_from_y() kind of functions were always "conversion" functions, i.e. take object y and return something from it as type x. Which I guess is technically what this function is, but I don't feel like that is the best way to represent it.
For one, this function effectively has 2 out parameters (block and deref), in that it also generates instructions and adds them to the block list. I guess it's not any different from a few other functions you're introducing in the patchset but, as it is, the comment feels somewhat partial. I would mention "block" as another byproduct of the function in the comment at the top.
Okay, I will write it as:
/* Initializes a deref from another deref (prefix) and a component index.
- *block is initialized to contain the new constant node instructions
used by the deref's path. */
In regard to the name, maybe just adding a new_ (or create_? generate_? init_?) in front would be enough. I don't have great suggestions, as usual.
I am for the "init_" prefix.
Somewhat minor, and probably more controversial, but maybe still worth mentioning: instead of returning a bool, the function could return a pointer to the deref. It should return NULL in the codepaths currently returning "false", to maintain the current semantics (which are fine). While it's unlikely that the return value is going to be super useful, making this function resemble the other similar ones introduced in this patch and previously has value in my mind. Also, of course, that doesn't mean you can drop the "deref" parameter.
Hmm, while the other functions return pointers to nodes (or to a specific type of node) we never return derefs.
Personally, when I see an initialization function that returns a pointer, my first inclination is to think that said function allocates memory, which isn't the case for derefs, which are most of time contained in other structs (hlsl_ir_store, hlsl_ir_load, or hlsl_ir_resource_load) and are never allocated separately.
Yes, that's a fair point.
+{
- unsigned int path_len, path_index, deref_path_len, i;
- struct hlsl_type *path_type;
- struct hlsl_ir_constant *c;
- list_init(&block->instrs);
- path_len = 0;
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
subtype_index_from_component_index(ctx, &path_type, &path_index);
++path_len;
- }
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
return false;
- deref_path_len = 0;
- for (i = 0; i < prefix->path_len; ++i)
hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node);
- path_type = get_type_from_deref(ctx, prefix);
- path_index = index;
- while (!type_is_single_component(path_type))
- {
unsigned int next_index = subtype_index_from_component_index(ctx, &path_type, &path_index);
if (!(c = hlsl_new_uint_constant(ctx, next_index, loc)))
{
hlsl_free_instr_list(&block->instrs);
return false;
}
list_add_tail(&block->instrs, &c->node.entry);
hlsl_src_from_node(&deref->path[deref_path_len++], &c->node);
- }
- assert(deref_path_len == deref->path_len);
- return true;
+}
- struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *node) {
@@ -435,6 +605,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)
For reference, I find the naming of this one okay (aside from node -> instr or something), probably just because of the new_ prefix.
It makes sense to me to keep a distinction between 'new_' and 'init_' when the new value's memory is allocated in the function or not.
Ok, I will rename it to 'hlsl_new_offset_instr_from_deref'.
On 8/2/22 15:25, Matteo Bruni wrote:
BTW, an alternative name for the function could be 'traverse_path_from_component_index', but I am not totally sure.
Also good, it feels like an improvement to me.
I wonder what Zeb and Giovanni think about this (if anything) :)
It's good enough.
Il 02/08/22 22:25, Matteo Bruni ha scritto:
BTW, an alternative name for the function could be 'traverse_path_from_component_index', but I am not totally sure.
Also good, it feels like an improvement to me.
I wonder what Zeb and Giovanni think about this (if anything) 😄
No specific thought, so it's good.
Giovanni.
Signed-off-by: Francisco Casas [email protected] Signed-off-by: Giovanni Mascellani [email protected] ---
v3: * No changes.
Signed-off-by: Francisco Casas [email protected] --- 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 535433ee..75cb8f41 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1590,10 +1590,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] ---
v3: * Make hlsl_new_store_component() use deref_from_component_index() instead of the old compute_component_path(). * Using hlsl_new_store_component() in initialize_var_components() in this patch instead of the next.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 28 ++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 56 +++++++++++++++++++--------------------- 3 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 75cb8f41..8e95ee83 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -988,6 +988,34 @@ 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) +{ + struct hlsl_block comp_path_block; + struct hlsl_ir_store *store; + + list_init(&block->instrs); + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_STORE, NULL, rhs->loc); + + if (!deref_from_component_index(ctx, &comp_path_block, &store->lhs, lhs, comp, &rhs->loc)) + { + vkd3d_free(store); + return NULL; + } + list_move_tail(&block->instrs, &comp_path_block.instrs); + 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 710d5748..b51735af 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))) @@ -723,6 +721,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; @@ -738,12 +737,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; @@ -755,9 +756,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))) @@ -1733,32 +1734,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; } @@ -2123,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;
@@ -2169,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) { @@ -2204,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: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v3:
- Make hlsl_new_store_component() use deref_from_component_index() instead of the old compute_component_path().
- Using hlsl_new_store_component() in initialize_var_components() in this patch instead of the next.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 28 ++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 56 +++++++++++++++++++--------------------- 3 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 75cb8f41..8e95ee83 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -988,6 +988,34 @@ 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)
+{
- struct hlsl_block comp_path_block;
- struct hlsl_ir_store *store;
- list_init(&block->instrs);
- if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
- init_node(&store->node, HLSL_IR_STORE, NULL, rhs->loc);
- if (!deref_from_component_index(ctx, &comp_path_block, &store->lhs, lhs, comp, &rhs->loc))
- {
vkd3d_free(store);
return NULL;
- }
- list_move_tail(&block->instrs, &comp_path_block.instrs);
- 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 710d5748..b51735af 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)))
@@ -723,6 +721,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;
@@ -738,12 +737,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;
@@ -755,9 +756,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)))
@@ -1733,32 +1734,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; }
@@ -2123,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;
@@ -2169,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) {
@@ -2204,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] ---
v3: * Using hlsl_new_store_component() in initialize_var_components() was moved to the previous patch.
Signed-off-by: Francisco Casas [email protected] --- libs/vkd3d-shader/hlsl.c | 115 +++++++++++---------------------------- libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d-shader/hlsl.y | 27 ++------- 3 files changed, 40 insertions(+), 106 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8e95ee83..2d5fe40a 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; @@ -985,7 +904,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 b51735af..e7ab6abe 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1202,6 +1202,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;
@@ -1213,6 +1214,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++) { @@ -1240,11 +1242,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); } @@ -1606,10 +1604,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) { @@ -1634,15 +1630,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) @@ -1656,13 +1648,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); @@ -1673,19 +1663,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
Signed-off-by: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v3:
- Using hlsl_new_store_component() in initialize_var_components() was moved to the previous patch.
Signed-off-by: Francisco Casas [email protected]
libs/vkd3d-shader/hlsl.c | 115 +++++++++++---------------------------- libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d-shader/hlsl.y | 27 ++------- 3 files changed, 40 insertions(+), 106 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8e95ee83..2d5fe40a 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;
@@ -985,7 +904,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_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 *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc);
@@ -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,
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 idx, struct hlsl_type **comp_type);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b51735af..e7ab6abe 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1202,6 +1202,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;
@@ -1213,6 +1214,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++) {
@@ -1240,11 +1242,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); }
@@ -1606,10 +1604,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) {
@@ -1634,15 +1630,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)
@@ -1656,13 +1648,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);
@@ -1673,19 +1663,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
At this point, the parse code is free of offsets; it only uses index paths.
Signed-off-by: Francisco Casas [email protected] ---
v3: * No changes.
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 2d5fe40a..a4d594b7 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -862,6 +862,28 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
+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; +} + void hlsl_cleanup_deref(struct hlsl_deref *deref) { unsigned int i; @@ -1131,9 +1153,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;
@@ -1141,10 +1162,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 e7ab6abe..d50d4ebe 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2402,10 +2402,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) @@ -2430,11 +2428,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; @@ -2444,13 +2439,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) { @@ -2486,15 +2479,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);
@@ -2508,7 +2494,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; @@ -2517,7 +2502,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")) { @@ -2599,15 +2583,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);
Signed-off-by: Giovanni Mascellani [email protected]
but with a small notice:
Il 20/07/22 15:23, Francisco Casas ha scritto:
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2d5fe40a..a4d594b7 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -862,6 +862,28 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
+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);
You just asserted that other->offset.node is NULL and *deref was initialized to zero, so that seems to be a noop, doesn't it?
Thanks, Giovanni.
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] ---
v3: * No changes.
Signed-off-by: Francisco Casas [email protected] --- 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 a4d594b7..20dcd9af 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -452,109 +452,6 @@ struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const stru } }
-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: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
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]
v3:
- No changes.
Signed-off-by: Francisco Casas [email protected]
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 a4d594b7..20dcd9af 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -452,109 +452,6 @@ struct hlsl_type *hlsl_get_type_from_path_index(struct hlsl_ctx *ctx, const stru } }
-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] Signed-off-by: Zebediah Figura [email protected] ---
v3: * Add space before '?' in ternary operator.
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..6437006b 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: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected] Signed-off-by: Zebediah Figura [email protected]
v3:
- Add space before '?' in ternary operator.
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..6437006b 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: Francisco Casas [email protected] ---
v3: * No changes.
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 6437006b..7a245007 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
Hi,
Il 20/07/22 15:23, Francisco Casas ha scritto:
-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);
}
- }
Here (and analogously in append_output_copy()) you can easily move the common call to hlsl_new_store_index() out of the conditional branch. I think it makes the code more readable.
Giovanni.
Signed-off-by: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas [email protected]
v3:
- No changes.
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 6437006b..7a245007 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
On Wed, Jul 20, 2022 at 3:24 PM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v3:
- No changes.
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 6437006b..7a245007 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)
I haven't put a lot of thought into this, but it seems to me we could pass a deref instead of a redundant load and be mostly set. Mostly because we then need to add the instructions to the instruction list in some other way (e.g. by passing an explicit list).
Hello,
On 28-07-22 16:59, Matteo Bruni wrote:
On Wed, Jul 20, 2022 at 3:24 PM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v3:
- No changes.
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 6437006b..7a245007 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)
I haven't put a lot of thought into this, but it seems to me we could pass a deref instead of a redundant load and be mostly set. Mostly because we then need to add the instructions to the instruction list in some other way (e.g. by passing an explicit list).
I tried it passing a hlsl_blocks to be initialized (like in the component load/store initializers) but in the end it didn't seem like a good idea to me:
The problem is that we would need to create derefs in the wild (outside hlsl_ir_nodes), which would mean exposing several static functions in hlsl.c, like init_deref_from_component_index(). We would also need to use "hlsl_cleanup_deref()" which for now is only non-static because it is needed in the the pass that translates index paths back to register offsets.
So I don't think exposing the deref functions is better than adding these redundant loads, which are later deleted by the DCE pass, if I am not mistaken.
Alternatively, we could create the nodes just as a container for the derefs and immediately free them, but that also seems a little ugly.
So my vote is to keep this signature. Maybe remove the "type" parameter since it can be obtained from the deref inside the load node.
On Thu, Aug 4, 2022 at 9:10 PM Francisco Casas [email protected] wrote:
Hello,
On 28-07-22 16:59, Matteo Bruni wrote:
On Wed, Jul 20, 2022 at 3:24 PM Francisco Casas [email protected] wrote:
Signed-off-by: Francisco Casas [email protected]
v3:
- No changes.
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 6437006b..7a245007 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)
I haven't put a lot of thought into this, but it seems to me we could pass a deref instead of a redundant load and be mostly set. Mostly because we then need to add the instructions to the instruction list in some other way (e.g. by passing an explicit list).
I tried it passing a hlsl_blocks to be initialized (like in the component load/store initializers) but in the end it didn't seem like a good idea to me:
The problem is that we would need to create derefs in the wild (outside hlsl_ir_nodes), which would mean exposing several static functions in hlsl.c, like init_deref_from_component_index(). We would also need to use "hlsl_cleanup_deref()" which for now is only non-static because it is needed in the the pass that translates index paths back to register offsets.
So I don't think exposing the deref functions is better than adding these redundant loads, which are later deleted by the DCE pass, if I am not mistaken.
Alternatively, we could create the nodes just as a container for the derefs and immediately free them, but that also seems a little ugly.
So my vote is to keep this signature. Maybe remove the "type" parameter since it can be obtained from the deref inside the load node.
Fair enough. That was hard to see without actually trying and it sounds like redundant loads are the lesser evil in this case. Maybe a comment somewhere explaining that these loads are redundant and supposed to be eliminated by DCE would be nice.
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] ---
v3: * 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 20dcd9af..6b187e7d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -795,25 +795,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 it can be passed to load/store functions. */ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) { @@ -969,19 +950,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 7a245007..08029361 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
Signed-off-by: Giovanni Mascellani [email protected]
Il 20/07/22 15:23, Francisco Casas ha scritto:
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]
v3:
- 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 20dcd9af..6b187e7d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -795,25 +795,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 it can be passed to load/store functions. */ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) {
@@ -969,19 +950,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_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc);struct hlsl_type *type, 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_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 *rhs, unsigned int writemask, struct vkd3d_shader_location loc);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 7a245007..08029361 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 Wed, Jul 20, 2022 at 3:24 PM Francisco Casas [email protected] wrote:
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]
v3:
- 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 20dcd9af..6b187e7d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -795,25 +795,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 it can be passed to load/store functions. */ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) { @@ -969,19 +950,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 7a245007..08029361 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)
Why "indx" now?
Hello,
On 28-07-22 17:00, Matteo Bruni wrote:
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)
Why "indx" now?
The rename is because I don't want to get it confused with "offset" as in "register offset", since it is a "component index" now.
In case you meant why I wrote "indx" instead of "idx", which seems to be the standard, it was just a mistake, I will change it.