* Bring back rbuild build to be used until bug 6372 is fixed.
[reactos.git] / dll / directx / wine / wined3d / state.c
index 6a415ee..a43cc38 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright 2005 Oliver Stieber
  * Copyright 2006 Henri Verbeet
  * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
- * Copyright 2009 Henri Verbeet for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -37,19 +37,19 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 
 /* GL locking for state handlers is done by the caller. */
 
-static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context);
 
-static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_undefined(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     ERR("Undefined state.\n");
 }
 
-static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_nop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state));
 }
 
-static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_fillmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WINED3DFILLMODE Value = stateblock->state.render_states[WINED3DRS_FILLMODE];
 
@@ -71,7 +71,7 @@ static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_lighting(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /* Lighting is not enabled if transformed vertices are drawn
      * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
@@ -94,10 +94,10 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_zenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /* No z test without depth stencil buffers */
-    if (!stateblock->device->depth_stencil)
+    if (!stateblock->device->fb.depth_stencil)
     {
         TRACE("No Z buffer - disabling depth test\n");
         glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
@@ -126,7 +126,7 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
-static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_cullmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /* glFrontFace() is set in context.c at context init and on an
      * offscreen / onscreen rendering switch. */
@@ -154,7 +154,7 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_shademode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     switch (stateblock->state.render_states[WINED3DRS_SHADEMODE])
     {
@@ -175,7 +175,7 @@ static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
-static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_ditherenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_DITHERENABLE])
     {
@@ -189,7 +189,7 @@ static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
-static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_zwritenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off.
      * If yes, this has to be merged with ZENABLE and ZFUNC. */
@@ -205,7 +205,7 @@ static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_zfunc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     GLenum depth_func = CompareFunc(stateblock->state.render_states[WINED3DRS_ZFUNC]);
 
@@ -230,7 +230,7 @@ static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     checkGLcall("glDepthFunc");
 }
 
-static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_ambient(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_AMBIENT], col);
@@ -240,12 +240,54 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     checkGLcall("glLightModel for MODEL_AMBIENT");
 }
 
