[14/19] WineD3D: Move samplers to the state table

Stefan Dösinger stefan at codeweavers.com
Tue Dec 19 16:26:39 CST 2006


This patch removes drawPrimitiveUploadTextures[PS] and starts making things 
easier. The D3DRS_COLORKEYENABLE hack in SetTexture can be removed now. 
Temporarily SetPixelShader has to dirtify the samplers if a shader is bound 
because colorops might have disabled texture units which the shader needs.

Because drawPrimitive doesn't necessarily check each used texture every 
drawprim call, bound textures may not be preloaded correctly. For this 
SetTexture keeps track of the assignments of textures and one stage they are 
assigned to. UnlockRect dirtifies the sampler to which the texture is 
assigned. The videotex d3d7 sdk sample shows this problem. As a side effect, 
the assignment count and the sampler number will be helpful for implementing 
sRGB textures too.
-------------- next part --------------
From 1de51b7cad87d10def67394042ebd163a539966d Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Mon, 18 Dec 2006 23:50:23 +0100
Subject: [PATCH] WineD3D: Move samplers to the state table

---
 dlls/wined3d/device.c          |   46 +++++++++++++--
 dlls/wined3d/drawprim.c        |  126 ----------------------------------------
 dlls/wined3d/state.c           |   92 ++++++++++++++++++++++++-----
 dlls/wined3d/surface.c         |   16 ++++-
 dlls/wined3d/wined3d_private.h |    3 +
 5 files changed, 131 insertions(+), 152 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a624a64..2a943b4 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3397,6 +3397,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         return WINED3D_OK;
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(Sampler));
+
     return WINED3D_OK;
 }
 
@@ -3677,6 +3679,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 
     if (NULL != pShader) {
         IWineD3DPixelShader_AddRef(pShader);
+        if(oldShader == NULL) {
+            /* Fixed function color ops deactivate the texture dimensions from the first stage which has colorop = disable
+             * Pixel shaders require that this is enabled, so dirtify all samplers, they will enable the dimensions.
+             * do not dirtify the colorop - it won't do anything when a ashader is bound
+             * This is temporary until pixel shaders are handled by the state table too
+             */
+            int i;
+            for(i = 0; i < MAX_SAMPLERS; i++) {
+                IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
+            }
+        }
     }
     if (NULL != oldShader) {
         IWineD3DPixelShader_Release(oldShader);
@@ -4467,6 +4480,7 @@ #endif
             WARN("(%p) Attempt to set scratch texture rejected\n", pTexture);
             return WINED3DERR_INVALIDCALL;
         }
+        This->stateBlock->textureDimensions[Stage] = IWineD3DBaseTexture_GetTextureDimensions(pTexture);
     }
 
     oldTexture = This->updateStateBlock->textures[Stage];
@@ -4489,6 +4503,9 @@ #endif
     * This means we should pass the refcount up to the parent
      *******************************/
     if (NULL != This->updateStateBlock->textures[Stage]) {
+        IWineD3DBaseTextureImpl *new = (IWineD3DBaseTextureImpl *) This->updateStateBlock->textures[Stage];
+        ULONG bindCount = InterlockedIncrement(&new->baseTexture.bindCount);
+
         IWineD3DBaseTexture_AddRef(This->updateStateBlock->textures[Stage]);
         if(oldTexture == NULL) {
             /* The source arguments for color and alpha ops have different meanings when a NULL texture is bound,
@@ -4497,23 +4514,40 @@ #endif
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_COLOROP));
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_ALPHAOP));
         }
+        if(bindCount == 1) {
+            new->baseTexture.sampler = Stage;
+        }
+        /* More than one assignment? Doesn't matter, we only need one gl texture unit to use for uploading */
+
     }
 
     if (NULL != oldTexture) {
+        IWineD3DBaseTextureImpl *old = (IWineD3DBaseTextureImpl *) oldTexture;
+        LONG bindCount = InterlockedDecrement(&old->baseTexture.bindCount);
+
         IWineD3DBaseTexture_Release(oldTexture);
         if(pTexture == NULL) {
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_COLOROP));
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_ALPHAOP));
         }
-    }
 
-    /* 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]) {
-        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORKEYENABLE));
+        if(bindCount && old->baseTexture.sampler == Stage) {
+            int i;
+            /* Have to do a search for the other sampler(s) where the texture is bound to
+             * Shouldn't happen as long as apps bind a texture only to one stage
+             */
+            TRACE("Searcing for other sampler / stage id where the texture is bound to\n");
+            for(i = 0; i < GL_LIMITS(sampler_stages); i++) {
+                if(This->updateStateBlock->textures[i] == oldTexture) {
+                    old->baseTexture.sampler = i;
+                    break;
+                }
+            }
+        }
     }
 
