From 354fdae524a02655eaecaa95f0bf6f04713bd7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 17 Jan 2007 00:06:34 +0100 Subject: [PATCH] wined3d: Implement per stream offsets. --- dlls/wined3d/directx.c | 2 +- dlls/wined3d/drawprim.c | 47 ++++++++++++++++++++++++++++++++--------- dlls/wined3d/state.c | 22 ++++++++++--------- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index cbcbdc2bb1d..0e6f4bcb806 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2244,7 +2244,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, ------------------------------------------------ */ if (This->dxVersion > 8) { /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */ - *pCaps->DevCaps2 = 0; + *pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET; /* TODO: VS3.0 needs at least D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET */ *pCaps->MaxNpatchTessellationLevel = 0; *pCaps->MasterAdapterOrdinal = 0; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 400ffb5a275..fdc98437083 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -628,8 +628,12 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */ DWORD specularColor = 0; /* Specular Color */ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + UINT *streamOffset = This->stateBlock->streamOffset; LONG SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex; + BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; + BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL; + TRACE("Using slow vertex array code\n"); /* Variable Initialization */ @@ -638,6 +642,29 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData else pIdxBufL = (const long *) idxData; } + /* Adding the stream offset once is cheaper than doing it every iteration. Do not modify the strided data, it is a pointer + * to the strided Data in the device and might be needed intact on the next draw + */ + for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) { + if(sd->u.s.texCoords[textureNo].lpData) { + texCoords[textureNo] = sd->u.s.texCoords[textureNo].lpData + streamOffset[sd->u.s.texCoords[textureNo].streamNo]; + } else { + texCoords[textureNo] = NULL; + } + } + if(sd->u.s.diffuse.lpData) { + diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo]; + } + if(sd->u.s.specular.lpData) { + specular = sd->u.s.specular.lpData + streamOffset[sd->u.s.specular.streamNo]; + } + if(sd->u.s.normal.lpData) { + normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo]; + } + if(sd->u.s.position.lpData) { + position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo]; + } + /* Start drawing in GL */ VTRACE(("glBegin(%x)\n", glPrimType)); glBegin(glPrimType); @@ -707,8 +734,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData continue; } - ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); - if (sd->u.s.texCoords[coordIdx].lpData == NULL) { + ptrToCoords = (float *)(texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride)); + if (texCoords[coordIdx] == NULL) { TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo); ++texture_idx; continue; @@ -796,8 +823,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData } /* End of textures */ /* Diffuse -------------------------------- */ - if (sd->u.s.diffuse.lpData != NULL) { - DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride)); + if (diffuse) { + DWORD *ptrToCoords = (DWORD *)(diffuse + (SkipnStrides * sd->u.s.diffuse.dwStride)); diffuseColor = ptrToCoords[0]; VTRACE(("diffuseColor=%lx\n", diffuseColor)); @@ -813,8 +840,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData } /* Specular ------------------------------- */ - if (sd->u.s.specular.lpData != NULL) { - DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride)); + if (specular) { + DWORD *ptrToCoords = (DWORD *)(specular + (SkipnStrides * sd->u.s.specular.dwStride)); specularColor = ptrToCoords[0]; VTRACE(("specularColor=%lx\n", specularColor)); @@ -850,16 +877,16 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData } /* Normal -------------------------------- */ - if (sd->u.s.normal.lpData != NULL) { - float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride)); + if (normal != NULL) { + float *ptrToCoords = (float *)(normal + (SkipnStrides * sd->u.s.normal.dwStride)); VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", ptrToCoords[0], ptrToCoords[1], ptrToCoords[2])); glNormal3f(ptrToCoords[0], ptrToCoords[1], ptrToCoords[2]); } /* Position -------------------------------- */ - if (sd->u.s.position.lpData != NULL) { - float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride)); + if (position) { + float *ptrToCoords = (float *)(position + (SkipnStrides * sd->u.s.position.dwStride)); x = ptrToCoords[0]; y = ptrToCoords[1]; z = ptrToCoords[2]; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index bc2686f011d..8d74006309d 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -2112,6 +2112,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) { static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) { GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0; int i; + UINT *offset = stateblock->streamOffset; for (i = 0; i < MAX_ATTRIBS; i++) { @@ -2130,7 +2131,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->loadBaseVertexIndex * strided->u.input[i].dwStride)); + strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) ); GL_EXTCALL(glEnableVertexAttribArrayARB(i)); } } @@ -2139,6 +2140,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDi static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) { unsigned int textureNo = 0; unsigned int texture_idx = 0; + UINT *offset = stateblock->streamOffset; GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0; TRACE("Using fast vertex array code\n"); @@ -2155,7 +2157,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->loadBaseVertexIndex * 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 + offset[sd->u.s.blendWeights.streamNo]); /* FIXME("TODO\n");*/ /* Note dwType == float3 or float4 == 2 or 3 */ @@ -2170,7 +2172,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->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride)); + sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); if(curVBO != sd->u.s.blendWeights.VBO) { GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO)); @@ -2182,7 +2184,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->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride); + sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]); checkGLcall("glWeightPointerARB"); @@ -2320,12 +2322,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->loadBaseVertexIndex * sd->u.s.position.dwStride); + sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); } 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->loadBaseVertexIndex * sd->u.s.position.dwStride); + sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); } checkGLcall("glVertexPointer(...)"); glEnableClientState(GL_VERTEX_ARRAY); @@ -2350,7 +2352,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->loadBaseVertexIndex * sd->u.s.normal.dwStride); + sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]); checkGLcall("glNormalPointer(...)"); glEnableClientState(GL_NORMAL_ARRAY); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); @@ -2384,7 +2386,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVerte } glColorPointer(4, GL_UNSIGNED_BYTE, sd->u.s.diffuse.dwStride, - sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride); + sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); glEnableClientState(GL_COLOR_ARRAY); checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); @@ -2411,7 +2413,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->loadBaseVertexIndex * sd->u.s.specular.dwStride); + sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]); vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)"); glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); @@ -2476,7 +2478,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->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride); + sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {