wined3d: Avoid negative draw start indices.
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index e955a8b..b13854b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4697,9 +4697,12 @@
                                debug_d3dprimitivetype(PrimitiveType),
                                StartVertex, PrimitiveCount);
 
-    if(StartVertex - This->stateBlock->baseVertexIndex < 0) ERR("Drawing negative\n");
+    if(This->stateBlock->loadBaseVertexIndex != 0) {
+        This->stateBlock->loadBaseVertexIndex = 0;
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
+    }
     /* 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 */,
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, 0/* NumVertices */, -1 /* indxStart */,
                   0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */);
     return WINED3D_OK;
 }
@@ -4728,6 +4731,11 @@
         idxStride = 4;
     }
 
+    if(This->stateBlock->loadBaseVertexIndex != This->stateBlock->baseVertexIndex) {
+        This->stateBlock->loadBaseVertexIndex = This->stateBlock->baseVertexIndex;
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
+    }
+
     drawPrimitive(iface, PrimitiveType, primCount, 0, NumVertices, startIndex,
                    idxStride, ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex);
 
@@ -4752,11 +4760,12 @@
     This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData;
     This->stateBlock->streamStride[0] = VertexStreamZeroStride;
     This->stateBlock->streamIsUP = TRUE;
+    This->stateBlock->loadBaseVertexIndex = 0;
 
     /* TODO: Only mark dirty if drawing from a different UP address */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
 
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, -This->stateBlock->baseVertexIndex /* start vertex */, 0  /* NumVertices */,
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* start vertex */, 0  /* NumVertices */,
                   0 /* indxStart*/, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */);
 
     /* MSDN specifies stream zero settings must be set to NULL */
@@ -4801,10 +4810,11 @@
     This->stateBlock->streamIsUP = TRUE;
     This->stateBlock->streamStride[0] = VertexStreamZeroStride;
 
-    /* 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;
+    This->stateBlock->loadBaseVertexIndex = 0;
+    /* Mark the state dirty until we have nicer tracking of the stream source pointers */
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
 
     drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* vertexStart */, NumVertices, 0 /* indxStart */, idxStride, pIndexData, MinVertexIndex);
 
@@ -4812,6 +4822,9 @@
     This->stateBlock->streamSource[0] = NULL;
     This->stateBlock->streamStride[0] = 0;
     This->stateBlock->pIndexData = NULL;
+    /* No need to mark the stream source state dirty here. Either the app calls UP drawing again, or it has to call
+     * SetStreamSource to specify a vertex buffer
+     */
 
     return WINED3D_OK;
 }
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 54db1e7..b913448 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -650,7 +650,7 @@
     DWORD diffuseColor = 0xFFFFFFFF;       /* Diffuse Color              */
     DWORD specularColor = 0;               /* Specular Color             */
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    LONG                       SkipnStrides = startVertex + This->stateBlock->baseVertexIndex;
+    LONG                       SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
 
     TRACE("Using slow vertex array code\n");
 
@@ -680,10 +680,10 @@
             /* 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] + This->stateBlock->baseVertexIndex;
+                SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
             } else {
                 VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
-                SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->baseVertexIndex;
+                SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
             }
         }
 
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 768bd12..cdb250e 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -2096,7 +2096,7 @@
                         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 + stateblock->baseVertexIndex * strided->u.input[i].dwStride));
+                        strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride));
         GL_EXTCALL(glEnableVertexAttribArrayARB(i));
    }
 }
@@ -2121,7 +2121,7 @@
 #endif
 
             TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
-                sd->u.s.blendWeights.lpData + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride);
+                sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride);
             /* FIXME("TODO\n");*/
             /* Note dwType == float3 or float4 == 2 or 3 */
 
@@ -2136,7 +2136,7 @@
             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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride));
+                sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride));
 
             if(curVBO != sd->u.s.blendWeights.VBO) {
                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
@@ -2148,7 +2148,7 @@
                 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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
+                sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
 
             checkGLcall("glWeightPointerARB");
 
@@ -2168,7 +2168,7 @@
                 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 + stateblock->baseVertexIndex * sd->u.s.blendWeights.dwStride);
+                sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
             checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
             glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
             checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
@@ -2200,7 +2200,7 @@
             (GL_EXTCALL)(FogCoordPointerEXT)(
                 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
                 sd->u.s.fog.dwStride,
-                sd->u.s.fog.lpData + stateblock->baseVertexIndex * sd->u.s.fog.dwStride);
+                sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
         } else {
             /* don't bother falling back to 'slow' as we don't support software FOG yet. */
             /* FIXME: fixme once */
@@ -2224,7 +2224,7 @@
                 (GL_EXTCALL)(TangentPointerEXT)(
                     WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
                     sd->u.s.tangent.dwStride,
-                    sd->u.s.tangent.lpData + stateblock->baseVertexIndex * sd->u.s.tangent.dwStride);
+                    sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
             } else {
                     glDisable(GL_TANGENT_ARRAY_EXT);
             }
@@ -2233,7 +2233,7 @@
                     (GL_EXTCALL)(BinormalPointerEXT)(
                         WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
                         sd->u.s.binormal.dwStride,
-                        sd->u.s.binormal.lpData + stateblock->baseVertexIndex * sd->u.s.binormal.dwStride);
+                        sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
             } else{
                     glDisable(GL_BINORMAL_ARRAY_EXT);
             }
@@ -2286,12 +2286,12 @@
         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 + stateblock->baseVertexIndex * sd->u.s.position.dwStride);
+                sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * 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 + stateblock->baseVertexIndex * sd->u.s.position.dwStride);
+                sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride);
         }
         checkGLcall("glVertexPointer(...)");
         glEnableClientState(GL_VERTEX_ARRAY);
@@ -2316,7 +2316,7 @@
         glNormalPointer(
             WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
             sd->u.s.normal.dwStride,
-            sd->u.s.normal.lpData + stateblock->baseVertexIndex * sd->u.s.normal.dwStride);
+            sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride);
         checkGLcall("glNormalPointer(...)");
         glEnableClientState(GL_NORMAL_ARRAY);
         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
@@ -2350,7 +2350,7 @@
         }
         glColorPointer(4, GL_UNSIGNED_BYTE,
                        sd->u.s.diffuse.dwStride,
-                       sd->u.s.diffuse.lpData + stateblock->baseVertexIndex * sd->u.s.diffuse.dwStride);
+                       sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride);
         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
         glEnableClientState(GL_COLOR_ARRAY);
         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
@@ -2377,7 +2377,7 @@
             }
             GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
                                                    sd->u.s.specular.dwStride,
-                                                   sd->u.s.specular.lpData + stateblock->baseVertexIndex * sd->u.s.specular.dwStride);
+                                                   sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride);
             vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
             vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
@@ -2442,7 +2442,7 @@
                     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 + stateblock->baseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
+                    sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             }
         } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8b7170f..27f95c8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1201,7 +1201,8 @@
 
     /* Indices */
     IWineD3DIndexBuffer*      pIndexData;
-    UINT                      baseVertexIndex; /* Note: only used for d3d8 */
+    UINT                      baseVertexIndex;
+    UINT                      loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
 
     /* Transform */
     WINED3DMATRIX             transforms[HIGHEST_TRANSFORMSTATE + 1];