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@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; }
Signed-off-by: Jan Sikorski jsikorski@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; } }
Signed-off-by: Jan Sikorski jsikorski@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);
Signed-off-by: Jan Sikorski jsikorski@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);
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.