[1/5] wined3d: Keep track of what stage a texturing unit is mapped to

H. Verbeet hverbeet at gmail.com
Fri Jun 22 13:43:19 CDT 2007


The idea behind this is that in order to map a vertex sampler to a
texturing unit we iterate over the units until we either find one that
isn't mapped yet, or find one that's mapped to a stage that isn't
currently being used. (The other obvious way to do this would be to
keep a list of unmapped/free units and pop one of from there.
Considering the array size I doubt that would buy us much performance
wise though, and it would probably be slightly more complicated.)

This patch adds the map required to keep track of what stage a unit is
mapped to.

Changelog:
  - Keep track of what stage a texturing unit is mapped to
-------------- next part --------------
---

 dlls/wined3d/device.c          |   29 +++++++++++++++++++++++++----
 dlls/wined3d/wined3d_private.h |    1 +
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ac418d9..5a9c936 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1811,7 +1811,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
 
     /* Initialize the texture unit mapping to a 1:1 mapping */
     for(state = 0; state < MAX_SAMPLERS; state++) {
-        This->texUnitMap[state] = state;
+        if (state < GL_LIMITS(samplers)) {
+            This->texUnitMap[state] = state;
+            This->rev_tex_unit_map[state] = state;
+        } else {
+            This->texUnitMap[state] = -1;
+            This->rev_tex_unit_map[state] = -1;
+        }
     }
     This->oneToOneTexUnitMap = TRUE;
 
@@ -3210,6 +3216,21 @@ static inline void markTextureStagesDirty(IWineD3DDeviceImpl *This, DWORD stage)
     }
 }
 
+static void device_map_stage(IWineD3DDeviceImpl *This, int stage, int unit) {
+    int i = This->rev_tex_unit_map[unit];
+    int j = This->texUnitMap[stage];
+
+    This->texUnitMap[stage] = unit;
+    if (i != -1 && i != stage) {
+        This->texUnitMap[i] = -1;
+    }
+
+    This->rev_tex_unit_map[unit] = stage;
+    if (j != -1 && j != unit) {
+        This->rev_tex_unit_map[j] = -1;
+    }
+}
+
 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
     DWORD i, tex;
     /* This code can assume that GL_NV_register_combiners are supported, otherwise
@@ -3232,7 +3253,7 @@ void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
         /* Restore a 1:1 mapping */
         for(i = 0; i < MAX_SAMPLERS; i++) {
             if(This->texUnitMap[i] != i) {
-                This->texUnitMap[i] = i;
+                device_map_stage(This, i, i);
                 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
                 if (i < MAX_TEXTURES) {
                     markTextureStagesDirty(This, i);
@@ -3265,14 +3286,14 @@ void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
                 /* Map to -1, so the check below doesn't fail if a non-NULL
                  * texture is set on this stage */
                 TRACE("Mapping texture stage %d to -1\n", i);
-                This->texUnitMap[i] = -1;
+                device_map_stage(This, i, -1);
 
                 continue;
             }
 
             TRACE("Mapping texture stage %d to unit %d\n", i, tex);
             if(This->texUnitMap[i] != tex) {
-                This->texUnitMap[i] = tex;
+                device_map_stage(This, i, tex);
                 IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
                 markTextureStagesDirty(This, i);
             }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3c0dfee..9a23783 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -721,6 +721,7 @@ struct IWineD3DDeviceImpl
 
     /* With register combiners we can skip junk texture stages */
     DWORD                     texUnitMap[MAX_SAMPLERS];
+    DWORD                     rev_tex_unit_map[MAX_SAMPLERS];
     BOOL                      oneToOneTexUnitMap;
 
     /* Stream source management */


More information about the wine-patches mailing list