Francisco Casas : vkd3d-shader/hlsl: Introduce hlsl_new_store_index().
Alexandre Julliard
julliard at winehq.org
Wed Aug 10 14:45:26 CDT 2022
Module: vkd3d
Branch: master
Commit: 5b664c7a5c7e72ec81c596006500d9df4866bfec
URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/5b664c7a5c7e72ec81c596006500d9df4866bfec
Author: Francisco Casas <fcasas at codeweavers.com>
Date: Wed Jul 13 16:56:21 2022 -0400
vkd3d-shader/hlsl: Introduce hlsl_new_store_index().
Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani at 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 986aa579..b4e3525f 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;
@@ -989,7 +908,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 8ef4d015..76721c8e 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 e75971be..a5152800 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_instr_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
More information about the wine-cvs
mailing list