d3d9: Don't store the d3d9 declaration in the wined3d object.

This commit is contained in:
H. Verbeet 2007-02-13 23:12:36 +01:00 committed by Alexandre Julliard
parent 32e5cac2be
commit dea795f7ac
7 changed files with 110 additions and 98 deletions

View file

@ -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);

View file

@ -476,6 +476,9 @@ typedef struct IDirect3DVertexDeclaration9Impl {
const IDirect3DVertexDeclaration9Vtbl *lpVtbl;
LONG ref;
D3DVERTEXELEMENT9 *elements;
size_t element_count;
/* IDirect3DVertexDeclaration9 fields */
IWineD3DVertexDeclaration *wineD3DVertexDeclaration;

View file

@ -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)) {

View file

@ -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;
}

View file

@ -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) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
TRACE("(This %p, pData %p, pNumElements %p)\n", This, pData, pNumElements);
TRACE("Setting *pNumElements to %d\n", This->declaration9NumElements);
*pNumElements = This->declaration9NumElements;
/* 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;
}
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) {
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface,
WINED3DVERTEXELEMENT *elements, size_t *element_count) {
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;
TRACE("(%p) : d3d version %d, elements %p, element_count %p\n",
This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion, elements, element_count);
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));
}
}
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;

View file

@ -1120,10 +1120,6 @@ typedef struct IWineD3DVertexDeclarationImpl {
DWORD* pDeclaration8;
DWORD declaration8Length;
/** dx9+ */
D3DVERTEXELEMENT9 *pDeclaration9;
UINT declaration9NumElements;
WINED3DVERTEXELEMENT *pDeclarationWine;
UINT declarationWNumElements;

View file

@ -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
/*****************************************************************************