Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- 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 2d8eba0b554..1a155736fd0 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 e46bdbade3f..46d815d0144 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 c673e2be327..525de9910be 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 5eaff1730b3..fe2d23b623e 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[] = {