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

Francisco Casas fcasas at codeweavers.com
Thu Jul 14 20:23:54 CDT 2022


Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
---
v2:
* Split from a previous patch.
---
 libs/vkd3d-shader/hlsl.c | 115 +++++++++++----------------------------
 libs/vkd3d-shader/hlsl.h |   4 +-
 libs/vkd3d-shader/hlsl.y |  43 ++++-----------
 3 files changed, 47 insertions(+), 115 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 2d7d33fa..0cd88ba6 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -249,87 +249,6 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e
     return type;
 }
 
-/* Returns the register offset of a given component within a type, given its index.
- * *comp_type will be set to the type of the component. */
-unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
-        unsigned int idx, struct hlsl_type **comp_type)
-{
-    switch (type->type)
-    {
-        case HLSL_CLASS_SCALAR:
-        case HLSL_CLASS_VECTOR:
-        {
-            assert(idx < type->dimx * type->dimy);
-            *comp_type = hlsl_get_scalar_type(ctx, type->base_type);
-            return idx;
-        }
-        case HLSL_CLASS_MATRIX:
-        {
-            unsigned int minor, major, x = idx % type->dimx, y = idx / type->dimx;
-
-            assert(idx < type->dimx * type->dimy);
-
-            if (hlsl_type_is_row_major(type))
-            {
-                minor = x;
-                major = y;
-            }
-            else
-            {
-                minor = y;
-                major = x;
-            }
-
-            *comp_type = hlsl_get_scalar_type(ctx, type->base_type);
-            return 4 * major + minor;
-        }
-
-        case HLSL_CLASS_ARRAY:
-        {
-            unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type);
-            unsigned int array_idx = idx / elem_comp_count;
-            unsigned int idx_in_elem = idx % elem_comp_count;
-
-            assert(array_idx < type->e.array.elements_count);
-
-            return array_idx * hlsl_type_get_array_element_reg_size(type->e.array.type) +
-                    hlsl_compute_component_offset(ctx, type->e.array.type, idx_in_elem, comp_type);
-        }
-
-        case HLSL_CLASS_STRUCT:
-        {
-            struct hlsl_struct_field *field;
-            unsigned int elem_comp_count, i;
-
-            for (i = 0; i < type->e.record.field_count; ++i)
-            {
-                field = &type->e.record.fields[i];
-                elem_comp_count = hlsl_type_component_count(field->type);
-
-                if (idx < elem_comp_count)
-                {
-                    return field->reg_offset +
-                            hlsl_compute_component_offset(ctx, field->type, idx, comp_type);
-                }
-                idx -= elem_comp_count;
-            }
-
-            assert(0);
-            return 0;
-        }
-
-        case HLSL_CLASS_OBJECT:
-        {
-            assert(idx == 0);
-            *comp_type = type;
-            return 0;
-        }
-    }
-
-    assert(0);
-    return 0;
-}
-
 static bool type_is_single_component(const struct hlsl_type *type)
 {
     return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT;
@@ -965,7 +884,39 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va
 
 struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
 {
-    return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc);
+    struct hlsl_deref lhs_deref;
+
+    hlsl_init_simple_deref_from_var(&lhs_deref, lhs);
+    return hlsl_new_store_index(ctx, &lhs_deref, NULL, rhs, 0, &rhs->loc);
+}
+
+struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs,
+        struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc)
+{
+    struct hlsl_ir_store *store;
+    unsigned int i;
+
+    assert(lhs);
+    assert(!lhs->offset.node);
+
+    if (!(store = hlsl_alloc(ctx, sizeof(*store))))
+        return NULL;
+    init_node(&store->node, HLSL_IR_STORE, NULL, *loc);
+
+    if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx))
+        return NULL;
+    for (i = 0; i < lhs->path_len; ++i)
+        hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node);
+    if (idx)
+        hlsl_src_from_node(&store->lhs.path[lhs->path_len], idx);
+
+    hlsl_src_from_node(&store->rhs, rhs);
+
+    if (!writemask && type_is_single_reg(rhs->data_type))
+        writemask = (1 << rhs->data_type->dimx) - 1;
+    store->writemask = writemask;
+
+    return store;
 }
 
 struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index c8820711..72e7fab2 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -768,6 +768,8 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b
         const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc);
 
 struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs);
+struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs,
+        struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc);
 struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
         const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
 