-static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static GLenum gl_blend_factor(WINED3DBLEND factor, const struct wined3d_format *dst_format)
 {
-    IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
+    switch (factor)
+    {
+        case WINED3DBLEND_ZERO:
+            return GL_ZERO;
+        case WINED3DBLEND_ONE:
+            return GL_ONE;
+        case WINED3DBLEND_SRCCOLOR:
+            return GL_SRC_COLOR;
+        case WINED3DBLEND_INVSRCCOLOR:
+            return GL_ONE_MINUS_SRC_COLOR;
+        case WINED3DBLEND_SRCALPHA:
+            return GL_SRC_ALPHA;
+        case WINED3DBLEND_INVSRCALPHA:
+            return GL_ONE_MINUS_SRC_ALPHA;
+        case WINED3DBLEND_DESTCOLOR:
+            return GL_DST_COLOR;
+        case WINED3DBLEND_INVDESTCOLOR:
+            return GL_ONE_MINUS_DST_COLOR;
+        /* To compensate for the lack of format switching with backbuffer
+         * offscreen rendering, and with onscreen rendering, we modify the
+         * alpha test parameters for (INV)DESTALPHA if the render target
+         * doesn't support alpha blending. A nonexistent alpha channel
+         * returns 1.0, so WINED3DBLEND_DESTALPHA becomes GL_ONE, and
+         * WINED3DBLEND_INVDESTALPHA becomes GL_ZERO. */
+        case WINED3DBLEND_DESTALPHA:
+            return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
+        case WINED3DBLEND_INVDESTALPHA:
+            return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
+        case WINED3DBLEND_SRCALPHASAT:
+            return GL_SRC_ALPHA_SATURATE;
+        case WINED3DBLEND_BLENDFACTOR:
+            return GL_CONSTANT_COLOR_EXT;
+        case WINED3DBLEND_INVBLENDFACTOR:
+            return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
+        default:
+            FIXME("Unhandled blend factor %#x.\n", factor);
+            return GL_NONE;
+    }
+}
+
+static void state_blend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
+{
+    struct wined3d_surface *target = stateblock->device->fb.render_targets[0];
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    int srcBlend = GL_ZERO;
-    int dstBlend = GL_ZERO;
+    GLenum srcBlend, dstBlend;
+    WINED3DBLEND d3d_blend;
 
     /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
      * blending parameters to work. */
@@ -257,7 +299,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
          * With blending on we could face a big performance penalty.
          * The d3d9 visual test confirms the behavior. */
         if (context->render_offscreen
-                && !(target->resource.format->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+                && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
         {
             glDisable(GL_BLEND);
             checkGLcall("glDisable GL_BLEND");
@@ -273,86 +315,25 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
         return;
     };
 
-    switch (stateblock->state.render_states[WINED3DRS_DESTBLEND])
+    /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy
+     * source blending values which are still valid up to d3d9. They should
+     * not occur as dest blend values. */
+    d3d_blend = stateblock->state.render_states[WINED3DRS_SRCBLEND];
+    if (d3d_blend == WINED3DBLEND_BOTHSRCALPHA)
     {
-        case WINED3DBLEND_ZERO               : dstBlend = GL_ZERO;  break;
-        case WINED3DBLEND_ONE                : dstBlend = GL_ONE;  break;
-        case WINED3DBLEND_SRCCOLOR           : dstBlend = GL_SRC_COLOR;  break;
-        case WINED3DBLEND_INVSRCCOLOR        : dstBlend = GL_ONE_MINUS_SRC_COLOR;  break;
-        case WINED3DBLEND_SRCALPHA           : dstBlend = GL_SRC_ALPHA;  break;
-        case WINED3DBLEND_INVSRCALPHA        : dstBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
-        case WINED3DBLEND_DESTCOLOR          : dstBlend = GL_DST_COLOR;  break;
-        case WINED3DBLEND_INVDESTCOLOR       : dstBlend = GL_ONE_MINUS_DST_COLOR;  break;
-
-        /* To compensate the lack of format switching with backbuffer offscreen rendering,
-         * and with onscreen rendering, we modify the alpha test parameters for (INV)DESTALPHA
-         * if the render target doesn't support alpha blending. A nonexistent alpha channel
-         * returns 1.0, so D3DBLEND_DESTALPHA is GL_ONE, and D3DBLEND_INVDESTALPHA is GL_ZERO
-         */
-        case WINED3DBLEND_DESTALPHA          :
-            dstBlend = target->resource.format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
-            break;
-        case WINED3DBLEND_INVDESTALPHA       :
-            dstBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
-            break;
-
-        case WINED3DBLEND_SRCALPHASAT        :
-            dstBlend = GL_SRC_ALPHA_SATURATE;
-            WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
-            break;
-
-        /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
-         * values which are still valid up to d3d9. They should not occur as dest blend values
-         */
-        case WINED3DBLEND_BOTHSRCALPHA       : dstBlend = GL_SRC_ALPHA;
-            srcBlend = GL_SRC_ALPHA;
-            FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
-            break;
-
-        case WINED3DBLEND_BOTHINVSRCALPHA    : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
-            srcBlend = GL_ONE_MINUS_SRC_ALPHA;
-            FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
-            break;
-
-        case WINED3DBLEND_BLENDFACTOR        : dstBlend = GL_CONSTANT_COLOR;   break;
-        case WINED3DBLEND_INVBLENDFACTOR     : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
-        default:
-            FIXME("Unrecognized dst blend value %#x.\n",
-                    stateblock->state.render_states[WINED3DRS_DESTBLEND]);
+        srcBlend = GL_SRC_ALPHA;
+        dstBlend = GL_ONE_MINUS_SRC_ALPHA;
     }
-
-    switch (stateblock->state.render_states[WINED3DRS_SRCBLEND])
+    else if (d3d_blend == WINED3DBLEND_BOTHINVSRCALPHA)
     {
-        case WINED3DBLEND_ZERO               : srcBlend = GL_ZERO;  break;
-        case WINED3DBLEND_ONE                : srcBlend = GL_ONE;  break;
-        case WINED3DBLEND_SRCCOLOR           : srcBlend = GL_SRC_COLOR;  break;
-        case WINED3DBLEND_INVSRCCOLOR        : srcBlend = GL_ONE_MINUS_SRC_COLOR;  break;
-        case WINED3DBLEND_SRCALPHA           : srcBlend = GL_SRC_ALPHA;  break;
-        case WINED3DBLEND_INVSRCALPHA        : srcBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
-        case WINED3DBLEND_DESTCOLOR          : srcBlend = GL_DST_COLOR;  break;
-        case WINED3DBLEND_INVDESTCOLOR       : srcBlend = GL_ONE_MINUS_DST_COLOR;  break;
-        case WINED3DBLEND_SRCALPHASAT        : srcBlend = GL_SRC_ALPHA_SATURATE;  break;
-
-        case WINED3DBLEND_DESTALPHA          :
-            srcBlend = target->resource.format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
-            break;
-        case WINED3DBLEND_INVDESTALPHA       :
-            srcBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
-            break;
-
-        case WINED3DBLEND_BOTHSRCALPHA       : srcBlend = GL_SRC_ALPHA;
-            dstBlend = GL_ONE_MINUS_SRC_ALPHA;
-            break;
-
-        case WINED3DBLEND_BOTHINVSRCALPHA    : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
-            dstBlend = GL_SRC_ALPHA;
-            break;
-
-        case WINED3DBLEND_BLENDFACTOR        : srcBlend = GL_CONSTANT_COLOR;   break;
-        case WINED3DBLEND_INVBLENDFACTOR     : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
-        default:
-            FIXME("Unrecognized src blend value %#x.\n",
-                    stateblock->state.render_states[WINED3DRS_SRCBLEND]);
+        srcBlend = GL_ONE_MINUS_SRC_ALPHA;
+        dstBlend = GL_SRC_ALPHA;
+    }
+    else
+    {
+        srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
+        dstBlend = gl_blend_factor(stateblock->state.render_states[WINED3DRS_DESTBLEND],
+                target->resource.format);
     }
 
     if (stateblock->state.render_states[WINED3DRS_EDGEANTIALIAS]
@@ -378,8 +359,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
 
     if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE])
     {
-        int srcBlendAlpha = GL_ZERO;
-        int dstBlendAlpha = GL_ZERO;
+        GLenum srcBlendAlpha, dstBlendAlpha;
 
         /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
         if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
@@ -388,68 +368,25 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
             return;
         }
 
-        switch (stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA])
+        /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy
+         * source blending values which are still valid up to d3d9. They should
+         * not occur as dest blend values. */
+        d3d_blend = stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA];
+        if (d3d_blend == WINED3DBLEND_BOTHSRCALPHA)
         {
-            case WINED3DBLEND_ZERO               : dstBlendAlpha = GL_ZERO;  break;
-            case WINED3DBLEND_ONE                : dstBlendAlpha = GL_ONE;  break;
-            case WINED3DBLEND_SRCCOLOR           : dstBlendAlpha = GL_SRC_COLOR;  break;
-            case WINED3DBLEND_INVSRCCOLOR        : dstBlendAlpha = GL_ONE_MINUS_SRC_COLOR;  break;
-            case WINED3DBLEND_SRCALPHA           : dstBlendAlpha = GL_SRC_ALPHA;  break;
-            case WINED3DBLEND_INVSRCALPHA        : dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;  break;
-            case WINED3DBLEND_DESTCOLOR          : dstBlendAlpha = GL_DST_COLOR;  break;
-            case WINED3DBLEND_INVDESTCOLOR       : dstBlendAlpha = GL_ONE_MINUS_DST_COLOR;  break;
-            case WINED3DBLEND_DESTALPHA          : dstBlendAlpha = GL_DST_ALPHA;  break;
-            case WINED3DBLEND_INVDESTALPHA       : dstBlendAlpha = GL_DST_ALPHA;  break;
-            case WINED3DBLEND_SRCALPHASAT        :
-                dstBlend = GL_SRC_ALPHA_SATURATE;
-                WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
-                break;
-            /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
-            * values which are still valid up to d3d9. They should not occur as dest blend values
-            */
-            case WINED3DBLEND_BOTHSRCALPHA       :
-                dstBlendAlpha = GL_SRC_ALPHA;
-                srcBlendAlpha = GL_SRC_ALPHA;
-                FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
-                break;
-            case WINED3DBLEND_BOTHINVSRCALPHA    :
-                dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
-                srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
-                FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
-                break;
-            case WINED3DBLEND_BLENDFACTOR        : dstBlendAlpha = GL_CONSTANT_COLOR;   break;
-            case WINED3DBLEND_INVBLENDFACTOR     : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR;  break;
-            default:
-                FIXME("Unrecognized dst blend alpha value %#x.\n",
-                        stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA]);
+            srcBlendAlpha = GL_SRC_ALPHA;
+            dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
         }
