Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Fix test failure, clean up a bit.
From: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Fix test failure, clean up a bit. --- dlls/d3dx9_36/tests/asm.c | 176 ++++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 75 deletions(-)
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c index bfc84b2f9c2..c8136425882 100644 --- a/dlls/d3dx9_36/tests/asm.c +++ b/dlls/d3dx9_36/tests/asm.c @@ -81,31 +81,46 @@ static void delete_directory(const char *name) RemoveDirectoryA(path); }
+struct test_include +{ + ID3DXInclude ID3DXInclude_iface; + BOOL terminated_data; +}; + +static inline struct test_include *impl_from_ID3DXInclude(ID3DXInclude *iface) +{ + return CONTAINING_RECORD(iface, struct test_include, ID3DXInclude_iface); +} + static HRESULT WINAPI testD3DXInclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type, const char *filename, const void *parent_data, const void **data, UINT *bytes) { - char *buffer; static const char shader[] = "#include "incl.vsh"\n" "mov REGISTER, v0\n"; static const char include[] = "#define REGISTER r0\nvs.1.1\n"; static const char include2[] = "#include "incl3.vsh"\n"; static const char include3[] = "vs.1.1\n"; + struct test_include *test_include = impl_from_ID3DXInclude(iface); + unsigned int size; + char *buffer;
trace("filename %s.\n", filename); - trace("parent_data %p: %s.\n", parent_data, parent_data ? (char *)parent_data : "(null)"); + trace("parent_data %p.\n", parent_data);
if (!strcmp(filename, "shader.vsh")) { - buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(shader)); - memcpy(buffer, shader, sizeof(shader)); - *bytes = sizeof(shader); + size = test_include->terminated_data ? sizeof(shader) : sizeof(shader) - 1; + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(buffer, shader, size); + *bytes = size; } else if (!strcmp(filename, "incl.vsh")) { - buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include)); - memcpy(buffer, include, sizeof(include)); - *bytes = sizeof(include); + size = test_include->terminated_data ? sizeof(include) : sizeof(include) - 1; + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(buffer, include, size); + *bytes = size; /* This is included from the first D3DXAssembleShader with non-null ID3DXInclude test * (parent_data == NULL) and from shader.vsh / shader[] (with matching parent_data). * Allow both cases. */ @@ -113,24 +128,26 @@ static HRESULT WINAPI testD3DXInclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE } else if (!strcmp(filename, "incl2.vsh")) { - buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include2)); - memcpy(buffer, include2, sizeof(include2)); - *bytes = sizeof(include2); + size = test_include->terminated_data ? sizeof(include2) : sizeof(include2) - 1; + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(buffer, include2, size); + *bytes = size; } else if (!strcmp(filename, "incl3.vsh")) { - buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include3)); - memcpy(buffer, include3, sizeof(include3)); - *bytes = sizeof(include3); - /* Also check for the correct parent_data content */ - ok(parent_data != NULL && !strncmp(include2, parent_data, strlen(include2)), "wrong parent_data value\n"); + size = test_include->terminated_data ? sizeof(include3) : sizeof(include3) - 1; + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(buffer, include3, size); + *bytes = size; + ok(parent_data != NULL && !strncmp(include2, parent_data, strlen(include2)), "wrong parent_data value.\n"); } else if (!strcmp(filename, "include/incl3.vsh")) { - buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include)); - memcpy(buffer, include, sizeof(include)); - *bytes = sizeof(include); - ok(!parent_data, "wrong parent_data value\n"); + size = test_include->terminated_data ? sizeof(include) : sizeof(include) - 1; + buffer = HeapAlloc(GetProcessHeap(), 0, size); + memcpy(buffer, include, size); + *bytes = size; + ok(!parent_data, "wrong parent_data value.\n"); } else { @@ -147,15 +164,12 @@ static HRESULT WINAPI testD3DXInclude_close(ID3DXInclude *iface, const void *dat return S_OK; }
-static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = { +static const struct ID3DXIncludeVtbl test_include_vtbl = +{ testD3DXInclude_open, testD3DXInclude_close };
-struct D3DXIncludeImpl { - ID3DXInclude ID3DXInclude_iface; -}; - static void assembleshader_test(void) { static const char test1[] = @@ -180,8 +194,6 @@ static void assembleshader_test(void) "vs.1.1\n"; static const char testincl4_wrong[] = "#error "wrong include"\n"; - HRESULT hr; - ID3DXBuffer *shader, *messages; static const D3DXMACRO defines[] = { { "DEF1", "10 + 15" @@ -193,8 +205,11 @@ static void assembleshader_test(void) NULL, NULL } }; - struct D3DXIncludeImpl include; char shader_vsh_path[MAX_PATH], shader3_vsh_path[MAX_PATH]; + ID3DXBuffer *shader, *messages; + struct test_include include; + unsigned int i; + HRESULT hr;
/* pDefines test */ shader = NULL; @@ -229,56 +244,67 @@ static void assembleshader_test(void) }
/* pInclude test */ - shader = NULL; - messages = NULL; - include.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl; - hr = D3DXAssembleShader(testshader, strlen(testshader), NULL, &include.ID3DXInclude_iface, - D3DXSHADER_SKIPVALIDATION, &shader, &messages); - ok(hr == D3D_OK, "pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); - if(messages) { - trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); - ID3DXBuffer_Release(messages); - } - if(shader) ID3DXBuffer_Release(shader); + for (i = 0; i < 2; ++i) + { + shader = NULL; + messages = NULL; + include.ID3DXInclude_iface.lpVtbl = &test_include_vtbl; + include.terminated_data = i; + winetest_push_context(i ? "terminated include data" : "nonterminated include data"); + hr = D3DXAssembleShader(testshader, strlen(testshader), NULL, &include.ID3DXInclude_iface, + D3DXSHADER_SKIPVALIDATION, &shader, &messages); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + if (messages) + { + trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); + ID3DXBuffer_Release(messages); + } + if (shader) + ID3DXBuffer_Release(shader);
- /* "unexpected #include file from memory" test */ - shader = NULL; - messages = NULL; - hr = D3DXAssembleShader(testshader, strlen(testshader), - NULL, NULL, D3DXSHADER_SKIPVALIDATION, - &shader, &messages); - ok(hr == D3DXERR_INVALIDDATA, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); - if(messages) { - trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); - ID3DXBuffer_Release(messages); - } - if(shader) ID3DXBuffer_Release(shader); + /* "unexpected #include file from memory" test */ + shader = NULL; + messages = NULL; + hr = D3DXAssembleShader(testshader, strlen(testshader), NULL, NULL, D3DXSHADER_SKIPVALIDATION, + &shader, &messages); + ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#x.\n", hr); + if (messages) + { + trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); + ID3DXBuffer_Release(messages); + } + if (shader) + ID3DXBuffer_Release(shader);
- /* recursive #include test */ - shader = NULL; - messages = NULL; - hr = D3DXAssembleShader(testshader2, strlen(testshader2), NULL, &include.ID3DXInclude_iface, - D3DXSHADER_SKIPVALIDATION, &shader, &messages); - todo_wine ok(hr == D3D_OK, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF); - if(messages) { - trace("recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); - ID3DXBuffer_Release(messages); - } - if(shader) ID3DXBuffer_Release(shader); + /* recursive #include test */ + shader = NULL; + messages = NULL; + hr = D3DXAssembleShader(testshader2, strlen(testshader2), NULL, &include.ID3DXInclude_iface, + D3DXSHADER_SKIPVALIDATION, &shader, &messages); + todo_wine_if(i) ok(hr == (i ? D3D_OK : D3DXERR_INVALIDDATA), "Unexpected hr %#x.\n", hr); + if (messages) + { + trace("Recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); + ID3DXBuffer_Release(messages); + } + if (shader) + ID3DXBuffer_Release(shader);
- /* #include with a path. */ - shader = NULL; - messages = NULL; - hr = D3DXAssembleShader(testshader3, strlen(testshader3), NULL, &include.ID3DXInclude_iface, - D3DXSHADER_SKIPVALIDATION, &shader, &messages); - ok(hr == D3D_OK, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000ffff); - if (messages) - { - trace("Path search D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); - ID3DXBuffer_Release(messages); + /* #include with a path. */ + shader = NULL; + messages = NULL; + hr = D3DXAssembleShader(testshader3, strlen(testshader3), NULL, &include.ID3DXInclude_iface, + D3DXSHADER_SKIPVALIDATION, &shader, &messages); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + if (messages) + { + trace("Path search D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages)); + ID3DXBuffer_Release(messages); + } + if (shader) + ID3DXBuffer_Release(shader); + winetest_pop_context(); } - if (shader) - ID3DXBuffer_Release(shader);
if (create_file("shader.vsh", testshader, sizeof(testshader) - 1, shader_vsh_path)) { @@ -443,7 +469,7 @@ static void d3dxpreprocess_test(void) HRESULT hr; ID3DXBuffer *shader, *messages; char shader_vsh_path[MAX_PATH], shader3_vsh_path[MAX_PATH]; - static struct D3DXIncludeImpl include = {{&D3DXInclude_Vtbl}}; + static struct test_include include = {{&test_include_vtbl}, TRUE};
if (create_file("shader.vsh", testshader, sizeof(testshader) - 1, shader_vsh_path)) {
From: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dcompiler_43/asmshader.l | 2 +- dlls/d3dcompiler_43/asmshader.y | 43 ++++++++++++++++++++++++++------- dlls/d3dcompiler_43/tests/asm.c | 28 +++++++++++++++------ 3 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/dlls/d3dcompiler_43/asmshader.l b/dlls/d3dcompiler_43/asmshader.l index 63ecddd1899..81718556787 100644 --- a/dlls/d3dcompiler_43/asmshader.l +++ b/dlls/d3dcompiler_43/asmshader.l @@ -96,7 +96,7 @@ NEWLINE (\n)|(\r\n)
COMMA ","
-IMMVAL -?(([0-9]+.?)|([0-9]*.[0-9]+))(f)? +IMMVAL (([0-9]+.?)|([0-9]*.[0-9]+))(f)?
ANY (.)
diff --git a/dlls/d3dcompiler_43/asmshader.y b/dlls/d3dcompiler_43/asmshader.y index 00c98b1dbc3..cdc75c18a3e 100644 --- a/dlls/d3dcompiler_43/asmshader.y +++ b/dlls/d3dcompiler_43/asmshader.y @@ -304,6 +304,8 @@ int asmshader_lex(void); %type <rel_reg> rel_reg %type <reg> predicate %type <immval> immsum +%type <immval> signed_integer +%type <immval> signed_float %type <sregs> sregs
%% @@ -713,11 +715,11 @@ instruction: INSTR_ADD omods dreg ',' sregs asm_ctx.line_no); set_parse_status(&asm_ctx.status, PARSE_WARN); } - | INSTR_DEF REG_CONSTFLOAT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL + | INSTR_DEF REG_CONSTFLOAT ',' signed_float ',' signed_float ',' signed_float ',' signed_float { asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val); } - | INSTR_DEFI REG_CONSTINT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL + | INSTR_DEFI REG_CONSTINT ',' signed_integer ',' signed_integer ',' signed_integer ',' signed_integer { asm_ctx.funcs->constI(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val); } @@ -1387,23 +1389,46 @@ rel_reg: /* empty */ $$.swizzle = $5; }
-immsum: IMMVAL +immsum: signed_integer + | immsum '+' signed_integer { - if(!$1.integer) { + $$.val = $1.val + $3.val; + } + | immsum '-' signed_integer + { + $$.val = $1.val - $3.val; + } + +signed_integer: + IMMVAL + { + if (!$1.integer) + { asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n", - asm_ctx.line_no, $1.val); + asm_ctx.line_no, $1.val); set_parse_status(&asm_ctx.status, PARSE_ERR); } $$.val = $1.val; } - | immsum '+' IMMVAL + | '-' IMMVAL { - if(!$3.integer) { + if (!$2.integer) + { asmparser_message(&asm_ctx, "Line %u: Unexpected float %f\n", - asm_ctx.line_no, $3.val); + asm_ctx.line_no, $2.val); set_parse_status(&asm_ctx.status, PARSE_ERR); } - $$.val = $1.val + $3.val; + $$.val = -$2.val; + } + +signed_float: + IMMVAL + { + $$.val = $1.val; + } + | '-' IMMVAL + { + $$.val = -$2.val; }
smod: SMOD_BIAS diff --git a/dlls/d3dcompiler_43/tests/asm.c b/dlls/d3dcompiler_43/tests/asm.c index 25471b51673..df686b9378c 100644 --- a/dlls/d3dcompiler_43/tests/asm.c +++ b/dlls/d3dcompiler_43/tests/asm.c @@ -34,7 +34,6 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena struct shader_test { const char *text; const DWORD bytes[128]; - BOOL todo; };
static void dump_shader(DWORD *shader) { @@ -60,7 +59,6 @@ static void exec_tests(const char *name, struct shader_test tests[], unsigned in messages = NULL; hr = D3DAssemble(tests[i].text, strlen(tests[i].text), NULL, NULL, NULL, D3DCOMPILE_SKIP_VALIDATION, &shader, &messages); - todo_wine_if(tests[i].todo) ok(hr == S_OK, "Test %s, shader %u: D3DAssemble failed with error %#lx - %ld.\n", name, i, hr, hr & 0xffff); if(messages) { trace("D3DAssemble messages:\n%s", (char *)ID3D10Blob_GetBufferPointer(messages)); @@ -214,7 +212,6 @@ static void vs_1_1_test(void) { "def c12, 0, -1, -0.5, 1024\n", {0xfffe0101, 0x00000051, 0xa00f000c, 0x00000000, 0xbf800000, 0xbf000000, 0x44800000, 0x0000ffff}, - TRUE }, { /* shader 14: writemasks, swizzles */ "vs_1_1\n" @@ -758,12 +755,11 @@ static void vs_2_0_test(void) { }, { /* shader 22 */ "vs_2_0\n" - "defi i0, -1, 1, 10, 0\n" + "defi i0, - 1, 1, 10, 0\n" "defi i1, 0, 40, 30, 10\n", {0xfffe0200, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a, 0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e, 0x0000000a, 0x0000ffff}, - TRUE }, { /* shader 23 */ "vs_2_0\n" @@ -976,7 +972,6 @@ static void ps_2_x_test(void) { {0xffff0201, 0x05000030, 0xf00f0000, 0xffffffff, 0x00000001, 0x0000000a, 0x00000000, 0x05000030, 0xf00f0001, 0x00000000, 0x00000028, 0x0000001e, 0x0000000a, 0x0000ffff}, - TRUE }, { /* shader 2 */ "ps_2_x\n" @@ -1177,7 +1172,12 @@ static void vs_3_0_test(void) { {0xfffe0300, 0x04000002, 0x800f0000, 0x90e42014, 0xf0e40800, 0x80e40002, 0x0000ffff} }, - + { /* shader 15 */ + "vs.3.0\n" + "add r0, v0[aL + 1 + 3], r2\n", + {0xfffe0300, 0x04000002, 0x800f0000, 0x90e42004, 0xf0e40800, 0x80e40002, + 0x0000ffff} + }, };
exec_tests("vs_3_0", tests, ARRAY_SIZE(tests)); @@ -1408,6 +1408,20 @@ static void failure_test(void) { /* shader 43: */ "ps_2_0\n" "texm3x3vspec t3, t0\n", + /* shader 44: expression in defi not allowed */ + "vs_2_0\n" + "defi i0, -1 - 1, 1, 10, 0\n" + "defi i1, 0, 40, 30, 10\n", + /* shader 45: '-' not allowed inside relative addressing operands */ + "vs.3.0\n" + "add r0, v0[aL - 3 + 5], r2\n", + /* shader 46: float constants in defi */ + "vs_2_0\n" + "defi i0, 1.0, 1.1, 10.2, 0.3\n" + "defi i1, 0, 40, 30, 10\n", + /* shader 47: double '-' sign */ + "vs.3.0\n" + "defi c0, -1, --1, 0, 0\n", }; HRESULT hr; unsigned int i;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=114915
Your paranoid android.
=== debian11 (build log) ===
01b0:err:d3d:wined3d_debug_callback 00169758: "0:43(1): error: error index must be >= 0". 01b0:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01b0:err:d3d:wined3d_debug_callback 00169758: "0:43(1): error: error index must be >= 0". 01b0:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01b0:err:d3d:wined3d_debug_callback 001697A0: "0:43(1): error: error index must be >= 0". 01b0:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01b0:err:d3d:wined3d_debug_callback 001697A0: "0:43(1): error: error index must be >= 0". 01b0:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0
=== debian11 (build log) ===
01b4:err:d3d:wined3d_debug_callback 0027A0B8: "0:43(1): error: error index must be >= 0". 01b4:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01b4:err:d3d:wined3d_debug_callback 0027A0B8: "0:43(1): error: error index must be >= 0". 01b4:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01bc:err:d3d:wined3d_debug_callback 000000000007BFF0: "0:43(1): error: error index must be >= 0". 01bc:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0 01bc:err:d3d:wined3d_debug_callback 000000000007BFF0: "0:43(1): error: error index must be >= 0". 01bc:fixme:d3d_shader:print_glsl_info_log 0:43(1): error: error index must be >= 0
From: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/mesh.c | 450 +++++++++++++++++++++++-------------------- 1 file changed, 237 insertions(+), 213 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index f74fba6e424..9871f62dfc4 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -1047,41 +1047,41 @@ cleanup: * replaces it, then it contains the same number as the index itself, e.g. * index 5 would contain 5. */ static HRESULT propagate_face_vertices(const DWORD *adjacency, DWORD *point_reps, - const DWORD *indices, DWORD *new_indices, DWORD face, DWORD numfaces) + const uint32_t *indices, uint32_t *new_indices, unsigned int face_idx, unsigned int face_count) { - const unsigned int VERTS_PER_FACE = 3; - DWORD edge, opp_edge; - DWORD face_base = VERTS_PER_FACE * face; + unsigned int face_base = 3 * face_idx; + unsigned int edge, opp_edge;
- for (edge = 0; edge < VERTS_PER_FACE; edge++) + for (edge = 0; edge < 3; ++edge) { - DWORD adj_face = adjacency[face_base + edge]; - DWORD adj_face_base; - DWORD i; - if (adj_face == -1) /* No adjacent face. */ + unsigned int adj_face = adjacency[face_base + edge]; + unsigned int adj_face_base; + unsigned int i; + + if (adj_face == ~0u) /* No adjacent face. */ continue; - else if (adj_face >= numfaces) + else if (adj_face >= face_count) { - /* This throws exception on Windows */ - WARN("Index out of bounds. Got %d expected less than %d.\n", - adj_face, numfaces); + /* This crashes on Windows. */ + WARN("Index out of bounds. Got %u, expected less than %u.\n", adj_face, face_count); return D3DERR_INVALIDCALL; } adj_face_base = 3 * adj_face;
/* Find opposite edge in adjacent face. */ - for (opp_edge = 0; opp_edge < VERTS_PER_FACE; opp_edge++) + for (opp_edge = 0; opp_edge < 3; ++opp_edge) { - DWORD opp_edge_index = adj_face_base + opp_edge; - if (adjacency[opp_edge_index] == face) + unsigned int opp_edge_index = adj_face_base + opp_edge; + + if (adjacency[opp_edge_index] == face_idx) break; /* Found opposite edge. */ }
/* Replaces vertices in opposite edge with vertices from current edge. */ - for (i = 0; i < 2; i++) + for (i = 0; i < 2; ++i) { - DWORD from = face_base + (edge + (1 - i)) % VERTS_PER_FACE; - DWORD to = adj_face_base + (opp_edge + i) % VERTS_PER_FACE; + unsigned int from = face_base + (edge + (1 - i)) % 3; + unsigned int to = adj_face_base + (opp_edge + i) % 3;
/* Propagate lowest index. */ if (new_indices[to] > new_indices[from]) @@ -1098,65 +1098,56 @@ static HRESULT propagate_face_vertices(const DWORD *adjacency, DWORD *point_reps static HRESULT WINAPI d3dx9_mesh_ConvertAdjacencyToPointReps(ID3DXMesh *iface, const DWORD *adjacency, DWORD *point_reps) { - struct d3dx9_mesh *This = impl_from_ID3DXMesh(iface); + struct d3dx9_mesh *mesh = impl_from_ID3DXMesh(iface); + uint16_t *indices_16bit = NULL; + uint32_t *new_indices = NULL; + uint32_t *indices = NULL; + unsigned int face, i; HRESULT hr; - DWORD face; - DWORD i; - DWORD *indices = NULL; - WORD *indices_16bit = NULL; - DWORD *new_indices = NULL; - const unsigned int VERTS_PER_FACE = 3;
TRACE("iface %p, adjacency %p, point_reps %p.\n", iface, adjacency, point_reps);
if (!adjacency) { WARN("NULL adjacency.\n"); - hr = D3DERR_INVALIDCALL; - goto cleanup; + return D3DERR_INVALIDCALL; }
if (!point_reps) { WARN("NULL point_reps.\n"); - hr = D3DERR_INVALIDCALL; - goto cleanup; + return D3DERR_INVALIDCALL; }
- /* Should never happen as CreateMesh does not allow meshes with 0 faces */ - if (This->numfaces == 0) + /* Should never happen as CreateMesh does not allow meshes with 0 faces. */ + if (!mesh->numfaces) { ERR("Number of faces was zero.\n"); - hr = D3DERR_INVALIDCALL; - goto cleanup; + return D3DERR_INVALIDCALL; }
- new_indices = HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE * This->numfaces * sizeof(*indices)); - if (!new_indices) - { - hr = E_OUTOFMEMORY; - goto cleanup; - } + if (!(new_indices = HeapAlloc(GetProcessHeap(), 0, 3 * mesh->numfaces * sizeof(*indices)))) + return E_OUTOFMEMORY;
- if (This->options & D3DXMESH_32BIT) + if (mesh->options & D3DXMESH_32BIT) { - hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void**)&indices); - if (FAILED(hr)) goto cleanup; - memcpy(new_indices, indices, VERTS_PER_FACE * This->numfaces * sizeof(*indices)); + if (FAILED(hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void **)&indices))) + goto cleanup; + memcpy(new_indices, indices, 3 * mesh->numfaces * sizeof(*indices)); } else { /* Make a widening copy of indices_16bit into indices and new_indices - * in order to re-use the helper function */ - hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void**)&indices_16bit); - if (FAILED(hr)) goto cleanup; - indices = HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE * This->numfaces * sizeof(*indices)); - if (!indices) + * in order to re-use the helper function. */ + if (FAILED(hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, (void **)&indices_16bit))) + goto cleanup; + + if (!(indices = HeapAlloc(GetProcessHeap(), 0, 3 * mesh->numfaces * sizeof(*indices)))) { hr = E_OUTOFMEMORY; goto cleanup; } - for (i = 0; i < VERTS_PER_FACE * This->numfaces; i++) + for (i = 0; i < 3 * mesh->numfaces; ++i) { new_indices[i] = indices_16bit[i]; indices[i] = indices_16bit[i]; @@ -1164,37 +1155,36 @@ static HRESULT WINAPI d3dx9_mesh_ConvertAdjacencyToPointReps(ID3DXMesh *iface, }
/* Vertices are ordered sequentially in the point representation. */ - for (i = 0; i < This->numvertices; i++) - { + for (i = 0; i < mesh->numvertices; ++i) point_reps[i] = i; - }
- /* Propagate vertices with low indices so as few vertices as possible - * are used in the mesh. - */ - for (face = 0; face < This->numfaces; face++) + /* Propagate vertices with low indices so as few vertices as possible are + * used in the mesh. */ + for (face = 0; face < mesh->numfaces; ++face) { - hr = propagate_face_vertices(adjacency, point_reps, indices, new_indices, face, This->numfaces); - if (FAILED(hr)) goto cleanup; + if (FAILED(hr = propagate_face_vertices(adjacency, point_reps, indices, new_indices, face, mesh->numfaces))) + goto cleanup; } - /* Go in opposite direction to catch all face orderings */ - for (face = 0; face < This->numfaces; face++) + /* Go in opposite direction to catch all face orderings. */ + for (face = 0; face < mesh->numfaces; ++face) { - hr = propagate_face_vertices(adjacency, point_reps, - indices, new_indices, - (This->numfaces - 1) - face, This->numfaces); - if (FAILED(hr)) goto cleanup; + if (FAILED(hr = propagate_face_vertices(adjacency, point_reps, indices, new_indices, + (mesh->numfaces - 1) - face, mesh->numfaces))) + goto cleanup; }
hr = D3D_OK; -cleanup: - if (This->options & D3DXMESH_32BIT) + + cleanup: + if (mesh->options & D3DXMESH_32BIT) { - if (indices) iface->lpVtbl->UnlockIndexBuffer(iface); + if (indices) + iface->lpVtbl->UnlockIndexBuffer(iface); } else { - if (indices_16bit) iface->lpVtbl->UnlockIndexBuffer(iface); + if (indices_16bit) + iface->lpVtbl->UnlockIndexBuffer(iface); HeapFree(GetProcessHeap(), 0, indices); } HeapFree(GetProcessHeap(), 0, new_indices); @@ -2604,18 +2594,18 @@ HRESULT WINAPI D3DXCreateMeshFVF(DWORD numfaces, DWORD numvertices, DWORD option
struct mesh_data { - DWORD num_vertices; - DWORD num_poly_faces; - DWORD num_tri_faces; + unsigned int num_vertices; + unsigned int num_poly_faces; + unsigned int num_tri_faces; D3DXVECTOR3 *vertices; - DWORD *num_tri_per_face; + unsigned int *num_tri_per_face; DWORD *indices;
DWORD fvf;
/* optional mesh data */
- DWORD num_normals; + unsigned int num_normals; D3DXVECTOR3 *normals; DWORD *normal_indices;
@@ -2623,12 +2613,12 @@ struct mesh_data {
DWORD *vertex_colors;
- DWORD num_materials; + unsigned int num_materials; D3DXMATERIAL *materials; DWORD *material_indices;
struct ID3DXSkinInfo *skin_info; - DWORD nb_bones; + unsigned int bone_count; };
static HRESULT parse_texture_filename(ID3DXFileData *filedata, char **filename_out) @@ -2758,8 +2748,9 @@ err:
static void destroy_materials(struct mesh_data *mesh) { - DWORD i; - for (i = 0; i < mesh->num_materials; i++) + unsigned int i; + + for (i = 0; i < mesh->num_materials; ++i) HeapFree(GetProcessHeap(), 0, mesh->materials[i].pTextureFilename); HeapFree(GetProcessHeap(), 0, mesh->materials); HeapFree(GetProcessHeap(), 0, mesh->material_indices); @@ -2770,18 +2761,19 @@ static void destroy_materials(struct mesh_data *mesh)
static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *mesh) { - HRESULT hr; - SIZE_T data_size; - const DWORD *data, *in_ptr; - GUID type; ID3DXFileData *child = NULL; - DWORD num_materials; - DWORD i; + unsigned int material_count; + const uint32_t *in_ptr; SIZE_T nb_children; + SIZE_T data_size; + const void *data; + unsigned int i; + HRESULT hr; + GUID type;
destroy_materials(mesh);
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); + hr = filedata->lpVtbl->Lock(filedata, &data_size, &data); if (FAILED(hr)) return hr;
/* template MeshMaterialList { @@ -2795,44 +2787,50 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me in_ptr = data; hr = E_FAIL;
- if (data_size < sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - num_materials = *in_ptr++; - if (!num_materials) { + material_count = *in_ptr++; + if (!material_count) { hr = D3D_OK; goto end; }
- if (data_size < 2 * sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < 2 * sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - if (*in_ptr++ != mesh->num_poly_faces) { - WARN("number of material face indices (%u) doesn't match number of faces (%u)\n", + if (*in_ptr++ != mesh->num_poly_faces) + { + WARN("Number of material face indices (%u) doesn't match number of faces (%u).\n", *(in_ptr - 1), mesh->num_poly_faces); goto end; } - if (data_size < 2 * sizeof(DWORD) + mesh->num_poly_faces * sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < 2 * sizeof(uint32_t) + mesh->num_poly_faces * sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - for (i = 0; i < mesh->num_poly_faces; i++) { - if (*in_ptr++ >= num_materials) { - WARN("face %u: reference to undefined material %u (only %u materials)\n", - i, *(in_ptr - 1), num_materials); + for (i = 0; i < mesh->num_poly_faces; ++i) + { + if (*in_ptr++ >= material_count) + { + WARN("Face %u: reference to undefined material %u (only %u materials).\n", + i, *(in_ptr - 1), material_count); goto end; } }
- mesh->materials = HeapAlloc(GetProcessHeap(), 0, num_materials * sizeof(*mesh->materials)); + mesh->materials = HeapAlloc(GetProcessHeap(), 0, material_count * sizeof(*mesh->materials)); mesh->material_indices = HeapAlloc(GetProcessHeap(), 0, mesh->num_poly_faces * sizeof(*mesh->material_indices)); if (!mesh->materials || !mesh->material_indices) { hr = E_OUTOFMEMORY; goto end; } - memcpy(mesh->material_indices, data + 2, mesh->num_poly_faces * sizeof(DWORD)); + memcpy(mesh->material_indices, (const uint32_t *)data + 2, mesh->num_poly_faces * sizeof(uint32_t));
hr = filedata->lpVtbl->GetChildren(filedata, &nb_children); if (FAILED(hr)) @@ -2847,9 +2845,11 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me if (FAILED(hr)) goto end;
- if (IsEqualGUID(&type, &TID_D3DRMMaterial)) { - if (mesh->num_materials >= num_materials) { - WARN("more materials defined than declared\n"); + if (IsEqualGUID(&type, &TID_D3DRMMaterial)) + { + if (mesh->num_materials >= material_count) + { + WARN("%u materials defined, only %u declared.\n", mesh->num_materials, material_count); hr = E_FAIL; goto end; } @@ -2861,8 +2861,9 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me IUnknown_Release(child); child = NULL; } - if (num_materials != mesh->num_materials) { - WARN("only %u of %u materials defined\n", num_materials, mesh->num_materials); + if (material_count != mesh->num_materials) + { + WARN("Only %u of %u materials defined.\n", material_count, mesh->num_materials); hr = E_FAIL; }
@@ -2875,14 +2876,14 @@ end:
static HRESULT parse_texture_coords(ID3DXFileData *filedata, struct mesh_data *mesh) { - HRESULT hr; + const uint32_t *data; SIZE_T data_size; - const BYTE *data; + HRESULT hr;
HeapFree(GetProcessHeap(), 0, mesh->tex_coords); mesh->tex_coords = NULL;
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); + hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data); if (FAILED(hr)) return hr;
/* template Coords2d { @@ -2897,18 +2898,21 @@ static HRESULT parse_texture_coords(ID3DXFileData *filedata, struct mesh_data *m
hr = E_FAIL;
- if (data_size < sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - if (*(DWORD*)data != mesh->num_vertices) { - WARN("number of texture coordinates (%u) doesn't match number of vertices (%u)\n", - *(DWORD*)data, mesh->num_vertices); + if (*data != mesh->num_vertices) + { + WARN("Number of texture coordinates (%u) doesn't match number of vertices (%u).\n", + *data, mesh->num_vertices); goto end; } - data += sizeof(DWORD); - if (data_size < sizeof(DWORD) + mesh->num_vertices * sizeof(*mesh->tex_coords)) { - WARN("truncated data (%ld bytes)\n", data_size); + ++data; + if (data_size < sizeof(uint32_t) + mesh->num_vertices * sizeof(*mesh->tex_coords)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; }
@@ -2930,16 +2934,15 @@ end:
static HRESULT parse_vertex_colors(ID3DXFileData *filedata, struct mesh_data *mesh) { - HRESULT hr; + unsigned int color_count, i; + const uint32_t *data; SIZE_T data_size; - const BYTE *data; - DWORD num_colors; - DWORD i; + HRESULT hr;
HeapFree(GetProcessHeap(), 0, mesh->vertex_colors); mesh->vertex_colors = NULL;
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); + hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data); if (FAILED(hr)) return hr;
/* template IndexedColor { @@ -2954,18 +2957,20 @@ static HRESULT parse_vertex_colors(ID3DXFileData *filedata, struct mesh_data *me
hr = E_FAIL;
- if (data_size < sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - num_colors = *(DWORD*)data; - data += sizeof(DWORD); - if (data_size < sizeof(DWORD) + num_colors * (sizeof(DWORD) + sizeof(D3DCOLORVALUE))) { - WARN("truncated data (%ld bytes)\n", data_size); + color_count = *data; + ++data; + if (data_size < sizeof(uint32_t) + color_count * (sizeof(uint32_t) + sizeof(D3DCOLORVALUE))) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; }
- mesh->vertex_colors = HeapAlloc(GetProcessHeap(), 0, mesh->num_vertices * sizeof(DWORD)); + mesh->vertex_colors = HeapAlloc(GetProcessHeap(), 0, mesh->num_vertices * sizeof(uint32_t)); if (!mesh->vertex_colors) { hr = E_OUTOFMEMORY; goto end; @@ -2973,18 +2978,20 @@ static HRESULT parse_vertex_colors(ID3DXFileData *filedata, struct mesh_data *me
for (i = 0; i < mesh->num_vertices; i++) mesh->vertex_colors[i] = D3DCOLOR_ARGB(0, 0xff, 0xff, 0xff); - for (i = 0; i < num_colors; i++) + for (i = 0; i < color_count; ++i) { D3DCOLORVALUE color; - DWORD index = *(DWORD*)data; - data += sizeof(DWORD); - if (index >= mesh->num_vertices) { - WARN("vertex color %u references undefined vertex %u (only %u vertices)\n", - i, index, mesh->num_vertices); + unsigned int index = *data; + + ++data; + if (index >= mesh->num_vertices) + { + WARN("Vertex color %u references undefined vertex %u (only %u vertices).\n", + i, index, mesh->num_vertices); goto end; } memcpy(&color, data, sizeof(color)); - data += sizeof(color); + data += sizeof(color) / sizeof(*data); color.r = min(1.0f, max(0.0f, color.r)); color.g = min(1.0f, max(0.0f, color.g)); color.b = min(1.0f, max(0.0f, color.b)); @@ -3006,12 +3013,12 @@ end:
static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh) { - HRESULT hr; + unsigned int num_face_indices = mesh->num_poly_faces * 2 + mesh->num_tri_faces; + DWORD *index_out_ptr; SIZE_T data_size; const BYTE *data; - DWORD *index_out_ptr; - DWORD i; - DWORD num_face_indices = mesh->num_poly_faces * 2 + mesh->num_tri_faces; + unsigned int i; + HRESULT hr;
HeapFree(GetProcessHeap(), 0, mesh->normals); mesh->num_normals = 0; @@ -3019,7 +3026,7 @@ static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh) mesh->normal_indices = NULL; mesh->fvf |= D3DFVF_NORMAL;
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); + hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data); if (FAILED(hr)) return hr;
/* template Vector { @@ -3041,20 +3048,22 @@ static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh)
hr = E_FAIL;
- if (data_size < sizeof(DWORD) * 2) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < sizeof(uint32_t) * 2) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - mesh->num_normals = *(DWORD*)data; - data += sizeof(DWORD); - if (data_size < sizeof(DWORD) * 2 + mesh->num_normals * sizeof(D3DXVECTOR3) + - num_face_indices * sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + mesh->num_normals = *(uint32_t *)data; + data += sizeof(uint32_t); + if (data_size < sizeof(uint32_t) * 2 + mesh->num_normals * sizeof(D3DXVECTOR3) + + num_face_indices * sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; }
mesh->normals = HeapAlloc(GetProcessHeap(), 0, mesh->num_normals * sizeof(D3DXVECTOR3)); - mesh->normal_indices = HeapAlloc(GetProcessHeap(), 0, num_face_indices * sizeof(DWORD)); + mesh->normal_indices = HeapAlloc(GetProcessHeap(), 0, num_face_indices * sizeof(uint32_t)); if (!mesh->normals || !mesh->normal_indices) { hr = E_OUTOFMEMORY; goto end; @@ -3065,33 +3074,39 @@ static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh) for (i = 0; i < mesh->num_normals; i++) D3DXVec3Normalize(&mesh->normals[i], &mesh->normals[i]);
- if (*(DWORD*)data != mesh->num_poly_faces) { - WARN("number of face normals (%u) doesn't match number of faces (%u)\n", - *(DWORD*)data, mesh->num_poly_faces); + if (*(uint32_t *)data != mesh->num_poly_faces) + { + WARN("Number of face normals (%u) doesn't match number of faces (%u).\n", + *(uint32_t *)data, mesh->num_poly_faces); goto end; } - data += sizeof(DWORD); + data += sizeof(uint32_t); index_out_ptr = mesh->normal_indices; for (i = 0; i < mesh->num_poly_faces; i++) { - DWORD j; - DWORD count = *(DWORD*)data; - if (count != mesh->num_tri_per_face[i] + 2) { - WARN("face %u: number of normals (%u) doesn't match number of vertices (%u)\n", + unsigned int count = *(uint32_t *)data; + unsigned int j; + + if (count != mesh->num_tri_per_face[i] + 2) + { + WARN("Face %u: number of normals (%u) doesn't match number of vertices (%u).\n", i, count, mesh->num_tri_per_face[i] + 2); goto end; } - data += sizeof(DWORD); + data += sizeof(uint32_t); + + for (j = 0; j < count; j++) + { + uint32_t normal_index = *(uint32_t *)data;
- for (j = 0; j < count; j++) { - DWORD normal_index = *(DWORD*)data; - if (normal_index >= mesh->num_normals) { - WARN("face %u, normal index %u: reference to undefined normal %u (only %u normals)\n", - i, j, normal_index, mesh->num_normals); + if (normal_index >= mesh->num_normals) + { + WARN("Face %u, normal index %u: reference to undefined normal %u (only %u normals).\n", + i, j, normal_index, mesh->num_normals); goto end; } *index_out_ptr++ = normal_index; - data += sizeof(DWORD); + data += sizeof(uint32_t); } }
@@ -3122,8 +3137,8 @@ static HRESULT parse_skin_mesh_info(ID3DXFileData *filedata, struct mesh_data *m } /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */ data += 2 * sizeof(WORD); - mesh_data->nb_bones = *(WORD*)data; - hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->nb_bones, &mesh_data->skin_info); + mesh_data->bone_count = *(WORD*)data; + hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->bone_count, &mesh_data->skin_info); } else { const char *name; DWORD nb_influences; @@ -3161,15 +3176,15 @@ end:
static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags) { - HRESULT hr; - SIZE_T data_size; + unsigned int skin_weights_info_count = 0; + ID3DXFileData *child = NULL; const BYTE *data, *in_ptr; DWORD *index_out_ptr; + SIZE_T child_count; + SIZE_T data_size; + unsigned int i; + HRESULT hr; GUID type; - ID3DXFileData *child = NULL; - DWORD i; - SIZE_T nb_children; - DWORD nb_skin_weights_info = 0;
/* * template Mesh { @@ -3181,55 +3196,62 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, * } */
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); + hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data); if (FAILED(hr)) return hr;
in_ptr = data; hr = E_FAIL;
- if (data_size < sizeof(DWORD) * 2) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size < sizeof(uint32_t) * 2) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - mesh_data->num_vertices = *(DWORD*)in_ptr; - if (data_size < sizeof(DWORD) * 2 + mesh_data->num_vertices * sizeof(D3DXVECTOR3)) { - WARN("truncated data (%ld bytes)\n", data_size); + mesh_data->num_vertices = *(uint32_t *)in_ptr; + if (data_size < sizeof(uint32_t) * 2 + mesh_data->num_vertices * sizeof(D3DXVECTOR3)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - in_ptr += sizeof(DWORD) + mesh_data->num_vertices * sizeof(D3DXVECTOR3); + in_ptr += sizeof(uint32_t) + mesh_data->num_vertices * sizeof(D3DXVECTOR3);
- mesh_data->num_poly_faces = *(DWORD*)in_ptr; - in_ptr += sizeof(DWORD); + mesh_data->num_poly_faces = *(uint32_t *)in_ptr; + in_ptr += sizeof(uint32_t);
mesh_data->num_tri_faces = 0; for (i = 0; i < mesh_data->num_poly_faces; i++) { - DWORD num_poly_vertices; - DWORD j; + unsigned int poly_vertices_count; + unsigned int j;
- if (data_size - (in_ptr - data) < sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + if (data_size - (in_ptr - data) < sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - num_poly_vertices = *(DWORD*)in_ptr; - in_ptr += sizeof(DWORD); - if (data_size - (in_ptr - data) < num_poly_vertices * sizeof(DWORD)) { - WARN("truncated data (%ld bytes)\n", data_size); + poly_vertices_count = *(uint32_t *)in_ptr; + in_ptr += sizeof(uint32_t); + if (data_size - (in_ptr - data) < poly_vertices_count * sizeof(uint32_t)) + { + WARN("Truncated data (%Id bytes).\n", data_size); goto end; } - if (num_poly_vertices < 3) { - WARN("face %u has only %u vertices\n", i, num_poly_vertices); + if (poly_vertices_count < 3) + { + WARN("Face %u has only %u vertices.\n", i, poly_vertices_count); goto end; } - for (j = 0; j < num_poly_vertices; j++) { - if (*(DWORD*)in_ptr >= mesh_data->num_vertices) { - WARN("face %u, index %u: undefined vertex %u (only %u vertices)\n", - i, j, *(DWORD*)in_ptr, mesh_data->num_vertices); + for (j = 0; j < poly_vertices_count; j++) + { + if (*(uint32_t *)in_ptr >= mesh_data->num_vertices) + { + WARN("Face %u, index %u: undefined vertex %u (only %u vertices).\n", + i, j, *(uint32_t *)in_ptr, mesh_data->num_vertices); goto end; } - in_ptr += sizeof(DWORD); + in_ptr += sizeof(uint32_t); } - mesh_data->num_tri_faces += num_poly_vertices - 2; + mesh_data->num_tri_faces += poly_vertices_count - 2; }
mesh_data->fvf = D3DFVF_XYZ; @@ -3245,30 +3267,31 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, goto end; }
- in_ptr = data + sizeof(DWORD); + in_ptr = data + sizeof(uint32_t); memcpy(mesh_data->vertices, in_ptr, mesh_data->num_vertices * sizeof(D3DXVECTOR3)); - in_ptr += mesh_data->num_vertices * sizeof(D3DXVECTOR3) + sizeof(DWORD); + in_ptr += mesh_data->num_vertices * sizeof(D3DXVECTOR3) + sizeof(uint32_t);
index_out_ptr = mesh_data->indices; for (i = 0; i < mesh_data->num_poly_faces; i++) { - DWORD count; + unsigned int count;
- count = *(DWORD*)in_ptr; - in_ptr += sizeof(DWORD); + count = *(uint32_t *)in_ptr; + in_ptr += sizeof(uint32_t); mesh_data->num_tri_per_face[i] = count - 2;
- while (count--) { - *index_out_ptr++ = *(DWORD*)in_ptr; - in_ptr += sizeof(DWORD); + while (count--) + { + *index_out_ptr++ = *(uint32_t *)in_ptr; + in_ptr += sizeof(uint32_t); } }
- hr = filedata->lpVtbl->GetChildren(filedata, &nb_children); + hr = filedata->lpVtbl->GetChildren(filedata, &child_count); if (FAILED(hr)) goto end;
- for (i = 0; i < nb_children; i++) + for (i = 0; i < child_count; i++) { hr = filedata->lpVtbl->GetChild(filedata, i, &child); if (FAILED(hr)) @@ -3303,10 +3326,10 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, hr = E_FAIL; goto end; } - hr = parse_skin_mesh_info(child, mesh_data, nb_skin_weights_info); + hr = parse_skin_mesh_info(child, mesh_data, skin_weights_info_count); if (FAILED(hr)) goto end; - nb_skin_weights_info++; + skin_weights_info_count++; } } if (FAILED(hr)) @@ -3316,9 +3339,10 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, child = NULL; }
- if (mesh_data->skin_info && (nb_skin_weights_info != mesh_data->nb_bones)) { - WARN("Mismatch between nb skin weights info %u encountered and nb bones %u from skin mesh header\n", - nb_skin_weights_info, mesh_data->nb_bones); + if (mesh_data->skin_info && (skin_weights_info_count != mesh_data->bone_count)) + { + WARN("Mismatch between skin weights info count %u and bones count %u from skin mesh header.\n", + skin_weights_info_count, mesh_data->bone_count); hr = E_FAIL; goto end; } @@ -3326,7 +3350,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, if ((provide_flags & PROVIDE_SKININFO) && !mesh_data->skin_info) { if (FAILED(hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, - mesh_data->nb_bones, &mesh_data->skin_info))) + mesh_data->bone_count, &mesh_data->skin_info))) goto end; }
From: Matteo Bruni mbruni@codeweavers.com
They don't really share any code in common.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/mesh.c | 92 +++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 39 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index 9871f62dfc4..7252e2f8fdd 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -3117,55 +3117,69 @@ end: return hr; }
-static HRESULT parse_skin_mesh_info(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD index) +static HRESULT parse_skin_mesh_header(ID3DXFileData *filedata, struct mesh_data *mesh_data) { - HRESULT hr; - SIZE_T data_size; const BYTE *data; + SIZE_T data_size; + HRESULT hr;
- TRACE("(%p, %p, %u)\n", filedata, mesh_data, index); + TRACE("filedata %p, mesh_data %p.\n", filedata, mesh_data);
- hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data); - if (FAILED(hr)) return hr; + if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data))) + return hr;
- hr = E_FAIL; + if (data_size < sizeof(WORD) * 3) + { + WARN("Truncated data (%Id bytes).\n", data_size); + filedata->lpVtbl->Unlock(filedata); + return E_FAIL; + } + /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */ + data += 2 * sizeof(WORD); + mesh_data->bone_count = *(WORD *)data; + hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->bone_count, + &mesh_data->skin_info);
- if (!mesh_data->skin_info) { - if (data_size < sizeof(WORD) * 3) { - WARN("truncated data (%ld bytes)\n", data_size); - goto end; - } - /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */ - data += 2 * sizeof(WORD); - mesh_data->bone_count = *(WORD*)data; - hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->bone_count, &mesh_data->skin_info); - } else { - const char *name; - DWORD nb_influences; + return hr; +}
- /* FIXME: String must be retrieved directly instead of through a pointer once ID3DXFILE is fixed */ - name = *(const char**)data; - data += sizeof(char*); +static HRESULT parse_skin_weights_info(ID3DXFileData *filedata, struct mesh_data *mesh_data, unsigned int index) +{ + unsigned int influence_count; + const char *name; + const BYTE *data; + SIZE_T data_size; + HRESULT hr;
- nb_influences = *(DWORD*)data; - data += sizeof(DWORD); + TRACE("filedata %p, mesh_data %p, index %u.\n", filedata, mesh_data, index);
- if (data_size < (sizeof(char*) + sizeof(DWORD) + nb_influences * (sizeof(DWORD) + sizeof(FLOAT)) + 16 * sizeof(FLOAT))) { - WARN("truncated data (%ld bytes)\n", data_size); - goto end; - } + if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data))) + return hr; + + /* FIXME: String will have to be retrieved directly instead of through a + * pointer once our ID3DXFileData implementation is fixed. */ + name = *(const char **)data; + data += sizeof(char *); + + influence_count = *(uint32_t *)data; + data += sizeof(uint32_t);
- hr = mesh_data->skin_info->lpVtbl->SetBoneName(mesh_data->skin_info, index, name); - if (SUCCEEDED(hr)) - hr = mesh_data->skin_info->lpVtbl->SetBoneInfluence(mesh_data->skin_info, index, nb_influences, - (const DWORD*)data, (const FLOAT*)(data + nb_influences * sizeof(DWORD))); - if (SUCCEEDED(hr)) - hr = mesh_data->skin_info->lpVtbl->SetBoneOffsetMatrix(mesh_data->skin_info, index, - (const D3DMATRIX*)(data + nb_influences * (sizeof(DWORD) + sizeof(FLOAT)))); + if (data_size < (sizeof(char *) + sizeof(uint32_t) + influence_count * (sizeof(uint32_t) + sizeof(float)) + + 16 * sizeof(float))) + { + WARN("Truncated data (%Id bytes).\n", data_size); + filedata->lpVtbl->Unlock(filedata); + return E_FAIL; }
-end: - filedata->lpVtbl->Unlock(filedata); + hr = mesh_data->skin_info->lpVtbl->SetBoneName(mesh_data->skin_info, index, name); + if (SUCCEEDED(hr)) + hr = mesh_data->skin_info->lpVtbl->SetBoneInfluence(mesh_data->skin_info, index, influence_count, + (const DWORD *)data, (const float *)(data + influence_count * sizeof(uint32_t))); + if (SUCCEEDED(hr)) + hr = mesh_data->skin_info->lpVtbl->SetBoneOffsetMatrix(mesh_data->skin_info, index, + (const D3DMATRIX *)(data + influence_count * (sizeof(uint32_t) + sizeof(float)))); + return hr; }
@@ -3317,7 +3331,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, hr = E_FAIL; goto end; } - hr = parse_skin_mesh_info(child, mesh_data, 0); + hr = parse_skin_mesh_header(child, mesh_data); if (FAILED(hr)) goto end; } else if (IsEqualGUID(&type, &DXFILEOBJ_SkinWeights)) { @@ -3326,7 +3340,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, hr = E_FAIL; goto end; } - hr = parse_skin_mesh_info(child, mesh_data, skin_weights_info_count); + hr = parse_skin_weights_info(child, mesh_data, skin_weights_info_count); if (FAILED(hr)) goto end; skin_weights_info_count++;
From: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/shader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index eae01674c0a..e4cd6d8c10e 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -2695,7 +2695,7 @@ static HRESULT get_shader_semantics(const DWORD *byte_code, D3DXSEMANTIC *semant D3DDECLUSAGE_FOG, D3DDECLUSAGE_PSIZE }; - DWORD reg_type, usage, index, version_token = *byte_code; + uint32_t reg_type, usage, index, version_token = *byte_code; BOOL is_ps = version_token >> 16 == 0xffff; unsigned int major, minor, i = 0, j; BYTE colors = 0, rastout = 0; @@ -2717,8 +2717,8 @@ static HRESULT get_shader_semantics(const DWORD *byte_code, D3DXSEMANTIC *semant { if (has_dcl && (*byte_code & 0xffff) == D3DSIO_DCL) { - DWORD usage_token = byte_code[1]; - DWORD reg = byte_code[2]; + uint32_t usage_token = byte_code[1]; + uint32_t reg = byte_code[2];
reg_type = ((reg & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) | ((reg & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2);