[dx73] performance of texture states

Ann and Jason Edmeades us at the-edmeades.demon.co.uk
Sat Aug 2 15:57:03 CDT 2003


This is the first patch which looks at the performance of changing the
textures on a texture unit. As was pointed out to me by Lucho, certain
information is per texture unit and hence not affected when a different
texture object is bound. This patch on my machine changes the displayed
fps by the Billboard sample from 30.6 to about 42.6.

There is still more optimization which can be done here, but this is a
start.

Let me know if anyone notices any regressions with this one.

Changelog
Only reapply the texture states necessary when a different texture gets
bound to the same texture unit.
Jason
-------------- next part --------------
--- dlls/d3d8/dx72/d3d8_private.h	2003-07-31 00:26:59.000000000 +0100
+++ dlls/d3d8/d3d8_private.h	2003-08-02 22:37:31.000000000 +0100
@@ -1239,7 +1239,7 @@
  * to see how not defined it here
  */ 
 void   GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
-void   setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage);
+void   setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, BOOL Force);
 void   set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
 
 SHORT  D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
--- dlls/d3d8/dx72/device.c	2003-07-30 23:45:41.000000000 +0100
+++ dlls/d3d8/device.c	2003-08-02 22:40:58.000000000 +0100
@@ -66,29 +66,18 @@
 } while (0)
 
 /* Apply the current values to the specified texture stage */
-void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
+void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, BOOL Force) {
     ICOM_THIS(IDirect3DDevice8Impl,iface);
     int i = 0;
     float col[4];
-
-    /* Make appropriate texture active */
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
-        glActiveTexture(GL_TEXTURE0 + Stage);
-#else
-        glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
-#endif
-        checkGLcall("glActiveTextureARB");
-    } else if (Stage > 0) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
-    }
+    BOOL changeTexture = TRUE;
 
     TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
     for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
 
+        switch (i) {
         /* Performance: For texture states where multiples effect the outcome, only bother
               applying the last one as it will pick up all the other values                */
-        switch (i) {
         case D3DTSS_COLORARG0:  /* Will be picked up when setting color op */
         case D3DTSS_COLORARG1:  /* Will be picked up when setting color op */
         case D3DTSS_COLORARG2:  /* Will be picked up when setting color op */
@@ -96,7 +85,42 @@
         case D3DTSS_ALPHAARG1:  /* Will be picked up when setting alpha op */
         case D3DTSS_ALPHAARG2:  /* Will be picked up when setting alpha op */
            break;
+
+        /* Performance: If the texture states only impact settings for the texture unit 
+             (compared to the texture object) then there is no need to reapply them. The
+             only time they need applying is the first time, since we cheat and put the  
+             values into the stateblock without applying.                                
+             Per-texture unit: texture function (eg. combine), ops and args
+                               env color
+                               lod bias
+                               texture coordinates
+                               texture coordinate generation modes
+                               eye linear/object linear plane coords             */
+        case D3DTSS_COLOROP:              
+        case D3DTSS_ALPHAOP:           
+        case D3DTSS_TEXCOORDINDEX:
+        case D3DTSS_TEXTURETRANSFORMFLAGS:
+           if (!Force) break; /* Drop through first time only */
+
         default:
+
+           /* Performance: Only change to this texture if we have to */
+           if (changeTexture) {
+               /* Make appropriate texture active */
+               if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+                   glActiveTexture(GL_TEXTURE0 + Stage);
+#else
+                   glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
+#endif
+                   checkGLcall("glActiveTextureARB");
+                } else if (Stage > 0) {
+                    FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+                }
+                changeTexture = FALSE;
+           }
+
+           /* Now apply the change */
            IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
         }
     }
@@ -2769,7 +2793,7 @@
     /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
        a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
     if (reapplyStates) {
-       setupTextureStates(iface, Stage);
+       setupTextureStates(iface, Stage, FALSE);
     }
 
     LEAVE_GL();   
--- dlls/d3d8/dx72/stateblock.c	2003-07-17 01:26:35.000000000 +0100
+++ dlls/d3d8/stateblock.c	2003-08-02 22:37:17.000000000 +0100
@@ -234,7 +234,7 @@
         checkGLcall("glTexImage1D");
 
         /* Reapply all the texture state information to this texture */
-        setupTextureStates(iface, i);
+        setupTextureStates(iface, i, TRUE);
     }
 
     LEAVE_GL();



More information about the wine-patches mailing list