Separate the setting of the DirectX texture and sampler states from
the setting of OpenGL states (now in applyTextureStateState and
applySamplerState).

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6fe83ba..577981d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -62,6 +62,9 @@
 /* static function declarations */
 static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
 
+static void WINAPI IWineD3DDeviceImpl_ApplyTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type);
+
+static void WINAPI IWineD3DDeviceImpl_ApplySamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type);
 
 /* helper macros */
 #define D3DMEMCHECK(object, ppResult) if(NULL == object) { *ppResult = NULL; WARN("Out of memory\n"); return D3DERR_OUTOFVIDEOMEMORY;}
@@ -224,7 +227,6 @@
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     int i = 0;
     float col[4];
-    BOOL changeTexture = TRUE;
 
     TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
     for (i = 1; i < WINED3D_HIGHEST_TEXTURE_STATE; i++) {
@@ -267,13 +269,13 @@
 
         if (skip == FALSE) {
            /* Now apply the change */
-           IWineD3DDevice_SetTextureStageState(iface, Stage, i, This->stateBlock->textureState[Stage][i]);
+           IWineD3DDeviceImpl_ApplyTextureStageState(iface, Stage, i);
         }
     }
 
     /* apply the sampler states to the texture */
     for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; i++) {
-        IWineD3DDevice_SetSamplerState(iface, Stage, i, This->stateBlock->samplerState[Stage][i]);
+        IWineD3DDeviceImpl_ApplySamplerState(iface, Stage, i);
     }
 
     /* Note the D3DRS value applies to all textures, but GL has one
@@ -421,7 +423,7 @@
 
     IWineD3DDeviceImpl     *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DStateBlockImpl *object;
-    int i,j;
+    int i;
 
     D3DCREATEOBJECTINSTANCE(object, StateBlock)
     object->blockType     = Type;
@@ -461,38 +463,15 @@
         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
             object->changed.renderState[SavedPixelStates_R[i]] = TRUE;
         }
-        for (j = 0; j < GL_LIMITS(textures); i++) {
-            for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
-                object->changed.textureState[j][SavedPixelStates_T[i]] = TRUE;
-            }
-        }
-        /* Setting sampler block changes states */
-        for (j = 0 ; j < GL_LIMITS(samplers); j++) {
-            for (i =0; i < NUM_SAVEDPIXELSTATES_S;i++) {
 
-                object->changed.samplerState[j][SavedPixelStates_S[i]] = TRUE;
-            }
-        }
     } else if (Type == WINED3DSBT_VERTEXSTATE) {
 
         memset(&object->changed, FALSE, sizeof(This->stateBlock->changed));
-
         /* TODO: Vertex Shader Constants */
         object->changed.vertexShader = TRUE;
         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
             object->changed.renderState[SavedVertexStates_R[i]] = TRUE;
         }
