wined3d: Slightly improve drawStridedSlow() performance.
Henri Verbeet
hverbeet at codeweavers.com
Thu Dec 4 10:41:30 CST 2008
This moves a couple of checks outside of the main drawing loop, since
they're not going to change anyway.
---
dlls/wined3d/drawprim.c | 204 ++++++++++++++++++++++++----------------------
1 files changed, 106 insertions(+), 98 deletions(-)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index e169587..28b6c30 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -297,9 +297,11 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
const UINT *streamOffset = This->stateBlock->streamOffset;
long SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
BOOL pixelShader = use_ps(This);
-
+ BOOL specular_fog = FALSE;
+ UINT texture_stages = GL_LIMITS(texture_stages);
const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
+ DWORD tex_mask = 0;
TRACE("Using slow vertex array code\n");
@@ -320,56 +322,92 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
return;
}
- /* 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; 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) {
+ /* Start drawing in GL */
+ VTRACE(("glBegin(%x)\n", glPrimType));
+ glBegin(glPrimType);
+
+ if (sd->u.s.position.lpData) position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo];
+
+ if (sd->u.s.normal.lpData) normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo];
+ else glNormal3f(0, 0, 0);
+
+ if (sd->u.s.diffuse.lpData) diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo];
+ else glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ if (This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR)
+ FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType));
+
+ 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];
- }
- if(FIXME_ON(d3d_draw)) {
- if(specular && This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
- (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position_transformed )&&
- This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
- if(GL_SUPPORT(EXT_FOG_COORD) && sd->u.s.specular.dwType != WINED3DDECLTYPE_D3DCOLOR) {
- FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType));
+ /* special case where the fog density is stored in the specular alpha channel */
+ if (This->stateBlock->renderState[WINED3DRS_FOGENABLE]
+ && (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE
+ || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4)
+ && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
+ {
+ if (GL_SUPPORT(EXT_FOG_COORD))
+ {
+ if (sd->u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR) specular_fog = TRUE;
+ else FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType));
+ }
+ else
+ {
+ static BOOL warned;
+
+ if (!warned)
+ {
+ /* TODO: Use the fog table code from old ddraw */
+ FIXME("Implement fog for transformed vertices in software\n");
+ warned = TRUE;
+ }
}
}
- if(This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR) {
- FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType));
- }
+ }
+ else if (GL_SUPPORT(EXT_SECONDARY_COLOR))
+ {
+ GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
}
- /* Start drawing in GL */
- VTRACE(("glBegin(%x)\n", glPrimType));
- glBegin(glPrimType);
+ for (textureNo = 0; textureNo < texture_stages; ++textureNo)
+ {
+ int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
+ int texture_idx = This->texUnitMap[textureNo];
- /* Default settings for data that is not passed */
- if (sd->u.s.normal.lpData == NULL) {
- glNormal3f(0, 0, 0);
- }
- if(sd->u.s.diffuse.lpData == NULL) {
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- }
- if(sd->u.s.specular.lpData == NULL) {
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
+ {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+ continue;
+ }
+
+ if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
+
+ if (texture_idx == -1) continue;
+
+ if (coordIdx > 7)
+ {
+ TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo);
+ continue;
+ }
+ else if (coordIdx < 0)
+ {
+ FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
+ continue;
+ }
+
+ if(sd->u.s.texCoords[textureNo].lpData)
+ {
+ texCoords[textureNo] =
+ sd->u.s.texCoords[textureNo].lpData + streamOffset[sd->u.s.texCoords[textureNo].streamNo];
+ tex_mask |= (1 << textureNo);
+ }
+ else
+ {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
+ if (GL_SUPPORT(ARB_MULTITEXTURE))
+ GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
+ else
+ glTexCoord4f(0, 0, 0, 1);
}
}
@@ -379,6 +417,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
/* For each primitive */
for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
+ UINT texture, tmp_tex_mask;
/* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
* function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
*/
@@ -396,47 +435,27 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
}
}
- /* Texture coords --------------------------- */
- for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
- continue ;
- }
-
- /* Query tex coords */
- if (This->stateBlock->textures[textureNo] != NULL || pixelShader) {
- int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
- int texture_idx = This->texUnitMap[textureNo];
- const void *ptrToCoords;
-
- if (coordIdx > 7) {
- VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
- continue;
- } else if (coordIdx < 0) {
- FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
- continue;
- }
+ tmp_tex_mask = tex_mask;
+ for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture)
+ {
+ int coord_idx;
+ const void *ptr;
- if (texture_idx == -1) continue;
+ if (!(tmp_tex_mask & 1)) continue;
- if (texCoords[coordIdx] == NULL) {
- TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
- } else {
- glTexCoord4f(0, 0, 0, 1);
- }
- continue;
- }
+ coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX];
+ ptr = texCoords[coord_idx] + (SkipnStrides * sd->u.s.texCoords[coord_idx].dwStride);
- ptrToCoords = texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride);
- if (GL_SUPPORT(ARB_MULTITEXTURE))
- multi_texcoord_funcs[sd->u.s.texCoords[coordIdx].dwType](GL_TEXTURE0_ARB + texture_idx, ptrToCoords);
- else
- texcoord_funcs[sd->u.s.texCoords[coordIdx].dwType](ptrToCoords);
+ if (GL_SUPPORT(ARB_MULTITEXTURE))
+ {
+ int texture_idx = This->texUnitMap[texture];
+ multi_texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](GL_TEXTURE0_ARB + texture_idx, ptr);
}
- } /* End of textures */
+ else
+ {
+ texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](ptr);
+ }
+ }
/* Diffuse -------------------------------- */
if (diffuse) {
@@ -463,24 +482,13 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
if (specular) {
const void *ptrToCoords = specular + SkipnStrides * sd->u.s.specular.dwStride;
- /* special case where the fog density is stored in the specular alpha channel */
- if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
- (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 )&&
- This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
- if(GL_SUPPORT(EXT_FOG_COORD)) {
- DWORD specularColor = ((const DWORD *)ptrToCoords)[0];
- GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
- } else {
- static BOOL warned = FALSE;
- if(!warned) {
- /* TODO: Use the fog table code from old ddraw */
- FIXME("Implement fog for transformed vertices in software\n");
- warned = TRUE;
- }
- }
- }
-
specular_funcs[sd->u.s.specular.dwType](ptrToCoords);
+
+ if (specular_fog)
+ {
+ DWORD specularColor = *(const DWORD *)ptrToCoords;
+ GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
+ }
}
/* Normal -------------------------------- */
--
1.5.6.4
--------------000104060501070805050102--
More information about the wine-patches
mailing list