-
-        switch (stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA])
+        else if (d3d_blend == WINED3DBLEND_BOTHINVSRCALPHA)
         {
-            case WINED3DBLEND_ZERO               : srcBlendAlpha = GL_ZERO;  break;
-            case WINED3DBLEND_ONE                : srcBlendAlpha = GL_ONE;  break;
-            case WINED3DBLEND_SRCCOLOR           : srcBlendAlpha = GL_SRC_COLOR;  break;
-            case WINED3DBLEND_INVSRCCOLOR        : srcBlendAlpha = GL_ONE_MINUS_SRC_COLOR;  break;
-            case WINED3DBLEND_SRCALPHA           : srcBlendAlpha = GL_SRC_ALPHA;  break;
-            case WINED3DBLEND_INVSRCALPHA        : srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;  break;
-            case WINED3DBLEND_DESTCOLOR          : srcBlendAlpha = GL_DST_COLOR;  break;
-            case WINED3DBLEND_INVDESTCOLOR       : srcBlendAlpha = GL_ONE_MINUS_DST_COLOR;  break;
-            case WINED3DBLEND_SRCALPHASAT        : srcBlendAlpha = GL_SRC_ALPHA_SATURATE;  break;
-            case WINED3DBLEND_DESTALPHA          : srcBlendAlpha = GL_DST_ALPHA;  break;
-            case WINED3DBLEND_INVDESTALPHA       : srcBlendAlpha = GL_DST_ALPHA;  break;
-            case WINED3DBLEND_BOTHSRCALPHA       :
-                srcBlendAlpha = GL_SRC_ALPHA;
-                dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
-                break;
-            case WINED3DBLEND_BOTHINVSRCALPHA    :
-                srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
-                dstBlendAlpha = GL_SRC_ALPHA;
-                break;
-            case WINED3DBLEND_BLENDFACTOR        : srcBlendAlpha = GL_CONSTANT_COLOR;   break;
-            case WINED3DBLEND_INVBLENDFACTOR     : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR;  break;
-            default:
-                FIXME("Unrecognized src blend alpha value %#x.\n",
-                        stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA]);
+            srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
+            dstBlendAlpha = GL_SRC_ALPHA;
+        }
+        else
+        {
+            srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
+            dstBlendAlpha = gl_blend_factor(stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA],
+                    target->resource.format);
         }
 
         GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
@@ -466,12 +403,12 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
         stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
 }
 
-static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_blendfactor_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
 }
 
-static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_blendfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     float col[4];
@@ -482,7 +419,7 @@ static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     checkGLcall("glBlendColor");
 }
 
-static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_alpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     int glParm = 0;
     float ref;
@@ -498,12 +435,12 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
      */
     if (stateblock->state.textures[0])
     {
-        IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
-        GLenum texture_dimensions = texture->baseTexture.target;
+        struct wined3d_texture *texture = stateblock->state.textures[0];
+        GLenum texture_dimensions = texture->target;
 
         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
         {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
+            struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
 
             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
             {
@@ -547,7 +484,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
-static void state_clipping(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_clipping(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_state *state = &stateblock->state;
@@ -629,16 +566,36 @@ static void state_clipping(DWORD state_id, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_blendop_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
 }
 
-static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static GLenum gl_blend_op(WINED3DBLENDOP op)
+{
+    switch (op)
+    {
+        case WINED3DBLENDOP_ADD:
+            return GL_FUNC_ADD_EXT;
+        case WINED3DBLENDOP_SUBTRACT:
+            return GL_FUNC_SUBTRACT_EXT;
+        case WINED3DBLENDOP_REVSUBTRACT:
+            return GL_FUNC_REVERSE_SUBTRACT_EXT;
+        case WINED3DBLENDOP_MIN:
+            return GL_MIN_EXT;
+        case WINED3DBLENDOP_MAX:
+            return GL_MAX_EXT;
+        default:
+            FIXME("Unhandled blend op %#x.\n", op);
+            return GL_NONE;
+    }
+}
+
+static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    int blendEquation = GL_FUNC_ADD;
-    int blendEquationAlpha = GL_FUNC_ADD;
+    int blendEquation = GL_FUNC_ADD_EXT;
+    int blendEquationAlpha = GL_FUNC_ADD_EXT;
 
     /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
     if (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]
@@ -648,29 +605,8 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
         return;
     }
 
-    switch (stateblock->state.render_states[WINED3DRS_BLENDOP])
-    {
-        case WINED3DBLENDOP_ADD              : blendEquation = GL_FUNC_ADD;              break;
-        case WINED3DBLENDOP_SUBTRACT         : blendEquation = GL_FUNC_SUBTRACT;         break;
-        case WINED3DBLENDOP_REVSUBTRACT      : blendEquation = GL_FUNC_REVERSE_SUBTRACT; break;
-        case WINED3DBLENDOP_MIN              : blendEquation = GL_MIN;                   break;
-        case WINED3DBLENDOP_MAX              : blendEquation = GL_MAX;                   break;
-        default:
-            FIXME("Unrecognized/Unhandled D3DBLENDOP value %#x.\n",
-                    stateblock->state.render_states[WINED3DRS_BLENDOP]);
-    }
-
-    switch (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA])
-    {
-        case WINED3DBLENDOP_ADD              : blendEquationAlpha = GL_FUNC_ADD;              break;
-        case WINED3DBLENDOP_SUBTRACT         : blendEquationAlpha = GL_FUNC_SUBTRACT;         break;
-        case WINED3DBLENDOP_REVSUBTRACT      : blendEquationAlpha = GL_FUNC_REVERSE_SUBTRACT; break;
-        case WINED3DBLENDOP_MIN              : blendEquationAlpha = GL_MIN;                   break;
-        case WINED3DBLENDOP_MAX              : blendEquationAlpha = GL_MAX;                   break;
-        default:
-            FIXME("Unrecognized/Unhandled D3DBLENDOP value %#x\n",
-                    stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]);
-    }
+    blendEquation = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOP]);
+    blendEquationAlpha = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]);
 
     if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE])
     {
@@ -684,7 +620,7 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
-static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_specularenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
@@ -801,7 +737,7 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock
     checkGLcall("glMaterialfv(GL_EMISSION)");
 }
 
