>From 1c7a93a3e18fcf117eef2b9dd7c0086b51872f52 Mon Sep 17 00:00:00 2001 From: Misha Koshelev Date: Mon, 26 Jul 2010 20:16:43 -0500 Subject: d3dx9: Implement D3DXCreateMeshFVF and ID3DXMesh. To: wine-patches Reply-To: wine-devel --- dlls/d3dx9_36/d3dx9_36_private.h | 18 ++ dlls/d3dx9_36/mesh.c | 381 +++++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/mesh.c | 18 +- 3 files changed, 406 insertions(+), 11 deletions(-) diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index 7488307..a1f7544 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -95,6 +95,24 @@ typedef struct ID3DXMatrixStackImpl D3DXMATRIX *stack; } ID3DXMatrixStackImpl; +/* ID3DXMesh */ +typedef struct ID3DXMeshImpl +{ + /* IUnknown fields */ + const ID3DXMeshVtbl *lpVtbl; + LONG ref; + + /* ID3DXMesh fields */ + DWORD numfaces; + DWORD numvertices; + DWORD options; + DWORD FVF; + + IDirect3DDevice9 *device; + IDirect3DVertexBuffer9 *vertex_buffer; + IDirect3DIndexBuffer9 *index_buffer; +} ID3DXMeshImpl; + /*ID3DXSprite */ typedef struct _SPRITE { LPDIRECT3DTEXTURE9 texture; diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index 5ff257c..78b62f8 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -27,9 +27,307 @@ #include "wingdi.h" #include "d3dx9.h" #include "wine/debug.h" +#include "d3dx9_36_private.h" WINE_DEFAULT_DEBUG_CHANNEL(d3dx); +/*** IUnknown methods ***/ +static HRESULT WINAPI ID3DXMeshImpl_QueryInterface(ID3DXMesh *iface, REFIID riid, LPVOID *object) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_ID3DXBaseMesh) || + IsEqualGUID(riid, &IID_ID3DXMesh)) + { + iface->lpVtbl->AddRef(iface); + *object = This; + return S_OK; + } + + WARN("Interface %s not found.\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI ID3DXMeshImpl_AddRef(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)->(): AddRef from %d\n", This, This->ref); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI ID3DXMeshImpl_Release(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(): Release from %d\n", This, ref + 1); + + if (!ref) + { + if (This->index_buffer) IDirect3DIndexBuffer9_Release(This->index_buffer); + if (This->vertex_buffer) IDirect3DVertexBuffer9_Release(This->vertex_buffer); + if (This->device) IDirect3DDevice9_Release(This->device); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +/*** ID3DXBaseMesh ***/ +static HRESULT WINAPI ID3DXMeshImpl_DrawSubset(ID3DXMesh *iface, DWORD attrib_id) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u): stub\n", This, attrib_id); + return E_NOTIMPL; +} + +static DWORD WINAPI ID3DXMeshImpl_GetNumFaces(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)\n", This); + + return This->numfaces; +} + +static DWORD WINAPI ID3DXMeshImpl_GetNumVertices(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)\n", This); + + return This->numvertices; +} + +static DWORD WINAPI ID3DXMeshImpl_GetFVF(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)\n", This); + + return This->FVF; +} + +static HRESULT WINAPI ID3DXMeshImpl_GetDeclaration(ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE]) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p): stub\n", This, declaration); + return E_NOTIMPL; +} + +static DWORD WINAPI ID3DXMeshImpl_GetNumBytesPerVertex(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p): stub\n", This); + return 0; /* arbitrary since we cannot return E_NOTIMPL */ +} + +static DWORD WINAPI ID3DXMeshImpl_GetOptions(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)\n", This); + + return This->options; +} + +static HRESULT WINAPI ID3DXMeshImpl_GetDevice(ID3DXMesh *iface, LPDIRECT3DDEVICE9* device) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)->(%p): stub\n", This, device); + + if (device == NULL) return D3DERR_INVALIDCALL; + *device = This->device; + IDirect3DDevice9_AddRef(This->device); + + return D3D_OK; +} + +static HRESULT WINAPI ID3DXMeshImpl_CloneMeshFVF(ID3DXMesh *iface, DWORD options, DWORD fvf, LPDIRECT3DDEVICE9 device, LPD3DXMESH* clone_mesh) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%u,%p,%p): stub\n", This, options, fvf, device, clone_mesh); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_CloneMesh(ID3DXMesh *iface, DWORD options, CONST D3DVERTEXELEMENT9* declaration, LPDIRECT3DDEVICE9 device, + LPD3DXMESH* clone_mesh) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p,%p,%p): stub\n", This, options, declaration, device, clone_mesh); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_GetVertexBuffer(ID3DXMesh *iface, LPDIRECT3DVERTEXBUFFER9* vertex_buffer) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)->(%p)\n", This, vertex_buffer); + + if (vertex_buffer == NULL) return D3DERR_INVALIDCALL; + *vertex_buffer = This->vertex_buffer; + if (This->vertex_buffer) IDirect3DVertexBuffer9_AddRef(This->vertex_buffer); + + return D3D_OK; +} + +static HRESULT WINAPI ID3DXMeshImpl_GetIndexBuffer(ID3DXMesh *iface, LPDIRECT3DINDEXBUFFER9* index_buffer) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + + TRACE("(%p)->(%p)\n", This, index_buffer); + + if (index_buffer == NULL) return D3DERR_INVALIDCALL; + *index_buffer = This->index_buffer; + if (This->index_buffer) IDirect3DIndexBuffer9_AddRef(This->index_buffer); + + return D3D_OK; +} + +static HRESULT WINAPI ID3DXMeshImpl_LockVertexBuffer(ID3DXMesh *iface, DWORD flags, LPVOID* data) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p): stub\n", This, flags, data); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_UnlockVertexBuffer(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_LockIndexBuffer(ID3DXMesh *iface, DWORD flags, LPVOID* data) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p): stub\n", This, flags, data); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_UnlockIndexBuffer(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_GetAttributeTable(ID3DXMesh *iface, D3DXATTRIBUTERANGE* attrib_table, DWORD* attrib_table_size) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p,%p): stub\n", This, attrib_table, attrib_table_size); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_ConvertPointRepsToAdjacency(ID3DXMesh *iface, CONST DWORD* point_reps, DWORD* adjacency) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p,%p): stub\n", This, point_reps, adjacency); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_ConvertAdjacencyToPointReps(ID3DXMesh *iface, CONST DWORD* adjacency, DWORD* point_reps) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p,%p): stub\n", This, adjacency, point_reps); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_GenerateAdjacency(ID3DXMesh *iface, FLOAT epsilon, DWORD* adjacency) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%f,%p): stub\n", This, epsilon, adjacency); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_UpdateSemantics(ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE]) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p): stub\n", This, declaration); + return E_NOTIMPL; +} + +/*** ID3DXMesh ***/ +static HRESULT WINAPI ID3DXMeshImpl_LockAttributeBuffer(ID3DXMesh *iface, DWORD flags, DWORD** data) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p): stub\n", This, flags, data); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_UnlockAttributeBuffer(ID3DXMesh *iface) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_Optimize(ID3DXMesh *iface, DWORD flags, CONST DWORD* adjacency_in, DWORD* adjacency_out, + DWORD* face_remap, LPD3DXBUFFER* vertex_remap, LPD3DXMESH* opt_mesh) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p,%p,%p,%p,%p): stub\n", This, flags, adjacency_in, adjacency_out, face_remap, vertex_remap, opt_mesh); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_OptimizeInplace(ID3DXMesh *iface, DWORD flags, CONST DWORD* adjacency_in, DWORD* adjacency_out, + DWORD* face_remap, LPD3DXBUFFER* vertex_remap) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%u,%p,%p,%p,%p): stub\n", This, flags, adjacency_in, adjacency_out, face_remap, vertex_remap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ID3DXMeshImpl_SetAttributeTable(ID3DXMesh *iface, CONST D3DXATTRIBUTERANGE* attrib_table, DWORD attrib_table_size) +{ + ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface; + FIXME("(%p)->(%p,%u): stub\n", This, attrib_table, attrib_table_size); + return E_NOTIMPL; +} + +static const struct ID3DXMeshVtbl D3DXMesh_Vtbl = +{ + /*** IUnknown methods ***/ + ID3DXMeshImpl_QueryInterface, + ID3DXMeshImpl_AddRef, + ID3DXMeshImpl_Release, + /*** ID3DXBaseMesh ***/ + ID3DXMeshImpl_DrawSubset, + ID3DXMeshImpl_GetNumFaces, + ID3DXMeshImpl_GetNumVertices, + ID3DXMeshImpl_GetFVF, + ID3DXMeshImpl_GetDeclaration, + ID3DXMeshImpl_GetNumBytesPerVertex, + ID3DXMeshImpl_GetOptions, + ID3DXMeshImpl_GetDevice, + ID3DXMeshImpl_CloneMeshFVF, + ID3DXMeshImpl_CloneMesh, + ID3DXMeshImpl_GetVertexBuffer, + ID3DXMeshImpl_GetIndexBuffer, + ID3DXMeshImpl_LockVertexBuffer, + ID3DXMeshImpl_UnlockVertexBuffer, + ID3DXMeshImpl_LockIndexBuffer, + ID3DXMeshImpl_UnlockIndexBuffer, + ID3DXMeshImpl_GetAttributeTable, + ID3DXMeshImpl_ConvertPointRepsToAdjacency, + ID3DXMeshImpl_ConvertAdjacencyToPointReps, + ID3DXMeshImpl_GenerateAdjacency, + ID3DXMeshImpl_UpdateSemantics, + /*** ID3DXMesh ***/ + ID3DXMeshImpl_LockAttributeBuffer, + ID3DXMeshImpl_UnlockAttributeBuffer, + ID3DXMeshImpl_Optimize, + ID3DXMeshImpl_OptimizeInplace, + ID3DXMeshImpl_SetAttributeTable +}; + /************************************************************************* * D3DXBoxBoundProbe */ @@ -331,9 +629,88 @@ BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST HRESULT WINAPI D3DXCreateMeshFVF(DWORD numfaces, DWORD numvertices, DWORD options, DWORD FVF, LPDIRECT3DDEVICE9 device, LPD3DXMESH *mesh) { - FIXME("(%d, %d, %d, %d, %p, %p): stub\n", numfaces, numvertices, options, FVF, device, mesh); + HRESULT hr; + IDirect3DVertexBuffer9 *vertex_buffer; + IDirect3DIndexBuffer9 *index_buffer; + ID3DXMeshImpl *object; - return E_NOTIMPL; + TRACE("(%d, %d, %d, %d, %p, %p)\n", numfaces, numvertices, options, FVF, device, mesh); + + if (numfaces == 0 || numvertices == 0 || FVF == 0 || !device || !mesh) + { + return D3DERR_INVALIDCALL; + } + + if (options != D3DXMESH_MANAGED) + { + FIXME("Only implemented for options == D3DXMESH_MANAGED.\n"); + return E_NOTIMPL; + } + + /* Create vertex buffer */ + hr = IDirect3DDevice9_CreateVertexBuffer(device, + numvertices * sizeof(D3DXVECTOR3) * 2, + 0, + FVF, + D3DPOOL_MANAGED, + &vertex_buffer, + NULL); + if (hr != D3D_OK) + { + if (hr == D3DERR_INVALIDCALL) + { + ERR("Parameters incorrect in call to IDirect3DDevice9_CreateVertexBuffer.\n"); + } + else if (hr != E_OUTOFMEMORY && hr != D3DERR_OUTOFVIDEOMEMORY) + { + ERR("Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n", hr); + } + return hr; + } + + /* Create index buffer */ + hr = IDirect3DDevice9_CreateIndexBuffer(device, + numfaces * sizeof(WORD) * 3, + 0, + D3DFMT_INDEX16, + D3DPOOL_MANAGED, + &index_buffer, + NULL); + if (hr != D3D_OK) + { + if (hr == D3DERR_INVALIDCALL || hr == D3DXERR_INVALIDDATA) + { + ERR("Parameters incorrect in call to IDirect3DDevice9_CreateVertexBuffer, return value was %x.\n", hr); + } + else if (hr != E_OUTOFMEMORY && hr != D3DERR_OUTOFVIDEOMEMORY) + { + ERR("Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n", hr); + } + return hr; + } + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXMeshImpl)); + if (object == NULL) + { + *mesh = NULL; + return E_OUTOFMEMORY; + } + object->lpVtbl = &D3DXMesh_Vtbl; + object->ref = 1; + + object->numfaces = numfaces; + object->numvertices = numvertices; + object->options = options; + object->FVF = FVF; + object->device = device; + IDirect3DDevice9_AddRef(device); + + object->vertex_buffer = vertex_buffer; + object->index_buffer = index_buffer; + + *mesh = (ID3DXMesh*)object; + + return D3D_OK; } HRESULT WINAPI D3DXCreateBox(LPDIRECT3DDEVICE9 device, FLOAT width, FLOAT height, diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index 1e0fb98..0caa28a 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -191,7 +191,7 @@ static void compare_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mes { ok(index_buffer_description.Format == D3DFMT_INDEX16, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n", name, index_buffer_description.Format, D3DFMT_INDEX16); ok(index_buffer_description.Type == D3DRTYPE_INDEXBUFFER, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n", name, index_buffer_description.Type, D3DRTYPE_INDEXBUFFER); - ok(index_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, index_buffer_description.Usage, 0); + todo_wine ok(index_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, index_buffer_description.Usage, 0); /* WINED3DUSAGE_MASK */ ok(index_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n", name, index_buffer_description.Pool, D3DPOOL_DEFAULT); expected = number_of_faces * sizeof(WORD) * 3; ok(index_buffer_description.Size == expected, "Test %s, result %x, expected %x\n", name, index_buffer_description.Size, expected); @@ -680,10 +680,10 @@ static void D3DXCreateMeshFVFTest(void) D3DDECL_END(), }; hr = D3DXCreateMeshFVF(0, 0, 0, 0, NULL, NULL); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, NULL, &d3dxmesh); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); d3d = Direct3DCreate9(D3D_SDK_VERSION); @@ -712,10 +712,10 @@ static void D3DXCreateMeshFVFTest(void) } hr = D3DXCreateMeshFVF(0, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateMeshFVF(1, 0, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateMeshFVF(1, 3, 0, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh); todo_wine ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK); @@ -726,13 +726,13 @@ static void D3DXCreateMeshFVFTest(void) } hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, 0, device, &d3dxmesh); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, NULL); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); + ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh); - todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); + ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); if (hr == D3D_OK) { @@ -751,7 +751,7 @@ static void D3DXCreateMeshFVFTest(void) /* declaration */ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, decl); - ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); + todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); if (hr == D3D_OK) { -- 1.7.1