-        for (j = 0; j < GL_LIMITS(textures); i++) {
-            for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
-                object->changed.textureState[j][SavedVertexStates_T[i]] = TRUE;
-            }
-        }
-        /* Setting sampler block changes states */
-        for (j = 0 ; j < GL_LIMITS(samplers); j++) {
-            for (i =0; i < NUM_SAVEDVERTEXSTATES_S;i++) {
-                object->changed.samplerState[j][SavedVertexStates_S[i]] = TRUE;
-            }
-        }
 
     /* Duplicate light chain */
     {
@@ -1641,14 +1620,7 @@
     ENTER_GL();
 
     if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) { /* handle texture matrices */
-#if 0 /* This is now set with the texture unit states, it may be a good idea to flag the change though! */
-        if (d3dts < GL_LIMITS(textures)) {
-            int tex = d3dts - D3DTS_TEXTURE0;
-            GLACTIVETEXTURE(tex);
-            set_texture_matrix((float *)lpmatrix,
-                               This->updateStateBlock->textureState[tex][WINED3DTSS_TEXTURETRANSFORMFLAGS], (This->stateBlock->textureState[tex][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU);
-        }
-#endif
+        /* This is now set with the texture unit states, it may be a good idea to flag the change though! */
     } else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */
         unsigned int k;
 
@@ -3299,8 +3271,15 @@
     return D3D_OK;
 }
 
-HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD Value) {
+/*****
+ * Apply / Get / Set Sampler States
+ * TODO: Verify against dx9 definitions
+ *****/
+
+/* NOTE: It is expected that this function is called a number of times in a row for the same texture unit, so it is more efficient if the caller sets the active texture unit before calling this function. set the correct Texture unit active before calling ApplySamplerState */
+static void WINAPI IWineD3DDeviceImpl_ApplySamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    DWORD Value = This->stateBlock->samplerState[Sampler][Type];
     /**
     * SetSampler is designed to allow for more than the standard up to 8 textures
     *  and Geforce has stopped supporting more than 6 standard textures in openGL.
@@ -3323,33 +3302,16 @@
     TRACE("(%p) Sampler(%ld), Type(%d) Value(%ld)\n",This, Sampler ,Type, Value);
 
     if(Sampler >  GL_LIMITS(samplers) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) {
-        FIXME("out of range %d %d sampler %ld type %u\n", GL_LIMITS(samplers), WINED3D_HIGHEST_SAMPLER_STATE, Sampler, Type);
-        return D3DERR_INVALIDCALL;
+        return;
     }
 
-    This->updateStateBlock->changed.samplerState[Sampler][Type] = TRUE;
-    This->updateStateBlock->set.samplerState[Sampler][Type]     = TRUE;
     TRACE("Setting sampler %ld %d to %ld \n", Sampler, Type, Value);
-    This->updateStateBlock->samplerState[Sampler][Type]         = Value;
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
-    }
 
     /* In addition, IDirect3DDevice9::SetSamplerState will now be used for filtering, tiling,
     clamping, MIPLOD, etc. This will work for up to 16 samplers.
     is this just GL_TEXTURE_2D or is it GL_TEXTURE_1D and GL_TEXTURE_3D as well?
     */
     ENTER_GL();
-    VTRACE(("Activating appropriate texture state %ld\n", Sampler));
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        GLACTIVETEXTURE(Sampler);
-    } else if (Sampler > 0) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-    }
-
 
     switch (Type) {
 
@@ -3587,6 +3549,40 @@
         TRACE("invalid sampler setting, Sampler=%ld, Type=%d, Value =%ld\n", Sampler, Type, Value);
     };
     LEAVE_GL();
+    return;
+}
+
+HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD Value) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    /**
+    * SetSampler is designed to allow for more than the standard up to 8 textures
+    *  and Geforce has stopped supporting more than 6 standard textures in openGL.
+    * So I have to use ARB for Gforce. (maybe if the sampler > 4 then use ARB?)
+    *
+    * http://developer.nvidia.com/object/General_FAQ.html#t6
+    *
+    * There are two new settings for GForce
+    * the sampler one:
+    * GL_MAX_TEXTURE_IMAGE_UNITS_ARB
+    * and the texture one:
+    * GL_MAX_TEXTURE_COORDS_ARB.
+    * Ok GForce say it's ok to use glTexParameter/glGetTexParameter(...).
+     ******************/
+    TRACE("(%p) Sampler(%ld), Type(%d) Value(%ld)\n",This, Sampler ,Type, Value);
+
+    if(Sampler >  GL_LIMITS(samplers) || Sampler < 0 || Type > WINED3D_HIGHEST_SAMPLER_STATE || Type < 0) {
+         FIXME("out of range %d %d sampler %ld type %u\n", GL_LIMITS(samplers), WINED3D_HIGHEST_SAMPLER_STATE, Sampler, Type);
+        return D3DERR_INVALIDCALL;
+    }
+    TRACE("Setting sampler %ld %d to %ld \n", Sampler, Type, Value);
+    This->updateStateBlock->samplerState[Sampler][Type]         = Value;
+
+    /* Handle recording of state blocks */
+    if (This->isRecordingState) {
+        TRACE("Recording... not performing anything\n");
+        return D3D_OK;
+    }
+
     return D3D_OK;
 }
 
@@ -3595,8 +3591,8 @@
     /** TODO: check that sampler is in  range **/
     *Value = This->updateStateBlock->samplerState[Sampler][Type];
     TRACE("(%p) : Sampler %ld Type %u Returning %ld\n", This, Sampler, Type, *Value);
-    return D3D_OK;
 
+    return D3D_OK;
 }
 
 HRESULT WINAPI IWineD3DDeviceImpl_SetScissorRect(IWineD3DDevice *iface, CONST RECT* pRect) {
@@ -3607,6 +3603,7 @@
     TRACE("(%p)Setting new Scissor Rect to %ld:%ld-%ld:%ld\n", This, pRect->left, pRect->top, pRect->right, pRect->bottom);
     glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
     LEAVE_GL();
+
     return D3D_OK;
 }
 