-static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_texfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i;
@@ -841,7 +777,7 @@ static void renderstate_stencil_twosided(struct wined3d_context *context, GLint
     checkGLcall("glStencilOp(...)");
 }
 
-static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_stencil(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD onesided_enable = FALSE;
@@ -858,7 +794,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     GLint stencilPass_ccw = GL_KEEP;
 
     /* No stencil test without a stencil buffer. */
-    if (!stateblock->device->depth_stencil)
+    if (!stateblock->device->fb.depth_stencil)
     {
         glDisable(GL_STENCIL_TEST);
         checkGLcall("glDisable GL_STENCIL_TEST");
@@ -939,9 +875,9 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
-static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_stencilwrite2s(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    DWORD mask = stateblock->device->depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
+    DWORD mask = stateblock->device->fb.depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
     GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
@@ -953,15 +889,15 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock
     glStencilMask(mask);
 }
 
-static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_stencilwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    DWORD mask = stateblock->device->depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
+    DWORD mask = stateblock->device->fb.depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
 
     glStencilMask(mask);
     checkGLcall("glStencilMask");
 }
 
-static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_fog_vertexpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
@@ -1001,7 +937,7 @@ static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock
     }
 }
 
-void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void state_fogstartend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     float fogstart, fogend;
     union {
@@ -1027,7 +963,7 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
             fogend = tmpvalue.f;
             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
             if(fogstart == fogend) {
-                fogstart = -1.0f / 0.0f;
+                fogstart = -INFINITY;
                 fogend = 0.0f;
             }
             break;
@@ -1050,7 +986,7 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     TRACE("Fog End == %f\n", fogend);
 }
 
-void state_fog_fragpart(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void state_fog_fragpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_state *state = &stateblock->state;
     enum fogsource new_source;
@@ -1202,13 +1138,13 @@ void state_fog_fragpart(DWORD state_id, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_rangefog_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
         WARN("Range fog enabled, but not supported by this opengl implementation\n");
 }
 
-static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_rangefog(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
     {
@@ -1220,7 +1156,7 @@ static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void state_fogcolor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_FOGCOLOR], col);
@@ -1228,7 +1164,7 @@ void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
-void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void state_fogdensity(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     union {
         DWORD d;
@@ -1239,10 +1175,10 @@ void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
 }
 
-static void state_colormat(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colormat(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_state *state = &stateblock->state;
-    IWineD3DDeviceImpl *device = stateblock->device;
+    struct wined3d_device *device = stateblock->device;
     GLenum Parm = 0;
 
     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
@@ -1363,7 +1299,7 @@ static void state_colormat(DWORD state_id, IWineD3DStateBlockImpl *stateblock, s
     context->tracking_parm = Parm;
 }
 
-static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_linepattern(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     union {
         DWORD                 d;
@@ -1384,37 +1320,7 @@ static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
-    union {
-        DWORD d;
-        float f;
-    } tmpvalue;
-
-    if (stateblock->state.render_states[WINED3DRS_ZBIAS])
-    {
-        tmpvalue.d = stateblock->state.render_states[WINED3DRS_ZBIAS];
-        TRACE("ZBias value %f\n", tmpvalue.f);
-        glPolygonOffset(0, -tmpvalue.f);
-        checkGLcall("glPolygonOffset(0, -Value)");
-        glEnable(GL_POLYGON_OFFSET_FILL);
-        checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
-        glEnable(GL_POLYGON_OFFSET_LINE);
-        checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
-        glEnable(GL_POLYGON_OFFSET_POINT);
-        checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
-    } else {
-        glDisable(GL_POLYGON_OFFSET_FILL);
-        checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
-        glDisable(GL_POLYGON_OFFSET_LINE);
-        checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
-        glDisable(GL_POLYGON_OFFSET_POINT);
-        checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
-    }
-}
-
-
-static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_normalize(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if(isStateDirty(context, STATE_VDECL)) {
         return;
@@ -1434,7 +1340,7 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
-static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_psizemin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     union {
         DWORD d;
@@ -1454,7 +1360,7 @@ static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, st
 
 }
 
-static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_psizemin_ext(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     union
@@ -1477,7 +1383,7 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfEXT(...)");
 }
 
-static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_psizemin_arb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     union
@@ -1500,7 +1406,7 @@ static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfARB(...)");
 }
 
-static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_pscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     /* TODO: Group this with the viewport */
@@ -1579,12 +1485,12 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     checkGLcall("glPointSize(...);");
 }
 
-static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_debug_monitor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WARN("token: %#x\n", stateblock->state.render_states[WINED3DRS_DEBUGMONITORTOKEN]);
 }
 
-static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colorwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD mask0 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE];
     DWORD mask1 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1];
@@ -1620,27 +1526,27 @@ static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DW
             mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
 }
 
-static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colorwrite0(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     set_color_mask(context->gl_info, 0, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE]);
 }
 
-static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colorwrite1(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     set_color_mask(context->gl_info, 1, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1]);
 }
 
-static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colorwrite2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     set_color_mask(context->gl_info, 2, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2]);
 }
 
-static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_colorwrite3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     set_color_mask(context->gl_info, 3, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3]);
 }
 
