[1/10] WineD3D: Use the baseVertexIndex in the stateblock
Stefan Dösinger
stefandoesinger at gmx.at
Tue Jan 2 14:07:39 CST 2007
In d3d8 the base vertex index is a parameter to SetIndices, in d3d7
and d3d9 it is a parameter to drawIndexedPrimitiveVB /
drawIndexedPrimitive. Right now d3d8 stores the device index in the
device and passes it to drawIndexedPrimitive. This is incorrect
because it has to be tracked in the stateblock and considered when
stateblocks are applied.
This patch removes the BaseVertexIndex paramter to
DrawIndexedPrimitive in wined3d. ddraw and d3d9 use the index buffer
parameter for that. For performance reason a SetBaseVertexIndex
method is added to wined3d to allow d3d9 to set the parameter without
messing around with the index buffer and its reference count.
The opengl arrays are loaded according to the baseVertexIndex
parameter. For non-indexed drawing the offset is corrected with the
start parameter to glDrawArrays. The man page does not forbid
negative start numbers if it is in a valid area withhin the setup
arrays. It does not explicitly mention that it is valid, but the
parameter is a signed int.
-------------- next part --------------
From 74b00ebc989dade92b4196c41a478d3a0d3085f5 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=C3=B6singer?= <stefan at imac.local>
Date: Tue, 2 Jan 2007 18:54:38 +0100
Subject: [PATCH] WineD3D: Use the baseVertexIndex stateblock member and parameter to SetIndices
---
dlls/d3d8/d3d8_private.h | 3 --
dlls/d3d8/device.c | 11 ++-----
dlls/d3d9/device.c | 7 +++-
dlls/ddraw/device.c | 3 +-
dlls/wined3d/device.c | 56 ++++++++++++++++++++++++++--------
dlls/wined3d/drawprim.c | 63 +++++++++++++++++---------------------
dlls/wined3d/vertexbuffer.c | 1 -
dlls/wined3d/wined3d_private.h | 3 +-
include/wine/wined3d_interface.h | 6 ++--
9 files changed, 86 insertions(+), 67 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index fe642a6..0466137 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -177,9 +177,6 @@ struct IDirect3DDevice8Impl
shader_handle *shader_handles;
shader_handle *free_shader_handles;
-/* FIXME: Move *baseVertexIndex somewhere sensible like wined3d */
- UINT baseVertexIndex;
-
/* Avoids recursion with nested ReleaseRef to 0 */
BOOL inDestruction;
};
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index e9bc3ac..b9aea7f 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -1134,7 +1134,7 @@ static HRESULT WINAPI IDirect3DDevice8Im
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) Relay\n" , This);
- return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, This->baseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
+ return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
}
static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
@@ -1307,18 +1307,15 @@ static HRESULT WINAPI IDirect3DDevice8Im
static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) Relay\n", This);
-/* FIXME: store base vertex index properly */
- This->baseVertexIndex = baseVertexIndex;
return IWineD3DDevice_SetIndices(This->WineD3DDevice,
NULL == pIndexData ? NULL : ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer,
- 0);
+ baseVertexIndex);
}
static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
IWineD3DIndexBuffer *retIndexData = NULL;
HRESULT rc = D3D_OK;
- UINT tmp;
TRACE("(%p) Relay\n", This);
@@ -1326,7 +1323,7 @@ static HRESULT WINAPI IDirect3DDevice8Im
return D3DERR_INVALIDCALL;
}
- rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData, &tmp);
+ rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData, pBaseVertexIndex);
if (D3D_OK == rc && NULL != retIndexData) {
IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
IWineD3DIndexBuffer_Release(retIndexData);
@@ -1334,8 +1331,6 @@ static HRESULT WINAPI IDirect3DDevice8Im
if(rc != D3D_OK) FIXME("Call to GetIndices failed\n");
*ppIndexData = NULL;
}
-/* FIXME: store base vertex index properly */
- *pBaseVertexIndex = This->baseVertexIndex;
return rc;
}
static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* ppShader) {
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 0b49d2f..aa788af 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -716,9 +716,12 @@ static HRESULT WINAPI IDirect3DDevice9Im
static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType,
INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
- IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+ IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
TRACE("(%p) Relay\n" , This);
- return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
+
+ /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
+ IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
+ return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
}
static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9 iface, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index c05089f..1e28fb0 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3697,7 +3697,7 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimiti
/* Set the index stream */
hr = IWineD3DDevice_SetIndices(This->wineD3DDevice,
This->indexbuffer,
- 0);
+ StartVertex);
/* Set the vertex stream source */
hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
@@ -3714,7 +3714,6 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimiti
hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
PrimitiveType,
- StartVertex,
0 /* minIndex */,
NumVertices,
0 /* StartIndex */,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 58f512d..d5a1f1e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2992,6 +2992,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
UINT BaseVertexIndex) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DIndexBuffer *oldIdxs;
+ UINT oldBaseIndex = This->updateStateBlock->baseVertexIndex;
TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
oldIdxs = This->updateStateBlock->pIndexData;
@@ -3013,6 +3014,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
if (NULL != oldIdxs) {
IWineD3DIndexBuffer_Release(oldIdxs);
}
+
+ /* So far only the base vertex index is tracked */
+ if(BaseVertexIndex != oldBaseIndex) {
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
+ }
return WINED3D_OK;
}
@@ -3034,6 +3040,26 @@ static HRESULT WINAPI IWineD3DDeviceImpl
return WINED3D_OK;
}
+/* 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) {
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ TRACE("(%p)->(%d)\n", This, BaseIndex);
+
+ if(This->updateStateBlock->baseVertexIndex == BaseIndex) {
+ TRACE("Application is setting the old value over, nothing to do\n");
+ return WINED3D_OK;
+ }
+
+ This->updateStateBlock->baseVertexIndex = BaseIndex;
+
+ if (This->isRecordingState) {
+ TRACE("Recording... not performing anything\n");
+ return WINED3D_OK;
+ }
+ IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
+ return WINED3D_OK;
+}
+
/*****
* Get / Set Viewports
*****/
@@ -4669,18 +4695,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl
TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType,
debug_d3dprimitivetype(PrimitiveType),
StartVertex, PrimitiveCount);
- drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, 0/* NumVertices */, -1 /* indxStart */,
- 0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */, NULL);
-
+ if(StartVertex - This->stateBlock->baseVertexIndex < 0) ERR("Drawing negative\n");
+ /* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */
+ drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex - This->stateBlock->baseVertexIndex, 0/* NumVertices */, -1 /* indxStart */,
+ 0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */, NULL);
return WINED3D_OK;
}
/* TODO: baseVIndex needs to be provided from This->stateBlock->baseVertexIndex when called from d3d8 */
static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *iface,
WINED3DPRIMITIVETYPE PrimitiveType,
- INT baseVIndex, UINT minIndex,
- UINT NumVertices, UINT startIndex, UINT primCount) {
+ UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
UINT idxStride = 2;
@@ -4690,9 +4716,9 @@ static HRESULT WINAPI IWineD3DDeviceIm
pIB = This->stateBlock->pIndexData;
This->stateBlock->streamIsUP = FALSE;
- TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, baseVidx=%d, countP=%d\n", This,
+ TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d\n", This,
PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
- minIndex, NumVertices, startIndex, baseVIndex, primCount);
+ minIndex, NumVertices, startIndex, primCount);
IWineD3DIndexBuffer_GetDesc(pIB, &IdxBufDsc);
if (IdxBufDsc.Format == WINED3DFMT_INDEX16) {
@@ -4701,7 +4727,7 @@ static HRESULT WINAPI IWineD3DDeviceIm
idxStride = 4;
}
- drawPrimitive(iface, PrimitiveType, primCount, baseVIndex, NumVertices, startIndex,
+ drawPrimitive(iface, PrimitiveType, primCount, 0, NumVertices, startIndex,
idxStride, ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex, NULL);
return WINED3D_OK;
@@ -4726,10 +4752,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
This->stateBlock->streamStride[0] = VertexStreamZeroStride;
This->stateBlock->streamIsUP = TRUE;
- /* Mark the state dirty until we have nicer tracking */
- IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
-
- drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* start vertex */, 0 /* NumVertices */,
+ drawPrimitive(iface, PrimitiveType, PrimitiveCount, -This->stateBlock->baseVertexIndex /* start vertex */, 0 /* NumVertices */,
0 /* indxStart*/, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */, NULL);
/* MSDN specifies stream zero settings must be set to NULL */
@@ -4774,6 +4797,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
/* Mark the state dirty until we have nicer tracking */
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+ /* Set to 0 as per msdn. Do it now due to the stream source loading during drawPrimitive */
+ This->stateBlock->baseVertexIndex = 0;
drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* vertexStart */, NumVertices, 0 /* indxStart */, idxStride, pIndexData, MinVertexIndex, NULL);
@@ -4788,8 +4813,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl
static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided (IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
- /* Mark the state dirty until we have nicer tracking */
+ /* Mark the state dirty until we have nicer tracking
+ * its fine to change baseVertexIndex because that call is only called by ddraw which does not need
+ * that value.
+ */
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+ This->stateBlock->baseVertexIndex = 0;
drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, 0, NULL, 0, DrawPrimStrideData);
return WINED3D_OK;
}
@@ -6689,6 +6718,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_
IWineD3DDeviceImpl_GetGammaRamp,
IWineD3DDeviceImpl_SetIndices,
IWineD3DDeviceImpl_GetIndices,
+ IWineD3DDeviceImpl_SetBasevertexIndex,
IWineD3DDeviceImpl_SetLight,
IWineD3DDeviceImpl_GetLight,
IWineD3DDeviceImpl_SetLightEnable,
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 63e1cae..4e39ae1 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -391,8 +391,7 @@ static BOOL fixed_get_input(
void primitiveDeclarationConvertToStridedData(
IWineD3DDevice *iface,
BOOL useVertexShaderFunction,
- WineDirect3DVertexStridedData *strided,
- LONG BaseVertexIndex,
+ WineDirect3DVertexStridedData *strided,
BOOL *fixup) {
/* We need to deal with frequency data!*/
@@ -442,7 +441,6 @@ void primitiveDeclarationConvertToStride
}
}
stride = This->stateBlock->streamStride[element->Stream];
- data += (BaseVertexIndex * stride);
data += element->Offset;
reg = element->Reg;
@@ -594,7 +592,7 @@ void primitiveConvertFVFtoOffset(DWORD t
}
}
-void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *strided, LONG BaseVertexIndex, BOOL *fixup) {
+void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *strided, BOOL *fixup) {
short LoopThroughTo = 0;
short nStream;
@@ -646,10 +644,6 @@ #endif
if (thisFVF == 0) continue;
/* Now convert the stream into pointers */
-
- /* Shuffle to the beginning of the vertexes to render and index from there */
- data = data + (BaseVertexIndex * stride);
-
primitiveConvertFVFtoOffset(thisFVF, stride, data, strided, streamVBO);
}
}
@@ -832,7 +826,7 @@ static void loadNumberedArrays(
WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
strided->u.input[i].dwStride,
- strided->u.input[i].lpData));
+ strided->u.input[i].lpData + This->stateBlock->baseVertexIndex * strided->u.input[i].dwStride));
GL_EXTCALL(glEnableVertexAttribArrayARB(i));
}
}
@@ -876,7 +870,7 @@ #if 1
#endif
TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
- sd->u.s.blendWeights.lpData, sd->u.s.blendWeights.dwStride);
+ sd->u.s.blendWeights.lpData + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride);
/* FIXME("TODO\n");*/
/* Note dwType == float3 or float4 == 2 or 3 */
@@ -891,7 +885,7 @@ #endif
VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
sd->u.s.blendWeights.dwStride,
- sd->u.s.blendWeights.lpData));
+ sd->u.s.blendWeights.lpData + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride));
if(curVBO != sd->u.s.blendWeights.VBO) {
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
@@ -903,7 +897,7 @@ #endif
WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
sd->u.s.blendWeights.dwStride,
- sd->u.s.blendWeights.lpData);
+ sd->u.s.blendWeights.lpData + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
checkGLcall("glWeightPointerARB");
@@ -923,7 +917,7 @@ #if 0
WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
sd->u.s.blendWeights.dwStride,
- sd->u.s.blendWeights.lpData);
+ sd->u.s.blendWeights.lpData + This->stateBlock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
@@ -955,7 +949,7 @@ #if 0 /* FOG --------------------------
(GL_EXTCALL)(FogCoordPointerEXT)(
WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
sd->u.s.fog.dwStride,
- sd->u.s.fog.lpData);
+ sd->u.s.fog.lpData + This->stateBlock->baseVertexIndex * sd->u.s.fog.dwStride);
} else {
/* don't bother falling back to 'slow' as we don't support software FOG yet. */
/* FIXME: fixme once */
@@ -979,7 +973,7 @@ #if 0 /* tangents ---------------------
(GL_EXTCALL)(TangentPointerEXT)(
WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
sd->u.s.tangent.dwStride,
- sd->u.s.tangent.lpData);
+ sd->u.s.tangent.lpData + This->stateBlock->baseVertexIndex * sd->u.s.tangent.dwStride);
} else {
glDisable(GL_TANGENT_ARRAY_EXT);
}
@@ -988,7 +982,7 @@ #if 0 /* tangents ---------------------
(GL_EXTCALL)(BinormalPointerEXT)(
WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
sd->u.s.binormal.dwStride,
- sd->u.s.binormal.lpData);
+ sd->u.s.binormal.lpData + This->stateBlock->baseVertexIndex * sd->u.s.binormal.dwStride);
} else{
glDisable(GL_BINORMAL_ARRAY_EXT);
}
@@ -1041,12 +1035,12 @@ #endif
if(sd->u.s.position.VBO == 0) {
glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
- sd->u.s.position.dwStride, sd->u.s.position.lpData);
+ sd->u.s.position.dwStride, sd->u.s.position.lpData + This->stateBlock->baseVertexIndex * sd->u.s.position.dwStride);
} else {
glVertexPointer(
WINED3D_ATR_SIZE(sd->u.s.position.dwType),
WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
- sd->u.s.position.dwStride, sd->u.s.position.lpData);
+ sd->u.s.position.dwStride, sd->u.s.position.lpData + This->stateBlock->baseVertexIndex * sd->u.s.position.dwStride);
}
checkGLcall("glVertexPointer(...)");
glEnableClientState(GL_VERTEX_ARRAY);
@@ -1071,7 +1065,7 @@ #endif
glNormalPointer(
WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
sd->u.s.normal.dwStride,
- sd->u.s.normal.lpData);
+ sd->u.s.normal.lpData + This->stateBlock->baseVertexIndex * sd->u.s.normal.dwStride);
checkGLcall("glNormalPointer(...)");
glEnableClientState(GL_NORMAL_ARRAY);
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
@@ -1105,7 +1099,7 @@ #endif
}
glColorPointer(4, GL_UNSIGNED_BYTE,
sd->u.s.diffuse.dwStride,
- sd->u.s.diffuse.lpData);
+ sd->u.s.diffuse.lpData + This->stateBlock->baseVertexIndex * sd->u.s.diffuse.dwStride);
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
glEnableClientState(GL_COLOR_ARRAY);
checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
@@ -1132,7 +1126,7 @@ #endif
}
GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
sd->u.s.specular.dwStride,
- sd->u.s.specular.lpData);
+ sd->u.s.specular.lpData + This->stateBlock->baseVertexIndex * sd->u.s.specular.dwStride);
vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
@@ -1197,7 +1191,7 @@ #endif
WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
sd->u.s.texCoords[coordIdx].dwStride,
- sd->u.s.texCoords[coordIdx].lpData);
+ sd->u.s.texCoords[coordIdx].lpData + This->stateBlock->baseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
} else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
@@ -1216,7 +1210,7 @@ #endif
}
static void drawStridedFast(IWineD3DDevice *iface,UINT numberOfVertices, GLenum glPrimitiveType,
- const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
if (idxData != NULL /* This crashes sometimes!*/) {
@@ -1241,7 +1235,7 @@ #endif
/* Note first is now zero as we shuffled along earlier */
TRACE("(%p) : glDrawArrays(%x, 0, %d)\n", This, glPrimitiveType, numberOfVertices);
- glDrawArrays(glPrimitiveType, 0, numberOfVertices);
+ glDrawArrays(glPrimitiveType, startVertex, numberOfVertices);
checkGLcall("glDrawArrays");
}
@@ -1256,13 +1250,12 @@ #endif
static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
UINT NumVertexes, GLenum glPrimType,
- const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex) {
unsigned int textureNo = 0;
unsigned int texture_idx = 0;
const short *pIdxBufS = NULL;
const long *pIdxBufL = NULL;
- LONG SkipnStrides = 0;
LONG vx_index;
float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
float nx = 0.0f, ny = 0.0, nz = 0.0f; /* normal x,y,z coordinates */
@@ -1271,6 +1264,7 @@ static void drawStridedSlow(IWineD3DDevi
DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
DWORD specularColor = 0; /* Specular Color */
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+ LONG SkipnStrides = startVertex + This->stateBlock->baseVertexIndex;
TRACE("Using slow vertex array code\n");
@@ -1300,10 +1294,10 @@ static void drawStridedSlow(IWineD3DDevi
/* Indexed so work out the number of strides to skip */
if (idxSize == 2) {
VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
- SkipnStrides = pIdxBufS[startIdx + vx_index];
+ SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->baseVertexIndex;
} else {
VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
- SkipnStrides = pIdxBufL[startIdx + vx_index];
+ SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->baseVertexIndex;
}
}
@@ -1717,6 +1711,7 @@ inline static void drawPrimitiveDrawStri
BOOL useVertexShaderFunction,
BOOL usePixelShaderFunction,
WineDirect3DVertexStridedData *dataLocations,
+ ULONG baseVIndex,
UINT numberOfvertices,
UINT numberOfIndicies,
GLenum glPrimType,
@@ -1789,9 +1784,9 @@ #undef BUFFER_OR_DATA
/* Draw vertex-by-vertex */
if (useDrawStridedSlow)
- drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx);
+ drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
else
- drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx);
+ drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx, baseVIndex);
/* Cleanup any shaders */
This->shader_backend->shader_cleanup(usePixelShaderFunction, useVertexShaderFunction);
@@ -2019,8 +2014,8 @@ void drawPrimitive(IWineD3DDevice *iface
if (This->stateBlock->vertexDecl != NULL ||
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration != NULL)
- primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction,
- &This->strided_streams, StartVertexIndex, &fixup);
+ primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction,
+ &This->strided_streams, &fixup);
} else {
@@ -2030,7 +2025,7 @@ void drawPrimitive(IWineD3DDevice *iface
TRACE("================ FVF ===================\n");
memset(&This->strided_streams, 0, sizeof(This->strided_streams));
- primitiveConvertToStridedData(iface, &This->strided_streams, StartVertexIndex, &fixup);
+ primitiveConvertToStridedData(iface, &This->strided_streams, &fixup);
drawPrimitiveTraceDataLocations(&This->strided_streams);
}
@@ -2049,7 +2044,7 @@ void drawPrimitive(IWineD3DDevice *iface
numberOfVertices = calculatedNumberOfindices;
drawPrimitiveDrawStrided(iface, useVertexShaderFunction, usePixelShaderFunction,
- &This->strided_streams, numberOfVertices, calculatedNumberOfindices, glPrimType,
+ &This->strided_streams, StartVertexIndex, numberOfVertices, calculatedNumberOfindices, glPrimType,
idxData, idxSize, minIndex, StartIdx, fixup);
}
diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index 820309f..922d014 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -204,7 +204,6 @@ inline BOOL WINAPI IWineD3DVertexBufferI
primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
FALSE,
&strided,
- 0,
&ret /* buffer contains fixed data, ignored here */);
This->Flags &= ~VBFLAG_LOAD;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a6fe6c5..37f4664 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -385,13 +385,12 @@ void drawPrimitive(IWineD3DDevice *iface
int minIndex,
WineDirect3DVertexStridedData *DrawPrimStrideData);
-void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *strided, LONG BaseVertexIndex, BOOL *fixup);
+void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *strided, BOOL *fixup);
void primitiveDeclarationConvertToStridedData(
IWineD3DDevice *iface,
BOOL useVertexShaderFunction,
WineDirect3DVertexStridedData *strided,
- LONG BaseVertexIndex,
BOOL *fixup);
void primitiveConvertFVFtoOffset(DWORD thisFVF,
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index 4a5a051..8a685f0 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -397,6 +397,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD
STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, WINED3DGAMMARAMP* pRamp) PURE;
STDMETHOD(SetIndices)(THIS_ struct IWineD3DIndexBuffer * pIndexData,UINT BaseVertexIndex) PURE;
STDMETHOD(GetIndices)(THIS_ struct IWineD3DIndexBuffer ** ppIndexData,UINT * pBaseVertexIndex) PURE;
+ STDMETHOD(SetBaseVertexIndex)(THIS_ UINT 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;
@@ -458,7 +459,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD
STDMETHOD(Present)(THIS_ CONST RECT * pSourceRect,CONST RECT * pDestRect,HWND hDestWindowOverride,CONST RGNDATA * pDirtyRegion) PURE;
STDMETHOD(Clear)(THIS_ DWORD Count, CONST WINED3DRECT * pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) PURE;
STDMETHOD(DrawPrimitive)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) PURE;
- STDMETHOD(DrawIndexedPrimitive)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, INT baseVIdx, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) PURE;
+ STDMETHOD(DrawIndexedPrimitive)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT minIndex, UINT NumVertices, UINT startIndex, UINT primCount) PURE;
STDMETHOD(DrawPrimitiveUP)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, WINED3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
STDMETHOD(DrawPrimitiveStrided)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData) PURE;
@@ -533,6 +534,7 @@ #define IWineD3DDevice_SetGammaRamp(p,a,
#define IWineD3DDevice_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b)
#define IWineD3DDevice_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b)
#define IWineD3DDevice_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b)
+#define IWineD3DDevice_SetBaseVertexIndex(p, a) (p)->lpVtbl->SetBaseVertexIndex(p, a)
#define IWineD3DDevice_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b)
#define IWineD3DDevice_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b)
#define IWineD3DDevice_SetLightEnable(p,a,b) (p)->lpVtbl->SetLightEnable(p,a,b)
@@ -596,7 +598,7 @@ #define IWineD3DDevice_EndScene(p)
#define IWineD3DDevice_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d)
#define IWineD3DDevice_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
#define IWineD3DDevice_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c)
-#define IWineD3DDevice_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f)
+#define IWineD3DDevice_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e)
#define IWineD3DDevice_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
#define IWineD3DDevice_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
#define IWineD3DDevice_DrawPrimitiveStrided(p,a,b,c) (p)->lpVtbl->DrawPrimitiveStrided(p,a,b,c)
--
1.4.2.4
-------------- next part --------------
More information about the wine-patches
mailing list