ntdll: Use symbolic names when possible.
[wine] / dlls / wined3d / basetexture.c
index 4b6b0d5..a1290f8 100644 (file)
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
-
-static const Wined3dTextureStateMap textureObjectSamplerStates[]  = {
-    {WINED3DSAMP_ADDRESSU,      WINED3DSAMP_ADDRESSU},
-    {WINED3DSAMP_ADDRESSV,      WINED3DSAMP_ADDRESSV},
-    {WINED3DSAMP_ADDRESSW,      WINED3DSAMP_ADDRESSW},
-/* NOTE: Sometimes it's a good idea to disable the setting of border colour, e.g. Axis and Allies */
-    {WINED3DSAMP_BORDERCOLOR,   WINED3DFUNC_NOTSUPPORTED/* WINED3DSAMP_BORDERCOLOR */},
-    {WINED3DSAMP_MAGFILTER,     WINED3DSAMP_MAGFILTER},
-    {WINED3DSAMP_MINFILTER,     WINED3DSAMP_MINFILTER},
-    {WINED3DSAMP_MIPFILTER,     WINED3DSAMP_MIPFILTER},
-/* applies to the texture unit
-    WINED3DSAMP_MIPMAPLODBIAS, WINED3DSAMP_MIPMAPLODBIAS,
-*/
-    {WINED3DSAMP_MAXMIPLEVEL,   WINED3DSAMP_MAXMIPLEVEL},
-#if 0
-    {WINED3DSAMP_MAXANISOTROPY, GL_SUPPORTED(EXT_TEXTURE_FILTER_ANISOTROPIC) ? WINED3DSAMP_MAXANISOTROPY : WINED3DFUNC_NOTSUPPORTED},
-#else
-    {WINED3DSAMP_MAXANISOTROPY, WINED3DSAMP_MAXANISOTROPY},
-#endif
-    {WINED3DSAMP_SRGBTEXTURE,   WINED3DFUNC_UNIMPLEMENTED},
-    {WINED3DSAMP_ELEMENTINDEX,  WINED3DFUNC_UNIMPLEMENTED},
-    {WINED3DSAMP_DMAPOFFSET,    WINED3DFUNC_UNIMPLEMENTED},
-    {-1, 0}
-};
-
-static const Wined3dTextureStateMap textureObjectTextureStates[] = {
-    {WINED3DTSS_ADDRESSW , WINED3DTSS_ADDRESSW},
-    {-1, 0}
-};
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 /* *******************************************
    IWineD3DBaseTexture IUnknown parts follow
@@ -96,8 +67,11 @@ ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
 /* class static */
 void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
     TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
     if (This->baseTexture.textureName != 0) {
+        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
         glDeleteTextures(1, &This->baseTexture.textureName);
@@ -134,7 +108,7 @@ DWORD    WINAPI        IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *
 }
 
 void     WINAPI        IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface) {
-    return IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
+    IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
 }
 
 WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface) {
@@ -187,11 +161,39 @@ DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
 
 HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+  IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+  UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
 
-  if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
+  if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
       TRACE("(%p) : returning invalid call\n", This);
       return WINED3DERR_INVALIDCALL;
   }
+  if(This->baseTexture.filterType != FilterType) {
+      /* What about multithreading? Do we want all the context overhead just to set this value?
+       * Or should we delay the applying until the texture is used for drawing? For now, apply
+       * immediately.
+       */
+      ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+      ENTER_GL();
+      glBindTexture(textureDimensions, This->baseTexture.textureName);
+      checkGLcall("glBindTexture");
+      switch(FilterType) {
+          case WINED3DTEXF_NONE:
+          case WINED3DTEXF_POINT:
+              glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST);
+              checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST)");
+
+          case WINED3DTEXF_LINEAR:
+              glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
+              checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)");
+
+          default:
+              WARN("Unexpected filter type %d, setting to GL_NICEST\n", FilterType);
+              glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
+              checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)");
+      }
+      LEAVE_GL();
+  }
   This->baseTexture.filterType = FilterType;
   TRACE("(%p) :\n", This);
   return WINED3D_OK;
@@ -200,7 +202,7 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture
 WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) {
   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
   FIXME("(%p) : stub\n", This);
-  if (!(This->baseTexture.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
+  if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
      return WINED3DTEXF_NONE;
   }
   return This->baseTexture.filterType;
@@ -236,7 +238,6 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
 
     textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
     ENTER_GL();
-
     /* Generate a texture name if we don't already have one */
     if (This->baseTexture.textureName == 0) {
         glGenTextures(1, &This->baseTexture.textureName);
@@ -266,6 +267,16 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
         This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW]   = WINED3DTADDRESS_WRAP;
         IWineD3DBaseTexture_SetDirty(iface, TRUE);
         isNewTexture = TRUE;
+
+        if(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP) {
+            /* This means double binding the texture at creation, but keeps the code simpler all
+             * in all, and the run-time path free from additional checks
+             */
+            glBindTexture(textureDimensions, This->baseTexture.textureName);
+            checkGLcall("glBindTexture");
+            glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+            checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)");
+        }
     }
 
     /* Bind the texture */