-static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_localviewer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_LOCALVIEWER])
     {
@@ -1652,7 +1558,7 @@ static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_lastpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_LASTPIXEL])
     {
@@ -1668,7 +1574,7 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
-static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_pointsprite_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     static BOOL warned;
 
@@ -1681,7 +1587,7 @@ static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
-static void state_pointsprite(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_pointsprite(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_state *state = &stateblock->state;
@@ -1707,7 +1613,7 @@ static void state_pointsprite(DWORD state_id, IWineD3DStateBlockImpl *stateblock
     }
 }
 
-static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_wrap(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /**
      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
@@ -1738,13 +1644,13 @@ static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
-static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_msaa_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
         WARN("Multisample antialiasing not supported by gl\n");
 }
 
-static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_msaa(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
     {
@@ -1756,7 +1662,7 @@ static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
-static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_scissor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_SCISSORTESTENABLE])
     {
@@ -1774,14 +1680,17 @@ static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
  * convert from D3D to GL we need to divide the D3D depth bias by that value.
  * There's no practical way to retrieve that value from a given GL
  * implementation, but the D3D application has essentially the same problem,
- * which makes a guess of 1e-6f seem reasonable here. Note that
- * SLOPESCALEDEPTHBIAS is a scaling factor for the depth slope, and doesn't
- * need to be scaled. */
-static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+ * which makes a guess of the depth buffer format's highest possible value a
+ * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
+ * depth slope, and doesn't need to be scaled. */
+static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]
             || stateblock->state.render_states[WINED3DRS_DEPTHBIAS])
     {
+        struct wined3d_surface *depth = stateblock->device->fb.depth_stencil;
+        float scale;
+
         union
         {
             DWORD d;
@@ -1794,7 +1703,21 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str
         glEnable(GL_POLYGON_OFFSET_FILL);
         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
 
-        glPolygonOffset(scale_bias.f, const_bias.f * 1e6f);
+        if (depth)
+        {
+            const struct wined3d_format *fmt = depth->resource.format;
+            scale = powf(2, fmt->depth_size) - 1;
+            TRACE("Depth format %s, using depthbias scale of %f\n",
+                  debug_d3dformat(fmt->id), scale);
+        }
+        else
+        {
+            /* The context manager will reapply this state on a depth stencil change */
+            TRACE("No depth stencil, using depthbias scale of 0.0\n");
+            scale = 0;
+        }
+
+        glPolygonOffset(scale_bias.f, const_bias.f * scale);
         checkGLcall("glPolygonOffset(...)");
     } else {
         glDisable(GL_POLYGON_OFFSET_FILL);
@@ -1802,13 +1725,13 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
-static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_zvisible(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_ZVISIBLE])
         FIXME("WINED3DRS_ZVISIBLE not implemented.\n");
 }
 
-static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_perspective(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_TEXTUREPERSPECTIVE])
     {
@@ -1820,33 +1743,33 @@ static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_stippledalpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_STIPPLEDALPHA])
         FIXME(" Stippled Alpha not supported yet.\n");
 }
 
-static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_antialias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_ANTIALIAS])
         FIXME("Antialias not supported yet.\n");
 }
 
-static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_multisampmask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK] != 0xffffffff)
         FIXME("WINED3DRS_MULTISAMPLEMASK %#x not yet implemented.\n",
                 stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK]);
 }
 
-static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_patchedgestyle(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
         FIXME("WINED3DRS_PATCHEDGESTYLE %#x not yet implemented.\n",
                 stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE]);
 }
 
-static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_patchsegments(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     union {
         DWORD d;
@@ -1866,28 +1789,28 @@ static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
-static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_positiondegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
         FIXME("WINED3DRS_POSITIONDEGREE %#x not yet implemented.\n",
                 stateblock->state.render_states[WINED3DRS_POSITIONDEGREE]);
 }
 
-static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_normaldegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
         FIXME("WINED3DRS_NORMALDEGREE %#x not yet implemented.\n",
                 stateblock->state.render_states[WINED3DRS_NORMALDEGREE]);
 }
 
-static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_tessellation(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION])
         FIXME("WINED3DRS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
                 stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
 }
 
-static void state_nvdb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_nvdb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     union {
         DWORD d;
@@ -1923,91 +1846,91 @@ static void state_nvdb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     state_tessellation(state, stateblock, context);
 }
 
-static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_wrapu(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_WRAPU])
         FIXME("Render state WINED3DRS_WRAPU not implemented yet.\n");
 }
 
-static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_wrapv(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_WRAPV])
         FIXME("Render state WINED3DRS_WRAPV not implemented yet.\n");
 }
 
-static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_monoenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_MONOENABLE])
         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet.\n");
 }
 
-static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_rop2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_ROP2])
         FIXME("Render state WINED3DRS_ROP2 not implemented yet.\n");
 }
 
-static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_planemask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_PLANEMASK])
         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet.\n");
 }
 
-static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_subpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_SUBPIXEL])
         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet.\n");
 }
 
-static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_subpixelx(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_SUBPIXELX])
         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet.\n");
 }
 
-static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_stippleenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_STIPPLEENABLE])
         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet.\n");
 }
 
-static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_mipmaplodbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_MIPMAPLODBIAS])
         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet.\n");
 }
 
-static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_anisotropy(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_ANISOTROPY])
         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet.\n");
 }
 
-static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_flushbatch(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_FLUSHBATCH])
         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet.\n");
 }
 
-static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_translucentsi(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_TRANSLUCENTSORTINDEPENDENT])
         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
 }
 
-static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_extents(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_EXTENTS])
         FIXME("Render state WINED3DRS_EXTENTS not implemented yet.\n");
 }
 
-static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_ckeyblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_COLORKEYBLENDENABLE])
         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet.\n");
 }
 
-static void state_swvp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_swvp(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (stateblock->state.render_states[WINED3DRS_SOFTWAREVERTEXPROCESSING])
         FIXME("Software vertex processing not implemented.\n");
@@ -3100,7 +3023,7 @@ static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined
 }
 
 
-static void tex_colorop(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void tex_colorop(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
@@ -3163,7 +3086,7 @@ static void tex_colorop(DWORD state_id, IWineD3DStateBlockImpl *stateblock, stru
             state->texture_states[stage][WINED3DTSS_COLORARG0]);
 }
 
-void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void tex_alphaop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
@@ -3191,12 +3114,12 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d
 
     if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !stage && stateblock->state.textures[0])
     {
-        IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
-        GLenum texture_dimensions = texture->baseTexture.target;
+        struct wined3d_texture *texture = stateblock->state.textures[0];
+        GLenum texture_dimensions = texture->target;
 
         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
         {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
+            struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
 
             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
             {
@@ -3264,7 +3187,7 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d
     }
 }
 
-static void transform_texture(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void transform_texture(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->device->texUnitMap[texUnit];
@@ -3307,7 +3230,7 @@ static void transform_texture(DWORD state_id, IWineD3DStateBlockImpl *stateblock
         if (!use_ps(state))
         {
             TRACE("Non power two matrix multiply fixup\n");
-            glMultMatrixf(state->textures[texUnit]->baseTexture.pow2Matrix);
+            glMultMatrixf(state->textures[texUnit]->pow2_matrix);
         }
     }
 }
@@ -3323,7 +3246,7 @@ static void unloadTexCoords(const struct wined3d_gl_info *gl_info)
     }
 }
 
