wined3d: Avoid negative draw start indices.
This commit is contained in:
parent
8e37fcd266
commit
09ab812e79
|
@ -4697,9 +4697,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface, WI
|
|||
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 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *
|
|||
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 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface,
|
|||
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 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
|
|||
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 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -650,7 +650,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
|
|||
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 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
|
|||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2096,7 +2096,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDi
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
#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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
(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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
(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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
(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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
}
|
||||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
}
|
||||
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 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte
|
|||
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)) {
|
||||
|
|
|
@ -1201,7 +1201,8 @@ struct IWineD3DStateBlockImpl
|
|||
|
||||
/* 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];
|
||||
|
|
Loading…
Reference in New Issue