Stefan Dösinger : wined3d: Add the state dirtification infrastructure.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 19 10:04:58 CST 2006


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Dec 19 13:00:03 2006 +0100

wined3d: Add the state dirtification infrastructure.

---

 dlls/wined3d/device.c          |   13 +++++++++++++
 dlls/wined3d/drawprim.c        |   12 ++++++++++++
 dlls/wined3d/wined3d_private.h |   20 ++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 685cdf9..217f666 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -7084,3 +7084,16 @@ const DWORD SavedVertexStates_T[NUM_SAVE
 const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S] = {
     WINED3DSAMP_DMAPOFFSET
 };
+
+void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
+    DWORD rep = StateTable[state].representative;
+    DWORD idx;
+    BYTE shift;
+
+    if(!rep || isStateDirty(This, rep)) return;
+
+    This->dirtyArray[This->numDirtyEntries++] = rep;
+    idx = rep >> 5;
+    shift = rep & 0x1f;
+    This->isStateDirty[idx] |= (1 << shift);
+}
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index a560084..06a86ae 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -2129,6 +2129,8 @@ void drawPrimitive(IWineD3DDevice *iface
     IWineD3DSwapChainImpl         *swapchain;
     int                           i;
     BOOL                          fixup = FALSE;
+    DWORD                         dirtyState, idx;
+    BYTE                          shift;
 
     BOOL lighting_changed, lighting_original = FALSE;
 
@@ -2163,6 +2165,16 @@ void drawPrimitive(IWineD3DDevice *iface
     /* Ok, we will be updating the screen from here onwards so grab the lock */
     ENTER_GL();
 
+    /* Apply dirty states */
+    for(i=0; i < This->numDirtyEntries; i++) {
+        dirtyState = This->dirtyArray[i];
+        idx = dirtyState >> 5;
+        shift = dirtyState & 0x1f;
+        This->isStateDirty[idx] &= ~(1 << shift);
+        StateTable[dirtyState].apply(dirtyState, This->stateBlock);
+    }
+    This->numDirtyEntries = 0; /* This makes the whole list clean */
+
     if(DrawPrimStrideData) {
 
         /* Note: this is a ddraw fixed-function code path */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index da3fbe9..c0a6614 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -413,6 +413,8 @@ typedef void (*APPLYSTATEFUNC)(DWORD sta
 #define STATE_RENDER(a) (a)
 #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
 
+#define STATE_HIGHEST (STATE_RENDER(WINEHIGHEST_RENDER_STATE))
+
 struct StateEntry
 {
     DWORD           representative;
@@ -627,10 +629,28 @@ typedef struct IWineD3DDeviceImpl
 
     /* Final position fixup constant */
     float                       posFixup[4];
+
+    /* State dirtification
+     * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
+     * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
+     * but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states
+     * only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states.
+     */
+    DWORD                   dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
+    DWORD                   numDirtyEntries;
+    DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
+
 } IWineD3DDeviceImpl;
 
 extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
 
+void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
+static inline BOOL isStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
+    DWORD idx = state >> 5;
+    BYTE shift = state & 0x1f;
+    return This->isStateDirty[idx] & (1 << shift);
+}
+
 /* Support for IWineD3DResource ::Set/Get/FreePrivateData. I don't think
  * anybody uses it for much so a good implementation is optional. */
 typedef struct PrivateData




More information about the wine-cvs mailing list