diff --git a/dlls/d3d9/tests/vertexdeclaration.c b/dlls/d3d9/tests/vertexdeclaration.c index c8b7a099fd7..d43b5ab6541 100644 --- a/dlls/d3d9/tests/vertexdeclaration.c +++ b/dlls/d3d9/tests/vertexdeclaration.c @@ -736,6 +736,52 @@ static void test_fvf_decl_management( return; } +static void test_vertex_declaration_alignment( + IDirect3DDevice9* device) { + + HRESULT hr; + IDirect3DVertexDeclaration9* result_decl = NULL; + int i; + + CONST D3DVERTEXELEMENT9 test_elements[5][3] = + { + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + }, + { + { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, + { 0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR , 0 }, + D3DDECL_END() + } + }; + HRESULT results[5] = {D3D_OK, E_FAIL, E_FAIL, E_FAIL, D3D_OK}; + + for(i = 0; i < sizeof(test_elements) / sizeof(test_elements[0]); i++) { + result_decl = NULL; + hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &result_decl); + ok(hr == results[i], "CreateVertexDeclaration for declaration %d returned %#x, expected %#x\n", + i, hr, results[i]); + if(result_decl) IDirect3DVertexDeclaration9_Release(result_decl); + } +} + START_TEST(vertexdeclaration) { static D3DVERTEXELEMENT9 simple_decl[] = { @@ -770,4 +816,5 @@ START_TEST(vertexdeclaration) test_get_declaration(decl_ptr, simple_decl, simple_decl_num_elements); test_fvf_decl_conversion(device_ptr); test_fvf_decl_management(device_ptr); + test_vertex_declaration_alignment(device_ptr); } diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c index 3973c98fbf9..0c48affdfba 100644 --- a/dlls/d3d9/vertexdeclaration.c +++ b/dlls/d3d9/vertexdeclaration.c @@ -368,7 +368,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9 if (FAILED(hr)) { /* free up object */ - FIXME("(%p) call to IWineD3DDevice_CreateVertexDeclaration failed\n", This); + WARN("(%p) call to IWineD3DDevice_CreateVertexDeclaration failed\n", This); HeapFree(GetProcessHeap(), 0, object->elements); HeapFree(GetProcessHeap(), 0, object); } else { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 6ab21576f6b..9f1b63536d2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1716,6 +1716,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* D3DCREATEOBJECTINSTANCE(object, VertexDeclaration) hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, elements, element_count); + if(FAILED(hr)) { + *ppVertexDeclaration = NULL; + HeapFree(GetProcessHeap(), 0, object); + } return hr; } diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c index 638266224a1..5bcf9044d59 100644 --- a/dlls/wined3d/vertexbuffer.c +++ b/dlls/wined3d/vertexbuffer.c @@ -572,9 +572,7 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if switch(This->conv_map[j]) { case CONV_NONE: /* Done already */ - /* Vertex attribute sizes are always multiples of 4, but we can't skip 3 additional bytes - * because the attributes don't have to start at aligned offsets - */ + j += 3; break; case CONV_D3DCOLOR: fixup_d3dcolor((DWORD *) (data + i * This->stride + j)); diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 4e1e1b61754..1984d6b10e1 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -159,6 +159,12 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte */ if(This->pDeclarationWine[i].Stream >= MAX_STREAMS) continue; + if(This->pDeclarationWine[i].Offset & 0x3) { + WARN("Declaration element %d is not 4 byte aligned(%d), returning E_FAIL\n", i, This->pDeclarationWine[i].Offset); + HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); + return E_FAIL; + } + if(!isPreLoaded[This->pDeclarationWine[i].Stream]) { This->streams[This->num_streams] = This->pDeclarationWine[i].Stream; This->num_streams++;