@@ -3801,42 +3798,26 @@
 }
 
 /*****
- * Get / Set Texture Stage States
+ * Apply / Get / Set Texture Stage States
  * TODO: Verify against dx9 definitions
  *****/
-HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
+/* NOTE: It's expected that this function is going to be called lots of times with the same stage active, so make it the callers responsibility to GLACTIVETEXTURE(Stage) for better state management. Set the correct Texture unit active before callnig ApplyTextureStageState */
+static void WINAPI IWineD3DDeviceImpl_ApplyTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    DWORD Value = This->updateStateBlock->textureState[Stage][Type];
     /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
 
     TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
 
-    /* Reject invalid texture units */
-    if (Stage >= GL_LIMITS(textures)) {
+    /* Check that the stage is within limits  */
+    if (Stage >= GL_LIMITS(textures) || Stage < 0) {
         TRACE("Attempt to access invalid texture rejected\n");
-        return D3DERR_INVALIDCALL;
-    }
-
-    This->updateStateBlock->changed.textureState[Stage][Type] = TRUE;
-    This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
-    This->updateStateBlock->textureState[Stage][Type] = Value;
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+        return;
     }
 
     ENTER_GL();
 
-    /* Make appropriate texture active */
-    VTRACE(("Activating appropriate texture state %ld\n", Stage));
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        GLACTIVETEXTURE(Stage);
-    } else if (Stage > 0) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-    }
-
     switch (Type) {
     case WINED3DTSS_ALPHAOP               :
     case WINED3DTSS_COLOROP               :
@@ -4142,6 +4123,24 @@
 
     LEAVE_GL();
 
+    return;
+}
+
+HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
+
+    TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
+
+    /* Reject invalid texture units */
+    if (Stage >= GL_LIMITS(textures)) {
+        TRACE("Attempt to access invalid texture rejected\n");
+        return D3DERR_INVALIDCALL;
+    }
+
+    This->updateStateBlock->textureState[Stage][Type]         = Value;
+
     return D3D_OK;
 }
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 3d6d56a..8941910 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1578,6 +1578,10 @@
 
 }
 
+/* loads any dirty textures and returns true if any of the textures are nonpower2 */
+BOOL inline drawPrimitiveUploadDirtyTextures(IWineD3DDeviceImpl* This) {
+    BOOL nonPower2 = FALSE;
+    unsigned int i;
 /**
 * OK, here we clear down any old junk iect in the context
 * enable the new texture and apply any state changes:
@@ -1589,9 +1593,6 @@
 * enable and bind the texture that is bound to that unit.
 * otherwise dissable all texture types on that unit.
 **/
-BOOL inline drawPrimitiveUploadDirtyTextures(IWineD3DDeviceImpl* This) {
-    BOOL nonPower2 = FALSE;
-    unsigned int i;
     /* upload the textures */
     for (i = 0; i< GL_LIMITS(textures); ++i) {
         /* Bind the texture to the stage here */
@@ -1653,7 +1654,7 @@
                 glEnable(GL_TEXTURE_1D);
                 This->stateBlock->textureDimensions[i] = GL_TEXTURE_1D;
                 glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[i]);
-              }
+            }
 /** these ops apply to the texture unit, so they are preseved between texture changes, but for now brute force and reapply all
         dx9_1pass_emboss_bump_mapping and dx9_2pass_emboss_bump_mapping are good texts to make sure the states are being applied when needed **/
             set_tex_op((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 2828d81..b6cb921 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -284,16 +284,11 @@
         /* FIXME: textures are upto MAX_SAMPLERS for d3d9? */
         /* Texture */
         for (j = 0; j < GL_LIMITS(textures); j++) {
+            /* TODO: move over to using memcpy */
             for (i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE ; i++) {
-
-                if (This->set.textureState[j][i] && (This->textureState[j][i] !=
-                                                                    targetStateBlock->textureState[j][i])) {
-                    TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, targetStateBlock->textureState[j][i],
-                    This->textureState[j][i]);
-                    This->textureState[j][i] =  targetStateBlock->textureState[j][i];
-                    This->renderState[i] = targetStateBlock->renderState[i];
-                }
-
+                TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, targetStateBlock->textureState[j][i],
+                This->textureState[j][i]);
+                This->textureState[j][i] =  targetStateBlock->textureState[j][i];
             }
 
             if ((This->set.textures[j] && (This->textures[j] != targetStateBlock->textures[j]))) {
@@ -304,15 +299,13 @@
         }
 
         /* Samplers */
+        /* TODO: move over to using memcpy */
         for (j = 0 ; j < GL_LIMITS(samplers); j++){
             for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE ; i++){ /* States are 1 based */
-                if (This->set.samplerState[j][i] && (This->samplerState[j][i] !=
-                                                        targetStateBlock->samplerState[j][i])) {
-                    TRACE("Updating sampler state %d,%d to %ld (was %ld)\n",
-                    j, i, targetStateBlock->samplerState[j][i],
-                    This->samplerState[j][i]);
-                    This->samplerState[j][i] = targetStateBlock->samplerState[j][i];
-                }
+                TRACE("Updating sampler state %d,%d to %ld (was %ld)\n",
+                j, i, targetStateBlock->samplerState[j][i],
+                This->samplerState[j][i]);
+                This->samplerState[j][i] = targetStateBlock->samplerState[j][i];
             }
         }
     }