-static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBlockImpl *stateblock,
+static void loadTexCoords(const struct wined3d_gl_info *gl_info, struct wined3d_stateblock *stateblock,
         const struct wined3d_stream_info *si, GLuint *curVBO)
 {
     unsigned int mapped_stage = 0;
@@ -3374,7 +3297,7 @@ static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBl
     checkGLcall("loadTexCoords");
 }
 
-static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void tex_coordindex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->device->texUnitMap[stage];
@@ -3550,10 +3473,10 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void shaderconstant(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void shaderconstant(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_state *state = &stateblock->state;
-    IWineD3DDeviceImpl *device = stateblock->device;
+    struct wined3d_device *device = stateblock->device;
 
     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
      * has an update pending
@@ -3566,12 +3489,12 @@ static void shaderconstant(DWORD state_id, IWineD3DStateBlockImpl *stateblock, s
     device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
 }
 
-static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void tex_bumpenvlscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
-    IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
+    const struct wined3d_shader *ps = stateblock->state.pixel_shader;
 
-    if (ps && stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
+    if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
     {
         /* The pixel shader has to know the luminance scale. Do a constants update if it
          * isn't scheduled anyway
@@ -3583,23 +3506,24 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void sampler_texmatrix(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const DWORD sampler = state - STATE_SAMPLER(0);
-    IWineD3DBaseTextureImpl *texture = stateblock->state.textures[sampler];
+    struct wined3d_texture *texture = stateblock->state.textures[sampler];
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
 
     if(!texture) return;
     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
-     * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
+     * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
      * scaling is reapplied or removed, the texture matrix has to be reapplied
      *
      * The mapped stage is already active because the sampler() function below, which is part of the
      * misc pipeline
      */
-    if(sampler < MAX_TEXTURES) {
-        const BOOL texIsPow2 = !texture->baseTexture.pow2Matrix_identity;
+    if (sampler < MAX_TEXTURES)
+    {
+        const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
 
         if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
         {
@@ -3611,10 +3535,11 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void sampler(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD sampler = state_id - STATE_SAMPLER(0);
-    DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
+    struct wined3d_device *device = stateblock->device;
+    DWORD mapped_stage = device->texUnitMap[sampler];
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_state *state = &stateblock->state;
     union {
@@ -3642,13 +3567,11 @@ static void sampler(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct w
 
     if (state->textures[sampler])
     {
-        IWineD3DBaseTexture *texture = (IWineD3DBaseTexture *)state->textures[sampler];
+        struct wined3d_texture *texture = state->textures[sampler];
         BOOL srgb = state->sampler_states[sampler][WINED3DSAMP_SRGBTEXTURE];
 
-        IWineD3DBaseTexture_BindTexture(texture, srgb);
-        basetexture_apply_state_changes(texture,
-                state->texture_states[sampler],
-                state->sampler_states[sampler], gl_info);
+        texture->texture_ops->texture_bind(texture, gl_info, srgb);
+        wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
 
         if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
         {
@@ -3656,7 +3579,7 @@ static void sampler(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct w
             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
                       GL_TEXTURE_LOD_BIAS_EXT,
                       tmpvalue.f);
-            checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
+            checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
         }
 
         if (!use_ps(state) && sampler < state->lowest_disabled_stage)
@@ -3671,12 +3594,8 @@ static void sampler(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct w
         }
 
         /* Trigger shader constant reloading (for NP2 texcoord fixup) */
-        if (!state->textures[sampler]->baseTexture.pow2Matrix_identity)
-        {
-            IWineD3DDeviceImpl *d3ddevice = stateblock->device;
-            d3ddevice->shader_backend->shader_load_np2fixup_constants(
-                (IWineD3DDevice*)d3ddevice, use_ps(state), use_vs(state));
-        }
+        if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
+            device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
     }
     else if (mapped_stage < gl_info->limits.textures)
     {
@@ -3691,15 +3610,15 @@ static void sampler(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct w
                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
             }
         } /* Otherwise tex_colorop disables the stage */
-        glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler]);
-        checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler])");
+        glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler]);
+        checkGLcall("glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler])");
     }
 }
 
-void apply_pixelshader(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+void apply_pixelshader(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_state *state = &stateblock->state;
-    IWineD3DDeviceImpl *device = stateblock->device;
+    struct wined3d_device *device = stateblock->device;
     BOOL use_vshader = use_vs(state);
     BOOL use_pshader = use_ps(state);
     unsigned int i;
@@ -3741,12 +3660,12 @@ void apply_pixelshader(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
-static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void shader_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
-    IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
+    const struct wined3d_shader *ps = stateblock->state.pixel_shader;
 
-    if (ps && stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
+    if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
     {
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
          * anyway
@@ -3758,7 +3677,7 @@ static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void transform_world(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     /* This function is called by transform_view below if the view matrix was changed too
      *
@@ -3790,7 +3709,7 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
-static void clipplane(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void clipplane(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_state *state = &stateblock->state;
     UINT index = state_id - STATE_CLIPPLANE(0);
@@ -3800,24 +3719,17 @@ static void clipplane(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct
         return;
     }
 
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
     if (!use_vs(state))
-    {
-        glMatrixMode(GL_MODELVIEW);
-        glPushMatrix();
         glLoadMatrixf(&state->transforms[WINED3DTS_VIEW].u.m[0][0]);
-    }
     else
-    {
         /* with vertex shaders, clip planes are not transformed in direct3d,
          * in OpenGL they are still transformed by the model view.
-         * Use this to swap the y coordinate if necessary
          */
-        glMatrixMode(GL_MODELVIEW);
-        glPushMatrix();
         glLoadIdentity();
-        if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
-    }
 
     TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
             state->clip_planes[index][0],
@@ -3830,7 +3742,7 @@ static void clipplane(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct
     glPopMatrix();
 }
 
-static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void transform_worldex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
     GLenum glMat;
@@ -3874,7 +3786,7 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_vertexblend_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WINED3DVERTEXBLENDFLAGS f = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
     static unsigned int once;
@@ -3885,7 +3797,7 @@ static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     else WARN("Vertex blend flags %#x not supported.\n", f);
 }
 
-static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void state_vertexblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     WINED3DVERTEXBLENDFLAGS val = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -3929,7 +3841,7 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
-static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void transform_view(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_light_info *light = NULL;
@@ -3947,7 +3859,7 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     checkGLcall("glLoadMatrixf(...)");
 
     /* Reset lights. TODO: Call light apply func */
-    for (k = 0; k < stateblock->device->maxConcurrentLights; ++k)
+    for (k = 0; k < gl_info->limits.lights; ++k)
     {
         light = stateblock->state.lights[k];
         if(!light) continue;
@@ -3991,7 +3903,7 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
-static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void transform_projection(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
@@ -4137,14 +4049,13 @@ static inline void unloadNumberedArrays(struct wined3d_context *context)
     }
 }
 
-static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
+static void loadNumberedArrays(struct wined3d_stateblock *stateblock,
         const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
     int i;
     struct wined3d_buffer *vb;
-    DWORD_PTR shift_index;
 
     /* Default to no instancing */
     stateblock->device->instancedDraw = FALSE;
@@ -4184,31 +4095,12 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
              * curVBO will be 0. If there is a vertex buffer but no vbo we
              * won't be load converted attributes anyway. */
             vb = stream->buffer;
-            if (curVBO && vb->conversion_shift)
-            {
-                TRACE("Loading attribute from shifted buffer\n");
-                TRACE("Attrib %d has original stride %d, new stride %d\n",
-                        i, stream_info->elements[i].stride, vb->conversion_stride);
-                TRACE("Original offset %p, additional offset 0x%08x\n",
-                        stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]);
-                TRACE("Opengl type %#x\n", stream_info->elements[i].format->gl_vtx_type);
-                shift_index = ((DWORD_PTR)stream_info->elements[i].data + stream->offset);
-                shift_index = shift_index % stream_info->elements[i].stride;
-                GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
-                        stream_info->elements[i].format->gl_vtx_type,
-                        stream_info->elements[i].format->gl_normalized,
-                        vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index]
-                        + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
-                        + stream->offset));
-
-            } else {
-                GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
-                        stream_info->elements[i].format->gl_vtx_type,
-                        stream_info->elements[i].format->gl_normalized,
-                        stream_info->elements[i].stride, stream_info->elements[i].data
-                        + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
-                        + stream->offset));
-            }
+            GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
+                    stream_info->elements[i].format->gl_vtx_type,
+                    stream_info->elements[i].format->gl_normalized,
+                    stream_info->elements[i].stride, stream_info->elements[i].data
+                    + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
+                    + stream->offset));
 
             if (!(context->numbered_array_mask & (1 << i)))
             {
@@ -4320,7 +4212,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
 }
 
 /* Used from 2 different functions, and too big to justify making it inlined */
