[PATCH vkd3d v2 8/9] vkd3d-shader/hlsl: Support matrix indexing.

Giovanni Mascellani gmascellani at codeweavers.com
Thu Apr 21 10:44:28 CDT 2022


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
v2:
* Use "scalar_type" instead of "scal_type"
* Use a vkd3d_string_buffer to format the variable's name
* Format the variable name with %u instead of %x
* Use hlsl_new_var_load() instead of hlsl_new_load()
* Rename compute_matrix_offset() to add_compute_matrix_offset()
---
 libs/vkd3d-shader/hlsl.y               | 89 +++++++++++++++++++++++++-
 tests/hlsl-matrix-indexing.shader_test |  8 +--
 2 files changed, 90 insertions(+), 7 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index ec0e23bb..d6d9dda6 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -581,6 +581,91 @@ static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hl
     return !!add_load(ctx, instrs, record, &c->node, field->type, loc);
 }
 
+static struct hlsl_ir_expr *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_compute_matrix_offset(struct hlsl_ctx *ctx, struct list *instrs,
+        struct hlsl_type *type, struct hlsl_ir_node *x, struct hlsl_ir_node *y,
+        const struct vkd3d_shader_location *loc)
+{
+    struct hlsl_ir_node *major, *minor;
+    struct hlsl_ir_expr *mul, *add;
+    struct hlsl_ir_constant *four;
+
+    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->node, minor, loc)))
+        return NULL;
+
+    return &add->node;
+}
+
+static bool add_matrix_load(struct hlsl_ctx *ctx, struct list *instrs,
+        struct hlsl_ir_node *matrix, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc)
+{
+    struct hlsl_type *mat_type = matrix->data_type, *ret_type, *scalar_type;
+    struct vkd3d_string_buffer name;
+    static unsigned int counter = 0;
+    struct hlsl_ir_load *load;
+    struct hlsl_ir_var *var;
+    unsigned int i;
+
+    ret_type = hlsl_get_vector_type(ctx, mat_type->base_type, mat_type->dimx);
+    scalar_type = hlsl_get_scalar_type(ctx, mat_type->base_type);
+
+    vkd3d_string_buffer_init(&name);
+    vkd3d_string_buffer_printf(&name, "<index-%u>", counter++);
+    var = hlsl_new_synthetic_var(ctx, name.buffer, ret_type, *loc);
+    vkd3d_string_buffer_cleanup(&name);
+    if (!var)
+        return false;
+
+    for (i = 0; i < mat_type->dimx; ++i)
+    {
+        struct hlsl_ir_node *offset;
+        struct hlsl_ir_store *store;
+        struct hlsl_ir_load *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 (!(offset = add_compute_matrix_offset(ctx, instrs, mat_type, &c->node, index, loc)))
+            return false;
+
+        if (!(value = add_load(ctx, instrs, matrix, offset, scalar_type, *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);
+    }
+
+    if (!(load = hlsl_new_var_load(ctx, var, *loc)))
+        return false;
+    list_add_tail(instrs, &load->node.entry);
+
+    return true;
+}
+
 static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array,
         struct hlsl_ir_node *index, const struct vkd3d_shader_location loc)
 {
@@ -597,9 +682,7 @@ static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hls
     }
     else if (expr_type->type == HLSL_CLASS_MATRIX)
     {
-        /* This needs to be lowered now, while we still have type information. */
-        FIXME("Index of matrix type.\n");
-        return false;
+        return add_matrix_load(ctx, instrs, array, index, &loc);
     }
     else if (expr_type->type == HLSL_CLASS_VECTOR)
     {
diff --git a/tests/hlsl-matrix-indexing.shader_test b/tests/hlsl-matrix-indexing.shader_test
index 8057179e..a0a89829 100644
--- a/tests/hlsl-matrix-indexing.shader_test
+++ b/tests/hlsl-matrix-indexing.shader_test
@@ -11,7 +11,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0
 uniform 4 float4 5.0 6.0 7.0 8.0
 uniform 8 float4 9.0 10.0 11.0 12.0
 uniform 12 float4 13.0 14.0 15.0 16.0
-todo draw quad
+draw quad
 probe all rgba (1.0, 2.0, 10.0, 15.0)
 
 [pixel shader]
@@ -27,7 +27,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0
 uniform 4 float4 5.0 6.0 7.0 8.0
 uniform 8 float4 9.0 10.0 11.0 12.0
 uniform 12 float4 13.0 14.0 15.0 16.0
-todo draw quad
+draw quad
 probe all rgba (1.0, 2.0, 10.0, 15.0)
 
 [pixel shader]
@@ -43,7 +43,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0
 uniform 4 float4 5.0 6.0 7.0 8.0
 uniform 8 float4 9.0 10.0 11.0 12.0
 uniform 12 float4 13.0 14.0 15.0 16.0
-todo draw quad
+draw quad
 probe all rgba (1.0, 5.0, 7.0, 12.0)
 
 [pixel shader]
@@ -58,5 +58,5 @@ float4 main() : SV_TARGET
 [test]
 uniform 0 float4 1.0 2.0 3.0 0.0
 uniform 4 float4 5.0 6.0 7.0 0.0
-todo draw quad
+draw quad
 probe all rgba (1.0, 3.0, 6.0, 7.0)
-- 
2.35.2




More information about the wine-devel mailing list