[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