[PATCH vkd3d v4 9/9] vkd3d-shader/hlsl: Parse the mul() intrinsic.

Giovanni Mascellani gmascellani at codeweavers.com
Tue Jun 7 02:43:22 CDT 2022


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
 libs/vkd3d-shader/hlsl.y                | 118 ++++++++++++++++++++++++
 tests/hlsl-majority-pragma.shader_test  |   2 +-
 tests/hlsl-majority-typedef.shader_test |   2 +-
 tests/hlsl-mul.shader_test              |  36 ++++----
 4 files changed, 138 insertions(+), 20 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 2aee5153..df5fda47 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -2046,6 +2046,123 @@ static bool intrinsic_min(struct hlsl_ctx *ctx,
     return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc);
 }
 
+static bool intrinsic_mul(struct hlsl_ctx *ctx,
+        const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+    struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2;
+    enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type);
+    struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type;
+    unsigned int i, j, k, vect_count = 0;
+    struct vkd3d_string_buffer *name;
+    static unsigned int counter = 0;
+    struct hlsl_ir_load *load;
+    struct hlsl_ir_var *var;
+
+    if (arg1->data_type->type == HLSL_CLASS_SCALAR || arg2->data_type->type == HLSL_CLASS_SCALAR)
+        return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1, arg2, loc);
+
+    if (arg1->data_type->type == HLSL_CLASS_VECTOR)
+    {
+        vect_count++;
+        cast_type1 = hlsl_get_matrix_type(ctx, base, arg1->data_type->dimx, 1);
+    }
+    if (arg2->data_type->type == HLSL_CLASS_VECTOR)
+    {
+        vect_count++;
+        cast_type2 = hlsl_get_matrix_type(ctx, base, 1, arg2->data_type->dimx);
+    }
+
+    matrix_type = hlsl_get_matrix_type(ctx, base, cast_type2->dimx, cast_type1->dimy);
+
+    if (vect_count == 0)
+    {
+        ret_type = matrix_type;
+    }
+    else if (vect_count == 1)
+    {
+        assert(matrix_type->dimx == 1 || matrix_type->dimy == 1);
+        ret_type = hlsl_get_vector_type(ctx, base, matrix_type->dimx * matrix_type->dimy);
+    }
+    else
+    {
+        assert(matrix_type->dimx == 1 && matrix_type->dimy == 1);
+        ret_type = hlsl_get_scalar_type(ctx, base);
+    }
+
+    if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc)))
+        return false;
+
+    if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc)))
+        return false;
+
+    name = vkd3d_string_buffer_get(&ctx->string_buffers);
+    vkd3d_string_buffer_printf(name, "<mul-%u>", counter++);
+    var = hlsl_new_synthetic_var(ctx, name->buffer, matrix_type, *loc);
+    vkd3d_string_buffer_release(&ctx->string_buffers, name);
+    if (!var)
+        return false;
+
+    for (i = 0; i < matrix_type->dimx; ++i)
+        for (j = 0; j < matrix_type->dimy; ++j)
+        {
+            struct hlsl_ir_node *node = NULL;
+            struct hlsl_type *scalar_type;
+            struct hlsl_ir_store *store;
+            struct hlsl_ir_constant *c;
+            unsigned int offset;
+
+            for (k = 0; k < cast_type1->dimx && k < cast_type2->dimy; ++k)
+            {
+                struct hlsl_ir_load *value1, *value2;
+                struct hlsl_ir_node *mul;
+
+                offset = hlsl_compute_component_offset(ctx, cast_type1, j * cast_type1->dimx + k, &scalar_type);
+                if (!(c = hlsl_new_uint_constant(ctx, offset, loc)))
+                    return false;
+                list_add_tail(params->instrs, &c->node.entry);
+
+                if (!(value1 = add_load(ctx, params->instrs, cast1, &c->node, scalar_type, *loc)))
+                    return false;
+
+                offset = hlsl_compute_component_offset(ctx, cast_type2, k * cast_type2->dimx + i, &scalar_type);
+                if (!(c = hlsl_new_uint_constant(ctx, offset, loc)))
+                    return false;
+                list_add_tail(params->instrs, &c->node.entry);
+
+                if (!(value2 = add_load(ctx, params->instrs, cast2, &c->node, scalar_type, *loc)))
+                    return false;
+
+                if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc)))
+                    return false;
+
+                if (node)
+                {
+                    if (!(node = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, node, mul, loc)))
+                        return false;
+                }
+                else
+                {
+                    node = mul;
+                }
+            }
+
+            offset = hlsl_compute_component_offset(ctx, matrix_type, j * matrix_type->dimx + i, &scalar_type);
+            if (!(c = hlsl_new_uint_constant(ctx, offset, loc)))
+                return false;
+            list_add_tail(params->instrs, &c->node.entry);
+
+            if (!(store = hlsl_new_store(ctx, var, &c->node, node, 0, *loc)))
+                return false;
+            list_add_tail(params->instrs, &store->node.entry);
+        }
+
+    if (!(load = hlsl_new_load(ctx, var, NULL, matrix_type, *loc)))
+        return false;
+    list_add_tail(params->instrs, &load->node.entry);
+
+    return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc);
+}
+
 static bool intrinsic_pow(struct hlsl_ctx *ctx,
         const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
 {
@@ -2106,6 +2223,7 @@ intrinsic_functions[] =
     {"floor",                               1, true,  intrinsic_floor},
     {"max",                                 2, true,  intrinsic_max},
     {"min",                                 2, true,  intrinsic_min},
+    {"mul",                                 2, true,  intrinsic_mul},
     {"pow",                                 2, true,  intrinsic_pow},
     {"round",                               1, true,  intrinsic_round},
     {"saturate",                            1, true,  intrinsic_saturate},
diff --git a/tests/hlsl-majority-pragma.shader_test b/tests/hlsl-majority-pragma.shader_test
index a9f917ff..e7fc75cd 100644
--- a/tests/hlsl-majority-pragma.shader_test
+++ b/tests/hlsl-majority-pragma.shader_test
@@ -17,5 +17,5 @@ uniform  0 float4 0.1 0.2 0.0 0.0
 uniform  4 float4 0.3 0.4 0.0 0.0
 uniform  8 float4 0.1 0.3 0.0 0.0
 uniform 12 float4 0.2 0.4 0.0 0.0
-todo draw quad
+draw quad
 probe all rgba (0.17, 0.39, 0.17, 0.39) 1
diff --git a/tests/hlsl-majority-typedef.shader_test b/tests/hlsl-majority-typedef.shader_test
index 192c96db..1460e9a0 100644
--- a/tests/hlsl-majority-typedef.shader_test
+++ b/tests/hlsl-majority-typedef.shader_test
@@ -18,5 +18,5 @@ uniform  0 float4 0.1 0.2 0.0 0.0
 uniform  4 float4 0.3 0.4 0.0 0.0
 uniform  8 float4 0.1 0.3 0.0 0.0
 uniform 12 float4 0.2 0.4 0.0 0.0
-todo draw quad
+draw quad
 probe all rgba (0.17, 0.39, 0.17, 0.39) 1
diff --git a/tests/hlsl-mul.shader_test b/tests/hlsl-mul.shader_test
index 1d137e69..7b453187 100644
--- a/tests/hlsl-mul.shader_test
+++ b/tests/hlsl-mul.shader_test
@@ -12,7 +12,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (30.0, 70.0, 110.0, 150.0)
 
 [pixel shader]
@@ -28,7 +28,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (90.0, 100.0, 110.0, 120.0)
 
 [pixel shader]
@@ -44,7 +44,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (14.0, 38.0, 62.0, 86.0)
 
 [pixel shader]
@@ -60,7 +60,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (38.0, 44.0, 50.0, 56.0)
 
 [pixel shader]
@@ -75,7 +75,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (14.0, 32.0, 50.0, 0.0)
 
 [pixel shader]
@@ -90,7 +90,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (30.0, 36.0, 42.0, 0.0)
 
 [pixel shader]
@@ -106,7 +106,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (50.0, 60.0, 70.0, 80.0)
 
 [pixel shader]
@@ -122,7 +122,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (50.0, 60.0, 70.0, 80.0)
 
 [pixel shader]
@@ -138,7 +138,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (10.0, 20.0, 30.0, 40.0)
 
 [pixel shader]
@@ -154,7 +154,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (10.0, 50.0, 90.0, 130.0)
 
 [pixel shader]
@@ -170,7 +170,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (10.0, 20.0, 30.0, 40.0)
 
 [pixel shader]
@@ -186,7 +186,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (10.0, 50.0, 90.0, 130.0)
 
 [pixel shader]
@@ -202,7 +202,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (90.0, 100.0, 110.0, 120.0)
 
 [pixel shader]
@@ -218,7 +218,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (5.0, 10.0, 15.0, 20.0)
 
 [pixel shader]
@@ -234,7 +234,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (2.0, 4.0, 6.0, 8.0)
 
 [pixel shader]
@@ -250,7 +250,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (30.0, 70.0, 110.0, 150.0)
 
 [pixel shader]
@@ -268,7 +268,7 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (83.0, 98.0, 113.0, 128.0)
 
 [pixel shader]
@@ -286,5 +286,5 @@ float4 main(float4 pos : sv_position) : sv_target
 }
 
 [test]
-todo draw quad
+draw quad
 probe all rgba (78.0, 96.0, 114.0, 0.0)
-- 
2.36.1




More information about the wine-devel mailing list