Stefan Dösinger : wined3d: Optimize render states in the stateblock.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Aug 13 06:31:35 CDT 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Jul 31 15:04:56 2007 +0200

wined3d: Optimize render states in the stateblock.

---

 dlls/wined3d/device.c          |   24 +++++++++++++++++++++---
 dlls/wined3d/stateblock.c      |   34 +++++++++++-----------------------
 dlls/wined3d/wined3d_private.h |    4 ++++
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index fcb1670..59bc35f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -466,6 +466,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
                 light->enabledChanged = TRUE;
             }
         }
+        for(j = 1; j <= WINEHIGHEST_RENDER_STATE; j++) {
+            object->contained_render_states[j - 1] = j;
+        }
+        object->num_contained_render_states = WINEHIGHEST_RENDER_STATE;
+
     } else if (Type == WINED3DSBT_PIXELSTATE) {
 
         TRACE("PIXELSTATE => Pretend all pixel shates have changed\n");
@@ -480,10 +485,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
             object->changed.pixelShaderConstantsB[i] = TRUE;
         for (i = 0; i < MAX_CONST_I; ++i)
             object->changed.pixelShaderConstantsI[i] = TRUE;
-        
+
         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
             object->changed.renderState[SavedPixelStates_R[i]] = TRUE;
+            object->contained_render_states[i] = SavedPixelStates_R[i];
         }
+        object->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
                 object->changed.textureState[j][SavedPixelStates_T[i]] = TRUE;
@@ -510,10 +517,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
             object->changed.vertexShaderConstantsB[i] = TRUE;
         for (i = 0; i < MAX_CONST_I; ++i)
             object->changed.vertexShaderConstantsI[i] = TRUE;
- 
+
         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
             object->changed.renderState[SavedVertexStates_R[i]] = TRUE;
+            object->contained_render_states[i] = SavedVertexStates_R[i];
         }
+        object->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
                 object->changed.textureState[j][SavedVertexStates_T[i]] = TRUE;
@@ -4301,6 +4310,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface)
 
 static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IWineD3DStateBlock** ppStateBlock) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    unsigned int i;
+    IWineD3DStateBlockImpl *object = This->updateStateBlock;
 
     if (!This->isRecordingState) {
         FIXME("(%p) not recording! returning error\n", This);
@@ -4308,7 +4319,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW
         return WINED3DERR_INVALIDCALL;
     }
 
-    *ppStateBlock = (IWineD3DStateBlock*)This->updateStateBlock;
+    for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
+        if(object->changed.renderState[i]) {
+            object->contained_render_states[object->num_contained_render_states] = i;
+            object->num_contained_render_states++;
+        }
+    }
+
+    *ppStateBlock = (IWineD3DStateBlock*) object;
     This->isRecordingState = FALSE;
     This->updateStateBlock = This->stateBlock;
     IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock);
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 3fefc2f..79bfe56 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -566,12 +566,10 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         }
 
         /* Render */
-        for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
-
-            if (This->changed.renderState[i] && (This->renderState[i] != targetStateBlock->renderState[i])) {
-                TRACE("Updating renderState %d to %d\n", i, targetStateBlock->renderState[i]);
-                This->renderState[i] = targetStateBlock->renderState[i];
-            }
+        for (i = 0; i <= This->num_contained_render_states; i++) {
+            TRACE("Updating renderState %d to %d\n",
+                  This->contained_render_states[i], targetStateBlock->renderState[This->contained_render_states[i]]);
+            This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]];
         }
 
         /* Texture states */
@@ -737,12 +735,6 @@ should really perform a delta so that only the changes get updated*/
             }
         }
 
-        /* Render */
-        for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
-            if (This->changed.renderState[i])
-                IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
-        }
-
         /* Texture states */
         for (j = 0; j < MAX_TEXTURES; j++) { /* Set The texture first, just in case it resets the states? */
             /* TODO: move over to memcpy */
@@ -778,12 +770,6 @@ should really perform a delta so that only the changes get updated*/
 
     } else if (This->blockType == WINED3DSBT_PIXELSTATE) {
 
-        for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
-            if (This->changed.renderState[SavedPixelStates_R[i]])
-                IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]);
-
-        }
-
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedPixelStates_T[i]] = This->textureState[j][SavedPixelStates_T[i]];
@@ -799,11 +785,6 @@ should really perform a delta so that only the changes get updated*/
 
     } else if (This->blockType == WINED3DSBT_VERTEXSTATE) {
 
-        for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
-            if (This->changed.renderState[SavedVertexStates_R[i]])
-                IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]);
-        }
-
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedVertexStates_T[i]] = This->textureState[j][SavedVertexStates_T[i]];
@@ -821,6 +802,13 @@ should really perform a delta so that only the changes get updated*/
     } else {
         FIXME("Unrecognized state block type %d\n", This->blockType);
     }
+
+    /* Render */
+    for (i = 0; i <= This->num_contained_render_states; i++) {
+        IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
+                                      This->renderState[This->contained_render_states[i]]);
+    }
+
     stateblock_savedstates_copy(iface, &((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed);
     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;
     for(j = 0; j < MAX_TEXTURES - 1; j++) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 55eabf8..b2fe145 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1356,6 +1356,10 @@ struct IWineD3DStateBlockImpl
 
     /* Scissor test rectangle */
     RECT                      scissorRect;
+
+    /* Contained state management */
+    DWORD                     contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
+    unsigned int              num_contained_render_states;
 };
 
 extern void stateblock_savedstates_set(




More information about the wine-cvs mailing list