[PATCH v2 1/4] wined3d: Align vertex attribute offsets to their size, if smaller than 4.
This should not change behavior for d3d9 and earlier, where all formats have sizes that are multiples of 4. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43422 Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com> --- dlls/wined3d/vertexdeclaration.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index c5df45541e4..ec8e2bc1d24 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -200,6 +200,7 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara for (i = 0; i < element_count; ++i) { struct wined3d_vertex_declaration_element *e = &declaration->elements[i]; + unsigned int alignment; e->format = wined3d_get_format(adapter, elements[i].format, 0); e->ffp_valid = declaration_element_valid_ffp(&elements[i]); @@ -212,6 +213,9 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara e->usage = elements[i].usage; e->usage_idx = elements[i].usage_idx; + alignment = e->format->byte_count; + if (alignment > 4) alignment = 4; + if (e->usage == WINED3D_DECL_USAGE_POSITIONT) declaration->position_transformed = TRUE; @@ -239,15 +243,15 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara prev = &declaration->elements[i - j]; if (prev->input_slot == e->input_slot) { - e->offset = (prev->offset + prev->format->byte_count + 3) & ~3; + e->offset = (prev->offset + prev->format->byte_count + alignment - 1) & ~(alignment - 1); break; } } } - if (e->offset & 0x3) - { - WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset); + if (e->offset & (alignment - 1)) { + WARN("Declaration element %u with format %s is not %d byte aligned(%u). returning E_FAIL.\n", + i, debug_d3dformat(elements[i].format), alignment, e->offset); heap_free(declaration->elements); return E_FAIL; } -- 2.30.0
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com> --- dlls/d3d8/vertexdeclaration.c | 8 ++++++-- dlls/d3d9/vertexdeclaration.c | 4 +++- dlls/wined3d/vertexdeclaration.c | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dlls/d3d8/vertexdeclaration.c b/dlls/d3d8/vertexdeclaration.c index 525666d680e..08c18500e1e 100644 --- a/dlls/d3d8/vertexdeclaration.c +++ b/dlls/d3d8/vertexdeclaration.c @@ -356,8 +356,10 @@ HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration heap_free(wined3d_elements); if (FAILED(hr)) { - WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr); + WARN("Failed to create wined3d vertex declaration, hr %#x.%s\n", hr, hr == E_INVALIDARG ? " Returning E_FAIL." : ""); heap_free(declaration->elements); + if (hr == E_INVALIDARG) + hr = E_FAIL; return hr; } @@ -378,7 +380,9 @@ HRESULT d3d8_vertex_declaration_init_fvf(struct d3d8_vertex_declaration *declara &d3d8_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_vertex_declaration); if (FAILED(hr)) { - WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr); + WARN("Failed to create wined3d vertex declaration, hr %#x.%s\n", hr, hr == E_INVALIDARG ? " Returning E_FAIL." : ""); + if (hr == E_INVALIDARG) + hr = E_FAIL; return hr; } diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c index c30a84313fb..73f6381f257 100644 --- a/dlls/d3d9/vertexdeclaration.c +++ b/dlls/d3d9/vertexdeclaration.c @@ -405,7 +405,9 @@ static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaratio if (FAILED(hr)) { heap_free(declaration->elements); - WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr); + WARN("Failed to create wined3d vertex declaration, hr %#x.%s\n", hr, hr == E_INVALIDARG ? " Returning E_FAIL." : ""); + if (hr == E_INVALIDARG) + hr = E_FAIL; return hr; } diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index ec8e2bc1d24..fdc0376a9f1 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -226,10 +226,10 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara if (!(e->format->flags[WINED3D_GL_RES_TYPE_BUFFER] & WINED3DFMT_FLAG_VERTEX_ATTRIBUTE)) { - FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n", + FIXME("The application tries to use an unsupported format (%s), returning E_INVALIDARG.\n", debug_d3dformat(elements[i].format)); heap_free(declaration->elements); - return E_FAIL; + return E_INVALIDARG; } if (e->offset == WINED3D_APPEND_ALIGNED_ELEMENT) @@ -250,10 +250,10 @@ static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declara } if (e->offset & (alignment - 1)) { - WARN("Declaration element %u with format %s is not %d byte aligned(%u). returning E_FAIL.\n", + WARN("Declaration element %u with format %s is not %d byte aligned(%u). returning E_INVALIDARG.\n", i, debug_d3dformat(elements[i].format), alignment, e->offset); heap_free(declaration->elements); - return E_FAIL; + return E_INVALIDARG; } } -- 2.30.0
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com> --- dlls/d3d10core/tests/d3d10core.c | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c index 4332ce2dcf2..ea274833f71 100644 --- a/dlls/d3d10core/tests/d3d10core.c +++ b/dlls/d3d10core/tests/d3d10core.c @@ -12270,6 +12270,97 @@ static void test_create_input_layout(void) ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_input_layout_alignment(void) +{ + ULONG refcount; + ID3D10Device *device; + unsigned int i; + + static const DWORD vs_code[] = + { +#if 0 + float4 main(float4 position : POSITION) : SV_POSITION + { + return position; + } +#endif + 0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040, + 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + }; + + static const struct + { + D3D10_INPUT_ELEMENT_DESC elements[2]; + HRESULT hr; + } + test_data[] = + { + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R16_UINT, 0, 2, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R16_UINT, 0, 1, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8_UINT, 0, 1, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R16_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32_UINT, 0, 2, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R16_UINT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 2, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 17, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 18, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 19, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + }; + + if (!(device = create_device())) + { + skip("Failed to create device.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(test_data); ++i) + { + ID3D10InputLayout *layout; + HRESULT hr = ID3D10Device_CreateInputLayout(device, test_data[i].elements, 2, vs_code, sizeof(vs_code), &layout); + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (SUCCEEDED(hr)) + ID3D10InputLayout_Release(layout); + } + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + static void test_input_assembler(void) { enum layout_id @@ -18511,6 +18602,7 @@ START_TEST(d3d10core) queue_test(test_sm4_continuec_instruction); queue_test(test_sm4_discard_instruction); queue_test(test_create_input_layout); + queue_test(test_input_layout_alignment); queue_test(test_input_assembler); queue_test(test_null_sampler); queue_test(test_immediate_constant_buffer); -- 2.30.0
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com> --- dlls/d3d11/tests/d3d11.c | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index d7a49f4af3a..75004944878 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -17879,6 +17879,97 @@ static void test_create_input_layout(void) ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_input_layout_alignment(void) +{ + ULONG refcount; + ID3D11Device *device; + unsigned int i; + + static const DWORD vs_code[] = + { +#if 0 + float4 main(float4 position : POSITION) : SV_POSITION + { + return position; + } +#endif + 0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040, + 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + }; + + static const struct + { + D3D11_INPUT_ELEMENT_DESC elements[2]; + HRESULT hr; + } + test_data[] = + { + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R16_UINT, 0, 2, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R16_UINT, 0, 1, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R8_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R8_UINT, 0, 1, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R16_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32_UINT, 0, 2, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R16_UINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 2, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 17, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 18, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 19, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, E_INVALIDARG}, + {{ + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }, S_OK}, + }; + + if (!(device = create_device(NULL))) + { + skip("Failed to create device.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(test_data); ++i) + { + ID3D11InputLayout *layout; + HRESULT hr = ID3D11Device_CreateInputLayout(device, test_data[i].elements, 2, vs_code, sizeof(vs_code), &layout); + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (SUCCEEDED(hr)) + ID3D11InputLayout_Release(layout); + } + + refcount = ID3D11Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + static void test_input_assembler(void) { enum layout_id @@ -31759,6 +31850,7 @@ START_TEST(d3d11) queue_test(test_sm4_discard_instruction); queue_test(test_sm5_swapc_instruction); queue_test(test_create_input_layout); + queue_test(test_input_layout_alignment); queue_test(test_input_assembler); queue_test(test_null_sampler); queue_test(test_check_feature_support); -- 2.30.0
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=85209 Your paranoid android. === w1064 (32 bit report) === d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. === w10pro64 (32 bit report) === d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:5658: Test failed: Got unexpected query result 0x0000000000000000.
participants (2)
-
Jan Sikorski -
Marvin