@@ -817,8 +819,6 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
         unsigned int default_majority, unsigned int modifiers);
 unsigned int hlsl_type_component_count(const struct hlsl_type *type);
 unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type);
-unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
-        unsigned int idx, struct hlsl_type **comp_type);
 struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
         unsigned int index);
 bool hlsl_type_is_row_major(const struct hlsl_type *type);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 8e5b8323..b824ccef 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1200,6 +1200,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
         struct vkd3d_string_buffer *name;
         static unsigned int counter = 0;
         struct hlsl_type *vector_type;
+        struct hlsl_deref var_deref;
         struct hlsl_ir_load *load;
         struct hlsl_ir_var *var;
 
@@ -1211,6 +1212,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
         vkd3d_string_buffer_release(&ctx->string_buffers, name);
         if (!var)
             return NULL;
+        hlsl_init_simple_deref_from_var(&var_deref, var);
 
         for (i = 0; i < hlsl_type_major_size(type); i++)
         {
@@ -1238,11 +1240,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
             if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc)))
                 return NULL;
 
-            if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc)))
-                return NULL;
-            list_add_tail(instrs, &c->node.entry);
-
-            if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc)))
+            if (!(store = hlsl_new_store_index(ctx, &var_deref, &c->node, value, 0, loc)))
                 return NULL;
             list_add_tail(instrs, &store->node.entry);
         }
@@ -1604,10 +1602,8 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
 {
     struct hlsl_type *lhs_type = lhs->data_type;
     struct hlsl_ir_store *store;
-    struct hlsl_ir_node *offset;
     struct hlsl_ir_expr *copy;
     unsigned int writemask = 0;
-    struct hlsl_block block;
 
     if (assign_op == ASSIGN_OP_SUB)
     {
@@ -1632,15 +1628,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
             return NULL;
     }
 
-    if (!(store = hlsl_alloc(ctx, sizeof(*store))))
-        return NULL;
-
     while (lhs->type != HLSL_IR_LOAD)
     {
         if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
         {
             hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS.");
-            vkd3d_free(store);
             return NULL;
         }
         else if (lhs->type == HLSL_IR_SWIZZLE)
@@ -1654,13 +1646,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
             if (!invert_swizzle(&s, &writemask, &width))
             {
                 hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
-                vkd3d_free(store);
                 return NULL;
             }
 
             if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
             {
-                vkd3d_free(store);
                 return NULL;
             }
             list_add_tail(instrs, &new_swizzle->node.entry);
@@ -1671,19 +1661,12 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
         else
         {
             hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
-            vkd3d_free(store);
             return NULL;
         }
     }
 
-    offset = hlsl_new_offset_node_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc);
-    list_move_tail(instrs, &block.instrs);
-
-    init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc);
-    store->writemask = writemask;
-    store->lhs.var = hlsl_ir_load(lhs)->src.var;
-    hlsl_src_from_node(&store->lhs.offset, offset);
-    hlsl_src_from_node(&store->rhs, rhs);
+    if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc)))
+        return NULL;
     list_add_tail(instrs, &store->node.entry);
 
     /* Don't use the instruction itself as a source, as this makes structure
@@ -1732,32 +1715,30 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
         struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src)
 {
     unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
+    struct hlsl_deref dst_deref;
     unsigned int k;
 
+    hlsl_init_simple_deref_from_var(&dst_deref, dst);
+
     for (k = 0; k < src_comp_count; ++k)
     {
         struct hlsl_type *dst_comp_type;
-        unsigned int dst_reg_offset;
         struct hlsl_ir_store *store;
-        struct hlsl_ir_constant *c;
         struct hlsl_ir_load *load;
         struct hlsl_ir_node *conv;
+        struct hlsl_block block;
 
         if (!(load = add_load_component(ctx, instrs, src, k, &src->loc)))
             return;
 
-        dst_reg_offset = hlsl_compute_component_offset(ctx, dst->data_type, *store_index, &dst_comp_type);
+        dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
 
         if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc)))
             return;
 
-        if (!(c = hlsl_new_uint_constant(ctx, dst_reg_offset, &src->loc)))
+        if (!(store = hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv)))
             return;
-        list_add_tail(instrs, &c->node.entry);
-
-        if (!(store = hlsl_new_store(ctx, dst, &c->node, conv, 0, src->loc)))
-            return;
-        list_add_tail(instrs, &store->node.entry);
+        list_move_tail(instrs, &block.instrs);
 
         ++*store_index;
     }
-- 
2.34.1




More information about the wine-devel mailing list