@@ -423,19 +416,17 @@
             if (This->set.textures[j] && This->changed.textures[j]) {
                 IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
             }
+            /* TODO: move over to memcpy */
             for (i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE; i++) {
-                if (This->set.textureState[j][i] && This->changed.textureState[j][i]) {
-                    IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
-                }
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][i] = This->textureState[j][i];
             }
         }
 
         /* Samplers */
+        /* TODO: move over to memcpy */
         for (j = 0 ; j < GL_LIMITS(samplers); j++){
             for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; i++){
-                 if (This->set.samplerState[j][i] && This->changed.samplerState[j][i] && This->samplerState[j][i] != 0) {
-                        IWineD3DDevice_SetSamplerState(pDevice, j, i, This->samplerState[j][i]);
-                 }
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][i] = This->samplerState[j][i];
             }
 
         }
@@ -450,9 +441,13 @@
 
         for (j = 0; j < GL_LIMITS(textures); i++) {
             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
-                if (This->set.textureState[j][SavedPixelStates_T[i]] &&
-                    This->changed.textureState[j][SavedPixelStates_T[i]])
-                    IWineD3DDevice_SetTextureStageState(pDevice, j, SavedPixelStates_T[i], This->textureState[j][SavedPixelStates_T[i]]);
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedPixelStates_T[i]] = This->textureState[j][SavedPixelStates_T[i]];
+            }
+        }
+
+        for (j = 0; j < GL_LIMITS(samplers); i++) {
+            for (i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][SavedPixelStates_S[i]] = This->samplerState[j][SavedPixelStates_S[i]];
             }
         }
 
@@ -465,9 +460,13 @@
 
         for (j = 0; j < GL_LIMITS(textures); i++) {
             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
-                if ( This->set.textureState[j][SavedVertexStates_T[i]] &&
-                    This->changed.textureState[j][SavedVertexStates_T[i]])
-                    IWineD3DDevice_SetTextureStageState(pDevice, j, SavedVertexStates_T[i], This->textureState[j][SavedVertexStates_T[i]]);
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][SavedVertexStates_T[i]] = This->textureState[j][SavedVertexStates_T[i]];
+            }
+        }
+
+        for (j = 0; j < GL_LIMITS(textures); i++) {
+            for (i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
+                ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][SavedVertexStates_S[i]] = This->textureState[j][SavedVertexStates_S[i]];
             }
         }
 
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 234e48f..701fd17 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1499,8 +1499,6 @@
     } else if(!calculatedCoords) { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
         mat[12] = mat[8];
         mat[13] = mat[9];
-        mat[8] = 0;
-        mat[9] = 0;
     }
 
     glLoadMatrixf(mat);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e8f2c92..b6c7192 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -784,9 +784,11 @@
         BOOL                      transform[HIGHEST_TRANSFORMSTATE + 1];
         BOOL                      viewport;
         BOOL                      renderState[WINEHIGHEST_RENDER_STATE + 1];
+#if 0
         BOOL                      textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
-        BOOL                      clipplane[MAX_CLIPPLANES];
         BOOL                      samplerState[MAX_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
+#endif
+        BOOL                      clipplane[MAX_CLIPPLANES];
         BOOL                      vertexDecl;
         BOOL                      pixelShader;
         BOOL                      vertexShader;