[7/16] WineD3D: Pass the baseVertexIndex of indexed drawing in the device structure

Stefan Dösinger stefandoesinger at gmx.at
Mon Jan 1 18:11:52 CST 2007


The idea behind this is that the basevertexindex for non-indexed  
drawing can be passed directly to glDrawArrays, while the indexed  
offset has to be taken into account when setting the opengl stream  
sources. This value is ignored for the strided data structure, only  
LoadVertexData and drawStridedSlow use it. This will allow the vertex  
buffer code to reuse the information from the device later.

-------------- next part --------------
From 8eb1fd336f96682b7a64916a856ed43f648d4ce0 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=C3=B6singer?= <stefan at imac.local>
Date: Wed, 27 Dec 2006 14:02:20 +0100
Subject: [PATCH] WineD3D: Pass the baseVertexIndex in the device impl structure

---
 dlls/wined3d/device.c          |   15 +++++++++-
 dlls/wined3d/drawprim.c        |   61 ++++++++++++++++++----------------------
 dlls/wined3d/vertexbuffer.c    |    1 -
 dlls/wined3d/wined3d_private.h |    4 +--
 4 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cfb3354..e4a6ab6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4664,6 +4664,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType,
                                debug_d3dprimitivetype(PrimitiveType),
                                StartVertex, PrimitiveCount);
+    if(This->baseVIndex != 0) {
+        /* TODO: Deal with that better */
+        This->baseVIndex = 0;
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+    }
     drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, 0/* NumVertices */, -1 /* indxStart */,
                   0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */, NULL);
 
@@ -4696,7 +4701,12 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
         idxStride = 4;
     }
 
-    drawPrimitive(iface, PrimitiveType, primCount, baseVIndex, NumVertices, startIndex,
+    if(This->baseVIndex != baseVIndex) {
+        This->baseVIndex = baseVIndex;
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+    }
+
+    drawPrimitive(iface, PrimitiveType, primCount, 0, NumVertices, startIndex,
                    idxStride, ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex, NULL);
 
     return WINED3D_OK;
@@ -4723,6 +4733,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 
     /* Mark the state dirty until we have nicer tracking */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+    This->baseVIndex = 0;
 
     drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* start vertex */, 0  /* NumVertices */,
                   0 /* indxStart*/, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */, NULL);
@@ -4769,6 +4780,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 
     /* Mark the state dirty until we have nicer tracking */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+    This->baseVIndex = 0;
 
     drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* vertexStart */, NumVertices, 0 /* indxStart */, idxStride, pIndexData, MinVertexIndex, NULL);
 
@@ -4785,6 +4797,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 
     /* Mark the state dirty until we have nicer tracking */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
+    This->baseVIndex = 0;
     drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, 0, NULL, 0, DrawPrimStrideData);
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index da555bc..644f1ff 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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->baseVIndex * 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,13 @@ #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                       SkipnStrides = startVertex;
     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   */
@@ -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->baseVIndex;
             } 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->baseVIndex;
             }
         }
 
@@ -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);
@@ -2020,7 +2015,7 @@ void drawPrimitive(IWineD3DDevice *iface
             ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration != NULL)            
 
             primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, 
-                &This->strided_streams, StartVertexIndex, &fixup);
+                &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 0915b73..f5a6dd3 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,
@@ -670,6 +669,7 @@ #define                         NEEDS_DI
 	
     /* Stream source management */
     WineDirect3DVertexStridedData strided_streams;
+    UINT                      baseVIndex;
 
 } IWineD3DDeviceImpl;
 
-- 
1.4.2.4

-------------- next part --------------



More information about the wine-patches mailing list