Module: wine Branch: master Commit: 527295e57f70358fd9dd6b5004da8bf3cd716ea3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=527295e57f70358fd9dd6b5004...
Author: Stefan Dösinger stefandoesinger@gmx.at Date: Tue Jun 19 22:20:26 2007 +0200
d3d8: Convert fvfs to vertex declarations.
---
dlls/d3d8/d3d8_private.h | 10 +++++++ dlls/d3d8/device.c | 64 +++++++++++++++++++++++++++++++++++++++++++-- dlls/d3d8/directx.c | 9 ++++++ 3 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 3182427..229762b 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -167,6 +167,12 @@ extern const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl;
typedef void * shader_handle;
+struct FvfToDecl +{ + DWORD fvf; + IWineD3DVertexDeclaration *decl; +}; + struct IDirect3DDevice8Impl { /* IUnknown fields */ @@ -179,6 +185,10 @@ struct IDirect3DDevice8Impl shader_handle *shader_handles; shader_handle *free_shader_handles;
+ /* FVF management */ + struct FvfToDecl *decls; + UINT numConvertedDecls, declArraySize; + /* Avoids recursion with nested ReleaseRef to 0 */ BOOL inDestruction; }; diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index f7bc68f..0b2436d 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -97,9 +97,16 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { TRACE("(%p) : ReleaseRef to %d\n", This, ref);
if (ref == 0) { + int i; + TRACE("Releasing wined3d device %p\n", This->WineD3DDevice); EnterCriticalSection(&d3d8_cs); This->inDestruction = TRUE; + + for(i = 0; i < This->numConvertedDecls; i++) { + IWineD3DVertexDeclaration_Release(This->decls[i].decl); + } + IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface, D3D8CB_DestroySwapChain); IWineD3DDevice_Release(This->WineD3DDevice); HeapFree(GetProcessHeap(), 0, This->shader_handles); @@ -1566,6 +1573,59 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 return hrc; }
+IWineD3DVertexDeclaration *IDirect3DDevice8Impl_FindDecl(IDirect3DDevice8Impl *This, DWORD fvf) +{ + HRESULT hr; + IWineD3DVertexDeclaration* pDecl = NULL; + int p, low, high; /* deliberately signed */ + struct FvfToDecl *convertedDecls = This->decls; + + TRACE("Searching for declaration for fvf %08x... ", fvf); + + low = 0; + high = This->numConvertedDecls - 1; + while(low <= high) { + p = (low + high) >> 1; + TRACE("%d ", p); + if(convertedDecls[p].fvf == fvf) { + TRACE("found %p\n", convertedDecls[p].decl); + return convertedDecls[p].decl; + } else if(convertedDecls[p].fvf < fvf) { + low = p + 1; + } else { + high = p - 1; + } + } + TRACE("not found. Creating and inserting at position %d.\n", low); + + hr = IWineD3DDevice_CreateVertexDeclarationFromFVF(This->WineD3DDevice, + &pDecl, + (IUnknown *) This, + fvf); + if (FAILED(hr)) return NULL; + + if(This->declArraySize == This->numConvertedDecls) { + int grow = This->declArraySize / 2; + convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls, + sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow)); + if(!convertedDecls) { + /* This will destroy it */ + IWineD3DVertexDeclaration_Release(pDecl); + return NULL; + } + This->decls = convertedDecls; + This->declArraySize += grow; + } + + memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(convertedDecls[0]) * (This->numConvertedDecls - low)); + convertedDecls[low].decl = pDecl; + convertedDecls[low].fvf = fvf; + This->numConvertedDecls++; + + TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls); + return pDecl; +} + static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; HRESULT hrc = D3D_OK; @@ -1575,9 +1635,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 ifa if (VS_HIGHESTFIXEDFXF >= pShader) { TRACE("Setting FVF, %d %d\n", VS_HIGHESTFIXEDFXF, pShader); IWineD3DDevice_SetFVF(This->WineD3DDevice, pShader); - - /* Call SetVertexShader with a NULL shader to set the vertexshader in the stateblock to NULL. */ - IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, NULL); + IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, IDirect3DDevice8Impl_FindDecl(This, pShader)); IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL); } else { TRACE("Setting shader\n"); diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 62d833a..54c87e6 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -472,6 +472,15 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte *ppReturnedDeviceInterface = NULL; }
+ object->declArraySize = 16; + object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls)); + if(!object->decls) { + ERR("Out of memory\n"); + IWineD3DDevice_Release(object->WineD3DDevice); + HeapFree(GetProcessHeap(), 0, object); + *ppReturnedDeviceInterface = NULL; + hr = E_OUTOFMEMORY; + } return hr; }