diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index af677067cd2..6ec3f186c00 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -515,6 +515,9 @@ typedef struct { const IDirect3DVertexDeclaration8Vtbl *lpVtbl; LONG ref_count; + DWORD *elements; + DWORD elements_size; /* Size of elements, in bytes */ + IWineD3DVertexDeclaration *wined3d_vertex_declaration; } IDirect3DVertexDeclaration8Impl; @@ -619,7 +622,7 @@ typedef struct IDirect3DPixelShader8Impl { * to see how not defined it here */ void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader); -size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, WINED3DVERTEXELEMENT **wined3d_elements); +size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, WINED3DVERTEXELEMENT **wined3d_elements); /* Callbacks */ extern HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height, diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 95a1331a9a6..22ba77c698b 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1214,13 +1214,25 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexDeclaration(IDirect3DDevi object->ref_count = 1; object->lpVtbl = &Direct3DVertexDeclaration8_Vtbl; - wined3d_element_count = convert_to_wined3d_declaration(declaration, &wined3d_elements); + wined3d_element_count = convert_to_wined3d_declaration(declaration, &object->elements_size, &wined3d_elements); + object->elements = HeapAlloc(GetProcessHeap(), 0, object->elements_size); + if (!object->elements) { + ERR("Memory allocation failed\n"); + HeapFree(GetProcessHeap(), 0, wined3d_elements); + HeapFree(GetProcessHeap(), 0, object); + *decl_ptr = NULL; + return D3DERR_OUTOFVIDEOMEMORY; + } + + CopyMemory(object->elements, declaration, object->elements_size); + hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wined3d_vertex_declaration, (IUnknown *)object, wined3d_elements, wined3d_element_count); HeapFree(GetProcessHeap(), 0, wined3d_elements); if (FAILED(hr)) { ERR("(%p) : IWineD3DDevice_CreateVertexDeclaration call failed\n", This); + HeapFree(GetProcessHeap(), 0, object->elements); HeapFree(GetProcessHeap(), 0, object); } else { *decl_ptr = (IDirect3DVertexDeclaration8 *)object; diff --git a/dlls/d3d8/vertexdeclaration.c b/dlls/d3d8/vertexdeclaration.c index afe9ff1ccb7..f2e5d576b0e 100644 --- a/dlls/d3d8/vertexdeclaration.c +++ b/dlls/d3d8/vertexdeclaration.c @@ -62,6 +62,7 @@ static ULONG WINAPI IDirect3DVertexDeclaration8Impl_Release(IDirect3DVertexDecla if (!ref_count) { IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration); + HeapFree(GetProcessHeap(), 0, This->elements); HeapFree(GetProcessHeap(), 0, This); } @@ -271,7 +272,7 @@ static const wined3d_usage_t wined3d_usage_lookup[] = { }; /* TODO: find out where rhw (or positionT) is for declaration8 */ -size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, WINED3DVERTEXELEMENT **wined3d_elements) +size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, WINED3DVERTEXELEMENT **wined3d_elements) { const DWORD *token = d3d8_elements; WINED3DVERTEXELEMENT *element; @@ -326,6 +327,8 @@ size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, WINED3DVERTEXE element->Stream = 0xFF; element->Type = WINED3DDECLTYPE_UNUSED; + *d3d8_elements_size = (++token - d3d8_elements) * sizeof(DWORD); + return element_count; }