[PATCH vkd3d v3 12/17] vkd3d-shader/hlsl: Introduce hlsl_new_store_index().

Francisco Casas fcasas at codeweavers.com
Wed Jul 20 08:23:19 CDT 2022


Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
---

v3:
* Using hlsl_new_store_component() in initialize_var_components() was
  moved to the previous patch.

Signed-off-by: Francisco Casas <fcasas 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 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
-- 
2.34.1




More information about the wine-devel mailing list