Stefan Dösinger : wined3d: Move the world matrix to the state table.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 3 05:37:31 CST 2007


Module: wine
Branch: master
Commit: 5fa0f7f77563bbd77f48b476817dd3c77a877d49
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5fa0f7f77563bbd77f48b476817dd3c77a877d49

Author: Stefan Dösinger <stefandoesinger at gmx.at>
Date:   Tue Jan  2 22:47:39 2007 +0100

wined3d: Move the world matrix to the state table.

---

 dlls/wined3d/device.c          |    7 +---
 dlls/wined3d/state.c           |   74 +++++++++++++++++++++++++++------------
 dlls/wined3d/surface.c         |    2 +
 dlls/wined3d/wined3d_private.h |    1 -
 4 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 00a888c..f205db9 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1936,7 +1936,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     }
 
     /* Initialize the current view state */
-    This->modelview_valid = 1;
     This->proj_valid = 0;
     This->view_ident = 1;
     This->last_was_rhw = 0;
@@ -2364,13 +2363,9 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
      */
 
     /* Capture the times we can just ignore the change for now */
-    if (d3dts == WINED3DTS_WORLDMATRIX(0)) {
-        This->modelview_valid = FALSE;
-    } else if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */
+    if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */
         This->view_ident = !memcmp(lpmatrix, identity, 16 * sizeof(float));
         /* Handled by the state manager */
-    } else { /* What was requested!?? */
-        WARN("invalid matrix specified: %i\n", d3dts);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(d3dts));
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 3361c85..ee56be2 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1813,6 +1813,29 @@ static void pixelshader(DWORD state, IWi
     }
 }
 
+static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock) {
+    /* Do not bother applying when we're in rhw mode. vertexdeclaration() will call
+     * transform_world if it switches out of rhw mode. This function is also called
+     * by transform_view below if the view matrix was changed
+     */
+    if(stateblock->wineD3DDevice->last_was_rhw) {
+        return;
+    }
+    glMatrixMode(GL_MODELVIEW);
+    checkGLcall("glMatrixMode");
+
+    /* In the general case, the view matrix is the identity matrix */
+    if (stateblock->wineD3DDevice->view_ident) {
+        glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
+        checkGLcall("glLoadMatrixf");
+    } else {
+        glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
+        checkGLcall("glLoadMatrixf");
+        glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
+        checkGLcall("glMultMatrixf");
+    }
+}
+
 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) {
     unsigned int k;
 
@@ -1823,12 +1846,9 @@ static void transform_view(DWORD state,
      */
 
     PLIGHTINFOEL *lightChain = NULL;
-    stateblock->wineD3DDevice->modelview_valid = FALSE;
 
     glMatrixMode(GL_MODELVIEW);
     checkGLcall("glMatrixMode(GL_MODELVIEW)");
-    glPushMatrix();
-    checkGLcall("glPushMatrix()");
     glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
     checkGLcall("glLoadMatrixf(...)");
 
@@ -1847,11 +1867,20 @@ static void transform_view(DWORD state,
         glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
         checkGLcall("glClipPlane");
     }
-    glPopMatrix();
-    checkGLcall("glPopMatrix()");
 
-    /* Call the vdecl update. Will be tidied up later */
-    StateTable[STATE_VDECL].apply(STATE_VDECL, stateblock);
+    if(stateblock->wineD3DDevice->last_was_rhw) {
+        glLoadIdentity();
+        checkGLcall("glLoadIdentity()");
+        /* No need to update the world matrix, the identity is fine */
+        return;
+    }
+
+    /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
+     * No need to do it here if the state is scheduled for update.
+     */
+    if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
+        transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
+    }
 }
 
 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateBlock) {
@@ -1869,9 +1898,10 @@ static void vertexdeclaration(DWORD stat
     BOOL transformed, lit;
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
+    BOOL wasrhw = device->last_was_rhw;
 
     device->streamFixedUp = FALSE;
-
+ 	
     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
      * here simply check whether a shader was set, or the user disabled shaders
      */
@@ -1945,22 +1975,20 @@ static void vertexdeclaration(DWORD stat
     } else {
 
         /* Untransformed, so relies on the view and projection matrices */
+        device->last_was_rhw = FALSE;
+        /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
         device->untransformed = TRUE;
 
-        if (!useVertexShaderFunction) {
-            device->modelview_valid = TRUE;
-            glMatrixMode(GL_MODELVIEW);
-            checkGLcall("glMatrixMode");
-
-            /* In the general case, the view matrix is the identity matrix */
-            if (device->view_ident) {
-                glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
-                checkGLcall("glLoadMatrixf");
-            } else {
-                glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
-                checkGLcall("glLoadMatrixf");
-                glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
-                checkGLcall("glMultMatrixf");
+        /* Don't bother checking for !useVertexShaderFunction here. If shaders are always on wasrhw will never
+         * be true. If they are switched on and off then knowing that the fixed function matrices are ok makes
+         * those switches cheaper
+         */
+        if (wasrhw) {
+            /* switching out of orthogonal mode? have to reapply the modelview matrix.
+             * Only do that when it is not dirty though
+             */
+            if(!isStateDirty(device, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
+                transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
             }
         }
 
@@ -2763,7 +2791,7 @@ const struct StateEntry StateTable[] =
     { /*254, undefined                              */      0,                                                  state_undefined     },
     { /*255, undefined                              */      0,                                                  state_undefined     },
       /* End huge gap */
-    { /*256, WINED3DTS_WORLDMATRIX(0)               */      STATE_VDECL,                                        vertexdeclaration   },
+    { /*256, WINED3DTS_WORLDMATRIX(0)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)),          transform_world     },
     { /*257, WINED3DTS_WORLDMATRIX(1)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)),          transform_worldex   },
     { /*258, WINED3DTS_WORLDMATRIX(2)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)),          transform_worldex   },
     { /*259, WINED3DTS_WORLDMATRIX(3)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)),          transform_worldex   },
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 031d320..200b52e 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1150,6 +1150,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
                we want to draw at screen position 0,0 - Set up ortho (rhw) mode as
                per drawprim (and leave set - it will sort itself out due to last_was_rhw */
             d3ddevice_set_ortho(This->resource.wineD3DDevice);
+            IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
 
             if (iface ==  implSwapChain->frontBuffer) {
                 glDrawBuffer(GL_FRONT);
@@ -2473,6 +2474,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
             /* Draw a textured quad
              */
             d3ddevice_set_ortho(This->resource.wineD3DDevice);
+            IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
 
             glBegin(GL_QUADS);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7e41f5c..7b5eaa1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -563,7 +563,6 @@ typedef struct IWineD3DDeviceImpl
     const shader_backend_t *shader_backend;
 
     /* Optimization */
-    BOOL                    modelview_valid;
     BOOL                    proj_valid;
     BOOL                    view_ident;        /* true iff view matrix is identity                */
     BOOL                    last_was_rhw;      /* true iff last draw_primitive was in xyzrhw mode */




More information about the wine-cvs mailing list