Zebediah Figura : d3dcompiler: Parse array types.

Alexandre Julliard julliard at winehq.org
Thu Mar 12 17:09:07 CDT 2020


Module: wine
Branch: master
Commit: 0e95c3faa2ed89cda4335ed19a0a19de3f1a3b0a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0e95c3faa2ed89cda4335ed19a0a19de3f1a3b0a

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Fri Mar  6 17:17:30 2020 -0600

d3dcompiler: Parse array types.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3dcompiler_43/d3dcompiler_private.h |  2 +
 dlls/d3dcompiler_43/hlsl.y                | 61 ++++++++++++++++++++++++++++++-
 dlls/d3dcompiler_43/tests/hlsl_d3d9.c     | 59 ++++++++++++++++++++++++++++++
 dlls/d3dcompiler_43/utils.c               |  4 +-
 4 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 2d8eba0b55..1a155736fd 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1154,8 +1154,10 @@ void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_fu
 struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type, DWORD major, DWORD minor,
         const char *entrypoint, char **messages) DECLSPEC_HIDDEN;
 
+const char *debug_base_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
+const char *debug_node_type(enum hlsl_ir_node_type type) DECLSPEC_HIDDEN;
 void debug_dump_ir_function_decl(const struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN;
 
 void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index e46bdbade3..46d815d014 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -926,6 +926,47 @@ static struct list *make_list(struct hlsl_ir_node *node)
     return list;
 }
 
+static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
+{
+    if (node->data_type->type != HLSL_CLASS_SCALAR)
+        return 0;
+
+    switch (node->type)
+    {
+    case HLSL_IR_CONSTANT:
+    {
+        struct hlsl_ir_constant *constant = constant_from_node(node);
+
+        switch (constant->node.data_type->base_type)
+        {
+        case HLSL_TYPE_UINT:
+            return constant->v.value.u[0];
+        case HLSL_TYPE_INT:
+            return constant->v.value.i[0];
+        case HLSL_TYPE_FLOAT:
+            return constant->v.value.f[0];
+        case HLSL_TYPE_DOUBLE:
+            return constant->v.value.d[0];
+        case HLSL_TYPE_BOOL:
+            return constant->v.value.b[0];
+        default:
+            WARN("Invalid type %s.\n", debug_base_type(constant->node.data_type));
+            return 0;
+        }
+    }
+    case HLSL_IR_CONSTRUCTOR:
+    case HLSL_IR_DEREF:
+    case HLSL_IR_EXPR:
+    case HLSL_IR_SWIZZLE:
+        FIXME("Unhandled type %s.\n", debug_node_type(node->type));
+        return 0;
+    case HLSL_IR_ASSIGNMENT:
+    default:
+        WARN("Invalid node type %s.\n", debug_node_type(node->type));
+        return 0;
+    }
+}
+
 %}
 
 %locations
@@ -1651,9 +1692,25 @@ array:                    /* Empty */
                             }
                         | '[' expr ']'
                             {
-                                FIXME("Array.\n");
-                                $$ = 0;
+                                unsigned int size = evaluate_array_dimension(node_from_list($2));
+
                                 free_instr_list($2);
+
+                                if (!size)
+                                {
+                                    hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
+                                            "array size is not a positive integer constant\n");
+                                    YYABORT;
+                                }
+                                TRACE("Array size %u.\n", size);
+
+                                if (size > 65536)
+                                {
+                                    hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
+                                            "array size must be between 1 and 65536");
+                                    YYABORT;
+                                }
+                                $$ = size;
                             }
 
 var_modifiers:            /* Empty */
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
index c673e2be32..525de9910b 100644
--- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
+++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
@@ -654,10 +654,47 @@ static void test_return(void)
     release_test_context(&test_context);
 }
 
+static void test_array_dimensions(void)
+{
+    struct test_context test_context;
+    ID3D10Blob *ps_code = NULL;
+    struct vec4 v;
+
+    static const char shader[] =
+        "float4 main(float x : TEXCOORD0) : COLOR\n"
+        "{\n"
+        "    const int dim = 4;\n"
+        "    float a[2 * 2] = {0.1, 0.2, 0.3, 0.4};\n"
+        "    float b[4.1] = a;\n"
+        "    float c[dim] = b;\n"
+        "    float d[true] = {c[0]};\n"
+        "    float e[65536];\n"
+        "    return float4(d[0], c[0], c[1], c[3]);\n"
+        "}";
+
+    if (!init_test_context(&test_context))
+        return;
+
+    todo_wine ps_code = compile_shader(shader, "ps_2_0");
+    if (ps_code)
+    {
+        draw_quad(test_context.device, ps_code);
+
+        v = get_color_vec4(test_context.device, 0, 0);
+        ok(compare_vec4(&v, 0.1f, 0.1f, 0.2f, 0.4f, 0),
+                "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
+
+        ID3D10Blob_Release(ps_code);
+    }
+
+    release_test_context(&test_context);
+}
+
 static void test_fail(void)
 {
     static const char *tests[] =
     {
+        /* 0 */
         "float4 test() : SV_TARGET\n"
         "{\n"
         "   return y;\n"
@@ -689,6 +726,7 @@ static void test_fail(void)
         "  return float4(x.x, x.y, 0, 0);\n"
         "}",
 
+        /* 5 */
         "float4 test() : SV_TARGET\n"
         "{\n"
         "   struct { int b,c; } x = {0};\n"
@@ -715,6 +753,26 @@ static void test_fail(void)
         "{\n"
         "    return pos;\n"
         "}",
+
+        /* 10 */
+        "float4 test(float2 pos: TEXCOORD0) : SV_TARGET\n"
+        "{\n"
+        "    float a[0];\n"
+        "    return float4(0, 0, 0, 0);\n"
+        "}",
+
+        "float4 test(float2 pos: TEXCOORD0) : SV_TARGET\n"
+        "{\n"
+        "    float a[65537];\n"
+        "    return float4(0, 0, 0, 0);\n"
+        "}",
+
+        "float4 test(float2 pos: TEXCOORD0) : SV_TARGET\n"
+        "{\n"
+        "    int x;\n"
+        "    float a[(x = 2)];\n"
+        "    return float4(0, 0, 0, 0);\n"
+        "}",
     };
 
     static const char *targets[] = {"ps_2_0", "ps_3_0", "ps_4_0"};
@@ -776,5 +834,6 @@ START_TEST(hlsl_d3d9)
     test_trig();
     test_comma();
     test_return();
+    test_array_dimensions();
     test_fail();
 }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 5eaff1730b..fe2d23b623 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1652,7 +1652,7 @@ void init_functions_tree(struct wine_rb_tree *funcs)
     wine_rb_init(&hlsl_ctx.functions, compare_function_rb);
 }
 
-static const char *debug_base_type(const struct hlsl_type *type)
+const char *debug_base_type(const struct hlsl_type *type)
 {
     const char *name = "(unknown)";
 
@@ -1744,7 +1744,7 @@ const char *debug_modifiers(DWORD modifiers)
     return wine_dbg_sprintf("%s", string[0] ? string + 1 : "");
 }
 
-static const char *debug_node_type(enum hlsl_ir_node_type type)
+const char *debug_node_type(enum hlsl_ir_node_type type)
 {
     static const char * const names[] =
     {




More information about the wine-cvs mailing list