Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/07/22 15:23, Francisco Casas ha scritto:
Signed-off-by: Francisco Casas fcasas@codeweavers.com
v3:
- Using hlsl_new_store_component() in initialize_var_components() was moved to the previous patch.
Signed-off-by: Francisco Casas fcasas@codeweavers.com
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