@@ -279,6 +290,12 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
             TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
             glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
             checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
+            if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
+                /* Cubemaps are always set to clamp, regardeless of the sampler state. */
+                glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+                glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+            }
         }
                
     } else { /* this only happened if we've run out of openGL textures */
@@ -330,138 +347,124 @@ static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
     }
 }
 
+static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type) {
+    GLint wrapParm;
+
+    if (state < minLookup[WINELOOKUP_WARPPARAM] || state > maxLookup[WINELOOKUP_WARPPARAM]) {
+        FIXME("Unrecognized or unsupported WINED3DTADDRESS_U value %d\n", state);
+    } else {
+        if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
+            /* Cubemaps are always set to clamp, regardeless of the sampler state. */
+            wrapParm = GL_CLAMP_TO_EDGE;
+        } else {
+            wrapParm = stateLookup[WINELOOKUP_WARPPARAM][state - minLookup[WINELOOKUP_WARPPARAM]];
+        }
+        TRACE("Setting WRAP_S to %d for %x\n", wrapParm, textureDimensions);
+        glTexParameteri(textureDimensions, type, wrapParm);
+        checkGLcall("glTexParameteri(..., type, wrapParm)");
+    }
+}
+
 void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
                                     const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
                                     const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    int i;
-    DWORD *state = This->baseTexture.states;
+    DWORD state;
     GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
+
     IWineD3DBaseTexture_PreLoad(iface);