-static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
+static void loadVertexData(const struct wined3d_context *context, struct wined3d_stateblock *stateblock,
         const struct wined3d_stream_info *si)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -4389,7 +4281,7 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
         {
             static const GLbyte one = 1;
             GL_EXTCALL(glWeightbvARB(1, &one));
-            checkGLcall("glWeightivARB(gl_info->max_blends, weights)");
+            checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
         }
     }
 
@@ -4583,9 +4475,9 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     loadTexCoords(gl_info, stateblock, si, &curVBO);
 }
 
-static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void streamsrc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    IWineD3DDeviceImpl *device = stateblock->device;
+    struct wined3d_device *device = stateblock->device;
     BOOL load_numbered = use_vs(&stateblock->state) && !device->useDrawStridedSlow;
     BOOL load_named = !use_vs(&stateblock->state) && !device->useDrawStridedSlow;
 
@@ -4615,27 +4507,21 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     }
 }
 
-static void vertexdeclaration(DWORD state_id, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void vertexdeclaration(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_state *state = &stateblock->state;
+    struct wined3d_device *device = stateblock->device;
     BOOL useVertexShaderFunction = use_vs(state);
     BOOL usePixelShaderFunction = use_ps(state);
     BOOL updateFog = FALSE;
-    IWineD3DDeviceImpl *device = stateblock->device;
     BOOL transformed;
     BOOL wasrhw = context->last_was_rhw;
     unsigned int i;
 
     transformed = device->strided_streams.position_transformed;
-    if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
+    if (transformed != context->last_was_rhw && !useVertexShaderFunction)
         updateFog = TRUE;
-    }
-
-    /* Reapply lighting if it is not scheduled for reapplication already */
-    if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
-        state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
-    }
 
     if (transformed) {
         context->last_was_rhw = TRUE;
@@ -4645,20 +4531,6 @@ static void vertexdeclaration(DWORD state_id, IWineD3DStateBlockImpl *stateblock
         context->last_was_rhw = FALSE;
         /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
         device->untransformed = TRUE;
-
-        /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
-         * Not needed as long as only hw shaders are supported
-         */
-
-        /* This sets the shader output position correction constants.
-         * TODO: Move to the viewport state
-         */
-        if (useVertexShaderFunction)
-        {
-            GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
-            device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
-            device->posFixup[3] = device->posFixup[1] * yoffset;
-        }
     }
 
     /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
@@ -4693,6 +4565,9 @@ static void vertexdeclaration(DWORD state_id, IWineD3DStateBlockImpl *stateblock
         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
         }
+        if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
+            state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
+        }
 
         if(context->last_was_vshader) {
             updateFog = TRUE;
@@ -4777,14 +4652,16 @@ static void vertexdeclaration(DWORD state_id, IWineD3DStateBlockImpl *stateblock
     }
 }
 
-static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void viewport_miscpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
+    struct wined3d_surface *target = stateblock->device->fb.render_targets[0];
     UINT width, height;
     WINED3DVIEWPORT vp = stateblock->state.viewport;
 
-    if(vp.Width > target->currentDesc.Width) vp.Width = target->currentDesc.Width;
-    if(vp.Height > target->currentDesc.Height) vp.Height = target->currentDesc.Height;
+    if (vp.Width > target->resource.width)
+        vp.Width = target->resource.width;
+    if (vp.Height > target->resource.height)
+        vp.Height = target->resource.height;
 
     glDepthRange(vp.MinZ, vp.MaxZ);
     checkGLcall("glDepthRange");
@@ -4804,24 +4681,20 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     checkGLcall("glViewport");
 }
 
