Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index 24829235a5b..edff59b6337 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -900,6 +900,54 @@ static void test_struct_assignment(void) release_test_context(&test_context); }
+static void test_struct_semantics(void) +{ + struct test_context test_context; + ID3D10Blob *ps_code = NULL; + struct vec4 v; + + static const char ps_source[] = + "struct input\n" + "{\n" + " struct\n" + " {\n" + " float4 texcoord : TEXCOORD0;\n" + " } m;\n" + "};\n" + "struct output\n" + "{\n" + " struct\n" + " {\n" + " float4 color : COLOR;\n" + " } m;\n" + "};\n" + "struct output main(struct input i)\n" + "{\n" + " struct output o;\n" + " o.m.color = i.m.texcoord;\n" + " return o;\n" + "}"; + + if (!init_test_context(&test_context)) + return; + + todo_wine ps_code = compile_shader(ps_source, "ps_2_0"); + if (ps_code) + { + draw_quad(test_context.device, ps_code); + + v = get_color_vec4(test_context.device, 64, 48); + todo_wine ok(compare_vec4(&v, 0.1f, 0.1f, 0.0f, 0.0f, 4096), + "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w); + v = get_color_vec4(test_context.device, 320, 240); + todo_wine ok(compare_vec4(&v, 0.5f, 0.5f, 0.0f, 0.0f, 4096), + "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 check_constant_desc(const char *prefix, const D3DXCONSTANT_DESC *desc, const D3DXCONSTANT_DESC *expect, BOOL nonzero_defaultvalue) { @@ -1208,6 +1256,7 @@ START_TEST(hlsl_d3d9) test_array_dimensions(); test_majority(); test_struct_assignment(); + test_struct_semantics();
test_constant_table(); test_fail();
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index edff59b6337..d82a0b015af 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -968,7 +968,7 @@ static void test_constant_table(void) { static const char *source = "typedef float3x3 matrix_t;\n" - "struct matrix_record { float3x3 a; };\n" + "struct matrix_record { float3x3 a; } dummy;\n" "uniform float4 a;\n" "uniform float b;\n" "uniform float unused;\n" @@ -1193,6 +1193,12 @@ static void test_fail(void) " o = float4(1, 1, 1, 1);\n" " return float4(0, 0, 0, 0);\n" "}", + + "struct {float4 a;};\n" + "float4 test() : SV_TARGET\n" + "{\n" + " return float4(0, 0, 0, 0);\n" + "}", };
static const char *targets[] = {"ps_2_0", "ps_3_0", "ps_4_0"};
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index d82a0b015af..83f5b7bdd56 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -948,6 +948,48 @@ static void test_struct_semantics(void) release_test_context(&test_context); }
+static void test_global_initializer(void) +{ + struct test_context test_context; + ID3DXConstantTable *constants; + ID3D10Blob *ps_code = NULL; + struct vec4 v; + HRESULT hr; + + static const char ps_source[] = + "float myfunc()\n" + "{\n" + " return 0.6;\n" + "}\n" + "static float sf = myfunc() + 0.2;\n" + "uniform float uf = 0.2;\n" + "float4 main() : COLOR\n" + "{\n" + " return float4(sf, uf, 0, 0);\n" + "}"; + + if (!init_test_context(&test_context)) + return; + + todo_wine ps_code = compile_shader(ps_source, "ps_2_0"); + if (ps_code) + { + hr = pD3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(ps_code), &constants); + ok(hr == D3D_OK, "Failed to get constant table, hr %#x.\n", hr); + hr = ID3DXConstantTable_SetDefaults(constants, test_context.device); + ok(hr == D3D_OK, "Failed to get constant table, hr %#x.\n", hr); + ID3DXConstantTable_Release(constants); + draw_quad(test_context.device, ps_code); + + v = get_color_vec4(test_context.device, 0, 0); + todo_wine ok(compare_vec4(&v, 0.8f, 0.2f, 0.0f, 0.0f, 4096), + "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 check_constant_desc(const char *prefix, const D3DXCONSTANT_DESC *desc, const D3DXCONSTANT_DESC *expect, BOOL nonzero_defaultvalue) { @@ -1263,6 +1305,7 @@ START_TEST(hlsl_d3d9) test_majority(); test_struct_assignment(); test_struct_semantics(); + test_global_initializer();
test_constant_table(); test_fail();
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/hlsl.y | 58 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 31 deletions(-)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 28d4dd7f2c3..393f8d52fbd 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -508,8 +508,8 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha return NULL; }
-static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, - const struct source_location loc) +static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, const struct source_location loc, + const char *semantic, unsigned int modifiers, const struct reg_reservation *reg_reservation) { struct hlsl_ir_var *var;
@@ -519,10 +519,22 @@ static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type return NULL; }
- var->name = strdup(name); + var->name = name; var->data_type = type; var->loc = loc; - list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry); + var->semantic = semantic; + var->modifiers = modifiers; + var->reg_reservation = reg_reservation; + return var; +} + +static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, + const struct source_location loc) +{ + struct hlsl_ir_var *var = new_var(strdup(name), type, loc, NULL, 0, NULL); + + if (var) + list_add_tail(&hlsl_ctx.globals->vars, &var->scope_entry); return var; }
@@ -785,23 +797,16 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) { - var = d3dcompiler_alloc(sizeof(*var)); - if (!var) - { - ERR("Out of memory.\n"); - free_parse_variable_def(v); - continue; - } if (v->array_size) type = new_array_type(basic_type, v->array_size); else type = basic_type; - var->data_type = type; - var->loc = v->loc; - var->name = v->name; - var->modifiers = modifiers; - var->semantic = v->semantic; - var->reg_reservation = v->reg_reservation; + + if (!(var = new_var(v->name, type, v->loc, v->semantic, modifiers, v->reg_reservation))) + { + free_parse_variable_def(v); + continue; + } debug_dump_decl(type, modifiers, v->name, v->loc.line);
if (hlsl_ctx.cur_scope == hlsl_ctx.globals) @@ -1081,29 +1086,20 @@ static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis
static BOOL add_func_parameter(struct list *list, struct parse_parameter *param, const struct source_location loc) { - struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl)); + struct hlsl_ir_var *var;
if (param->type->type == HLSL_CLASS_MATRIX) assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
- if (!decl) - { - ERR("Out of memory.\n"); + if (!(var = new_var(param->name, param->type, loc, param->semantic, param->modifiers, param->reg_reservation))) return FALSE; - } - decl->data_type = param->type; - decl->loc = loc; - decl->name = param->name; - decl->semantic = param->semantic; - decl->reg_reservation = param->reg_reservation; - decl->modifiers = param->modifiers;
- if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE)) + if (!add_declaration(hlsl_ctx.cur_scope, var, FALSE)) { - free_declaration(decl); + free_declaration(var); return FALSE; } - list_add_tail(list, &decl->param_entry); + list_add_tail(list, &var->param_entry); return TRUE; }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Formatting, fix ok() messages.
dlls/d3dx10_43/tests/d3dx10.c | 167 ++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index cd61d766e8e6..12ec0f4df750 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -22,6 +22,117 @@ #include "d3dx10.h" #include "wine/test.h"
+ +/* 1x1 8bpp bmp image */ +static const BYTE test_bmp_8bpp[] = +{ + 0x42, 0x4d, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf1, 0xf2, 0xf3, 0x80, 0xf4, 0xf5, 0xf6, 0x81, 0x00, 0x00, + 0x00, 0x00 +}; + +/* 2x2 32bpp XRGB bmp image */ +static const BYTE test_bmp_32bpp_xrgb[] = +{ + 0x42, 0x4d, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb0, 0xc0, 0x00, 0xa1, 0xb1, 0xc1, 0x00, 0xa2, 0xb2, + 0xc2, 0x00, 0xa3, 0xb3, 0xc3, 0x00 +}; + +/* 2x2 32bpp ARGB bmp image */ +static const BYTE test_bmp_32bpp_argb[] = +{ + 0x42, 0x4d, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb0, 0xc0, 0x00, 0xa1, 0xb1, 0xc1, 0x00, 0xa2, 0xb2, + 0xc2, 0x00, 0xa3, 0xb3, 0xc3, 0x01 +}; + +/* png image */ +static const BYTE test_png_grayscale[] = +{ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x7e, 0x9b, + 0x55, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0x0f, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x1b, 0xb6, 0xee, 0x56, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, + 0x42, 0x60, 0x82 +}; + +/* 4x2 DXT5 dds image */ +static const BYTE test_dds_dxt5[] = +{ + 0x44, 0x44, 0x53, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x44, 0x58, 0x54, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x87, 0x0f, 0x78, 0x05, 0x05, 0x50, 0x50 +}; + +/* 4x4 DXT1 cube map */ +static const BYTE test_dds_cube[] = +{ + 0x44, 0x44, 0x53, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x07, 0x10, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x44, 0x58, 0x54, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x40, 0x00, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, + 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, + 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, + 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0x32, 0x96, 0x0b, 0x7b, 0xcc, 0x55, 0xcc, 0x55, 0x0e, 0x84, 0x0e, 0x84, 0x00, 0x00, 0x00, 0x00 +}; + +static const struct test_image +{ + const BYTE *data; + unsigned int size; + D3DX10_IMAGE_INFO expected; +} +test_image[] = +{ + { + test_bmp_8bpp, sizeof(test_bmp_8bpp), + {1, 1, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_BMP} + }, + { + test_bmp_32bpp_xrgb, sizeof(test_bmp_32bpp_xrgb), + {2, 2, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_BMP} + }, + { + test_bmp_32bpp_argb, sizeof(test_bmp_32bpp_argb), + {2, 2, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_BMP} + }, + { + test_png_grayscale, sizeof(test_png_grayscale), + {1, 1, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_PNG} + }, + { + test_dds_dxt5, sizeof(test_dds_dxt5), + {4, 2, 1, 1, 1, 0, DXGI_FORMAT_BC3_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS} + }, + { + test_dds_cube, sizeof(test_dds_cube), + {4, 4, 1, 6, 3, 0x4, DXGI_FORMAT_BC1_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS} + }, +}; + static BOOL compare_float(float f, float g, unsigned int ulps) { int x = *(int *)&f; @@ -786,10 +897,66 @@ static void test_D3DX10CreateAsyncResourceLoader(void) ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); }
+static void test_get_image_info(void) +{ + D3DX10_IMAGE_INFO image_info; + unsigned int i; + DWORD dword; + HRESULT hr; + + todo_wine { + hr = D3DX10GetImageInfoFromMemory(test_image[0].data, 0, NULL, &image_info, NULL); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + hr = D3DX10GetImageInfoFromMemory(NULL, test_image[0].size, NULL, &image_info, NULL); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + hr = D3DX10GetImageInfoFromMemory(&dword, sizeof(dword), NULL, &image_info, NULL); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + } + + for (i = 0; i < ARRAY_SIZE(test_image); ++i) + { + hr = D3DX10GetImageInfoFromMemory(test_image[i].data, test_image[i].size, NULL, &image_info, NULL); + todo_wine ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr); + if (hr != S_OK) + continue; + + todo_wine { + ok(image_info.Width == test_image[i].expected.Width, + "Test %u: Got unexpected Width %u, expected %u.\n", + i, image_info.Width, test_image[i].expected.Width); + ok(image_info.Height == test_image[i].expected.Height, + "Test %u: Got unexpected Height %u, expected %u.\n", + i, image_info.Height, test_image[i].expected.Height); + ok(image_info.Depth == test_image[i].expected.Depth, + "Test %u: Got unexpected Depth %u, expected %u.\n", + i, image_info.Depth, test_image[i].expected.Depth); + ok(image_info.ArraySize == test_image[i].expected.ArraySize, + "Test %u: Got unexpected ArraySize %u, expected %u.\n", + i, image_info.ArraySize, test_image[i].expected.ArraySize); + ok(image_info.MipLevels == test_image[i].expected.MipLevels, + "Test %u: Got unexpected MipLevels %u, expected %u.\n", + i, image_info.MipLevels, test_image[i].expected.MipLevels); + ok(image_info.MiscFlags == test_image[i].expected.MiscFlags, + "Test %u: Got unexpected MiscFlags %#x, expected %#x.\n", + i, image_info.MiscFlags, test_image[i].expected.MiscFlags); + ok(image_info.Format == test_image[i].expected.Format, + "Test %u: Got unexpected Format %#x, expected %#x.\n", + i, image_info.Format, test_image[i].expected.Format); + ok(image_info.ResourceDimension == test_image[i].expected.ResourceDimension, + "Test %u: Got unexpected ResourceDimension %u, expected %u.\n", + i, image_info.ResourceDimension, test_image[i].expected.ResourceDimension); + ok(image_info.ImageFileFormat == test_image[i].expected.ImageFileFormat, + "Test %u: Got unexpected ImageFileFormat %u, expected %u.\n", + i, image_info.ImageFileFormat, test_image[i].expected.ImageFileFormat); + } + } +} + START_TEST(d3dx10) { test_D3DX10UnsetAllDeviceObjects(); test_D3DX10CreateAsyncMemoryLoader(); test_D3DX10CreateAsyncFileLoader(); test_D3DX10CreateAsyncResourceLoader(); + test_get_image_info(); }
From: Gijs Vermeulen gijsvrm@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48779 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Style, formatting.
dlls/d3dx9_36/skin.c | 29 +++++++++++++++-- dlls/d3dx9_36/tests/mesh.c | 64 +++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx9_36/skin.c b/dlls/d3dx9_36/skin.c index 2c10260e2ab1..040c1e083e26 100644 --- a/dlls/d3dx9_36/skin.c +++ b/dlls/d3dx9_36/skin.c @@ -298,9 +298,34 @@ static D3DXMATRIX * WINAPI d3dx9_skin_info_GetBoneOffsetMatrix(ID3DXSkinInfo *if
static HRESULT WINAPI d3dx9_skin_info_Clone(ID3DXSkinInfo *iface, ID3DXSkinInfo **skin_info) { - FIXME("iface %p, skin_info %p stub!\n", iface, skin_info); + struct d3dx9_skin_info *skin = impl_from_ID3DXSkinInfo(iface); + unsigned int i; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, skin_info %p.\n", iface, skin_info); + + if (FAILED(hr = D3DXCreateSkinInfo(skin->num_vertices, skin->vertex_declaration, skin->num_bones, skin_info))) + return hr; + + for (i = 0; i < skin->num_bones; ++i) + { + struct bone *current_bone = &skin->bones[i]; + + if (current_bone->name && FAILED(hr = (*skin_info)->lpVtbl->SetBoneName(*skin_info, i, current_bone->name))) + break; + if (¤t_bone->transform + && FAILED(hr = (*skin_info)->lpVtbl->SetBoneOffsetMatrix(*skin_info, i, ¤t_bone->transform))) + break; + if (current_bone->vertices && current_bone->weights + && FAILED(hr = (*skin_info)->lpVtbl->SetBoneInfluence(*skin_info, i, current_bone->num_influences, + current_bone->vertices, current_bone->weights))) + break; + } + + if (FAILED(hr)) + (*skin_info)->lpVtbl->Release(*skin_info); + + return hr; }
static HRESULT WINAPI d3dx9_skin_info_Remap(ID3DXSkinInfo *iface, DWORD num_vertices, DWORD *vertex_remap) diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 81f902291dea..c357200656b0 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -4966,14 +4966,20 @@ cleanup:
static void test_create_skin_info(void) { - HRESULT hr; - ID3DXSkinInfo *skininfo = NULL; D3DVERTEXELEMENT9 empty_declaration[] = { D3DDECL_END() }; D3DVERTEXELEMENT9 declaration_out[MAX_FVF_DECL_SIZE]; const D3DVERTEXELEMENT9 declaration_with_nonzero_stream[] = { {1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END() }; + D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE]; + DWORD exp_vertices[2], vertices[2]; + float exp_weights[2], weights[2]; + const char *exp_string, *string; + ID3DXSkinInfo *skininfo = NULL; + DWORD exp_fvf, fvf; + unsigned int i; + HRESULT hr;
hr = D3DXCreateSkinInfo(0, empty_declaration, 0, &skininfo); ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); @@ -4990,6 +4996,7 @@ static void test_create_skin_info(void) ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); if (skininfo) { + ID3DXSkinInfo *clone = NULL; DWORD dword_result; float flt_result; const char *string_result; @@ -5023,6 +5030,10 @@ static void test_create_skin_info(void) transform = skininfo->lpVtbl->GetBoneOffsetMatrix(skininfo, -1); ok(transform == NULL, "Expected NULL, got %p\n", transform);
+ hr = skininfo->lpVtbl->Clone(skininfo, &clone); + ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); + IUnknown_Release(clone); + { /* test [GS]etBoneOffsetMatrix */ hr = skininfo->lpVtbl->SetBoneOffsetMatrix(skininfo, 1, &identity_matrix); @@ -5066,12 +5077,7 @@ static void test_create_skin_info(void)
{ /* test [GS]etBoneInfluence */ - DWORD vertices[2]; - FLOAT weights[2]; - int i; DWORD num_influences; - DWORD exp_vertices[2]; - FLOAT exp_weights[2];
/* vertex and weight arrays untouched when num_influences is 0 */ vertices[0] = 0xdeadbeef; @@ -5139,14 +5145,17 @@ static void test_create_skin_info(void) ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); ok(vertices[0] == 0xdeadbeef, "expected vertex 0xdeadbeef, got %u\n", vertices[0]); ok(weights[0] == FLT_MAX, "expected weight %g, got %g\n", FLT_MAX, weights[0]); + + hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, num_influences, exp_vertices, exp_weights); + ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); }
{ /* test [GS]etFVF and [GS]etDeclaration */ D3DVERTEXELEMENT9 declaration_in[MAX_FVF_DECL_SIZE]; - DWORD fvf = D3DFVF_XYZ; DWORD got_fvf;
+ fvf = D3DFVF_XYZ; hr = skininfo->lpVtbl->SetDeclaration(skininfo, NULL); ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
@@ -5182,6 +5191,45 @@ static void test_create_skin_info(void) ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr); compare_elements(declaration_out, declaration_in, __LINE__, 0); } + + /* Test Clone() */ + hr = skininfo->lpVtbl->Clone(skininfo, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + clone = NULL; + hr = skininfo->lpVtbl->Clone(skininfo, &clone); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = clone->lpVtbl->GetDeclaration(clone, declaration); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + compare_elements(declaration, declaration_out, __LINE__, 0); + + hr = D3DXFVFFromDeclarator(declaration_out, &exp_fvf); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + fvf = clone->lpVtbl->GetFVF(clone); + ok(fvf == exp_fvf, "Got unexpected fvf %#x.\n", fvf); + + exp_string = skininfo->lpVtbl->GetBoneName(skininfo, 0); + string = clone->lpVtbl->GetBoneName(clone, 0); + ok(!strcmp(string, exp_string), "Got unexpected bone 0 name %s.\n", debugstr_a(string)); + + transform = clone->lpVtbl->GetBoneOffsetMatrix(clone, 0); + check_matrix(transform, &identity_matrix); + + hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, exp_vertices, exp_weights); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = clone->lpVtbl->GetBoneInfluence(clone, 0, vertices, weights); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(vertices); ++i) + { + ok(vertices[i] == exp_vertices[i], "influence[%u]: got unexpected vertex %u, expected %u.\n", + i, vertices[i], exp_vertices[i]); + ok(((DWORD *)weights)[i] == ((DWORD *)exp_weights)[i], + "influence[%u]: got unexpected weight %.8e, expected %.8e.\n", i, weights[i], exp_weights[i]); + } + + IUnknown_Release(clone); } if (skininfo) IUnknown_Release(skininfo); skininfo = NULL;
This is necessary so that global variable initializers can work correctly (both static and extern).
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/d3dcompiler_private.h | 1 + dlls/d3dcompiler_43/hlsl.y | 155 ++++++++++++---------- dlls/d3dcompiler_43/utils.c | 4 + 3 files changed, 93 insertions(+), 67 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 9feaee0d8ac..bc8734f0148 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -706,6 +706,7 @@ struct hlsl_ir_var unsigned int modifiers; const struct reg_reservation *reg_reservation; struct list scope_entry, param_entry; + struct list initializer;
unsigned int first_write, last_read; }; diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 393f8d52fbd..734289f66a5 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -525,6 +525,7 @@ static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, con var->semantic = semantic; var->modifiers = modifiers; var->reg_reservation = reg_reservation; + list_init(&var->initializer); return var; }
@@ -770,30 +771,18 @@ static void free_parse_variable_def(struct parse_variable_def *v) d3dcompiler_free(v); }
-static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) +static BOOL declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) { struct hlsl_type *type; struct parse_variable_def *v, *v_next; struct hlsl_ir_var *var; - struct hlsl_ir_node *assignment; BOOL ret, local = TRUE; - struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
if (basic_type->type == HLSL_CLASS_MATRIX) assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
- if (!statements_list) - { - ERR("Out of memory.\n"); - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - free_parse_variable_def(v); - d3dcompiler_free(var_list); - return NULL; - } - list_init(statements_list); - if (!var_list) - return statements_list; + return TRUE;
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) { @@ -808,6 +797,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; } debug_dump_decl(type, modifiers, v->name, v->loc.line); + list_init(&var->initializer);
if (hlsl_ctx.cur_scope == hlsl_ctx.globals) { @@ -835,7 +825,6 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, if (v->initializer.args_count) { unsigned int size = initializer_size(&v->initializer); - struct hlsl_ir_load *load;
TRACE("Variable with initializer.\n"); if (type->type <= HLSL_CLASS_LAST_NUMERIC @@ -862,7 +851,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
if (type->type == HLSL_CLASS_STRUCT) { - struct_var_initializer(statements_list, var, &v->initializer); + struct_var_initializer(&var->initializer, var, &v->initializer); d3dcompiler_free(v); continue; } @@ -888,19 +877,16 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; }
- list_move_tail(statements_list, v->initializer.instrs); + list_move_tail(&var->initializer, v->initializer.instrs); d3dcompiler_free(v->initializer.instrs); - - load = new_var_load(var, var->loc); - list_add_tail(statements_list, &load->node.entry); - assignment = make_assignment(&load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); d3dcompiler_free(v->initializer.args); - list_add_tail(statements_list, &assignment->entry); + + implicit_conversion(node_from_list(&var->initializer), var->data_type, &var->loc); } d3dcompiler_free(v); } d3dcompiler_free(var_list); - return statements_list; + return TRUE; }
static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field) @@ -1282,6 +1268,20 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type return decl; }
+/* Append an instruction assigning "var" to its own initializer. */ +static BOOL add_assignment_to_initializer(struct hlsl_ir_var *var) +{ + struct hlsl_ir_assignment *assign; + + if (!list_empty(&var->initializer)) + { + if (!(assign = make_simple_assignment(var, node_from_list(&var->initializer)))) + return FALSE; + list_add_tail(&var->initializer, &assign->node.entry); + } + return TRUE; +} + %}
%locations @@ -1416,9 +1416,6 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type %type <boolval> boolean %type <type> base_type %type <type> type -%type <list> declaration_statement -%type <list> declaration -%type <list> struct_declaration %type <type> struct_spec %type <type> named_struct_spec %type <type> unnamed_struct_spec @@ -1566,7 +1563,8 @@ struct_declaration: var_modifiers struct_spec variables_def_optional ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT; - $$ = declare_vars(type, modifiers, $3); + if (!declare_vars(type, modifiers, $3)) + YYABORT; }
struct_spec: named_struct_spec @@ -1908,18 +1906,11 @@ base_type: d3dcompiler_free($2); }
-declaration_statement: declaration - | struct_declaration - | typedef - { - $$ = d3dcompiler_alloc(sizeof(*$$)); - if (!$$) - { - ERR("Out of memory\n"); - YYABORT; - } - list_init($$); - } +declaration_statement: + + declaration + | struct_declaration + | typedef
typedef_type: type | struct_spec @@ -1967,7 +1958,8 @@ declaration: var_modifiers type variables_def ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT; - $$ = declare_vars(type, modifiers, $3); + if (!declare_vars(type, modifiers, $3)) + YYABORT; }
variables_def_optional: /* Empty */ @@ -2148,12 +2140,29 @@ statement_list: statement d3dcompiler_free($2); }
-statement: declaration_statement - | expr_statement - | compound_statement - | jump_statement - | selection_statement - | loop_statement +statement: + + declaration_statement + { + struct hlsl_ir_var *var; + + /* Append any initializers made by this declaration_statement to the + * instruction list. */ + if (!($$ = d3dcompiler_alloc(sizeof(*$$)))) + YYABORT; + list_init($$); + LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry) + { + if (!add_assignment_to_initializer(var)) + YYABORT; + list_move_tail($$, &var->initializer); + } + } + | expr_statement + | compound_statement + | jump_statement + | selection_statement + | loop_statement
jump_statement: KW_RETURN expr ';' { @@ -2206,27 +2215,39 @@ if_body: statement $$.else_instrs = $3; }
-loop_statement: KW_WHILE '(' expr ')' statement - { - $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1)); - } - | KW_DO statement KW_WHILE '(' expr ')' ';' - { - $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1)); - } - | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement - { - $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1)); - pop_scope(&hlsl_ctx); - } - | KW_FOR '(' scope_start declaration expr_statement expr ')' statement - { - if (!$4) - hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING, - "no expressions in for loop initializer"); - $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1)); - pop_scope(&hlsl_ctx); - } +loop_statement: + + KW_WHILE '(' expr ')' statement + { + $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1)); + } + | KW_DO statement KW_WHILE '(' expr ')' ';' + { + $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1)); + } + | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement + { + $$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1)); + pop_scope(&hlsl_ctx); + } + | KW_FOR '(' scope_start declaration expr_statement expr ')' statement + { + struct hlsl_ir_var *var; + + $$ = create_loop(LOOP_FOR, NULL, $5, $6, $8, get_location(&@1)); + + /* Prepend any initializers made by this declaration to the + * instruction list. Walk through the list in reverse, so that the + * initializers are executed in the order that they were declared. */ + LIST_FOR_EACH_ENTRY_REV(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry) + { + if (!add_assignment_to_initializer(var)) + YYABORT; + list_move_head($$, &var->initializer); + } + + pop_scope(&hlsl_ctx); + }
expr_statement: ';' { diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index 4769ebc399b..e17b830d916 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -798,6 +798,10 @@ struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name)
void free_declaration(struct hlsl_ir_var *decl) { + struct hlsl_ir_node *instr, *next; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &decl->initializer, struct hlsl_ir_node, entry) + free_instr(instr); d3dcompiler_free((void *)decl->name); d3dcompiler_free((void *)decl->semantic); d3dcompiler_free((void *)decl->reg_reservation);
On Thu, Jun 11, 2020 at 11:45 PM Zebediah Figura z.figura12@gmail.com wrote:
This is necessary so that global variable initializers can work correctly (both static and extern).
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/d3dcompiler_43/d3dcompiler_private.h | 1 + dlls/d3dcompiler_43/hlsl.y | 155 ++++++++++++---------- dlls/d3dcompiler_43/utils.c | 4 + 3 files changed, 93 insertions(+), 67 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 9feaee0d8ac..bc8734f0148 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -706,6 +706,7 @@ struct hlsl_ir_var unsigned int modifiers; const struct reg_reservation *reg_reservation; struct list scope_entry, param_entry;
struct list initializer;
unsigned int first_write, last_read;
}; diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 393f8d52fbd..734289f66a5 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -525,6 +525,7 @@ static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, con var->semantic = semantic; var->modifiers = modifiers; var->reg_reservation = reg_reservation;
- list_init(&var->initializer); return var;
}
@@ -770,30 +771,18 @@ static void free_parse_variable_def(struct parse_variable_def *v) d3dcompiler_free(v); }
-static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) +static BOOL declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) { struct hlsl_type *type; struct parse_variable_def *v, *v_next; struct hlsl_ir_var *var;
struct hlsl_ir_node *assignment; BOOL ret, local = TRUE;
struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
if (basic_type->type == HLSL_CLASS_MATRIX) assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
if (!statements_list)
{
ERR("Out of memory.\n");
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
free_parse_variable_def(v);
d3dcompiler_free(var_list);
return NULL;
}
list_init(statements_list);
if (!var_list)
return statements_list;
return TRUE;
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) {
@@ -808,6 +797,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; } debug_dump_decl(type, modifiers, v->name, v->loc.line);
list_init(&var->initializer); if (hlsl_ctx.cur_scope == hlsl_ctx.globals) {
@@ -835,7 +825,6 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, if (v->initializer.args_count) { unsigned int size = initializer_size(&v->initializer);
struct hlsl_ir_load *load; TRACE("Variable with initializer.\n"); if (type->type <= HLSL_CLASS_LAST_NUMERIC
@@ -862,7 +851,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
if (type->type == HLSL_CLASS_STRUCT) {
struct_var_initializer(statements_list, var, &v->initializer);
struct_var_initializer(&var->initializer, var, &v->initializer); d3dcompiler_free(v); continue; }
@@ -888,19 +877,16 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; }
list_move_tail(statements_list, v->initializer.instrs);
list_move_tail(&var->initializer, v->initializer.instrs); d3dcompiler_free(v->initializer.instrs);
load = new_var_load(var, var->loc);
list_add_tail(statements_list, &load->node.entry);
assignment = make_assignment(&load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); d3dcompiler_free(v->initializer.args);
list_add_tail(statements_list, &assignment->entry);
} d3dcompiler_free(var_list);implicit_conversion(node_from_list(&var->initializer), var->data_type, &var->loc); } d3dcompiler_free(v);
- return statements_list;
- return TRUE;
}
static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field) @@ -1282,6 +1268,20 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type return decl; }
+/* Append an instruction assigning "var" to its own initializer. */ +static BOOL add_assignment_to_initializer(struct hlsl_ir_var *var) +{
- struct hlsl_ir_assignment *assign;
- if (!list_empty(&var->initializer))
- {
if (!(assign = make_simple_assignment(var, node_from_list(&var->initializer))))
return FALSE;
list_add_tail(&var->initializer, &assign->node.entry);
- }
- return TRUE;
+}
%}
%locations @@ -1416,9 +1416,6 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type %type <boolval> boolean %type <type> base_type %type <type> type -%type <list> declaration_statement -%type <list> declaration -%type <list> struct_declaration %type <type> struct_spec %type <type> named_struct_spec %type <type> unnamed_struct_spec @@ -1566,7 +1563,8 @@ struct_declaration: var_modifiers struct_spec variables_def_optional ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT;
$$ = declare_vars(type, modifiers, $3);
if (!declare_vars(type, modifiers, $3))
YYABORT; }
struct_spec: named_struct_spec @@ -1908,18 +1906,11 @@ base_type: d3dcompiler_free($2); }
-declaration_statement: declaration
| struct_declaration
| typedef
{
$$ = d3dcompiler_alloc(sizeof(*$$));
if (!$$)
{
ERR("Out of memory\n");
YYABORT;
}
list_init($$);
}
+declaration_statement:
declaration
- | struct_declaration
- | typedef
typedef_type: type | struct_spec @@ -1967,7 +1958,8 @@ declaration: var_modifiers type variables_def ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT;
$$ = declare_vars(type, modifiers, $3);
if (!declare_vars(type, modifiers, $3))
YYABORT; }
variables_def_optional: /* Empty */ @@ -2148,12 +2140,29 @@ statement_list: statement d3dcompiler_free($2); }
-statement: declaration_statement
| expr_statement
| compound_statement
| jump_statement
| selection_statement
| loop_statement
+statement:
declaration_statement
{
struct hlsl_ir_var *var;
/* Append any initializers made by this declaration_statement to the
* instruction list. */
if (!($$ = d3dcompiler_alloc(sizeof(*$$))))
YYABORT;
list_init($$);
LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!add_assignment_to_initializer(var))
YYABORT;
list_move_tail($$, &var->initializer);
}
}
I see what you're doing but I'm a bit bothered by the part where you store the initializers into struct hlsl_ir_var. I don't know that it is a fair "complaint", it's certainly mostly stylistical. But hear my variation and see if it makes any sense to you.
Initializers could be temporarily stored in a special list inside hlsl_ctx. Here in declaration_statement and other places where you process initializers, you list_move_head() from that list to $$ and that's it. Local static initializers should probably be stored into a separate list, together with global initializers (assuming static locals are a thing in HLSL, I don't recall off the top of my head).
- | expr_statement
- | compound_statement
- | jump_statement
- | selection_statement
- | loop_statement
jump_statement: KW_RETURN expr ';' { @@ -2206,27 +2215,39 @@ if_body: statement $$.else_instrs = $3; }
-loop_statement: KW_WHILE '(' expr ')' statement
{
$$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
}
| KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
}
| KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
{
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
| KW_FOR '(' scope_start declaration expr_statement expr ')' statement
{
if (!$4)
hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING,
"no expressions in for loop initializer");
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
+loop_statement:
KW_WHILE '(' expr ')' statement
{
$$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
}
- | KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
}
- | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
{
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
- | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
{
struct hlsl_ir_var *var;
$$ = create_loop(LOOP_FOR, NULL, $5, $6, $8, get_location(&@1));
/* Prepend any initializers made by this declaration to the
* instruction list. Walk through the list in reverse, so that the
* initializers are executed in the order that they were declared. */
LIST_FOR_EACH_ENTRY_REV(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!add_assignment_to_initializer(var))
YYABORT;
list_move_head($$, &var->initializer);
}
If I'm reading this correctly, here the temporary list idea would avoid the need to go in reverse, which might be a bit less surprising overall.
On 6/17/20 10:29 AM, Matteo Bruni wrote:
On Thu, Jun 11, 2020 at 11:45 PM Zebediah Figura z.figura12@gmail.com wrote:
This is necessary so that global variable initializers can work correctly (both static and extern).
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/d3dcompiler_43/d3dcompiler_private.h | 1 + dlls/d3dcompiler_43/hlsl.y | 155 ++++++++++++---------- dlls/d3dcompiler_43/utils.c | 4 + 3 files changed, 93 insertions(+), 67 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 9feaee0d8ac..bc8734f0148 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -706,6 +706,7 @@ struct hlsl_ir_var unsigned int modifiers; const struct reg_reservation *reg_reservation; struct list scope_entry, param_entry;
struct list initializer;
unsigned int first_write, last_read;
}; diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 393f8d52fbd..734289f66a5 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -525,6 +525,7 @@ static struct hlsl_ir_var *new_var(const char *name, struct hlsl_type *type, con var->semantic = semantic; var->modifiers = modifiers; var->reg_reservation = reg_reservation;
- list_init(&var->initializer); return var;
}
@@ -770,30 +771,18 @@ static void free_parse_variable_def(struct parse_variable_def *v) d3dcompiler_free(v); }
-static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) +static BOOL declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list) { struct hlsl_type *type; struct parse_variable_def *v, *v_next; struct hlsl_ir_var *var;
struct hlsl_ir_node *assignment; BOOL ret, local = TRUE;
struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
if (basic_type->type == HLSL_CLASS_MATRIX) assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
if (!statements_list)
{
ERR("Out of memory.\n");
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
free_parse_variable_def(v);
d3dcompiler_free(var_list);
return NULL;
}
list_init(statements_list);
if (!var_list)
return statements_list;
return TRUE;
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) {
@@ -808,6 +797,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; } debug_dump_decl(type, modifiers, v->name, v->loc.line);
list_init(&var->initializer); if (hlsl_ctx.cur_scope == hlsl_ctx.globals) {
@@ -835,7 +825,6 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, if (v->initializer.args_count) { unsigned int size = initializer_size(&v->initializer);
struct hlsl_ir_load *load; TRACE("Variable with initializer.\n"); if (type->type <= HLSL_CLASS_LAST_NUMERIC
@@ -862,7 +851,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
if (type->type == HLSL_CLASS_STRUCT) {
struct_var_initializer(statements_list, var, &v->initializer);
struct_var_initializer(&var->initializer, var, &v->initializer); d3dcompiler_free(v); continue; }
@@ -888,19 +877,16 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, continue; }
list_move_tail(statements_list, v->initializer.instrs);
list_move_tail(&var->initializer, v->initializer.instrs); d3dcompiler_free(v->initializer.instrs);
load = new_var_load(var, var->loc);
list_add_tail(statements_list, &load->node.entry);
assignment = make_assignment(&load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); d3dcompiler_free(v->initializer.args);
list_add_tail(statements_list, &assignment->entry);
} d3dcompiler_free(var_list);implicit_conversion(node_from_list(&var->initializer), var->data_type, &var->loc); } d3dcompiler_free(v);
- return statements_list;
- return TRUE;
}
static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *field) @@ -1282,6 +1268,20 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type return decl; }
+/* Append an instruction assigning "var" to its own initializer. */ +static BOOL add_assignment_to_initializer(struct hlsl_ir_var *var) +{
- struct hlsl_ir_assignment *assign;
- if (!list_empty(&var->initializer))
- {
if (!(assign = make_simple_assignment(var, node_from_list(&var->initializer))))
return FALSE;
list_add_tail(&var->initializer, &assign->node.entry);
- }
- return TRUE;
+}
%}
%locations @@ -1416,9 +1416,6 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type %type <boolval> boolean %type <type> base_type %type <type> type -%type <list> declaration_statement -%type <list> declaration -%type <list> struct_declaration %type <type> struct_spec %type <type> named_struct_spec %type <type> unnamed_struct_spec @@ -1566,7 +1563,8 @@ struct_declaration: var_modifiers struct_spec variables_def_optional ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT;
$$ = declare_vars(type, modifiers, $3);
if (!declare_vars(type, modifiers, $3))
YYABORT; }
struct_spec: named_struct_spec @@ -1908,18 +1906,11 @@ base_type: d3dcompiler_free($2); }
-declaration_statement: declaration
| struct_declaration
| typedef
{
$$ = d3dcompiler_alloc(sizeof(*$$));
if (!$$)
{
ERR("Out of memory\n");
YYABORT;
}
list_init($$);
}
+declaration_statement:
declaration
- | struct_declaration
- | typedef
typedef_type: type | struct_spec @@ -1967,7 +1958,8 @@ declaration: var_modifiers type variables_def ';'
if (!(type = apply_type_modifiers($2, &modifiers, get_location(&@1)))) YYABORT;
$$ = declare_vars(type, modifiers, $3);
if (!declare_vars(type, modifiers, $3))
YYABORT; }
variables_def_optional: /* Empty */ @@ -2148,12 +2140,29 @@ statement_list: statement d3dcompiler_free($2); }
-statement: declaration_statement
| expr_statement
| compound_statement
| jump_statement
| selection_statement
| loop_statement
+statement:
declaration_statement
{
struct hlsl_ir_var *var;
/* Append any initializers made by this declaration_statement to the
* instruction list. */
if (!($$ = d3dcompiler_alloc(sizeof(*$$))))
YYABORT;
list_init($$);
LIST_FOR_EACH_ENTRY(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!add_assignment_to_initializer(var))
YYABORT;
list_move_tail($$, &var->initializer);
}
}
I see what you're doing but I'm a bit bothered by the part where you store the initializers into struct hlsl_ir_var. I don't know that it is a fair "complaint", it's certainly mostly stylistical. But hear my variation and see if it makes any sense to you.
Initializers could be temporarily stored in a special list inside hlsl_ctx. Here in declaration_statement and other places where you process initializers, you list_move_head() from that list to $$ and that's it.
It would work, I think, and I agree it'd be simpler than this patch. The one place this approach gets hairy is with uniform initializers (which translate to default values). We could parse that in declare_vars() and store it as a flat value in hlsl_ir_var without difficulty, but we'd need to be able to run constant folding over it (and maybe other passes? Of course, I don't even have examples of anything that needs uniform initializers.)
Local static initializers should probably be stored into a separate list, together with global initializers (assuming static locals are a thing in HLSL, I don't recall off the top of my head).
Yes, and they act like C static locals, which is to say, like static globals.
- | expr_statement
- | compound_statement
- | jump_statement
- | selection_statement
- | loop_statement
jump_statement: KW_RETURN expr ';' { @@ -2206,27 +2215,39 @@ if_body: statement $$.else_instrs = $3; }
-loop_statement: KW_WHILE '(' expr ')' statement
{
$$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
}
| KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
}
| KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
{
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
| KW_FOR '(' scope_start declaration expr_statement expr ')' statement
{
if (!$4)
hlsl_report_message(get_location(&@4), HLSL_LEVEL_WARNING,
"no expressions in for loop initializer");
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
+loop_statement:
KW_WHILE '(' expr ')' statement
{
$$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, get_location(&@1));
}
- | KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, get_location(&@1));
}
- | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
{
$$ = create_loop(LOOP_FOR, $4, $5, $6, $8, get_location(&@1));
pop_scope(&hlsl_ctx);
}
- | KW_FOR '(' scope_start declaration expr_statement expr ')' statement
{
struct hlsl_ir_var *var;
$$ = create_loop(LOOP_FOR, NULL, $5, $6, $8, get_location(&@1));
/* Prepend any initializers made by this declaration to the
* instruction list. Walk through the list in reverse, so that the
* initializers are executed in the order that they were declared. */
LIST_FOR_EACH_ENTRY_REV(var, &hlsl_ctx.cur_scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!add_assignment_to_initializer(var))
YYABORT;
list_move_head($$, &var->initializer);
}
If I'm reading this correctly, here the temporary list idea would avoid the need to go in reverse, which might be a bit less surprising overall.
On Wed, Jun 17, 2020 at 5:47 PM Zebediah Figura zfigura@codeweavers.com wrote:
On 6/17/20 10:29 AM, Matteo Bruni wrote:
I see what you're doing but I'm a bit bothered by the part where you store the initializers into struct hlsl_ir_var. I don't know that it is a fair "complaint", it's certainly mostly stylistical. But hear my variation and see if it makes any sense to you.
Initializers could be temporarily stored in a special list inside hlsl_ctx. Here in declaration_statement and other places where you process initializers, you list_move_head() from that list to $$ and that's it.
It would work, I think, and I agree it'd be simpler than this patch. The one place this approach gets hairy is with uniform initializers (which translate to default values). We could parse that in declare_vars() and store it as a flat value in hlsl_ir_var without difficulty, but we'd need to be able to run constant folding over it (and maybe other passes? Of course, I don't even have examples of anything that needs uniform initializers.)
Good point on uniform initializers, that's a bit awkward. It seems to me that those are annoying either way, since they probably can refer to arbitrary (constant) expressions and need to be constant folded to compute the default value, but you want to load the uniform in the actual shader. Hopefully they can wait...
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/hlsl.y | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 734289f66a5..c651fb9d7fa 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -3005,6 +3005,21 @@ HRESULT parse_hlsl(enum shader_type type, DWORD major, DWORD minor, "entry point "%s" is missing a return value semantic", entry_func->func->name); }
+ /* Walk through the list in reverse, so that initializers are added in the + * order that they were declared. */ + LIST_FOR_EACH_ENTRY_REV(var, &hlsl_ctx.globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->modifiers & HLSL_STORAGE_STATIC) + { + if (!add_assignment_to_initializer(var)) + { + hlsl_ctx.status = PARSE_ERR; + hr = E_OUTOFMEMORY; + } + list_move_head(entry_func->body, &var->initializer); + } + } + /* Index 0 means unused; index 1 means function entry, so start at 2. */ index_instructions(entry_func->body, 2);