-    /* run through a couple of loops and apply and states that are different */
-    /* this will reduce the number of texture state changes to an absolute minimum
-    for multi-parameter states we  pickup the first one that changes, work out the correct values for the other states
-    and set all the states that we've just applied to their new values */
-
-    for (i = 0 ;textureObjectSamplerStates[i].state != -1; i++) {
-        if (*state != samplerStates[textureObjectSamplerStates[i].state]) {
-            /* apply the state */
-            TRACE("(%p) : Changing state %u from %d to %d\n", This, i, *state , samplerStates[textureObjectSamplerStates[i].state]);
-            switch (textureObjectSamplerStates[i].function) {
-            case WINED3DSAMP_ADDRESSU:
-            case WINED3DSAMP_ADDRESSV: /* fall through */
-            case WINED3DSAMP_ADDRESSW: /* fall through */
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-                if (*state < minLookup[WINELOOKUP_WARPPARAM] || *state > maxLookup[WINELOOKUP_WARPPARAM]) {
-                    FIXME("Unrecognized or unsupported WINED3DTADDRESS_* value %d, state %d\n", *state, textureObjectSamplerStates[i].function);
-                } else {
-                    GLint wrapParm = stateLookup[WINELOOKUP_WARPPARAM][*state - minLookup[WINELOOKUP_WARPPARAM]];
-                    TRACE("Setting WRAP_R to %d for %x\n", wrapParm, textureDimensions);
-                    glTexParameteri(textureDimensions, warpLookupType(textureObjectSamplerStates[i].function), wrapParm);
-                    checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
-                }
-            break;
-            case WINED3DSAMP_BORDERCOLOR:
-            {
-                GLint col[4];
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-                D3DCOLORTOGLINT4(*state, col);
-                TRACE("Setting border color for %u to %x\n", textureDimensions, *state);
-                glTexParameteriv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
-                checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
-            }
-            break;
-            case WINED3DSAMP_MAGFILTER:
-                {
-                    GLint glValue;
-                    *state = samplerStates[textureObjectSamplerStates[i].state];
-                    if (*state < minLookup[WINELOOKUP_MAGFILTER] || *state > maxLookup[WINELOOKUP_MAGFILTER]) {
-                        FIXME("Unrecognized or unsupported MAGFILTER* value %d, state %d\n", *state, textureObjectSamplerStates[i].function);
-                    }
-                    glValue = stateLookup[WINELOOKUP_MAGFILTER][*state - minLookup[WINELOOKUP_MAGFILTER]];
-                    TRACE("ValueMAG=%d setting MAGFILTER to %x\n", *state, glValue);
-                    glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
-                /* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
-                    if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == *state) {
-                        glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
-                    }
-                }
-            break;
-
-            case WINED3DSAMP_MINFILTER:
-                This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
-            case WINED3DSAMP_MIPFILTER: /* fall through */
-                {
-                    GLint glValue;
-                    *state = samplerStates[textureObjectSamplerStates[i].state];
-                    if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
-                        This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
-                        This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
-                        This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
-                    {
-
-                        FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d, state %d D3DSAMP_MIPFILTER value %d, state %d\n",
-                                This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
-                                textureObjectSamplerStates[WINED3DTEXSTA_MINFILTER].function,
-                                This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],
-                                textureObjectSamplerStates[WINED3DTEXSTA_MIPFILTER].function);
-                    }
-                    glValue = minMipLookup[min(max(This->baseTexture.states[WINED3DTEXSTA_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
-                                                [min(max(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
-
-                    TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n", 
-                            This->baseTexture.states[WINED3DTEXSTA_MINFILTER], 
-                            This->baseTexture.states[WINED3DTEXSTA_MIPFILTER], glValue);
-                    glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
-                    checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
-                }
-            break;
-            case WINED3DSAMP_MAXMIPLEVEL:
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-                /**
-                * Not really the same, but the more apprioprate than nothing
-                */
-                glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, *state);
-            break;
-            case WINED3DSAMP_MAXANISOTROPY:
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-                if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
-                    glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT,  *state);
-                    checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
-                } else {
-                    WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
-                }
-            break;
-            case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
-                TRACE("(%p) : stub\n", This);
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-            break;
-            case WINED3DFUNC_NOTSUPPORTED: /* nop */
-                TRACE("(%p) : %s function is not supported by this opengl implementation\n", This, "unknown" /* TODO: replace with debug_blah... */);
-                *state = samplerStates[textureObjectSamplerStates[i].state];
-            break;
-            }
+
+    if(samplerStates[WINED3DSAMP_ADDRESSU]      != This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]) {
+        state = samplerStates[WINED3DSAMP_ADDRESSU];
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S);
+        This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = state;
+    }
+
+    if(samplerStates[WINED3DSAMP_ADDRESSV]      != This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]) {
+        state = samplerStates[WINED3DSAMP_ADDRESSV];
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T);
+        This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = state;
+    }
+
+    if(samplerStates[WINED3DSAMP_ADDRESSW]      != This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]) {
+        state = samplerStates[WINED3DSAMP_ADDRESSW];
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R);
+        This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = state;
+    }
+
+    if(samplerStates[WINED3DSAMP_BORDERCOLOR]   != This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR]) {
+        float col[4];
+
+        state = samplerStates[WINED3DSAMP_BORDERCOLOR];
+        D3DCOLORTOGLFLOAT4(state, col);
+        TRACE("Setting border color for %u to %x\n", textureDimensions, state);
+        glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
+        checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
+        This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = state;
+    }
+
+    if(samplerStates[WINED3DSAMP_MAGFILTER]     != This->baseTexture.states[WINED3DTEXSTA_MAGFILTER]) {
+        GLint glValue;
+        state = samplerStates[WINED3DSAMP_MAGFILTER];
+        if (state < minLookup[WINELOOKUP_MAGFILTER] || state > maxLookup[WINELOOKUP_MAGFILTER]) {
+            FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
         }
-        state++;
+        glValue = stateLookup[WINELOOKUP_MAGFILTER][state - minLookup[WINELOOKUP_MAGFILTER]];
+        TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
+        glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
+        /* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
+        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state) {
+            glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
+        }
+        This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = state;
     }
 
-    for(i = 0 ;textureObjectTextureStates[i].state != - 1; i++) {
-        if(*state != textureStates[textureObjectTextureStates[i].state] ) {
-            /* apply the state */
-            *state = textureStates[textureObjectTextureStates[i].state];
-            switch (textureObjectTextureStates[i].function) {
-            case WINED3DTSS_ADDRESSW:
-            /* I'm not sure what to do if this is set as well as ADDRESSW on the sampler, how do they interact together? */
-            break;
-            case WINED3DFUNC_UNIMPLEMENTED: /* unimplemented */
-            TRACE("(%p) : stub\n", This);
-            break;
-            case WINED3DFUNC_NOTSUPPORTED: /* nop */
-            TRACE("(%p) : function no supported by this opengl implementation\n", This);
-            break;
-            }
+    if(samplerStates[WINED3DSAMP_MINFILTER]     != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] ||
+       samplerStates[WINED3DSAMP_MIPFILTER]     != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] ||
+       samplerStates[WINED3DSAMP_MAXMIPLEVEL]   != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]) {
+        GLint glValue;
+
+        This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
+        This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
+        This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
+
+        if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
+            This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
+            This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
+            This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
+        {
+
+            FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
+                  This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
+                  This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]);
+        }
+        glValue = minMipLookup[min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
+                [min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
+
+        TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
+              samplerStates[WINED3DSAMP_MINFILTER],
+              samplerStates[WINED3DSAMP_MIPFILTER], glValue);
+        glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
+        checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
+
+        if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
+            glValue = 0;
+        } else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
+            glValue = This->baseTexture.levels - 1;
+        } else {
+            glValue = This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];
+        }
+        glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
+    }
+
+    if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) {
+        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
+            glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
+            checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
+        } else {
+            WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
         }
-        state++;
+        This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
     }
 }