-static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void viewport_vertexpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
-
-    stateblock->device->posFixup[2] = (63.0f / 64.0f) / stateblock->state.viewport.Width;
-    stateblock->device->posFixup[3] = stateblock->device->posFixup[1] * yoffset;
-
     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
     }
     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
         state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
     }
+    /* Update the position fixup. */
     if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
         shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 }
 
-static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void light(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     UINT Index = state - STATE_ACTIVELIGHT(0);
     const struct wined3d_light_info *lightInfo = stateblock->state.lights[Index];
@@ -4935,9 +4808,9 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3
     }
 }
 
-static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void scissorrect(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
-    IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
+    struct wined3d_surface *target = stateblock->device->fb.render_targets[0];
     RECT *pRect = &stateblock->state.scissor_rect;
     UINT height;
     UINT width;
@@ -4958,7 +4831,7 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     checkGLcall("glScissor");
 }
 
-static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void indexbuffer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
@@ -4973,7 +4846,7 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
-static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void frontface(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     if (context->render_offscreen)
     {
@@ -4985,6 +4858,34 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     }
 }
 
+static void psorigin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
+{
+    static BOOL warned;
+
+    if (!warned)
+    {
+        WARN("Point sprite coordinate origin switching not supported.\n");
+        warned = TRUE;
+    }
+}
+
+static void psorigin(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
+
+    if (glPointParameteri)
+    {
+        glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
+        checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
+    }
+    else if (gl_info->supported[NV_POINT_SPRITE])
+    {
+        GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
+        checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
+    }
+}
+
 const struct StateEntryTemplate misc_state_template[] = {
     { STATE_RENDER(WINED3DRS_SRCBLEND),                   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_DESTBLEND),                  { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
@@ -5000,6 +4901,9 @@ const struct StateEntryTemplate misc_state_template[] = {
     { STATE_VDECL,                                        { STATE_VDECL,                                        streamsrc           }, WINED3D_GL_EXT_NONE             },
     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, WINED3D_GL_EXT_NONE             },
     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, WINED3D_GL_EXT_NONE             },
+    { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin            }, WINED3D_GL_VERSION_2_0          },
+    { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin_w          }, WINED3D_GL_EXT_NONE             },
+
     /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
      * vshader loadings are untied from each other
      */
@@ -5080,7 +4984,6 @@ const struct StateEntryTemplate misc_state_template[] = {
     { STATE_RENDER(WINED3DRS_SUBPIXEL),                   { STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_SUBPIXELX),                  { STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3DRS_ZBIAS),                      { STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_ANISOTROPY),                 { STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    }, WINED3D_GL_EXT_NONE             },
@@ -5675,51 +5578,51 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
-/* Context activation is done by the caller. */
-static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
+/* Context activation and GL locking are done by the caller. */
+static void ffp_enable(BOOL enable) {}
 
-static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
+static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
 {
-    pCaps->PrimitiveMiscCaps = 0;
-    pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
-                            WINED3DTEXOPCAPS_ADDSIGNED   |
-                            WINED3DTEXOPCAPS_ADDSIGNED2X |
-                            WINED3DTEXOPCAPS_MODULATE    |
-                            WINED3DTEXOPCAPS_MODULATE2X  |
-                            WINED3DTEXOPCAPS_MODULATE4X  |
-                            WINED3DTEXOPCAPS_SELECTARG1  |
-                            WINED3DTEXOPCAPS_SELECTARG2  |
-                            WINED3DTEXOPCAPS_DISABLE;
+    caps->PrimitiveMiscCaps = 0;
+    caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
+            | WINED3DTEXOPCAPS_ADDSIGNED
+            | WINED3DTEXOPCAPS_ADDSIGNED2X
+            | WINED3DTEXOPCAPS_MODULATE
+            | WINED3DTEXOPCAPS_MODULATE2X
+            | WINED3DTEXOPCAPS_MODULATE4X
+            | WINED3DTEXOPCAPS_SELECTARG1
+            | WINED3DTEXOPCAPS_SELECTARG2
+            | WINED3DTEXOPCAPS_DISABLE;
 
     if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
             || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
     {
-        pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA  |
-                                WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
-                                WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
-                                WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
-                                WINED3DTEXOPCAPS_LERP               |
-                                WINED3DTEXOPCAPS_SUBTRACT;
+        caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
+                | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
+                | WINED3DTEXOPCAPS_BLENDFACTORALPHA
+                | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
+                | WINED3DTEXOPCAPS_LERP
+                | WINED3DTEXOPCAPS_SUBTRACT;
     }
     if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
     {
-        pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH              |
-                                WINED3DTEXOPCAPS_MULTIPLYADD            |
-                                WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
-                                WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
-                                WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
+        caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
+                | WINED3DTEXOPCAPS_MULTIPLYADD
+                | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
+                | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
+                | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
     }
     if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
-        pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
+        caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
 
-    pCaps->MaxTextureBlendStages = gl_info->limits.textures;
-    pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
+    caps->MaxTextureBlendStages = gl_info->limits.textures;
+    caps->MaxSimultaneousTextures = gl_info->limits.textures;
 }
 
-static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
-static void ffp_fragment_free(IWineD3DDevice *iface) {}
+static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
+static void ffp_fragment_free(struct wined3d_device *device) {}
 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
 {
     if (TRACE_ON(d3d))
@@ -5756,13 +5659,13 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
     return i;
 }
 
-static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void multistate_apply_2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     stateblock->device->multistate_funcs[state][0](state, stateblock, context);
     stateblock->device->multistate_funcs[state][1](state, stateblock, context);
 }
 
-static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+static void multistate_apply_3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
 {
     stateblock->device->multistate_funcs[state][0](state, stateblock, context);
     stateblock->device->multistate_funcs[state][1](state, stateblock, context);
@@ -5812,6 +5715,7 @@ static void validate_state_table(struct StateEntry *state_table)
         { 17,  18},
         { 21,  21},
         { 42,  45},
+        { 47,  47},
         { 61, 127},
         {149, 150},
         {169, 169},
@@ -5832,6 +5736,7 @@ static void validate_state_table(struct StateEntry *state_table)
         STATE_VIEWPORT,
         STATE_SCISSORRECT,
         STATE_FRONTFACE,
+        STATE_POINTSPRITECOORDORIGIN,
     };
     unsigned int i, current;