Module: wine Branch: master Commit: 6ec6c941fabbbb7cbfedce17017bee40ded16709 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6ec6c941fabbbb7cbfedce1701...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sat Aug 25 00:09:33 2007 +0200
wined3d: BaseVertexIndex can be negative.
---
dlls/d3d8/device.c | 9 ++++++++- dlls/wined3d/device.c | 4 ++-- dlls/wined3d/drawprim.c | 20 ++++++++++++++++++-- dlls/wined3d/wined3d_private.h | 4 ++-- include/wine/wined3d_interface.h | 4 ++-- 5 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 74a0d13..205120e 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1803,6 +1803,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, I TRACE("(%p) Relay\n", This);
EnterCriticalSection(&d3d8_cs); + /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that + * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large + * vertex buffers can't be created to address them with an index that requires the 32nd bit + * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least + * problem) + */ IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex); hr = IWineD3DDevice_SetIndices(This->WineD3DDevice, pIndexData ? ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer : NULL); @@ -1822,7 +1828,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I }
EnterCriticalSection(&d3d8_cs); - IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, pBaseVertexIndex); + /* The case from UINT to INT is safe because d3d8 will never set negative values */ + IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex); rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData); if (SUCCEEDED(rc) && retIndexData) { IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 425ffe2..2b2dac5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2829,7 +2829,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetIndices(IWineD3DDevice *iface, IWine }
/* Method to offer d3d9 a simple way to set the base vertex index without messing with the index buffer */ -static HRESULT WINAPI IWineD3DDeviceImpl_SetBaseVertexIndex(IWineD3DDevice *iface, UINT BaseIndex) { +static HRESULT WINAPI IWineD3DDeviceImpl_SetBaseVertexIndex(IWineD3DDevice *iface, INT BaseIndex) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p)->(%d)\n", This, BaseIndex);
@@ -2849,7 +2849,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetBaseVertexIndex(IWineD3DDevice *ifac return WINED3D_OK; }
-static HRESULT WINAPI IWineD3DDeviceImpl_GetBaseVertexIndex(IWineD3DDevice *iface, UINT* base_index) { +static HRESULT WINAPI IWineD3DDeviceImpl_GetBaseVertexIndex(IWineD3DDevice *iface, INT* base_index) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p) : base_index %p\n", This, base_index);
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 3a47912..2dcaa5d 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -178,6 +178,7 @@ void primitiveDeclarationConvertToStridedData( if (This->stateBlock->streamSource[element->Stream] == NULL) continue;
+ stride = This->stateBlock->streamStride[element->Stream]; if (This->stateBlock->streamIsUP) { TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); streamVBO = 0; @@ -185,6 +186,22 @@ void primitiveDeclarationConvertToStridedData( } else { TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO); + + /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets + * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory + * sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap + * around to some big value. Hope that with the indices, the driver wraps it back internally. If + * not, drawStridedSlow is needed, including a vertex buffer path. + */ + if(This->stateBlock->loadBaseVertexIndex < 0) { + WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); + streamVBO = 0; + data = ((IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; + if(data + This->stateBlock->loadBaseVertexIndex * stride < 0) { + FIXME("System memory vertex data load offset is negative!\n"); + } + } + if(fixup) { if( streamVBO != 0) *fixup = TRUE; else if(*fixup && !useVertexShaderFunction && @@ -195,7 +212,6 @@ void primitiveDeclarationConvertToStridedData( } } } - stride = This->stateBlock->streamStride[element->Stream]; data += element->Offset; reg = element->Reg;
@@ -284,7 +300,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData DWORD specularColor = 0; /* Specular Color */ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; UINT *streamOffset = This->stateBlock->streamOffset; - DWORD SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex; + long SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0328780..61a6385 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1343,8 +1343,8 @@ struct IWineD3DStateBlockImpl
/* Indices */ IWineD3DIndexBuffer* pIndexData; - UINT baseVertexIndex; - UINT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */ + INT baseVertexIndex; + INT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
/* Transform */ WINED3DMATRIX transforms[HIGHEST_TRANSFORMSTATE + 1]; diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 35430b9..603eeb5 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -405,8 +405,8 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, WINED3DGAMMARAMP* pRamp) PURE; STDMETHOD(SetIndices)(THIS_ struct IWineD3DIndexBuffer * pIndexData) PURE; STDMETHOD(GetIndices)(THIS_ struct IWineD3DIndexBuffer ** ppIndexData) PURE; - STDMETHOD(SetBaseVertexIndex)(THIS_ UINT baseIndex); - STDMETHOD(GetBaseVertexIndex)(THIS_ UINT *baseIndex); + STDMETHOD(SetBaseVertexIndex)(THIS_ INT baseIndex); + STDMETHOD(GetBaseVertexIndex)(THIS_ INT *baseIndex); STDMETHOD(SetLight)(THIS_ DWORD Index,CONST WINED3DLIGHT * pLight) PURE; STDMETHOD(GetLight)(THIS_ DWORD Index,WINED3DLIGHT * pLight) PURE; STDMETHOD(SetLightEnable)(THIS_ DWORD Index,BOOL Enable) PURE;