Stefan Dösinger : wined3d: Catch nop render state changes.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 19 10:05:01 CST 2006


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Dec 15 19:16:36 2006 +0100

wined3d: Catch nop render state changes.

---

 dlls/wined3d/device.c   |   47 +++++++++++++++++++++++++++++++----------------
 dlls/wined3d/drawprim.c |   16 ++--------------
 2 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 5a4a270..32fc71b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2068,6 +2068,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain;
+    DWORD state;
 
     TRACE("(%p)->(%p,%p)\n", This, pPresentationParameters, D3DCB_CreateAdditionalSwapChain);
     if(This->d3d_initialized) return WINED3DERR_INVALIDCALL;
@@ -2148,6 +2149,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     /* Clear the screen */
     IWineD3DDevice_Clear((IWineD3DDevice *) This, 0, NULL, WINED3DCLEAR_STENCIL|WINED3DCLEAR_ZBUFFER|WINED3DCLEAR_TARGET, 0x00, 1.0, 0);
 
+    /* Mark all states dirty. The Setters will not mark a state dirty when the new value is equal to the old value
+     * This might create a problem in 2 situations:
+     * ->The D3D default value is 0, but the opengl default value is something else
+     * ->D3D7 unintialized D3D and reinitializes it. This way the context is destroyed, be the stateblock unchanged
+     */
+    for(state = 0; state <= STATE_HIGHEST; state++) {
+        IWineD3DDeviceImpl_MarkStateDirty(This, state);
+    }
+
     This->d3d_initialized = TRUE;
     return WINED3D_OK;
 }
@@ -3316,8 +3326,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, WINED3DRENDERSTATETYPE State, DWORD Value) {
 
     IWineD3DDeviceImpl  *This     = (IWineD3DDeviceImpl *)iface;
+    DWORD oldValue = This->stateBlock->renderState[State];
 
     TRACE("(%p)->state = %s(%d), value = %d\n", This, debug_d3drenderstate(State), State, Value);
+
     This->updateStateBlock->changed.renderState[State] = TRUE;
     This->updateStateBlock->set.renderState[State] = TRUE;
     This->updateStateBlock->renderState[State] = Value;
@@ -3328,7 +3340,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         return WINED3D_OK;
     }
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(State));
+    /* Compared here and not before the assignment to allow proper stateblock recording */
+    if(Value == oldValue) {
+        TRACE("Application is setting the old value over, nothing to do\n");
+    } else {
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(State));
+    }
 
     return WINED3D_OK;
 }
@@ -4546,19 +4563,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         IWineD3DBaseTexture_Release(oldTexture);
     }
 
-    /* Reset color keying */
+    /* Color keying is affected by the texture. Temporarily mark the color key state (=alpha test)
+     * dirty until textures are integrated with the state management
+     */
     if(Stage == 0 && This->stateBlock->renderState[WINED3DRS_COLORKEYENABLE]) {
-        BOOL enable_ckey = FALSE;
-
-        if(pTexture) {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)pTexture)->surfaces[0];
-            if(surf->CKeyFlags & DDSD_CKSRCBLT) enable_ckey = TRUE;
-        }
-
-        if(enable_ckey) {
-            glAlphaFunc(GL_NOTEQUAL, 0.0);
-            checkGLcall("glAlphaFunc");
-        }
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORKEYENABLE));
     }
 
     return WINED3D_OK;
@@ -6007,6 +6016,7 @@ static void device_reapply_stateblock(IW
 
     BOOL oldRecording;  
     IWineD3DStateBlockImpl *oldUpdateStateBlock;
+    DWORD i;
 
     /* Disable recording */
     oldUpdateStateBlock = This->updateStateBlock;
@@ -6017,6 +6027,13 @@ static void device_reapply_stateblock(IW
     /* Reapply the state block */ 
     IWineD3DStateBlock_Apply((IWineD3DStateBlock *)This->stateBlock);
 
+    /* Temporaryily mark all render states dirty to force reapplication
+     * until the context management for is integrated with the state management
+     */
+    for(i = 1; i < WINEHIGHEST_RENDER_STATE; i++) {
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(i));
+    }
+
     /* Restore recording */
     This->isRecordingState = oldRecording;
     This->updateStateBlock = oldUpdateStateBlock;
@@ -6030,7 +6047,6 @@ static void device_reapply_stateblock(IW
  * make this unnecessary */
 static void device_render_to_texture(IWineD3DDeviceImpl* This, BOOL isTexture) {
 
-    DWORD cullMode;
     BOOL oldRecording;
     IWineD3DStateBlockImpl *oldUpdateStateBlock;
 
@@ -6049,8 +6065,7 @@ static void device_render_to_texture(IWi
     }
     This->last_was_rhw = FALSE;
     This->proj_valid = FALSE;
-    IWineD3DDevice_GetRenderState((IWineD3DDevice*) This, WINED3DRS_CULLMODE, &cullMode);
-    IWineD3DDevice_SetRenderState((IWineD3DDevice*) This, WINED3DRS_CULLMODE, cullMode);
+    IWineD3DDeviceImpl_MarkStateDirty(This, WINED3DRS_CULLMODE);
 
     /* Restore recording */
     This->isRecordingState = oldRecording;
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 06a86ae..6ac7462 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -332,20 +332,8 @@ static void primitiveInitState(
 
         } else if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] 
                   && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != WINED3DFOG_NONE) {
-            
-            if(GL_SUPPORT(EXT_FOG_COORD)) {
-                glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)\n");
-                /* Reapply the fog range */
-                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGSTART, This->stateBlock->renderState[WINED3DRS_FOGSTART]);
-                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGEND, This->stateBlock->renderState[WINED3DRS_FOGEND]);
-                /* Restore the fog mode */
-                IWineD3DDevice_SetRenderState(iface, WINED3DRS_FOGTABLEMODE, This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE]);
-            } else {
-                /* Enable GL_FOG again because we disabled it above */
-                glEnable(GL_FOG);
-                checkGLcall("glEnable(GL_FOG)");
-            }
+            /* Reapply the fog */
+            StateTable[STATE_RENDER(WINED3DRS_FOGENABLE)].apply(STATE_RENDER(WINED3DRS_FOGSTART), This->stateBlock);
         }
     }
 }




More information about the wine-cvs mailing list