From dea795f7ac6bfabe0c90f6d36d295a33d36996dd Mon Sep 17 00:00:00 2001 From: "H. Verbeet" Date: Tue, 13 Feb 2007 23:12:36 +0100 Subject: [PATCH] d3d9: Don't store the d3d9 declaration in the wined3d object. --- dlls/d3d8/device.c | 2 +- dlls/d3d9/d3d9_private.h | 3 ++ dlls/d3d9/vertexdeclaration.c | 72 ++++++++++++++++++++++++--- dlls/wined3d/device.c | 10 ++-- dlls/wined3d/vertexdeclaration.c | 105 +++++++++++---------------------------- dlls/wined3d/wined3d_private.h | 4 -- include/wine/wined3d_interface.h | 10 ++-- 7 files changed, 109 insertions(+), 97 deletions(-) diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 06eca3237fb..04352d4a8cf 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1179,7 +1179,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexDeclaration(IDirect3DDevi object->ref_count = 1; object->lpVtbl = &Direct3DVertexDeclaration8_Vtbl; - hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, declaration, &object->wined3d_vertex_declaration, (IUnknown *)object); + hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wined3d_vertex_declaration, (IUnknown *)object, (CONST WINED3DVERTEXELEMENT *)declaration, 0); if (FAILED(hr)) { ERR("(%p) : IWineD3DDevice_CreateVertexDeclaration call failed\n", This); HeapFree(GetProcessHeap(), 0, object); diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 58969e3a449..435a37ea55f 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -476,6 +476,9 @@ typedef struct IDirect3DVertexDeclaration9Impl { const IDirect3DVertexDeclaration9Vtbl *lpVtbl; LONG ref; + D3DVERTEXELEMENT9 *elements; + size_t element_count; + /* IDirect3DVertexDeclaration9 fields */ IWineD3DVertexDeclaration *wineD3DVertexDeclaration; diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c index e8dfe0ce365..a7f548607b4 100644 --- a/dlls/d3d9/vertexdeclaration.c +++ b/dlls/d3d9/vertexdeclaration.c @@ -237,13 +237,21 @@ static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDevice(LPDIRECT3DVERTEX static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDeclaration(LPDIRECT3DVERTEXDECLARATION9 iface, D3DVERTEXELEMENT9* pDecl, UINT* pNumElements) { IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface; - DWORD NumElements; - HRESULT hr; - TRACE("(%p) : Relay\n", iface); - hr = IWineD3DVertexDeclaration_GetDeclaration(This->wineD3DVertexDeclaration, pDecl, &NumElements); - *pNumElements = NumElements; - return hr; + TRACE("(%p) : pDecl %p, pNumElements %p)\n", This, pDecl, pNumElements); + + *pNumElements = This->element_count; + + /* Passing a NULL pDecl is used to just retrieve the number of elements */ + if (!pDecl) { + TRACE("NULL pDecl passed. Returning D3D_OK.\n"); + return D3D_OK; + } + + TRACE("Copying %p to %p\n", This->elements, pDecl); + CopyMemory(pDecl, This->elements, This->element_count * sizeof(D3DVERTEXELEMENT9)); + + return D3D_OK; } static const IDirect3DVertexDeclaration9Vtbl Direct3DVertexDeclaration9_Vtbl = @@ -257,12 +265,41 @@ static const IDirect3DVertexDeclaration9Vtbl Direct3DVertexDeclaration9_Vtbl = IDirect3DVertexDeclaration9Impl_GetDeclaration }; +static size_t convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elements, WINED3DVERTEXELEMENT **wined3d_elements) { + const D3DVERTEXELEMENT9* element; + size_t element_count = 1; + size_t i; + + TRACE("d3d9_elements %p, wined3d_elements %p\n", d3d9_elements, wined3d_elements); + + element = d3d9_elements; + while (element++->Stream != 0xff && element_count++ < 128); + + if (element_count == 128) { + return 0; + } + + *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(WINED3DVERTEXELEMENT)); + if (!*wined3d_elements) { + FIXME("Memory allocation failed\n"); + return 0; + } + + for (i = 0; i < element_count; ++i) { + CopyMemory(*wined3d_elements + i, d3d9_elements + i, sizeof(D3DVERTEXELEMENT9)); + (*wined3d_elements)[i].Reg = -1; + } + + return element_count; +} /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9 iface, CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; IDirect3DVertexDeclaration9Impl *object = NULL; + WINED3DVERTEXELEMENT* wined3d_elements; + size_t element_count; HRESULT hr = D3D_OK; TRACE("(%p) : Relay\n", iface); @@ -270,16 +307,37 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9 WARN("(%p) : Caller passed NULL As ppDecl, returning D3DERR_INVALIDCALL\n",This); return D3DERR_INVALIDCALL; } + + element_count = convert_to_wined3d_declaration(pVertexElements, &wined3d_elements); + if (!element_count) { + FIXME("(%p) : Error parsing vertex declaration\n", This); + return D3DERR_INVALIDCALL; + } + /* Allocate the storage for the device */ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexDeclaration9Impl)); if (NULL == object) { + HeapFree(GetProcessHeap(), 0, wined3d_elements); FIXME("Allocation of memory failed, returning D3DERR_OUTOFVIDEOMEMORY\n"); return D3DERR_OUTOFVIDEOMEMORY; } object->lpVtbl = &Direct3DVertexDeclaration9_Vtbl; object->ref = 1; - hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, pVertexElements, &object->wineD3DVertexDeclaration, (IUnknown *)object); + + object->elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(D3DVERTEXELEMENT9)); + if (!object->elements) { + HeapFree(GetProcessHeap(), 0, wined3d_elements); + HeapFree(GetProcessHeap(), 0, object); + ERR("Memory allocation failed\n"); + return D3DERR_OUTOFVIDEOMEMORY; + } + CopyMemory(object->elements, pVertexElements, element_count * sizeof(D3DVERTEXELEMENT9)); + object->element_count = element_count; + + hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wineD3DVertexDeclaration, (IUnknown *)object, wined3d_elements, element_count); + + HeapFree(GetProcessHeap(), 0, wined3d_elements); if (FAILED(hr)) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 60fe8dae5d6..65af9eeb0a3 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1658,15 +1658,19 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, U /***** * Vertex Declaration *****/ -static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface, CONST VOID* pDeclaration, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *parent) { +static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface, IWineD3DVertexDeclaration** ppVertexDeclaration, + IUnknown *parent, const WINED3DVERTEXELEMENT *elements, size_t element_count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DVertexDeclarationImpl *object = NULL; HRESULT hr = WINED3D_OK; - TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, pDeclaration, ppVertexDeclaration); + + TRACE("(%p) : directXVersion %u, elements %p, element_count %d, ppDecl=%p\n", + This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, elements, element_count, ppVertexDeclaration); + D3DCREATEOBJECTINSTANCE(object, VertexDeclaration) object->allFVF = 0; - hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, (void *)pDeclaration); + hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, elements, element_count); return hr; } diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 9697d02bdda..019d2c90a6e 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -373,40 +373,6 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; return WINED3D_OK; } -static HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DVertexDeclaration* iface, const D3DVERTEXELEMENT9* pDecl) { - IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; - const D3DVERTEXELEMENT9* pToken = pDecl; - int i; - - TRACE("(%p) : pDecl(%p)\n", This, pDecl); - - This->declaration9NumElements = 1; - for(pToken = pDecl;0xFF != pToken->Stream && This->declaration9NumElements < 128 ; pToken++) This->declaration9NumElements++; - - if (This->declaration9NumElements == 128) { - FIXME("?(%p) Error parsing vertex declaration\n", This); - return WINED3DERR_INVALIDCALL; - } - - - /* copy the declaration */ - This->pDeclaration9 = HeapAlloc(GetProcessHeap(), 0, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9)); - memcpy(This->pDeclaration9, pDecl, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9)); - - /* copy to wine style declaration */ - This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, This->declaration9NumElements * sizeof(WINED3DVERTEXELEMENT)); - for(i = 0; i < This->declaration9NumElements; ++i) { - memcpy(This->pDeclarationWine + i, This->pDeclaration9 + i, sizeof(D3DVERTEXELEMENT9)); - This->pDeclarationWine[i].Reg = -1; - TRACE("Adding element %d:\n", i); - dump_wined3dvertexelement(&This->pDeclarationWine[i]); - } - - This->declarationWNumElements = This->declaration9NumElements; - - return WINED3D_OK; -} - /* ******************************************* IWineD3DVertexDeclaration IUnknown parts follow ******************************************* */ @@ -438,7 +404,6 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat ref = InterlockedDecrement(&This->ref); if (ref == 0) { HeapFree(GetProcessHeap(), 0, This->pDeclaration8); - HeapFree(GetProcessHeap(), 0, This->pDeclaration9); HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); HeapFree(GetProcessHeap(), 0, This->constants); HeapFree(GetProcessHeap(), 0, This); @@ -495,61 +460,47 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration8(IWineD3DVert return WINED3D_OK; } -static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration9(IWineD3DVertexDeclaration* iface, D3DVERTEXELEMENT9* pData, DWORD* pNumElements) { +static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface, + WINED3DVERTEXELEMENT *elements, size_t *element_count) { IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; + HRESULT hr = WINED3D_OK; - TRACE("(This %p, pData %p, pNumElements %p)\n", This, pData, pNumElements); - - TRACE("Setting *pNumElements to %d\n", This->declaration9NumElements); - *pNumElements = This->declaration9NumElements; + TRACE("(%p) : d3d version %d, elements %p, element_count %p\n", + This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion, elements, element_count); - /* Passing a NULL pData is used to just retrieve the number of elements */ - if (!pData) { - TRACE("NULL pData passed. Returning WINED3D_OK.\n"); - return WINED3D_OK; + if (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion == 8) { + /* FIXME: This is an ugly hack of course... */ + hr = IWineD3DVertexDeclarationImpl_GetDeclaration8(iface, (DWORD *)elements, element_count); + } else { + *element_count = This->declarationWNumElements; + if (elements) { + CopyMemory(elements, This->pDeclarationWine, This->declarationWNumElements * sizeof(WINED3DVERTEXELEMENT)); + } } - TRACE("Copying %p to %p\n", This->pDeclaration9, pData); - memcpy(pData, This->pDeclaration9, This->declaration9NumElements * sizeof(*pData)); - return WINED3D_OK; -} - -static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface, VOID *pData, DWORD *pSize) { - IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; - HRESULT hr = WINED3D_OK; - - TRACE("(%p) : d3d version %d r\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); - switch (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion) { - case 8: - hr = IWineD3DVertexDeclarationImpl_GetDeclaration8(iface, (DWORD *)pData, pSize); - break; - case 9: - hr = IWineD3DVertexDeclarationImpl_GetDeclaration9(iface, (D3DVERTEXELEMENT9 *)pData, pSize); - break; - default: - FIXME("(%p) : Unsupported DirectX version %u\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); - break; - } return hr; } -static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface, VOID *pDecl) { +static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface, + const WINED3DVERTEXELEMENT *elements, size_t element_count) { IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; HRESULT hr = WINED3D_OK; TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); - switch (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion) { - case 8: + + if (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion == 8) { TRACE("Parsing declaration 8\n"); - hr = IWineD3DVertexDeclarationImpl_ParseDeclaration8(iface, (CONST DWORD *)pDecl); - break; - case 9: - TRACE("Parsing declaration 9\n"); - hr = IWineD3DVertexDeclarationImpl_ParseDeclaration9(iface, (CONST D3DVERTEXELEMENT9 *)pDecl); - break; - default: - FIXME("(%p) : Unsupported DirectX version %u\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); - break; + /* FIXME: This is an ugly hack of course... */ + hr = IWineD3DVertexDeclarationImpl_ParseDeclaration8(iface, (CONST DWORD *)elements); + } else { + This->declarationWNumElements = element_count; + This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); + if (!This->pDeclarationWine) { + ERR("Memory allocation failed\n"); + hr = WINED3DERR_OUTOFVIDEOMEMORY; + } else { + CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count); + } } TRACE("Returning\n"); return hr; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b23cdcdd403..3d8a7ad94b9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1120,10 +1120,6 @@ typedef struct IWineD3DVertexDeclarationImpl { DWORD* pDeclaration8; DWORD declaration8Length; - /** dx9+ */ - D3DVERTEXELEMENT9 *pDeclaration9; - UINT declaration9NumElements; - WINED3DVERTEXELEMENT *pDeclarationWine; UINT declarationWNumElements; diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 093e18f23ce..89085976937 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -356,7 +356,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool, struct IWineD3DCubeTexture** ppCubeTexture, HANDLE* pSharedHandle, IUnknown *parent, D3DCB_CREATESURFACEFN pFn) PURE; STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, struct IWineD3DQuery **ppQuery, IUnknown *pParent); STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2); - STDMETHOD(CreateVertexDeclaration)(THIS_ CONST VOID* pDeclaration, struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent) PURE; + STDMETHOD(CreateVertexDeclaration)(THIS_ struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent, const WINED3DVERTEXELEMENT *elements, size_t element_count) PURE; STDMETHOD(CreateVertexShader)(THIS_ struct IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE; STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE; STDMETHOD_(HRESULT,CreatePalette)(THIS_ DWORD Flags, PALETTEENTRY *PalEnt, struct IWineD3DPalette **Palette, IUnknown *Parent); @@ -495,7 +495,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) #define IWineD3DDevice_CreateCubeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g,h,i) #define IWineD3DDevice_CreateQuery(p,a,b,c) (p)->lpVtbl->CreateQuery(p,a,b,c) #define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e) -#define IWineD3DDevice_CreateVertexDeclaration(p,b,c,d) (p)->lpVtbl->CreateVertexDeclaration(p,b,c,d) +#define IWineD3DDevice_CreateVertexDeclaration(p,a,b,c,d) (p)->lpVtbl->CreateVertexDeclaration(p,a,b,c,d) #define IWineD3DDevice_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) #define IWineD3DDevice_CreatePixelShader(p,a,b,c) (p)->lpVtbl->CreatePixelShader(p,a,b,c) #define IWineD3DDevice_CreatePalette(p, a, b, c, d) (p)->lpVtbl->CreatePalette(p, a, b, c, d) @@ -1263,8 +1263,8 @@ DECLARE_INTERFACE_(IWineD3DVertexDeclaration,IWineD3DBase) STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE; /*** IWineD3DVertexDeclaration methods ***/ STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE; - STDMETHOD(GetDeclaration)(THIS_ VOID *pDecl, DWORD *pSize) PURE; - STDMETHOD(SetDeclaration)(THIS_ VOID *pDecl) PURE; + STDMETHOD(GetDeclaration)(THIS_ WINED3DVERTEXELEMENT *elements, size_t *elements_count) PURE; + STDMETHOD(SetDeclaration)(THIS_ const WINED3DVERTEXELEMENT *elements, size_t element_count) PURE; }; #undef INTERFACE @@ -1278,7 +1278,7 @@ DECLARE_INTERFACE_(IWineD3DVertexDeclaration,IWineD3DBase) /*** IWineD3DVertexDeclaration methods ***/ #define IWineD3DVertexDeclaration_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DVertexDeclaration_GetDeclaration(p,a,b) (p)->lpVtbl->GetDeclaration(p,a,b) -#define IWineD3DVertexDeclaration_SetDeclaration(p,b) (p)->lpVtbl->SetDeclaration(p,b) +#define IWineD3DVertexDeclaration_SetDeclaration(p,a,b) (p)->lpVtbl->SetDeclaration(p,a,b) #endif /***************************************************************************** -- 2.11.4.GIT