+    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(Stage));
+
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index a53fae7..c550d04 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1845,126 +1845,6 @@ inline void drawPrimitiveTraceDataLocati
 
 }
 
-static void drawPrimitiveUploadTexturesPS(IWineD3DDeviceImpl* This) {
-    INT i;
-
-    for (i = 0; i < GL_LIMITS(samplers); ++i) {
-        /* Pixel shader support should imply multitexture support. */
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
-            checkGLcall("glActiveTextureARB");
-        } else if (i) {
-            WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-        }
-
-        if (!This->stateBlock->textures[i]) continue;
-
-        /* Enable the correct target. Is this required for GLSL? For ARB_fragment_program it isn't, afaik. */
-        glDisable(GL_TEXTURE_1D);
-        This->stateBlock->textureDimensions[i] = IWineD3DBaseTexture_GetTextureDimensions(This->stateBlock->textures[i]);
-        switch(This->stateBlock->textureDimensions[i]) {
-            case GL_TEXTURE_2D:
-                glDisable(GL_TEXTURE_3D);
-                glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                break;
-            case GL_TEXTURE_3D:
-                glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                glDisable(GL_TEXTURE_2D);
-                break;
-            case GL_TEXTURE_CUBE_MAP_ARB:
-                glDisable(GL_TEXTURE_2D);
-                glDisable(GL_TEXTURE_3D);
-                break;
-        }
-        glEnable(This->stateBlock->textureDimensions[i]);
-
-        /* Upload texture, apply states */
-        IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
-        IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, i, REAPPLY_ALPHAOP);
-        IWineD3DBaseTexture_ApplyStateChanges(This->stateBlock->textures[i], This->stateBlock->textureState[i], This->stateBlock->samplerState[i]);
-    }
-}
-
-/* uploads textures and setup texture states ready for rendering */
-static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
-    INT current_sampler = 0;
-    float constant_color[4];
-    unsigned int i;
-
-    /* ARB_texture_env_combine is limited to GL_MAX_TEXTURE_UNITS stages. On
-     * nVidia cards GL_MAX_TEXTURE_UNITS is generally not larger than 4.
-     * Register combiners however provide up to 8 combiner stages. In order to
-     * take advantage of this, we need to be separate D3D texture stages from
-     * GL texture units. When using register combiners GL_MAX_TEXTURE_UNITS
-     * corresponds to MaxSimultaneousTextures and GL_MAX_GENERAL_COMBINERS_NV
-     * corresponds to MaxTextureBlendStages in the caps. */
-
-    if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
-        D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[WINED3DRS_TEXTUREFACTOR], constant_color);
-        GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &constant_color[0]));
-    }
-
-    for (i = 0; i < GL_LIMITS(texture_stages); ++i) {
-        INT texture_idx = -1;
-
-        /* WINED3DTOP_DISABLE disables the current & any higher texture stages */
-        if (This->stateBlock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) break;
-
-        if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[i]*/ TRUE) {
-            texture_idx = current_sampler++;
-
-            /* Active the texture unit corresponding to the current texture stage */
-            if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-                GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
-                checkGLcall("glActiveTextureARB");
-            } else if (i) {
-                WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-            }
-        }
-
-        if (This->stateBlock->textures[i]) {
-            /* Enable the correct target. This has to stay here until samplers are moved over to the state table */
-            glDisable(GL_TEXTURE_1D);
-            This->stateBlock->textureDimensions[i] = IWineD3DBaseTexture_GetTextureDimensions(This->stateBlock->textures[i]);
-            switch(This->stateBlock->textureDimensions[i]) {
-                case GL_TEXTURE_2D:
-                    glDisable(GL_TEXTURE_3D);
-                    glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                    break;
-                case GL_TEXTURE_3D:
-                    glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                    glDisable(GL_TEXTURE_2D);
-                    break;
-                case GL_TEXTURE_CUBE_MAP_ARB:
-                    glDisable(GL_TEXTURE_2D);
-                    glDisable(GL_TEXTURE_3D);
-                    break;
-            }
-
-            /* imply GL_SUPPORT(NV_TEXTURE_SHADER) when setting texture_shader_active */
-            if (This->texture_shader_active && This->stateBlock->textureDimensions[i] == GL_TEXTURE_2D) {
-                glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
-            } else {
-                glEnable(This->stateBlock->textureDimensions[i]);
-            }
-
-            /* Upload texture, apply states */
-            IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
-            IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This, i, texture_idx, REAPPLY_ALPHAOP);
-            IWineD3DBaseTexture_ApplyStateChanges(This->stateBlock->textures[i], This->stateBlock->textureState[i], This->stateBlock->samplerState[i]);
-        } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
-            /* ARB_texture_env_combine needs a valid texture bound to the
-             * texture unit, even if it isn't used. Bind a dummy texture. */
-            glDisable(GL_TEXTURE_2D);
-            glDisable(GL_TEXTURE_3D);
-            glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-            glEnable(GL_TEXTURE_1D);
-            This->stateBlock->textureDimensions[i] = GL_TEXTURE_1D;
-            glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
-        }
-    }
-}
-
 static void check_fbo_status(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
@@ -2170,12 +2050,6 @@ void drawPrimitive(IWineD3DDevice *iface
     /* Now initialize the materials state */
     init_materials(iface, (dataLocations->u.s.diffuse.lpData != NULL || dataLocations->u.s.diffuse.VBO != 0));
 
-    if (usePixelShaderFunction) {
-        drawPrimitiveUploadTexturesPS(This);
-    } else {
-        drawPrimitiveUploadTextures(This);
-    }
-
     {
         GLenum glPrimType;
         /* Ok, Work out which primitive is requested and how many vertexes that
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 8881ba7..1e07ca5 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -517,6 +517,8 @@ static void state_texfactor(DWORD state,
             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
             checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
         }
+    } else {
+        GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
     }
 }
 
@@ -1647,6 +1649,64 @@ static void tex_resultarg(DWORD state, I
     }
 }
 
+static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock) {
+    DWORD sampler = state - STATE_SAMPLER(0);
+
+    TRACE("Sampler: %d\n", sampler);
+    /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
+     * only has to bind textures and set the per texture states
+     */
+    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+        /* TODO: register combiners! */
+        if(sampler >= GL_LIMITS(sampler_stages)) {
+            return;
+        }
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + sampler));
+        checkGLcall("glActiveTextureARB");
+    } else if (sampler > 0) {
+        /* We can't do anything here */
+        WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+        return;
+    }
+
+    if(stateblock->textures[sampler]) {
+        IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
+        IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)stateblock->wineD3DDevice, sampler, sampler, REAPPLY_ALPHAOP);
+        IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
+
+        if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
+            ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
+            /* Using a pixel shader? Verify the sampler types */
+
+            /* Make sure that the texture dimensions are enabled. I don't have to disable the other
+             * dimensions because the shader knows from which texture type to sample from. For the sake of
+             * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
+             * dimensions. This should make wrong sampling sources visible :-)
+             */
+            glEnable(stateblock->textureDimensions[sampler]);
+            checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
+        } else if(sampler < stateblock->lowest_disabled_stage) {
+            activate_dimensions(sampler, stateblock);
+
+            if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
+                /* If color keying is enabled update the alpha test, it depends on the existance
+                 * of a color key in stage 0
+                 */
+                state_alpha(WINED3DRS_COLORKEYENABLE, stateblock);
+            }
+        }
+    } else if(sampler < GL_LIMITS(texture_stages)) {
+        if(sampler < stateblock->lowest_disabled_stage) {
+            /* TODO: Check if the colorop is dirty to do that job
+             * TODO: What should I do with pixel shaders here ???
+             */
+            activate_dimensions(sampler, stateblock);
+        } /* Otherwise tex_colorop disables the stage */
+        glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
+        checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
+    }
+}
+
 const struct StateEntry StateTable[] =
 {
       /* State name                                         representative,                                     apply function */
@@ -2128,20 +2188,20 @@ const struct StateEntry StateTable[] =
     { /*7, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
     { /*7, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
     /* Sampler states */
-    { /* 0, Sampler 0                               */      STATE_SAMPLER(0),                                   state_undefined     },
-    { /* 1, Sampler 1                               */      STATE_SAMPLER(1),                                   state_undefined     },
-    { /* 2, Sampler 2                               */      STATE_SAMPLER(2),                                   state_undefined     },
-    { /* 3, Sampler 3                               */      STATE_SAMPLER(3),                                   state_undefined     },
-    { /* 4, Sampler 3                               */      STATE_SAMPLER(4),                                   state_undefined     },
-    { /* 5, Sampler 5                               */      STATE_SAMPLER(5),                                   state_undefined     },
-    { /* 6, Sampler 6                               */      STATE_SAMPLER(6),                                   state_undefined     },
-    { /* 7, Sampler 7                               */      STATE_SAMPLER(7),                                   state_undefined     },
-    { /* 8, Sampler 8                               */      STATE_SAMPLER(8),                                   state_undefined     },
-    { /* 9, Sampler 9                               */      STATE_SAMPLER(9),                                   state_undefined     },
-    { /*10, Sampler 10                              */      STATE_SAMPLER(10),                                  state_undefined     },
-    { /*11, Sampler 11                              */      STATE_SAMPLER(11),                                  state_undefined     },
-    { /*12, Sampler 12                              */      STATE_SAMPLER(12),                                  state_undefined     },
-    { /*13, Sampler 13                              */      STATE_SAMPLER(13),                                  state_undefined     },
-    { /*14, Sampler 14                              */      STATE_SAMPLER(14),                                  state_undefined     },
-    { /*15, Sampler 15                              */      STATE_SAMPLER(15),                                  state_undefined     },
+    { /* 0, Sampler 0                               */      STATE_SAMPLER(0),                                   sampler             },
+    { /* 1, Sampler 1                               */      STATE_SAMPLER(1),                                   sampler             },
+    { /* 2, Sampler 2                               */      STATE_SAMPLER(2),                                   sampler             },
+    { /* 3, Sampler 3                               */      STATE_SAMPLER(3),                                   sampler             },
+    { /* 4, Sampler 3                               */      STATE_SAMPLER(4),                                   sampler             },
+    { /* 5, Sampler 5                               */      STATE_SAMPLER(5),                                   sampler             },
+    { /* 6, Sampler 6                               */      STATE_SAMPLER(6),                                   sampler             },
+    { /* 7, Sampler 7                               */      STATE_SAMPLER(7),                                   sampler             },
+    { /* 8, Sampler 8                               */      STATE_SAMPLER(8),                                   sampler             },
+    { /* 9, Sampler 9                               */      STATE_SAMPLER(9),                                   sampler             },
+    { /*10, Sampler 10                              */      STATE_SAMPLER(10),                                  sampler             },
+    { /*11, Sampler 11                              */      STATE_SAMPLER(11),                                  sampler             },
+    { /*12, Sampler 12                              */      STATE_SAMPLER(12),                                  sampler             },
+    { /*13, Sampler 13                              */      STATE_SAMPLER(13),                                  sampler             },
+    { /*14, Sampler 14                              */      STATE_SAMPLER(14),                                  sampler             },
+    { /*15, Sampler 15                              */      STATE_SAMPLER(15),                                  sampler             },
 };
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index cc5ac2a..780f2f6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1119,10 +1119,17 @@ static HRESULT WINAPI IWineD3DSurfaceImp
     }
 
     if (0 == This->resource.usage) { /* classic surface */
-        /**
-         * nothing to do
-         * waiting to reload the surface via IDirect3DDevice8::UpdateTexture
+        IWineD3DBaseTextureImpl *impl;
+        /* Check if the texture is bound, if yes dirtify the sampler to force a re-upload of the texture
+         * Can't load the texture here because PreLoad may destroy and recreate the gl texture, so sampler
+         * states need resetting
          */
+        if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) {
+            if(impl->baseTexture.bindCount) {
+                IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler));
+            }
+            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl);
+        }
     } else if (WINED3DUSAGE_RENDERTARGET & This->resource.usage) { /* render surfaces */
 
         /****************************
@@ -1158,6 +1165,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
                     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + tex));
                     checkGLcall("glActiveTextureARB");
                 }
+                IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(tex));
                 glDisable(GL_TEXTURE_2D);
                 checkGLcall("glDisable GL_TEXTURE_2D");
                 glDisable(GL_TEXTURE_1D);
@@ -1168,6 +1176,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
                 checkGLcall("glActiveTextureARB");
             }
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0));
 
             /* And back buffers are not blended. Disable the depth test, 
                that helps performance */
@@ -2394,6 +2403,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
 
             /* Unbind the old texture */
             glBindTexture(GL_TEXTURE_2D, 0);
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0));
 
             if (GL_SUPPORT(ARB_MULTITEXTURE)) {
             /* We use texture unit 0 for blts */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5c30b9c..ab81162 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -797,7 +797,8 @@ typedef struct IWineD3DBaseTextureClass
     UINT                    LOD;
     WINED3DTEXTUREFILTERTYPE filterType;
     DWORD                   states[MAX_WINETEXTURESTATES];
-
+    LONG                    bindCount;
+    DWORD                   sampler;
 } IWineD3DBaseTextureClass;
 
 typedef struct IWineD3DBaseTextureImpl
-- 
1.4.2.4



More information about the wine-patches mailing list