d3dcompiler: Parse array types.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-03-06 17:17:30 -06:00 committed by Alexandre Julliard
parent dbc4ad1722
commit 0e95c3faa2
4 changed files with 122 additions and 4 deletions

View file

@ -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;

View file

@ -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 */

View file

@ -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();
}

View file

@ -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[] =
{