- sync wined3d with wine
authorKamil Hornicek <kamil.hornicek@reactos.org>
Tue, 9 Dec 2008 12:16:19 +0000 (12:16 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Tue, 9 Dec 2008 12:16:19 +0000 (12:16 +0000)
svn path=/trunk/; revision=37957

35 files changed:
reactos/dll/directx/wine/wined3d/arb_program_shader.c
reactos/dll/directx/wine/wined3d/ati_fragment_shader.c
reactos/dll/directx/wine/wined3d/baseshader.c
reactos/dll/directx/wine/wined3d/basetexture.c
reactos/dll/directx/wine/wined3d/clipper.c
reactos/dll/directx/wine/wined3d/context.c
reactos/dll/directx/wine/wined3d/cubetexture.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/indexbuffer.c
reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c
reactos/dll/directx/wine/wined3d/palette.c
reactos/dll/directx/wine/wined3d/pixelshader.c
reactos/dll/directx/wine/wined3d/resource.c
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/stateblock.c
reactos/dll/directx/wine/wined3d/surface.c
reactos/dll/directx/wine/wined3d/surface_base.c
reactos/dll/directx/wine/wined3d/surface_gdi.c
reactos/dll/directx/wine/wined3d/swapchain.c
reactos/dll/directx/wine/wined3d/swapchain_base.c
reactos/dll/directx/wine/wined3d/swapchain_gdi.c
reactos/dll/directx/wine/wined3d/texture.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexbuffer.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/volume.c
reactos/dll/directx/wine/wined3d/volumetexture.c
reactos/dll/directx/wine/wined3d/wined3d.idl [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/wined3d.rbuild
reactos/dll/directx/wine/wined3d/wined3d_gl.h [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/wined3d_main.c
reactos/dll/directx/wine/wined3d/wined3d_private.h

index 12148e6..9d51250 100644 (file)
@@ -36,6 +36,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_constants);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION      (*gl_info)
 
@@ -66,8 +67,9 @@ struct shader_arb_priv {
  * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
  *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
  */
-static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info, GLuint target_type,
-        unsigned int max_constants, float* constants, char *dirty_consts) {
+static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
+        GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
+{
     local_constant* lconst;
     DWORD i, j;
     unsigned int ret;
@@ -173,7 +175,7 @@ static void shader_arb_load_constants(
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device; 
     IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
-    WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
     unsigned char i;
 
     if (useVertexShader) {
@@ -205,7 +207,7 @@ static void shader_arb_load_constants(
         for(i = 0; i < psi->numbumpenvmatconsts; i++) {
             /* The state manager takes care that this function is always called if the bump env matrix changes
              */
-            float *data = (float *) &stateBlock->textureState[(int) psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
+            const float *data = (const float *)&stateBlock->textureState[(int) psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
             GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst[i].const_num, data));
             deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].const_num] = 1;
 
@@ -215,47 +217,18 @@ static void shader_arb_load_constants(
                  * don't care about them. The pointers are valid for sure because the stateblock is bigger.
                  * (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and WINED3DTSS_ADDRESSW, so most likely 0 or NaN
                  */
-                float *scale = (float *) &stateBlock->textureState[(int) psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];
+                const float *scale = (const float *)&stateBlock->textureState[(int) psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];
                 GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst[i].const_num, scale));
                 deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].const_num] = 1;
             }
         }
-
-        if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
-           !((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
-            float comparison[4];
-            float mul_low[4];
-
-            if(stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
-                comparison[0] = srgb_cmp; comparison[1] = srgb_cmp;
-                comparison[2] = srgb_cmp; comparison[3] = srgb_cmp;
-
-                mul_low[0] = srgb_mul_low; mul_low[1] = srgb_mul_low;
-                mul_low[2] = srgb_mul_low; mul_low[3] = srgb_mul_low;
-            } else {
-                comparison[0] = 1.0 / 0.0; comparison[1] = 1.0 / 0.0;
-                comparison[2] = 1.0 / 0.0; comparison[3] = 1.0 / 0.0;
-
-                mul_low[0] = 1.0; mul_low[1] = 1.0;
-                mul_low[2] = 1.0; mul_low[3] = 1.0;
-            }
-            GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->srgb_cmp_const, comparison));
-            GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->srgb_low_const, mul_low));
-            checkGLcall("Load sRGB correction constants\n");
-            deviceImpl->activeContext->pshader_const_dirty[psi->srgb_low_const] = 1;
-            deviceImpl->activeContext->pshader_const_dirty[psi->srgb_cmp_const] = 1;
-
-        }
     }
 }
 
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
-static void shader_generate_arb_declarations(
-    IWineD3DBaseShader *iface,
-    shader_reg_maps* reg_maps,
-    SHADER_BUFFER* buffer,
-    WineD3D_GL_Info* gl_info) {
-
+static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
+        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
+{
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     DWORD i, cur;
@@ -263,7 +236,7 @@ static void shader_generate_arb_declarations(
     unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
             (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
     UINT extra_constants_needed = 0;
-    local_constant* lconst;
+    const local_constant *lconst;
 
     /* Temporary Output register */
     shader_addline(buffer, "TEMP TMP_OUT;\n");
@@ -325,49 +298,16 @@ static void shader_generate_arb_declarations(
     }
 
     if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
-        IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
-        /* If there are 2 constants left to use, use them to pass the sRGB correction values in. This way
-         * srgb write correction can be turned on and off dynamically without recompilation. Otherwise
-         * hardcode them. The drawback of hardcoding is that the shader needs recompilation to turn sRGB
-         * off again
-         */
-        if(max_constantsF + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF) && FALSE) {
-            /* The idea is that if srgb is enabled, then disabled, the constant loading code
-             * can effectively disable sRGB correction by passing 1.0 and INF as the multiplication
-             * and comparison constants. If it disables it that way, the shader won't be recompiled
-             * and the code will stay in, so sRGB writing can be turned on again by setting the
-             * constants from the spec
-             */
-            ps_impl->srgb_mode_hardcoded = 0;
-            ps_impl->srgb_low_const = GL_LIMITS(pshader_constantsF) - extra_constants_needed;
-            ps_impl->srgb_cmp_const = GL_LIMITS(pshader_constantsF) - extra_constants_needed - 1;
-            shader_addline(buffer, "PARAM srgb_mul_low = program.env[%d];\n", ps_impl->srgb_low_const);
-            shader_addline(buffer, "PARAM srgb_comparison = program.env[%d];\n", ps_impl->srgb_cmp_const);
-        } else {
-            shader_addline(buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
-                           srgb_mul_low, srgb_mul_low, srgb_mul_low);
-            shader_addline(buffer, "PARAM srgb_comparison =  {%f, %f, %f, %f};\n",
-                           srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
-            ps_impl->srgb_mode_hardcoded = 1;
-        }
-        /* These can be hardcoded, they do not cause any harm because no fragment will enter the high
-         * path if the comparison value is set to INF
-         */
+        shader_addline(buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
+                        srgb_mul_low, srgb_mul_low, srgb_mul_low);
+        shader_addline(buffer, "PARAM srgb_comparison =  {%f, %f, %f, %f};\n",
+                        srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
         shader_addline(buffer, "PARAM srgb_pow =  {%f, %f, %f, 1.0};\n",
                        srgb_pow, srgb_pow, srgb_pow);
         shader_addline(buffer, "PARAM srgb_mul_hi =  {%f, %f, %f, 1.0};\n",
                        srgb_mul_high, srgb_mul_high, srgb_mul_high);
         shader_addline(buffer, "PARAM srgb_sub_hi =  {%f, %f, %f, 0.0};\n",
                        srgb_sub_high, srgb_sub_high, srgb_sub_high);
-        ps_impl->srgb_enabled = 1;
-    } else if(pshader) {
-        IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
-
-        /* Do not write any srgb fixup into the shader to save shader size and processing time.
-         * As a consequence, we can't toggle srgb write on without recompilation
-         */
-        ps_impl->srgb_enabled = 0;
-        ps_impl->srgb_mode_hardcoded = 1;
     }
 
     /* Load local constants using the program-local space,
@@ -418,7 +358,8 @@ static const char * const shift_tab[] = {
     "coefdiv.x"  /* 15 (d2)   */
 };
 
-static void shader_arb_get_write_mask(SHADER_OPCODE_ARG* arg, const DWORD param, char *write_mask) {
+static void shader_arb_get_write_mask(const SHADER_OPCODE_ARG *arg, const DWORD param, char *write_mask)
+{
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) arg->shader;
     char *ptr = write_mask;
     char vshader = shader_is_vshader_version(This->baseShader.hex_version);
@@ -522,8 +463,8 @@ static void pshader_get_register_name(IWineD3DBaseShader* iface,
 }
 
 /* TODO: merge with pixel shader */
-static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) {
-
+static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine)
+{
   IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader;
 
   /* oPos, oFog and oPts in D3D */
@@ -605,7 +546,9 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param,
   }
 }
 
-static void shader_hw_sample(SHADER_OPCODE_ARG* arg, DWORD sampler_idx, const char *dst_str, const char *coord_reg, BOOL projected, BOOL bias) {
+static void shader_hw_sample(const SHADER_OPCODE_ARG *arg, DWORD sampler_idx, const char *dst_str,
+        const char *coord_reg, BOOL projected, BOOL bias)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
     const char *tex_type;
@@ -653,229 +596,81 @@ static void shader_hw_sample(SHADER_OPCODE_ARG* arg, DWORD sampler_idx, const ch
     }
 }
 
-static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, const char *writemask,
-                                 const char *one, const char *two, WINED3DFORMAT fmt,
-                                 WineD3D_GL_Info *gl_info) {
-    switch(fmt) {
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER) && fmt == WINED3DFMT_V8U8) {
-                if(0) {
-                    /* The 3rd channel returns 1.0 in d3d, but 0.0 in gl. Fix this while we're at it :-)
-                     * disabled until an application that needs it is found because it causes unneeded
-                     * shader recompilation in some game
-                     */
-                    if(strlen(writemask) >= 4) {
-                        shader_addline(buffer, "MOV %s.%c, %s;\n", reg, writemask[3], one);
-                    }
-                }
-            } else {
-                /* Correct the sign, but leave the blue as it is - it was loaded correctly already
-                 * ARB shaders are a bit picky wrt writemasks and swizzles. If we're free to scale
-                 * all registers, do so, this saves an instruction.
-                 */
-                if(strlen(writemask) >= 5) {
-                    shader_addline(buffer, "MAD %s, %s, %s, -%s;\n", reg, reg, two, one);
-                } else if(strlen(writemask) >= 3) {
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[1],
-                                   reg, writemask[1],
-                                   two, one);
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[2],
-                                   reg, writemask[2],
-                                   two, one);
-                } else if(strlen(writemask) == 2) {
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n", reg, writemask[1],
-                                   reg, writemask[1], two, one);
-                }
-            }
-            break;
-
-        case WINED3DFMT_X8L8V8U8:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                /* Red and blue are the signed channels, fix them up; Blue(=L) is correct already,
-                 * and a(X) is always 1.0. Cannot do a full conversion due to L(blue)
-                 */
-                if(strlen(writemask) >= 3) {
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[1],
-                                   reg, writemask[1],
-                                   two, one);
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[2],
-                                   reg, writemask[2],
-                                   two, one);
-                } else if(strlen(writemask) == 2) {
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[1],
-                                   reg, writemask[1],
-                                   two, one);
-                }
-            }
-            break;
-
-        case WINED3DFMT_L6V5U5:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                if(strlen(writemask) >= 4) {
-                    /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
-                    shader_addline(buffer, "MOV TMP.g, %s.%c;\n",
-                                   reg, writemask[2]);
-                    shader_addline(buffer, "MAD %s.%c%c, %s.%c%c%c%c, %s, -%s;\n",
-                                   reg, writemask[1], writemask[2],
-                                   reg, writemask[3], writemask[1], writemask[3], writemask[1],
-                                   two, one);
-                    shader_addline(buffer, "MOV %s.%c, TMP.g;\n", reg,
-                                   writemask[3]);
-                } else if(strlen(writemask) == 3) {
-                    /* This is bad: We have VL, but we need VU */
-                    FIXME("2 components sampled from a converted L6V5U5 texture\n");
-                } else {
-                    shader_addline(buffer, "MAD %s.%c, %s.%c, %s, -%s;\n",
-                                   reg, writemask[1],
-                                   reg, writemask[1],
-                                   two, one);
-                }
-            }
-            break;
-
-        case WINED3DFMT_Q8W8V8U8:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                /* Correct the sign in all channels */
-                switch(strlen(writemask)) {
-                    case 4:
-                        shader_addline(buffer, "MAD %s.%c, %s.%c, coefmul.x, -one;\n",
-                                       reg, writemask[3],
-                                       reg, writemask[3]);
-                        /* drop through */
-                    case 3:
-                        shader_addline(buffer, "MAD %s.%c, %s.%c, coefmul.x, -one;\n",
-                                       reg, writemask[2],
-                                       reg, writemask[2]);
-                        /* drop through */
-                    case 2:
-                        shader_addline(buffer, "MAD %s.%c, %s.%c, coefmul.x, -one;\n",
-                                       reg, writemask[1],
-                                       reg, writemask[1]);
-                        break;
-
-                        /* Should not occur, since it's at minimum '.' and a letter */
-                    case 1:
-                        ERR("Unexpected writemask: \"%s\"\n", writemask);
-                        break;
-
-                    case 5:
-                    default:
-                        shader_addline(buffer, "MAD %s, %s, coefmul.x, -one;\n", reg, reg);
-                }
-            }
-            break;
-
-        case WINED3DFMT_ATI2N:
-            /* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
-             * which means the first one is replicated across .rgb, and the 2nd one is in
-             * .a. We need the 2nd in .g
-             *
-             * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they
-             * are swapped compared to d3d. So swap red and green.
-             */
-            if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
-                shader_addline(buffer, "SWZ %s, %s, %c, %c, 1, 0;\n",
-                               reg, reg, writemask[2], writemask[1]);
-            } else {
-                if(strlen(writemask) == 5) {
-                    shader_addline(buffer, "MOV %s.%c, %s.%c;\n",
-                                reg, writemask[2], reg, writemask[4]);
-                } else if(strlen(writemask) == 2) {
-                    /* Nothing to do */
-                } else {
-                    /* This is bad: We have VL, but we need VU */
-                    FIXME("2 or 3 components sampled from a converted ATI2N texture\n");
-                }
-            }
-            break;
-
-            /* stupid compiler */
+static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channel_source)
+{
+    switch(channel_source)
+    {
+        case CHANNEL_SOURCE_ZERO: return "0";
+        case CHANNEL_SOURCE_ONE: return "1";
+        case CHANNEL_SOURCE_X: return "x";
+        case CHANNEL_SOURCE_Y: return "y";
+        case CHANNEL_SOURCE_Z: return "z";
+        case CHANNEL_SOURCE_W: return "w";
         default:
-            break;
+            FIXME("Unhandled channel source %#x\n", channel_source);
+            return "undefined";
     }
 }
 
-static void shader_arb_color_correction(SHADER_OPCODE_ARG* arg) {
-    IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
-    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) shader->baseShader.device;
-    WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
-    WINED3DFORMAT fmt;
-    WINED3DFORMAT conversion_group;
-    IWineD3DBaseTextureImpl *texture;
-    UINT i;
-    BOOL recorded = FALSE;
-    DWORD sampler_idx;
-    DWORD hex_version = shader->baseShader.hex_version;
-    char reg[256];
-    char writemask[6];
+static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, DWORD dst_mask,
+        const char *one, const char *two, struct color_fixup_desc fixup)
+{
+    DWORD mask;
 
-    switch(arg->opcode->opcode) {
-        case WINED3DSIO_TEX:
-            if (hex_version < WINED3DPS_VERSION(2,0)) {
-                sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
-            } else {
-                sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
-            }
-            break;
+    if (is_yuv_fixup(fixup))
+    {
+        enum yuv_fixup yuv_fixup = get_yuv_fixup(fixup);
+        FIXME("YUV fixup (%#x) not supported\n", yuv_fixup);
+        return;
+    }
 
-        case WINED3DSIO_TEXLDL:
-            FIXME("Add color fixup for vertex texture WINED3DSIO_TEXLDL\n");
-            return;
+    mask = 0;
+    if (fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0;
+    if (fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1;
+    if (fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2;
+    if (fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3;
+    mask &= dst_mask;
 
-        case WINED3DSIO_TEXDP3TEX:
-        case WINED3DSIO_TEXM3x3TEX:
-        case WINED3DSIO_TEXM3x3SPEC:
-        case WINED3DSIO_TEXM3x3VSPEC:
-        case WINED3DSIO_TEXBEM:
-        case WINED3DSIO_TEXREG2AR:
-        case WINED3DSIO_TEXREG2GB:
-        case WINED3DSIO_TEXREG2RGB:
-            sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
-            break;
+    if (mask)
+    {
+        shader_addline(buffer, "SWZ %s, %s, %s, %s, %s, %s;\n", reg, reg,
+                shader_arb_get_fixup_swizzle(fixup.x_source), shader_arb_get_fixup_swizzle(fixup.y_source),
+                shader_arb_get_fixup_swizzle(fixup.z_source), shader_arb_get_fixup_swizzle(fixup.w_source));
+    }
 
-        default:
-            /* Not a texture sampling instruction, nothing to do */
-            return;
-    };
+    mask = 0;
+    if (fixup.x_sign_fixup) mask |= WINED3DSP_WRITEMASK_0;
+    if (fixup.y_sign_fixup) mask |= WINED3DSP_WRITEMASK_1;
+    if (fixup.z_sign_fixup) mask |= WINED3DSP_WRITEMASK_2;
+    if (fixup.w_sign_fixup) mask |= WINED3DSP_WRITEMASK_3;
+    mask &= dst_mask;
 
-    texture = (IWineD3DBaseTextureImpl *) deviceImpl->stateBlock->textures[sampler_idx];
-    if(texture) {
-        fmt = texture->resource.format;
-        conversion_group = texture->baseTexture.shader_conversion_group;
-    } else {
-        fmt = WINED3DFMT_UNKNOWN;
-        conversion_group = WINED3DFMT_UNKNOWN;
-    }
+    if (mask)
+    {
+        char reg_mask[6];
+        char *ptr = reg_mask;
 
-    /* before doing anything, record the sampler with the format in the format conversion list,
-     * but check if it's not there already
-     */
-    for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
-        if(shader->baseShader.sampled_samplers[i] == sampler_idx) {
-            recorded = TRUE;
+        if (mask != WINED3DSP_WRITEMASK_ALL)
+        {
+            *ptr++ = '.';
+            if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
+            if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
+            if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
+            if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
         }
+        *ptr = '\0';
+
+        shader_addline(buffer, "MAD %s%s, %s, %s, -%s;\n", reg, reg_mask, reg, two, one);
     }
-    if(!recorded) {
-        shader->baseShader.sampled_samplers[shader->baseShader.num_sampled_samplers] = sampler_idx;
-        shader->baseShader.num_sampled_samplers++;
-        shader->baseShader.sampled_format[sampler_idx] = conversion_group;
-    }
+}
 
+static void shader_arb_color_correction(const struct SHADER_OPCODE_ARG* arg, struct color_fixup_desc fixup)
+{
+    char reg[256];
     pshader_get_register_name(arg->shader, arg->dst, reg);
-    shader_arb_get_write_mask(arg, arg->dst, writemask);
-    if(strlen(writemask) == 0) strcpy(writemask, ".xyzw");
-
-    gen_color_correction(arg->buffer, reg, writemask, "one", "coefmul.x", fmt, gl_info);
-
+    gen_color_correction(arg->buffer, reg, arg->dst & WINED3DSP_WRITEMASK_ALL, "one", "coefmul.x", fixup);
 }
 
-
 static void pshader_gen_input_modifier_line (
     IWineD3DBaseShader *iface,
     SHADER_BUFFER* buffer,
@@ -943,19 +738,16 @@ static void pshader_gen_input_modifier_line (
         sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
 }
 
-static inline void pshader_gen_output_modifier_line(
-    SHADER_BUFFER* buffer,
-    int saturate,
-    char *write_mask,
-    int shift,
-    char *regstr) {
-
+static inline void pshader_gen_output_modifier_line(SHADER_BUFFER *buffer, int saturate, const char *write_mask,
+        int shift, const char *regstr)
+{
     /* Generate a line that does the output modifier computation */
     shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
         regstr, write_mask, regstr, shift_tab[shift]);
 }
 
-static void pshader_hw_bem(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_bem(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
 
     SHADER_BUFFER* buffer = arg->buffer;
@@ -993,8 +785,8 @@ static void pshader_hw_bem(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_wmask[20];
@@ -1027,8 +819,8 @@ static void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
         pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
-static void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_cmp(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_wmask[20];
     char dst_name[50];
@@ -1056,7 +848,8 @@ static void pshader_hw_cmp(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_DP2ADD instruction in ARB.
  * dst = dot2(src0, src1) + src2 */
-static void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_dp2add(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_wmask[20];
     char dst_name[50];
@@ -1082,13 +875,13 @@ static void pshader_hw_dp2add(SHADER_OPCODE_ARG* arg) {
 }
 
 /* Map the opcode 1-to-1 to the GL code */
-static void shader_hw_map2gl(SHADER_OPCODE_ARG* arg)
+static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD dst = arg->dst;
-    DWORD* src = arg->src;
+    const DWORD *src = arg->src;
     char arguments[256];
     unsigned int i;
 
@@ -1166,7 +959,7 @@ static void shader_hw_map2gl(SHADER_OPCODE_ARG* arg)
     }
 }
 
-static void shader_hw_mov(SHADER_OPCODE_ARG *arg)
+static void shader_hw_mov(const SHADER_OPCODE_ARG *arg)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
 
@@ -1213,7 +1006,8 @@ static void shader_hw_mov(SHADER_OPCODE_ARG *arg)
     }
 }
 
-static void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD hex_version = This->baseShader.hex_version;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -1237,12 +1031,13 @@ static void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 
     DWORD dst = arg->dst;
-    DWORD* src = arg->src;
+    const DWORD *src = arg->src;
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD hex_version = This->baseShader.hex_version;
     BOOL projected = FALSE, bias = FALSE;
@@ -1301,8 +1096,8 @@ static void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
   shader_hw_sample(arg, reg_sampler_code, reg_dest, reg_coord, projected, bias);
 }
 
-static void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texcoord(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD dst = arg->dst;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -1322,8 +1117,8 @@ static void pshader_hw_texcoord(SHADER_OPCODE_ARG* arg) {
    }
 }
 
-static void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texreg2ar(const SHADER_OPCODE_ARG *arg)
+{
      SHADER_BUFFER* buffer = arg->buffer;
      IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
      IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
@@ -1341,8 +1136,8 @@ static void pshader_hw_texreg2ar(SHADER_OPCODE_ARG* arg) {
      shader_hw_sample(arg, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
 
-static void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texreg2gb(const SHADER_OPCODE_ARG *arg)
+{
      SHADER_BUFFER* buffer = arg->buffer;
 
      DWORD reg1 = arg->dst & WINED3DSP_REGNUM_MASK;
@@ -1356,8 +1151,8 @@ static void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) {
      shader_hw_sample(arg, reg1, dst_str, "TMP", FALSE, FALSE);
 }
 
-static void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texreg2rgb(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD reg1 = arg->dst & WINED3DSP_REGNUM_MASK;
     char dst_str[8];
@@ -1368,7 +1163,8 @@ static void pshader_hw_texreg2rgb(SHADER_OPCODE_ARG* arg) {
     shader_hw_sample(arg, reg1, dst_str, src_str, FALSE, FALSE);
 }
 
-static void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texbem(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     BOOL has_bumpmat = FALSE;
     BOOL has_luminance = FALSE;
@@ -1439,8 +1235,8 @@ static void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x2pad(const SHADER_OPCODE_ARG *arg)
+{
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = arg->buffer;
     char src0_name[50];
@@ -1449,8 +1245,8 @@ static void pshader_hw_texm3x2pad(SHADER_OPCODE_ARG* arg) {
     shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name);
 }
 
-static void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x2tex(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
@@ -1466,8 +1262,8 @@ static void pshader_hw_texm3x2tex(SHADER_OPCODE_ARG* arg) {
     shader_hw_sample(arg, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
 
-static void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x3pad(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -1479,8 +1275,8 @@ static void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg) {
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
-static void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x3tex(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
@@ -1500,8 +1296,8 @@ static void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg) {
     current_state->current_row = 0;
 }
 
-static void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x3vspec(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
@@ -1536,8 +1332,8 @@ static void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
     current_state->current_row = 0;
 }
 
-static void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_hw_texm3x3spec(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
@@ -1573,7 +1369,8 @@ static void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) {
     current_state->current_row = 0;
 }
 
-static void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texdepth(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_name[50];
 
@@ -1602,7 +1399,8 @@ static void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) {
 /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
  * Take a 3-component dot product of the TexCoord[dstreg] and src,
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
-static void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texdp3tex(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
     char src0[50];
@@ -1618,7 +1416,8 @@ static void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXDP3 instruction in ARB:
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
-static void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texdp3(const SHADER_OPCODE_ARG *arg)
+{
     char src0[50];
     char dst_str[50];
     char dst_mask[6];
@@ -1637,7 +1436,8 @@ static void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
  * Perform the 3rd row of a 3x3 matrix multiply */
-static void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texm3x3(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_str[50];
     char dst_mask[6];
@@ -1659,7 +1459,8 @@ static void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) {
  * Calculate tmp0.y = TexCoord[dstreg] . src.xyz;  (tmp0.x has already been calculated)
  * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
  */
-static void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) {
+static void pshader_hw_texm3x2depth(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD dst_reg = arg->dst & WINED3DSP_REGNUM_MASK;
     char src0[50];
@@ -1679,11 +1480,14 @@ static void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) {
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for
     Vertex/Pixel shaders to ARB_vertex_program codes */
-static void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
-
+static void shader_hw_mnxn(const SHADER_OPCODE_ARG *arg)
+{
     int i;
     int nComponents = 0;
     SHADER_OPCODE_ARG tmpArg;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
+    const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
+    DWORD shader_version = shader->baseShader.hex_version;
 
     memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG));
 
@@ -1698,23 +1502,23 @@ static void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
     switch(arg->opcode->opcode) {
     case WINED3DSIO_M4x4:
         nComponents = 4;
-        tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP4);
+        tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP4);
         break;
     case WINED3DSIO_M4x3:
         nComponents = 3;
-        tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP4);
+        tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP4);
         break;
     case WINED3DSIO_M3x4:
         nComponents = 4;
-        tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+        tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
         break;
     case WINED3DSIO_M3x3:
         nComponents = 3;
-        tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+        tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
         break;
     case WINED3DSIO_M3x2:
         nComponents = 2;
-        tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+        tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
         break;
     default:
         break;
@@ -1727,7 +1531,8 @@ static void shader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) {
+static void vshader_hw_rsq_rcp(const SHADER_OPCODE_ARG *arg)
+{
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD dst = arg->dst;
@@ -1750,7 +1555,8 @@ static void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) {
     shader_addline(buffer, "%s;\n", tmpLine);
 }
 
-static void shader_hw_nrm(SHADER_OPCODE_ARG* arg) {
+static void shader_hw_nrm(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_name[50];
     char src_name[50];
@@ -1772,7 +1578,8 @@ static void shader_hw_nrm(SHADER_OPCODE_ARG* arg) {
         pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
-static void shader_hw_sincos(SHADER_OPCODE_ARG* arg) {
+static void shader_hw_sincos(const SHADER_OPCODE_ARG *arg)
+{
     /* This instruction exists in ARB, but the d3d instruction takes two extra parameters which
      * must contain fixed constants. So we need a separate function to filter those constants and
      * can't use map2gl
@@ -1796,7 +1603,8 @@ static void shader_hw_sincos(SHADER_OPCODE_ARG* arg) {
 
 }
 
-static GLuint create_arb_blt_vertex_program(WineD3D_GL_Info *gl_info) {
+static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
+{
     GLuint program_id = 0;
     const char *blt_vprogram =
         "!!ARBvp1.0\n"
@@ -1820,7 +1628,7 @@ static GLuint create_arb_blt_vertex_program(WineD3D_GL_Info *gl_info) {
     return program_id;
 }
 
-static GLuint create_arb_blt_fragment_program(WineD3D_GL_Info *gl_info, enum tex_types tex_type)
+static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
 {
     GLuint program_id = 0;
     const char *blt_fprograms[tex_type_count] =
@@ -1872,12 +1680,13 @@ static GLuint create_arb_blt_fragment_program(WineD3D_GL_Info *gl_info, enum tex
 static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (useVS) {
         TRACE("Using vertex shader\n");
+        IWineD3DVertexShaderImpl_CompileShader(This->stateBlock->vertexShader);
 
-        priv->current_vprogram_id = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId;
+        priv->current_vprogram_id = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->prgId;
 
         /* Bind the vertex program */
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
@@ -1894,9 +1703,11 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     }
 
     if (usePS) {
+        struct ps_compile_args compile_args;
         TRACE("Using pixel shader\n");
-
-        priv->current_fprogram_id = ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId;
+        find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args);
+        priv->current_fprogram_id = find_gl_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader,
+                                                    &compile_args);
 
         /* Bind the fragment program */
         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
@@ -1923,7 +1734,7 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
     GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
@@ -1937,7 +1748,7 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te
 static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (priv->current_vprogram_id) {
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
@@ -1968,21 +1779,39 @@ static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
 
 static void shader_arb_cleanup(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     if (GL_SUPPORT(ARB_VERTEX_PROGRAM)) glDisable(GL_VERTEX_PROGRAM_ARB);
     if (GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) glDisable(GL_FRAGMENT_PROGRAM_ARB);
 }
 
 static void shader_arb_destroy(IWineD3DBaseShader *iface) {
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
-    WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info;
+    IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
+    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
+    char pshader = shader_is_pshader_version(baseShader->baseShader.hex_version);
 
-    ENTER_GL();
-    GL_EXTCALL(glDeleteProgramsARB(1, &This->baseShader.prgId));
-    checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->baseShader.prgId))");
-    LEAVE_GL();
-    This->baseShader.prgId = 0;
-    This->baseShader.is_compiled = FALSE;
+    if(pshader) {
+        IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
+        UINT i;
+
+        ENTER_GL();
+        for(i = 0; i < This->num_gl_shaders; i++) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
+            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
+        }
+        LEAVE_GL();
+        HeapFree(GetProcessHeap(), 0, This->gl_shaders);
+        This->gl_shaders = NULL;
+        This->num_gl_shaders = 0;
+    } else {
+        IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
+
+        ENTER_GL();
+        GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId));
+        checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId))");
+        ((IWineD3DVertexShaderImpl *) This)->prgId = 0;
+        LEAVE_GL();
+    }
+    baseShader->baseShader.is_compiled = FALSE;
 }
 
 static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
@@ -1993,7 +1822,7 @@ static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
 
 static void shader_arb_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
     int i;
 
@@ -2035,13 +1864,14 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
     /* [0.0;1.0] clamping. Not needed, this is done implicitly */
 }
 
-static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
+    const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     const char *fragcolor;
-    WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
-    local_constant* lconst;
+    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
+    const local_constant *lconst;
+    GLuint retval;
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBfp1.0\n");
@@ -2078,7 +1908,7 @@ static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFE
     } else {
         fragcolor = "TMP_COLOR";
     }
-    if(This->srgb_enabled) {
+    if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
     }
     if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
@@ -2089,12 +1919,12 @@ static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFE
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
-    GL_EXTCALL(glGenProgramsARB(1, &This->baseShader.prgId));
+    GL_EXTCALL(glGenProgramsARB(1, &retval));
 
-    TRACE("Creating a hw pixel shader, prg=%d\n", This->baseShader.prgId);
-    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, This->baseShader.prgId));
+    TRACE("Creating a hw pixel shader, prg=%d\n", retval);
+    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, retval));
 
-    TRACE("Created hw pixel shader, prg=%d\n", This->baseShader.prgId);
+    TRACE("Created hw pixel shader, prg=%d\n", retval);
     /* Create the program and check for errors */
     GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                buffer->bsize, buffer->buffer));
@@ -2104,26 +1934,28 @@ static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFE
         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
         FIXME("HW PixelShader Error at position %d: %s\n",
               errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
-        This->baseShader.prgId = -1;
+        retval = 0;
     }
 
     /* Load immediate constants */
     if(!This->baseShader.load_local_constsF) {
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-            float *value = (float *) lconst->value;
+            const float *value = (const float *)lconst->value;
             GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst->idx, value));
             checkGLcall("glProgramLocalParameter4fvARB");
         }
     }
+
+    return retval;
 }
 
 static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
+    const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
-    WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
-    local_constant* lconst;
+    const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
+    const local_constant *lconst;
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBvp1.0\n");
@@ -2195,12 +2027,12 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
-    GL_EXTCALL(glGenProgramsARB(1, &This->baseShader.prgId));
+    GL_EXTCALL(glGenProgramsARB(1, &This->prgId));
 
-    TRACE("Creating a hw vertex shader, prg=%d\n", This->baseShader.prgId);
-    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->baseShader.prgId));
+    TRACE("Creating a hw vertex shader, prg=%d\n", This->prgId);
+    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->prgId));
 
-    TRACE("Created hw vertex shader, prg=%d\n", This->baseShader.prgId);
+    TRACE("Created hw vertex shader, prg=%d\n", This->prgId);
     /* Create the program and check for errors */
     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                buffer->bsize, buffer->buffer));
@@ -2210,19 +2042,20 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
         FIXME("HW VertexShader Error at position %d: %s\n",
               errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
-        This->baseShader.prgId = -1;
+        This->prgId = -1;
     }
 
     /* Load immediate constants */
     if(!This->baseShader.load_local_constsF) {
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-            float *value = (float *) lconst->value;
+            const float *value = (const float *)lconst->value;
             GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value));
         }
     }
 }
 
-static void shader_arb_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) {
+static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
+{
     /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
      * then overwrite the shader specific ones
      */
@@ -2241,21 +2074,23 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info
     }
 }
 
-static BOOL shader_arb_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt));
-    switch(fmt) {
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-        case WINED3DFMT_X8L8V8U8:
-        case WINED3DFMT_L6V5U5:
-        case WINED3DFMT_Q8W8V8U8:
-        case WINED3DFMT_ATI2N:
-            TRACE("[OK]\n");
-            return TRUE;
-        default:
-            TRACE("[FAILED\n");
-            return FALSE;
+static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+    {
+        TRACE("Checking support for color_fixup:\n");
+        dump_color_fixup_desc(fixup);
+    }
+
+    /* We support everything except YUV conversions. */
+    if (!is_yuv_fixup(fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
     }
+
+    TRACE("[FAILED]\n");
+    return FALSE;
 }
 
 static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
@@ -2360,7 +2195,7 @@ const shader_backend_t arb_program_shader_backend = {
     shader_arb_generate_pshader,
     shader_arb_generate_vshader,
     shader_arb_get_caps,
-    shader_arb_conv_supported,
+    shader_arb_color_fixup_supported,
 };
 
 /* ARB_fragment_program fixed function pipeline replacement definitions */
@@ -2407,7 +2242,7 @@ static HRESULT arbfp_alloc(IWineD3DDevice *iface) {
 }
 
 static void arbfp_free_ffpshader(void *value, void *gli) {
-    WineD3D_GL_Info *gl_info = gli;
+    const WineD3D_GL_Info *gl_info = gli;
     struct arbfp_ffp_desc *entry_arb = value;
 
     ENTER_GL();
@@ -2429,7 +2264,8 @@ static void arbfp_free(IWineD3DDevice *iface) {
     }
 }
 
-static void arbfp_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps) {
+static void arbfp_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
+{
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
                            WINED3DTEXOPCAPS_SELECTARG2                  |
@@ -2792,7 +2628,8 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
 }
 
 /* The stateblock is passed for GLINFO_LOCATION */
-static GLuint gen_arbfp_ffp_shader(struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock) {
+static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock)
+{
     unsigned int stage;
     SHADER_BUFFER buffer;
     BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
@@ -2976,8 +2813,8 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_frag_settings *settings, IWineD3DS
         }
 
         sprintf(colorcor_dst, "tex%u", stage);
-        gen_color_correction(&buffer, colorcor_dst, ".rgba", "const.x", "const.y",
-                                settings->op[stage].color_correction, &GLINFO_LOCATION);
+        gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y",
+                settings->op[stage].color_correction);
     }
 
     /* Generate the main shader */
@@ -3061,13 +2898,11 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
     BOOL use_pshader = use_ps(device);
     BOOL use_vshader = use_vs(device);
     struct ffp_frag_settings settings;
-    struct arbfp_ffp_desc *desc;
+    const struct arbfp_ffp_desc *desc;
     unsigned int i;
 
     if(isStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE))) {
-        if(use_pshader) {
-            IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
-        } else if(device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) {
+        if(!use_pshader && device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) {
             /* Reload fixed function constants since they collide with the pixel shader constants */
             for(i = 0; i < MAX_TEXTURES; i++) {
                 set_bumpmat_arbfp(STATE_TEXTURESTAGE(i, WINED3DTSS_BUMPENVMAT00), stateblock, context);
@@ -3078,28 +2913,28 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
         return;
     }
 
-    if(use_pshader) {
-        IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
-    } else {
+    if(!use_pshader) {
         /* Find or create a shader implementing the fixed function pipeline settings, then activate it */
         gen_ffp_frag_op(stateblock, &settings, FALSE);
-        desc = (struct arbfp_ffp_desc *) find_ffp_frag_shader(priv->fragment_shaders, &settings);
+        desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(priv->fragment_shaders, &settings);
         if(!desc) {
-            desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc));
-            if(!desc) {
+            struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
+            if (!new_desc)
+            {
                 ERR("Out of memory\n");
                 return;
             }
-            desc->num_textures_used = 0;
+            new_desc->num_textures_used = 0;
             for(i = 0; i < GL_LIMITS(texture_stages); i++) {
                 if(settings.op[i].cop == WINED3DTOP_DISABLE) break;
-                desc->num_textures_used = i;
+                new_desc->num_textures_used = i;
             }
 
-            memcpy(&desc->parent.settings, &settings, sizeof(settings));
-            desc->shader = gen_arbfp_ffp_shader(&settings, stateblock);
-            add_ffp_frag_shader(priv->fragment_shaders, &desc->parent);
-            TRACE("Allocated fixed function replacement shader descriptor %p\n", desc);
+            memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
+            new_desc->shader = gen_arbfp_ffp_shader(&settings, stateblock);
+            add_ffp_frag_shader(priv->fragment_shaders, &new_desc->parent);
+            TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
+            desc = new_desc;
         }
 
         /* Now activate the replacement program. GL_FRAGMENT_PROGRAM_ARB is already active(however, note the
@@ -3313,7 +3148,7 @@ const struct fragment_pipeline arbfp_fragment_pipeline = {
     arbfp_get_caps,
     arbfp_alloc,
     arbfp_free,
-    shader_arb_conv_supported,
+    shader_arb_color_fixup_supported,
     arbfp_fragmentstate_template,
     TRUE /* We can disable projected textures */
 };
@@ -3350,11 +3185,12 @@ static void arbfp_blit_free(IWineD3DDevice *iface) {
     LEAVE_GL();
 }
 
-static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, WINED3DFORMAT fmt, GLenum textype, char *luminance) {
+static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup, GLenum textype, char *luminance)
+{
     char chroma;
     const char *tex, *texinstr;
 
-    if(fmt == WINED3DFMT_UYVY) {
+    if (yuv_fixup == YUV_FIXUP_UYVY) {
         chroma = 'r';
         *luminance = 'a';
     } else {
@@ -3436,7 +3272,8 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, WINED3DFORMAT fmt, GLenum
     return TRUE;
 }
 
-static BOOL gen_yv12_read(SHADER_BUFFER *buffer, WINED3DFORMAT fmt, GLenum textype, char *luminance) {
+static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance)
+{
     const char *tex;
 
     switch(textype) {
@@ -3581,7 +3418,8 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, WINED3DFORMAT fmt, GLenum texty
     return TRUE;
 }
 
-static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, WINED3DFORMAT fmt, GLenum textype) {
+static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixup, GLenum textype)
+{
     GLenum shader;
     SHADER_BUFFER buffer;
     char luminance_component;
@@ -3649,16 +3487,29 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, WINED3DFORMAT fmt, GLen
     shader_addline(&buffer, "PARAM yuv_coef = {1.403, 0.344, 0.714, 1.770};\n");
     shader_addline(&buffer, "PARAM size = program.local[0];\n");
 
-    if(fmt == WINED3DFMT_UYVY || fmt ==WINED3DFMT_YUY2) {
-        if(gen_planar_yuv_read(&buffer, fmt, textype, &luminance_component) == FALSE) {
-            HeapFree(GetProcessHeap(), 0, buffer.buffer);
-            return 0;
-        }
-    } else {
-        if(gen_yv12_read(&buffer, fmt, textype, &luminance_component) == FALSE) {
+    switch (yuv_fixup)
+    {
+        case YUV_FIXUP_UYVY:
+        case YUV_FIXUP_YUY2:
+            if (!gen_planar_yuv_read(&buffer, yuv_fixup, textype, &luminance_component))
+            {
+                HeapFree(GetProcessHeap(), 0, buffer.buffer);
+                return 0;
+            }
+            break;
+
+        case YUV_FIXUP_YV12:
+            if (!gen_yv12_read(&buffer, textype, &luminance_component))
+            {
+                HeapFree(GetProcessHeap(), 0, buffer.buffer);
+                return 0;
+            }
+            break;
+
+        default:
+            FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
             HeapFree(GetProcessHeap(), 0, buffer.buffer);
             return 0;
-        }
     }
 
     /* Calculate the final result. Formula is taken from
@@ -3685,25 +3536,24 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, WINED3DFORMAT fmt, GLen
     HeapFree(GetProcessHeap(), 0, buffer.buffer);
     LEAVE_GL();
 
-    if(fmt == WINED3DFMT_YUY2) {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            priv->yuy2_rect_shader = shader;
-        } else {
-            priv->yuy2_2d_shader = shader;
-        }
-    } else if(fmt == WINED3DFMT_UYVY) {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            priv->uyvy_rect_shader = shader;
-        } else {
-            priv->uyvy_2d_shader = shader;
-        }
-    } else {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            priv->yv12_rect_shader = shader;
-        } else {
-            priv->yv12_2d_shader = shader;
-        }
+    switch (yuv_fixup)
+    {
+        case YUV_FIXUP_YUY2:
+            if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yuy2_rect_shader = shader;
+            else priv->yuy2_2d_shader = shader;
+            break;
+
+        case YUV_FIXUP_UYVY:
+            if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->uyvy_rect_shader = shader;
+            else priv->uyvy_2d_shader = shader;
+            break;
+
+        case YUV_FIXUP_YV12:
+            if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader;
+            else priv->yv12_2d_shader = shader;
+            break;
     }
+
     return shader;
 }
 
@@ -3712,13 +3562,15 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum t
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
     float size[4] = {width, height, 1, 1};
     struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
+    enum yuv_fixup yuv_fixup;
 
     getFormatDescEntry(fmt, &GLINFO_LOCATION, &glDesc);
 
-    if(glDesc->conversion_group != WINED3DFMT_YUY2 && glDesc->conversion_group != WINED3DFMT_UYVY &&
-       glDesc->conversion_group != WINED3DFMT_YV12) {
-        TRACE("Format: %s\n", debug_d3dformat(glDesc->conversion_group));
+    if (!is_yuv_fixup(glDesc->color_fixup))
+    {
+        TRACE("Fixup:\n");
+        dump_color_fixup_desc(glDesc->color_fixup);
         /* Don't bother setting up a shader for unconverted formats */
         ENTER_GL();
         glEnable(textype);
@@ -3727,30 +3579,33 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum t
         return WINED3D_OK;
     }
 
-    if(glDesc->conversion_group == WINED3DFMT_YUY2) {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            shader = priv->yuy2_rect_shader;
-        } else {
-            shader = priv->yuy2_2d_shader;
-        }
-    } else if(glDesc->conversion_group == WINED3DFMT_UYVY) {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            shader = priv->uyvy_rect_shader;
-        } else {
-            shader = priv->uyvy_2d_shader;
-        }
-    } else {
-        if(textype == GL_TEXTURE_RECTANGLE_ARB) {
-            shader = priv->yv12_rect_shader;
-        } else {
-            shader = priv->yv12_2d_shader;
-        }
-    }
+    yuv_fixup = get_yuv_fixup(glDesc->color_fixup);
 
-    if(!shader) {
-        shader = gen_yuv_shader(device, glDesc->conversion_group, textype);
+    switch(yuv_fixup)
+    {
+        case YUV_FIXUP_YUY2:
+            shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yuy2_rect_shader : priv->yuy2_2d_shader;
+            break;
+
+        case YUV_FIXUP_UYVY:
+            shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->uyvy_rect_shader : priv->uyvy_2d_shader;
+            break;
+
+        case YUV_FIXUP_YV12:
+            shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader : priv->yv12_2d_shader;
+            break;
+
+        default:
+            FIXME("Unsupported YUV fixup %#x, not setting a shader\n", yuv_fixup);
+            ENTER_GL();
+            glEnable(textype);
+            checkGLcall("glEnable(textype)");
+            LEAVE_GL();
+            return E_NOTIMPL;
     }
 
+    if (!shader) shader = gen_yuv_shader(device, yuv_fixup, textype);
+
     ENTER_GL();
     glEnable(GL_FRAGMENT_PROGRAM_ARB);
     checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
@@ -3782,15 +3637,40 @@ static void arbfp_blit_unset(IWineD3DDevice *iface) {
     LEAVE_GL();
 }
 
-static BOOL arbfp_blit_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking blit format support for format %s:", debug_d3dformat(fmt));
-    switch(fmt) {
-        case WINED3DFMT_YUY2:
-        case WINED3DFMT_UYVY:
-        case WINED3DFMT_YV12:
+static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    enum yuv_fixup yuv_fixup;
+
+    if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+    {
+        TRACE("Checking support for fixup:\n");
+        dump_color_fixup_desc(fixup);
+    }
+
+    if (is_identity_fixup(fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
+    /* We only support YUV conversions. */
+    if (!is_yuv_fixup(fixup))
+    {
+        TRACE("[FAILED]\n");
+        return FALSE;
+    }
+
+    yuv_fixup = get_yuv_fixup(fixup);
+    switch(yuv_fixup)
+    {
+        case YUV_FIXUP_YUY2:
+        case YUV_FIXUP_UYVY:
+        case YUV_FIXUP_YV12:
             TRACE("[OK]\n");
             return TRUE;
+
         default:
+            FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
             TRACE("[FAILED]\n");
             return FALSE;
     }
@@ -3801,7 +3681,7 @@ const struct blit_shader arbfp_blit = {
     arbfp_blit_free,
     arbfp_blit_set,
     arbfp_blit_unset,
-    arbfp_blit_conv_supported
+    arbfp_blit_color_fixup_supported,
 };
 
 #undef GLINFO_LOCATION
index a53108e..90ca192 100644 (file)
@@ -26,6 +26,7 @@
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 /* Some private defines, Constant associations, etc.
  * Env bump matrix and per stage constant should be independent,
@@ -159,7 +160,9 @@ static const char *debug_rep(GLuint rep) {
 }
 
 #define GLINFO_LOCATION (*gl_info)
-static GLuint register_for_arg(DWORD arg, WineD3D_GL_Info *gl_info, unsigned int stage, GLuint *mod, GLuint *rep, GLuint tmparg) {
+static GLuint register_for_arg(DWORD arg, const WineD3D_GL_Info *gl_info,
+        unsigned int stage, GLuint *mod, GLuint *rep, GLuint tmparg)
+{
     GLenum ret;
 
     if(mod) *mod = GL_NONE;
@@ -224,7 +227,8 @@ static GLuint register_for_arg(DWORD arg, WineD3D_GL_Info *gl_info, unsigned int
     return ret;
 }
 
-static GLuint find_tmpreg(struct texture_stage_op op[MAX_TEXTURES]) {
+static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
+{
     int lowest_read = -1;
     int lowest_write = -1;
     int i;
@@ -284,7 +288,8 @@ static GLuint find_tmpreg(struct texture_stage_op op[MAX_TEXTURES]) {
     }
 }
 
-static GLuint gen_ati_shader(struct texture_stage_op op[MAX_TEXTURES], WineD3D_GL_Info *gl_info) {
+static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const WineD3D_GL_Info *gl_info)
+{
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
     unsigned int stage;
     GLuint arg0, arg1, arg2, extrarg;
@@ -339,21 +344,30 @@ static GLuint gen_ati_shader(struct texture_stage_op op[MAX_TEXTURES], WineD3D_G
 
     /* Pass 2: Generate perturbation calculations */
     for(stage = 0; stage < GL_LIMITS(textures); stage++) {
+        GLuint argmodextra_x, argmodextra_y;
+        struct color_fixup_desc fixup;
+
         if(op[stage].cop == WINED3DTOP_DISABLE) break;
         if(op[stage].cop != WINED3DTOP_BUMPENVMAP &&
            op[stage].cop != WINED3DTOP_BUMPENVMAPLUMINANCE) continue;
 
-        /* Nice thing, we get the color correction for free :-) */
-        if(op[stage].color_correction == WINED3DFMT_V8U8) {
-            argmodextra = GL_2X_BIT_ATI | GL_BIAS_BIT_ATI;
-        } else {
-            argmodextra = 0;
+        if (fixup.x_source != CHANNEL_SOURCE_X || fixup.y_source != CHANNEL_SOURCE_Y)
+        {
+            FIXME("Swizzles not implemented\n");
+            argmodextra_x = GL_NONE;
+            argmodextra_y = GL_NONE;
+        }
+        else
+        {
+            /* Nice thing, we get the color correction for free :-) */
+            argmodextra_x = fixup.x_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
+            argmodextra_y = fixup.y_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
         }
 
         TRACE("glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_%d_ATI, GL_RED_BIT_ATI, GL_NONE, GL_REG_%d_ATI, GL_NONE, %s, ATI_FFP_CONST_BUMPMAT(%d), GL_NONE, GL_NONE, GL_REG_%d_ATI, GL_RED, GL_NONE)\n",
-              stage + 1, stage, debug_argmod(argmodextra), stage, stage + 1);
+              stage + 1, stage, debug_argmod(argmodextra_x), stage, stage + 1);
         GL_EXTCALL(glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_RED_BIT_ATI, GL_NONE,
-                                         GL_REG_0_ATI + stage, GL_NONE, argmodextra,
+                                         GL_REG_0_ATI + stage, GL_NONE, argmodextra_x,
                                          ATI_FFP_CONST_BUMPMAT(stage), GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
                                          GL_REG_0_ATI + stage + 1, GL_RED, GL_NONE));
 
@@ -372,9 +386,9 @@ static GLuint gen_ati_shader(struct texture_stage_op op[MAX_TEXTURES], WineD3D_G
         GL_EXTCALL(glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE,
                                         ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE));
         TRACE("glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_%d_ATI, GL_GREEN_BIT_ATI, GL_NONE, GL_REG_%d_ATI, GL_NONE, %s, GL_REG_5_ATI, GL_NONE, GL_NONE, GL_REG_%d_ATI, GL_GREEN, GL_NONE)\n",
-              stage + 1, stage, debug_argmod(argmodextra), stage + 1);
+              stage + 1, stage, debug_argmod(argmodextra_y), stage + 1);
         GL_EXTCALL(glColorFragmentOp3ATI(GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
-                                         GL_REG_0_ATI + stage, GL_NONE, argmodextra,
+                                         GL_REG_0_ATI + stage, GL_NONE, argmodextra_y,
                                          GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
                                          GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE));
     }
@@ -802,30 +816,32 @@ static GLuint gen_ati_shader(struct texture_stage_op op[MAX_TEXTURES], WineD3D_G
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl          *This = stateblock->wineD3DDevice;
-    struct atifs_ffp_desc       *desc;
+    const struct atifs_ffp_desc *desc;
     struct ffp_frag_settings     settings;
     struct atifs_private_data   *priv = (struct atifs_private_data *) This->fragment_priv;
     DWORD mapped_stage;
     unsigned int i;
 
     gen_ffp_frag_op(stateblock, &settings, TRUE);
-    desc = (struct atifs_ffp_desc *) find_ffp_frag_shader(priv->fragment_shaders, &settings);
+    desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(priv->fragment_shaders, &settings);
     if(!desc) {
-        desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc));
-        if(!desc) {
+        struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
+        if (!new_desc)
+        {
             ERR("Out of memory\n");
             return;
         }
-        desc->num_textures_used = 0;
+        new_desc->num_textures_used = 0;
         for(i = 0; i < GL_LIMITS(texture_stages); i++) {
             if(settings.op[i].cop == WINED3DTOP_DISABLE) break;
-            desc->num_textures_used = i;
+            new_desc->num_textures_used = i;
         }
 
-        memcpy(&desc->parent.settings, &settings, sizeof(settings));
-        desc->shader = gen_ati_shader(settings.op, &GLINFO_LOCATION);
-        add_ffp_frag_shader(priv->fragment_shaders, &desc->parent);
-        TRACE("Allocated fixed function replacement shader descriptor %p\n", desc);
+        memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
+        new_desc->shader = gen_ati_shader(settings.op, &GLINFO_LOCATION);
+        add_ffp_frag_shader(priv->fragment_shaders, &new_desc->parent);
+        TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
+        desc = new_desc;
     }
 
     /* GL_ATI_fragment_shader depends on the GL_TEXTURE_xD enable settings. Update the texture stages
@@ -1017,7 +1033,8 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
     }
 }
 
-static void atifs_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps) {
+static void atifs_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
+{
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
                            WINED3DTEXOPCAPS_SELECTARG2                  |
@@ -1101,17 +1118,25 @@ static void atifs_free(IWineD3DDevice *iface) {
 }
 #undef GLINFO_LOCATION
 
-static BOOL atifs_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt));
-    switch(fmt) {
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-            TRACE("[OK]\n");
-            return TRUE;
-        default:
-            TRACE("[FAILED\n");
-            return FALSE;
+static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+    {
+        TRACE("Checking support for fixup:\n");
+        dump_color_fixup_desc(fixup);
     }
+
+    /* We only support sign fixup of the first two channels. */
+    if (fixup.x_source == CHANNEL_SOURCE_X && fixup.y_source == CHANNEL_SOURCE_Y
+            && fixup.z_source == CHANNEL_SOURCE_Z && fixup.w_source == CHANNEL_SOURCE_W
+            && !fixup.z_sign_fixup && !fixup.w_sign_fixup)
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
+    TRACE("[FAILED]\n");
+    return FALSE;
 }
 
 const struct fragment_pipeline atifs_fragment_pipeline = {
@@ -1119,7 +1144,7 @@ const struct fragment_pipeline atifs_fragment_pipeline = {
     atifs_get_caps,
     atifs_alloc,
     atifs_free,
-    atifs_conv_supported,
+    atifs_color_fixup_supported,
     atifs_fragmentstate_template,
     TRUE /* We can disable projected textures */
 };
index f7c8d35..c0b149f 100644 (file)
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLNAME_REQUIRE_GLSL  ((const char *)1)
 
+static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version);
+
 static inline BOOL shader_is_version_token(DWORD token) {
     return shader_is_pshader_version(token) ||
            shader_is_vshader_version(token);
@@ -73,45 +76,39 @@ int shader_addline(
     return 0;
 }
 
-const SHADER_OPCODE* shader_get_opcode(
-    IWineD3DBaseShader *iface, const DWORD code) {
-
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl*) iface;
-
+const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code)
+{
     DWORD i = 0;
-    DWORD hex_version = This->baseShader.hex_version;
-    const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
 
     /** TODO: use dichotomic search */
-    while (NULL != shader_ins[i].name) {
-        if (((code & WINED3DSI_OPCODE_MASK) == shader_ins[i].opcode) &&
-            (((hex_version >= shader_ins[i].min_version) && (hex_version <= shader_ins[i].max_version)) ||
-            ((shader_ins[i].min_version == 0) && (shader_ins[i].max_version == 0)))) {
-            return &shader_ins[i];
+    while (opcode_table[i].name)
+    {
+        if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
+                && shader_version >= opcode_table[i].min_version
+                && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
+        {
+            return &opcode_table[i];
         }
         ++i;
     }
-    FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n", 
-       code, code, code & WINED3DSI_OPCODE_MASK, hex_version);
+
+    FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
+            code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
+
     return NULL;
 }
 
 /* Read a parameter opcode from the input stream,
  * and possibly a relative addressing token.
  * Return the number of tokens read */
-int shader_get_param(
-    IWineD3DBaseShader* iface,
-    const DWORD* pToken,
-    DWORD* param,
-    DWORD* addr_token) {
-
+static int shader_get_param(const DWORD *pToken, DWORD shader_version, DWORD *param, DWORD *addr_token)
+{
     /* PS >= 3.0 have relative addressing (with token)
      * VS >= 2.0 have relative addressing (with token)
      * VS >= 1.0 < 2.0 have relative addressing (without token)
      * The version check below should work in general */
 
-    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
-    char rel_token = WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2 &&
+    char rel_token = WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2 &&
         ((*pToken & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
 
     *param = *pToken;
@@ -139,11 +136,8 @@ static inline int shader_skip_opcode(
  * Note: This function assumes source or destination token format.
  * It will not work with specially-formatted tokens like DEF or DCL, 
  * but hopefully those would be recognized */
-
-int shader_skip_unrecognized(
-    IWineD3DBaseShader* iface,
-    const DWORD* pToken) {
-
+static int shader_skip_unrecognized(const DWORD *pToken, DWORD shader_version)
+{
     int tokens_read = 0;
     int i = 0;
 
@@ -151,12 +145,12 @@ int shader_skip_unrecognized(
     while (*pToken & 0x80000000) {
 
         DWORD param, addr_token;
-        tokens_read += shader_get_param(iface, pToken, &param, &addr_token);
+        tokens_read += shader_get_param(pToken, shader_version, &param, &addr_token);
         pToken += tokens_read;
 
         FIXME("Unrecognized opcode param: token=0x%08x "
             "addr_token=0x%08x name=", param, addr_token);
-        shader_dump_param(iface, param, addr_token, i);
+        shader_dump_param(param, addr_token, i, shader_version);
         FIXME("\n");
         ++i;
     }
@@ -165,9 +159,8 @@ int shader_skip_unrecognized(
 
 /* Convert floating point offset relative
  * to a register file to an absolute offset for float constants */
-
-unsigned int shader_get_float_offset(const DWORD reg) {
-
+static unsigned int shader_get_float_offset(const DWORD reg)
+{
      unsigned int regnum = reg & WINED3DSP_REGNUM_MASK;
      int regtype = shader_get_regtype(reg);
 
@@ -208,6 +201,8 @@ HRESULT shader_get_registers_used(
     IWineD3DStateBlockImpl *stateBlock) {
 
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+    const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
+    DWORD shader_version = This->baseShader.hex_version;
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
 
     /* There are some minor differences between pixel and vertex shaders */
@@ -245,7 +240,7 @@ HRESULT shader_get_registers_used(
 
         /* Fetch opcode */
         opcode_token = *pToken++;
-        curOpcode = shader_get_opcode(iface, opcode_token);
+        curOpcode = shader_get_opcode(shader_ins, shader_version, opcode_token);
 
         /* Unhandled opcode, and its parameters */
         if (NULL == curOpcode) {
@@ -425,7 +420,7 @@ HRESULT shader_get_registers_used(
             for (i = 0; i < limit; ++i) {
 
                 DWORD param, addr_token, reg, regtype;
-                pToken += shader_get_param(iface, pToken, &param, &addr_token);
+                pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
 
                 regtype = shader_get_regtype(param);
                 reg = param & WINED3DSP_REGNUM_MASK;
@@ -495,11 +490,8 @@ HRESULT shader_get_registers_used(
     return WINED3D_OK;
 }
 
-static void shader_dump_decl_usage(
-    IWineD3DBaseShaderImpl* This,
-    DWORD decl, 
-    DWORD param) {
-
+static void shader_dump_decl_usage(DWORD decl, DWORD param, DWORD shader_version)
+{
     DWORD regtype = shader_get_regtype(param);
 
     TRACE("dcl");
@@ -520,8 +512,7 @@ static void shader_dump_decl_usage(
         DWORD idx = (decl & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
 
         /* Pixel shaders 3.0 don't have usage semantics */
-        char pshader = shader_is_pshader_version(This->baseShader.hex_version);
-        if (pshader && This->baseShader.hex_version < WINED3DPS_VERSION(3,0))
+        if (shader_is_pshader_version(shader_version) && shader_version < WINED3DPS_VERSION(3,0))
             return;
         else
             TRACE("_");
@@ -579,20 +570,16 @@ static void shader_dump_decl_usage(
     }
 }
 
-static void shader_dump_arr_entry(
-    IWineD3DBaseShader *iface,
-    const DWORD param,
-    const DWORD addr_token,
-    unsigned int reg,
-    int input) {
-
+static void shader_dump_arr_entry(const DWORD param, const DWORD addr_token,
+        unsigned int reg, int input, DWORD shader_version)
+{
     char relative =
         ((param & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
 
     if (relative) {
         TRACE("[");
         if (addr_token)
-            shader_dump_param(iface, addr_token, 0, input);
+            shader_dump_param(addr_token, 0, input, shader_version);
         else
             TRACE("a0.x");
         TRACE(" + ");
@@ -602,13 +589,8 @@ static void shader_dump_arr_entry(
          TRACE("]");
 }
 
-void shader_dump_param(
-    IWineD3DBaseShader *iface,
-    const DWORD param, 
-    const DWORD addr_token,
-    int input) {
-
-    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version)
+{
     static const char * const rastout_reg_names[] = { "oPos", "oFog", "oPts" };
     static const char * const misctype_reg_names[] = { "vPos", "vFace"};
     char swizzle_reg_chars[4];
@@ -618,7 +600,7 @@ void shader_dump_param(
     DWORD modifier = param & WINED3DSP_SRCMOD_MASK;
 
     /* There are some minor differences between pixel and vertex shaders */
-    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+    char pshader = shader_is_pshader_version(shader_version);
 
     /* For one, we'd prefer color components to be shown for pshaders.
      * FIXME: use the swizzle function for this */
@@ -650,14 +632,14 @@ void shader_dump_param(
             break;
         case WINED3DSPR_INPUT:
             TRACE("v");
-            shader_dump_arr_entry(iface, param, addr_token, reg, input);
+            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
         case WINED3DSPR_CONST:
         case WINED3DSPR_CONST2:
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
-            shader_dump_arr_entry(iface, param, addr_token, shader_get_float_offset(param), input);
+            shader_dump_arr_entry(param, addr_token, shader_get_float_offset(param), input, shader_version);
             break;
         case WINED3DSPR_TEXTURE: /* vs: case D3DSPR_ADDR */
             TRACE("%c%u", (pshader? 't':'a'), reg);
@@ -679,20 +661,20 @@ void shader_dump_param(
             /* Vertex shaders >= 3.0 use general purpose output registers
              * (WINED3DSPR_OUTPUT), which can include an address token */
 
-            if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) {
+            if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) {
                 TRACE("o");
-                shader_dump_arr_entry(iface, param, addr_token, reg, input);
+                shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             }
             else 
                TRACE("oT%u", reg);
             break;
         case WINED3DSPR_CONSTINT:
             TRACE("i");
-            shader_dump_arr_entry(iface, param, addr_token, reg, input);
+            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
         case WINED3DSPR_CONSTBOOL:
             TRACE("b");
-            shader_dump_arr_entry(iface, param, addr_token, reg, input);
+            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
         case WINED3DSPR_LABEL:
             TRACE("l%u", reg);
@@ -778,19 +760,79 @@ void shader_dump_param(
     }
 }
 
+static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
+        IWineD3DDeviceImpl *device, const struct SHADER_OPCODE_ARG *arg)
+{
+    DWORD hex_version = shader->baseShader.hex_version;
+    IWineD3DBaseTextureImpl *texture;
+    struct color_fixup_desc fixup;
+    BOOL recorded = FALSE;
+    DWORD sampler_idx;
+    UINT i;
+
+    switch(arg->opcode->opcode)
+    {
+        case WINED3DSIO_TEX:
+            if (hex_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
+            else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
+            break;
+
+        case WINED3DSIO_TEXLDL:
+            FIXME("Add color fixup for vertex texture WINED3DSIO_TEXLDL\n");
+            return;
+
+        case WINED3DSIO_TEXDP3TEX:
+        case WINED3DSIO_TEXM3x3TEX:
+        case WINED3DSIO_TEXM3x3SPEC:
+        case WINED3DSIO_TEXM3x3VSPEC:
+        case WINED3DSIO_TEXBEM:
+        case WINED3DSIO_TEXREG2AR:
+        case WINED3DSIO_TEXREG2GB:
+        case WINED3DSIO_TEXREG2RGB:
+            sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
+            break;
+
+        default:
+            /* Not a texture sampling instruction, nothing to do */
+            return;
+    };
+
+    texture = (IWineD3DBaseTextureImpl *)device->stateBlock->textures[sampler_idx];
+    if (texture) fixup = texture->baseTexture.shader_color_fixup;
+    else fixup = COLOR_FIXUP_IDENTITY;
+
+    /* before doing anything, record the sampler with the format in the format conversion list,
+     * but check if it's not there already */
+    for (i = 0; i < shader->baseShader.num_sampled_samplers; ++i)
+    {
+        if (shader->baseShader.sampled_samplers[i] == sampler_idx)
+        {
+            recorded = TRUE;
+            break;
+        }
+    }
+
+    if (!recorded)
+    {
+        shader->baseShader.sampled_samplers[shader->baseShader.num_sampled_samplers] = sampler_idx;
+        ++shader->baseShader.num_sampled_samplers;
+    }
+
+    device->shader_backend->shader_color_correction(arg, fixup);
+}
+
 /** Shared code in order to generate the bulk of the shader string.
     Use the shader_header_fct & shader_footer_fct to add strings
     that are specific to pixel or vertex functions
     NOTE: A description of how to parse tokens can be found on msdn */
-void shader_generate_main(
-    IWineD3DBaseShader *iface,
-    SHADER_BUFFER* buffer,
-    shader_reg_maps* reg_maps,
-    CONST DWORD* pFunction) {
-
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
+        const shader_reg_maps* reg_maps, CONST DWORD* pFunction)
+{
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
+    const SHADER_OPCODE *opcode_table = This->baseShader.shader_ins;
     const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
+    DWORD shader_version = This->baseShader.hex_version;
     const DWORD *pToken = pFunction;
     const SHADER_OPCODE *curOpcode = NULL;
     SHADER_HANDLER hw_fct = NULL;
@@ -824,7 +866,7 @@ void shader_generate_main(
 
             /* Read opcode */
             hw_arg.opcode_token = *pToken++;
-            curOpcode = shader_get_opcode(iface, hw_arg.opcode_token);
+            curOpcode = shader_get_opcode(opcode_table, shader_version, hw_arg.opcode_token);
 
             /* Select handler */
             if (curOpcode == NULL)
@@ -835,7 +877,7 @@ void shader_generate_main(
             /* Unknown opcode and its parameters */
             if (NULL == curOpcode) {
                 FIXME("Unrecognized opcode: token=0x%08x\n", hw_arg.opcode_token);
-                pToken += shader_skip_unrecognized(iface, pToken); 
+                pToken += shader_skip_unrecognized(pToken, shader_version);
 
             /* Nothing to do */
             } else if (WINED3DSIO_DCL == curOpcode->opcode ||
@@ -857,7 +899,7 @@ void shader_generate_main(
                 if (curOpcode->dst_token) {
 
                     DWORD param, addr_token = 0;
-                    pToken += shader_get_param(iface, pToken, &param, &addr_token);
+                    pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
                     hw_arg.dst = param;
                     hw_arg.dst_addr = addr_token;
                 }
@@ -870,7 +912,7 @@ void shader_generate_main(
                 for (i = 0; i < (curOpcode->num_params - curOpcode->dst_token); i++) {
 
                     DWORD param, addr_token = 0; 
-                    pToken += shader_get_param(iface, pToken, &param, &addr_token);
+                    pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
                     hw_arg.src[i] = param;
                     hw_arg.src_addr[i] = addr_token;
                 }
@@ -879,7 +921,7 @@ void shader_generate_main(
                 hw_fct(&hw_arg);
 
                 /* Add color correction if needed */
-                device->shader_backend->shader_color_correction(&hw_arg);
+                shader_color_correction(This, device, &hw_arg);
 
                 /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
                 /* FIXME: This should be internal to the shader backend.
@@ -899,8 +941,8 @@ void shader_generate_main(
     }
 }
 
-void shader_dump_ins_modifiers(const DWORD output) {
-
+static void shader_dump_ins_modifiers(const DWORD output)
+{
     DWORD shift = (output & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
     DWORD mmask = output & WINED3DSP_DSTMOD_MASK;
 
@@ -939,155 +981,167 @@ void shader_trace_init(
 
     TRACE("(%p) : Parsing program\n", This);
 
-    if (NULL != pToken) {
-        while (WINED3DVS_END() != *pToken) {
-            if (shader_is_version_token(*pToken)) { /** version */
-                This->baseShader.hex_version = *pToken;
-                TRACE("%s_%u_%u\n", shader_is_pshader_version(This->baseShader.hex_version)? "ps": "vs",
-                    WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version),
-                    WINED3DSHADER_VERSION_MINOR(This->baseShader.hex_version));
-                ++pToken;
-                ++len;
-                continue;
+    if (!pFunction)
+    {
+        WARN("Got a NULL pFunction, returning.\n");
+        This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
+        return;
+    }
+
+    while (WINED3DVS_END() != *pToken)
+    {
+        if (shader_is_version_token(*pToken)) /* version */
+        {
+            This->baseShader.hex_version = *pToken;
+            TRACE("%s_%u_%u\n", shader_is_pshader_version(This->baseShader.hex_version)? "ps": "vs",
+                WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version),
+                WINED3DSHADER_VERSION_MINOR(This->baseShader.hex_version));
+            ++pToken;
+            ++len;
+            continue;
+        }
+        if (shader_is_comment(*pToken)) /* comment */
+        {
+            DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
+            ++pToken;
+            TRACE("//%s\n", (const char*)pToken);
+            pToken += comment_len;
+            len += comment_len + 1;
+            continue;
+        }
+        opcode_token = *pToken++;
+        curOpcode = shader_get_opcode(This->baseShader.shader_ins, This->baseShader.hex_version, opcode_token);
+        len++;
+
+        if (!curOpcode)
+        {
+            int tokens_read;
+            FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
+            tokens_read = shader_skip_unrecognized(pToken, This->baseShader.hex_version);
+            pToken += tokens_read;
+            len += tokens_read;
+        }
+        else
+        {
+            if (curOpcode->opcode == WINED3DSIO_DCL)
+            {
+                DWORD usage = *pToken;
+                DWORD param = *(pToken + 1);
+
+                shader_dump_decl_usage(usage, param, This->baseShader.hex_version);
+                shader_dump_ins_modifiers(param);
+                TRACE(" ");
+                shader_dump_param(param, 0, 0, This->baseShader.hex_version);
+                pToken += 2;
+                len += 2;
             }
-            if (shader_is_comment(*pToken)) { /** comment */
-                DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
-                ++pToken;
-                TRACE("//%s\n", (const char*)pToken);
-                pToken += comment_len;
-                len += comment_len + 1;
-                continue;
+            else if (curOpcode->opcode == WINED3DSIO_DEF)
+            {
+                unsigned int offset = shader_get_float_offset(*pToken);
+
+                TRACE("def c%u = %f, %f, %f, %f", offset,
+                        *(const float *)(pToken + 1),
+                        *(const float *)(pToken + 2),
+                        *(const float *)(pToken + 3),
+                        *(const float *)(pToken + 4));
+                pToken += 5;
+                len += 5;
             }
-            opcode_token = *pToken++;
-            curOpcode = shader_get_opcode(iface, opcode_token);
-            len++;
-
-            if (NULL == curOpcode) {
+            else if (curOpcode->opcode == WINED3DSIO_DEFI)
+            {
+                TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK,
+                        *(pToken + 1),
+                        *(pToken + 2),
+                        *(pToken + 3),
+                        *(pToken + 4));
+                pToken += 5;
+                len += 5;
+            }
+            else if (curOpcode->opcode == WINED3DSIO_DEFB)
+            {
+                TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
+                        *(pToken + 1)? "true": "false");
+                pToken += 2;
+                len += 2;
+            }
+            else
+            {
+                DWORD param, addr_token;
                 int tokens_read;
-                FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
-                tokens_read = shader_skip_unrecognized(iface, pToken);
-                pToken += tokens_read;
-                len += tokens_read;
-
-            } else {
-                if (curOpcode->opcode == WINED3DSIO_DCL) {
-
-                    DWORD usage = *pToken;
-                    DWORD param = *(pToken + 1);
-
-                    shader_dump_decl_usage(This, usage, param);
-                    shader_dump_ins_modifiers(param);
-                    TRACE(" ");
-                    shader_dump_param(iface, param, 0, 0);
-                    pToken += 2;
-                    len += 2;
-
-                } else if (curOpcode->opcode == WINED3DSIO_DEF) {
-
-                        unsigned int offset = shader_get_float_offset(*pToken);
-
-                        TRACE("def c%u = %f, %f, %f, %f", offset,
-                            *(const float *)(pToken + 1),
-                            *(const float *)(pToken + 2),
-                            *(const float *)(pToken + 3),
-                            *(const float *)(pToken + 4));
-
-                        pToken += 5;
-                        len += 5;
-                } else if (curOpcode->opcode == WINED3DSIO_DEFI) {
-
-                        TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK,
-                            *(pToken + 1),
-                            *(pToken + 2),
-                            *(pToken + 3),
-                            *(pToken + 4));
-
-                        pToken += 5;
-                        len += 5;
-
-                } else if (curOpcode->opcode == WINED3DSIO_DEFB) {
-
-                        TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
-                            *(pToken + 1)? "true": "false");
-
-                        pToken += 2;
-                        len += 2;
-
-                } else {
 
-                    DWORD param, addr_token;
-                    int tokens_read;
-
-                    /* Print out predication source token first - it follows
-                     * the destination token. */
-                    if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) {
-                        TRACE("(");
-                        shader_dump_param(iface, *(pToken + 2), 0, 1);
-                        TRACE(") ");
-                    }
-                    if (opcode_token & WINED3DSI_COISSUE) {
-                        /* PixWin marks instructions with the coissue flag with a '+' */
-                        TRACE("+");
-                    }
-
-                    TRACE("%s", curOpcode->name);
-
-                    if (curOpcode->opcode == WINED3DSIO_IFC ||
-                        curOpcode->opcode == WINED3DSIO_BREAKC) {
-
-                        DWORD op = (opcode_token & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
-                        switch (op) {
-                            case COMPARISON_GT: TRACE("_gt"); break;
-                            case COMPARISON_EQ: TRACE("_eq"); break;
-                            case COMPARISON_GE: TRACE("_ge"); break;
-                            case COMPARISON_LT: TRACE("_lt"); break;
-                            case COMPARISON_NE: TRACE("_ne"); break;
-                            case COMPARISON_LE: TRACE("_le"); break;
-                            default:
-                                TRACE("_(%u)", op);
-                        }
-                    } else if (curOpcode->opcode == WINED3DSIO_TEX &&
-                               This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) {
-                        if(opcode_token & WINED3DSI_TEXLD_PROJECT) TRACE("p");
-                    }
-
-                    /* Destination token */
-                    if (curOpcode->dst_token) {
-
-                        /* Destination token */
-                        tokens_read = shader_get_param(iface, pToken, &param, &addr_token);
-                        pToken += tokens_read;
-                        len += tokens_read;
+                /* Print out predication source token first - it follows
+                 * the destination token. */
+                if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
+                {
+                    TRACE("(");
+                    shader_dump_param(*(pToken + 2), 0, 1, This->baseShader.hex_version);
+                    TRACE(") ");
+                }
+                if (opcode_token & WINED3DSI_COISSUE)
+                {
+                    /* PixWin marks instructions with the coissue flag with a '+' */
+                    TRACE("+");
+                }
 
-                        shader_dump_ins_modifiers(param);
-                        TRACE(" ");
-                        shader_dump_param(iface, param, addr_token, 0);
+                TRACE("%s", curOpcode->name);
+
+                if (curOpcode->opcode == WINED3DSIO_IFC
+                        || curOpcode->opcode == WINED3DSIO_BREAKC)
+                {
+                    DWORD op = (opcode_token & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
+
+                    switch (op)
+                    {
+                        case COMPARISON_GT: TRACE("_gt"); break;
+                        case COMPARISON_EQ: TRACE("_eq"); break;
+                        case COMPARISON_GE: TRACE("_ge"); break;
+                        case COMPARISON_LT: TRACE("_lt"); break;
+                        case COMPARISON_NE: TRACE("_ne"); break;
+                        case COMPARISON_LE: TRACE("_le"); break;
+                        default: TRACE("_(%u)", op);
                     }
+                }
+                else if (curOpcode->opcode == WINED3DSIO_TEX
+                        && This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)
+                        && (opcode_token & WINED3DSI_TEXLD_PROJECT))
+                {
+                    TRACE("p");
+                }
 
-                    /* Predication token - already printed out, just skip it */
-                    if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) {
-                        pToken++;
-                        len++;
-                    }
+                /* Destination token */
+                if (curOpcode->dst_token)
+                {
+                    tokens_read = shader_get_param(pToken, This->baseShader.hex_version, &param, &addr_token);
+                    pToken += tokens_read;
+                    len += tokens_read;
 
-                    /* Other source tokens */
-                    for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i) {
+                    shader_dump_ins_modifiers(param);
+                    TRACE(" ");
+                    shader_dump_param(param, addr_token, 0, This->baseShader.hex_version);
+                }
 
-                        tokens_read = shader_get_param(iface, pToken, &param, &addr_token);
-                        pToken += tokens_read;
-                        len += tokens_read;
+                /* Predication token - already printed out, just skip it */
+                if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
+                {
+                    pToken++;
+                    len++;
+                }
 
-                        TRACE((i == 0)? " " : ", ");
-                        shader_dump_param(iface, param, addr_token, 1);
-                    }
+                /* Other source tokens */
+                for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i)
+                {
+                    tokens_read = shader_get_param(pToken, This->baseShader.hex_version, &param, &addr_token);
+                    pToken += tokens_read;
+                    len += tokens_read;
+
+                    TRACE((i == 0)? " " : ", ");
+                    shader_dump_param(param, addr_token, 1, This->baseShader.hex_version);
                 }
-                TRACE("\n");
             }
+            TRACE("\n");
         }
-        This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
-    } else {
-        This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
     }
+    This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
 }
 
 static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
@@ -1096,41 +1150,45 @@ static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types t
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 static void shader_none_cleanup(IWineD3DDevice *iface) {}
-static void shader_none_color_correction(SHADER_OPCODE_ARG* arg) {}
+static void shader_none_color_correction(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup) {}
 static void shader_none_destroy(IWineD3DBaseShader *iface) {}
 static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
 static void shader_none_free(IWineD3DDevice *iface) {}
 static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;}
-static void shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
     FIXME("NONE shader backend asked to generate a pixel shader\n");
+    return 0;
 }
 static void shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
     FIXME("NONE shader backend asked to generate a vertex shader\n");
 }
 
 #define GLINFO_LOCATION      (*gl_info)
-static void shader_none_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) {
+static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
+{
     /* Set the shader caps to 0 for the none shader backend */
     pCaps->VertexShaderVersion  = 0;
     pCaps->PixelShaderVersion    = 0;
     pCaps->PixelShader1xMaxValue = 0.0;
 }
 #undef GLINFO_LOCATION
-static BOOL shader_none_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking shader format support for format %s", debug_d3dformat(fmt));
-    switch(fmt) {
-        /* Faked to make some apps happy. */
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-        case WINED3DFMT_L6V5U5:
-        case WINED3DFMT_X8L8V8U8:
-        case WINED3DFMT_Q8W8V8U8:
-            TRACE("[OK]\n");
-            return TRUE;
-        default:
-            TRACE("[FAILED]\n");
-            return FALSE;
+static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+    {
+        TRACE("Checking support for fixup:\n");
+        dump_color_fixup_desc(fixup);
     }
+
+    /* Faked to make some apps happy. */
+    if (!is_yuv_fixup(fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
+    TRACE("[FAILED]\n");
+    return FALSE;
 }
 
 const shader_backend_t none_shader_backend = {
@@ -1148,7 +1206,7 @@ const shader_backend_t none_shader_backend = {
     shader_none_generate_pshader,
     shader_none_generate_vshader,
     shader_none_get_caps,
-    shader_none_conv_supported
+    shader_none_color_fixup_supported,
 };
 
 /* *******************************************
index 69574b2..158650e 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
-/* *******************************************
-   IWineD3DBaseTexture IUnknown parts follow
-   ******************************************* */
-HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface(IWineD3DBaseTexture *iface, REFIID riid, LPVOID *ppobj)
+void basetexture_cleanup(IWineD3DBaseTexture *iface)
 {
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IWineD3DBase)
-        || IsEqualGUID(riid, &IID_IWineD3DResource)
-        || IsEqualGUID(riid, &IID_IWineD3DBaseTexture)) {
-        IUnknown_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-ULONG WINAPI IWineD3DBaseTextureImpl_AddRef(IWineD3DBaseTexture *iface) {
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    ULONG ref = InterlockedIncrement(&This->resource.ref);
-
-    TRACE("(%p) : AddRef increasing from %d\n", This,ref - 1);
-    return ref;
-}
-
-ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->resource.ref);
-    TRACE("(%p) : Releasing from %d\n", This, ref + 1);
-    if (ref == 0) {
-        IWineD3DBaseTextureImpl_CleanUp(iface);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
-
-/* class static */
-void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
@@ -78,41 +40,12 @@ void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
         glDeleteTextures(1, &This->baseTexture.textureName);
         LEAVE_GL();
     }
-    IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
-}
 
-/* ****************************************************
-   IWineD3DBaseTexture IWineD3DResource parts follow
-   **************************************************** */
-HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice(IWineD3DBaseTexture *iface, IWineD3DDevice** ppDevice) {
-    return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
+    resource_cleanup((IWineD3DResource *)iface);
 }
 
-HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
-}
-
-HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
-}
-
-HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData(IWineD3DBaseTexture *iface, REFGUID refguid) {
-    return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
-}
-
-DWORD    WINAPI        IWineD3DBaseTextureImpl_SetPriority(IWineD3DBaseTexture *iface, DWORD PriorityNew) {
-    return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
-}
-
-DWORD    WINAPI        IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *iface) {
-    return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
-}
-
-void     WINAPI        IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface) {
-    IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
-}
-
-void     WINAPI        IWineD3DBaseTextureImpl_UnLoad(IWineD3DBaseTexture *iface) {
+void basetexture_unload(IWineD3DBaseTexture *iface)
+{
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
@@ -126,21 +59,10 @@ void     WINAPI        IWineD3DBaseTextureImpl_UnLoad(IWineD3DBaseTexture *iface
     This->baseTexture.dirty = TRUE;
 }
 
-WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface) {
-    return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
-}
-
-HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUnknown **pParent) {
-    return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
-}
-
-/* ******************************************************
-   IWineD3DBaseTexture IWineD3DBaseTexture parts follow
-   ****************************************************** */
-
 /* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading
  * so just pretend that they work unless something really needs a failure. */
-DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew) {
+DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 
     if (This->resource.pool != WINED3DPOOL_MANAGED) {
@@ -156,7 +78,8 @@ DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LO
     return This->baseTexture.LOD;
 }
 
-DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) {
+DWORD basetexture_get_lod(IWineD3DBaseTexture *iface)
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 
     if (This->resource.pool != WINED3DPOOL_MANAGED) {
@@ -168,13 +91,15 @@ DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) {
     return This->baseTexture.LOD;
 }
 
-DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
+DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface)
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
     return This->baseTexture.levels;
 }
 
-HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
+HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType)
+{
   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
   IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
   UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
@@ -216,7 +141,8 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture
   return WINED3D_OK;
 }
 
-WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) {
+WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture *iface)
+{
   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
   FIXME("(%p) : stub\n", This);
   if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
@@ -225,15 +151,16 @@ WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWi
   return This->baseTexture.filterType;
 }
 
-void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface) {
+void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface)
+{
   IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
   /* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */
   FIXME("(%p) : stub\n", This);
   return ;
 }
 
-/* Internal function, No d3d mapping */
-BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL dirty) {
+BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty)
+{
     BOOL old;
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     old = This->baseTexture.dirty;
@@ -241,12 +168,14 @@ BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL di
     return old;
 }
 
-BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface) {
+BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface)
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     return This->baseTexture.dirty;
 }
 
-HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
+HRESULT basetexture_bind(IWineD3DBaseTexture *iface)
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     HRESULT hr = WINED3D_OK;
     UINT textureDimensions;
@@ -330,32 +259,6 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
     return hr;
 }
 
-UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *iface){
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    FIXME("(%p) : This shouldn't be called\n", This);
-    return WINED3D_OK;
-}
-
-BOOL WINAPI IWineD3DBaseTextureImpl_IsCondNP2(IWineD3DBaseTexture *iface){
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    FIXME("(%p) : This shouldn't be called\n", This);
-    return FALSE;
-}
-
-static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
-    switch(Type) {
-    case WINED3DSAMP_ADDRESSU:
-        return GL_TEXTURE_WRAP_S;
-    case WINED3DSAMP_ADDRESSV:
-        return GL_TEXTURE_WRAP_T;
-    case WINED3DSAMP_ADDRESSW:
-        return GL_TEXTURE_WRAP_R;
-    default:
-        FIXME("Unexpected warp type %d\n", Type);
-        return 0;
-    }
-}
-
 static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type,
                               BOOL cond_np2) {
     GLint wrapParm;
@@ -381,9 +284,10 @@ static inline void apply_wrap(const GLint textureDimensions, const DWORD state,
     }
 }
 
-void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
-                                    const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
-                                    const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
+void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
+        const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
+        const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1])
+{
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
     DWORD state;
     GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
@@ -426,7 +330,7 @@ void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface
         if (state > WINED3DTEXF_ANISOTROPIC) {
             FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
         } else {
-            glValue = (*This->baseTexture.magLookup)[state - WINED3DTEXF_NONE];
+            glValue = This->baseTexture.magLookup[state - WINED3DTEXF_NONE];
             TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
             glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
             /* We need to reset the Anisotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentation to see how it should be switched off. */
@@ -455,9 +359,9 @@ void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface
                   This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
                   This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]);
         }
-        glValue = (*This->baseTexture.minMipLookup)
+        glValue = This->baseTexture.minMipLookup
                 [min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
-                [min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
+                .mip[min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
 
         TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
               samplerStates[WINED3DSAMP_MINFILTER],
@@ -487,38 +391,3 @@ void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface
         This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
     }
 }
-
-
-static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
-{
-    /* IUnknown */
-    IWineD3DBaseTextureImpl_QueryInterface,
-    IWineD3DBaseTextureImpl_AddRef,
-    IWineD3DBaseTextureImpl_Release,
-    /* IWineD3DResource */
-    IWineD3DBaseTextureImpl_GetParent,
-    IWineD3DBaseTextureImpl_GetDevice,
-    IWineD3DBaseTextureImpl_SetPrivateData,
-    IWineD3DBaseTextureImpl_GetPrivateData,
-    IWineD3DBaseTextureImpl_FreePrivateData,
-    IWineD3DBaseTextureImpl_SetPriority,
-    IWineD3DBaseTextureImpl_GetPriority,
-    IWineD3DBaseTextureImpl_PreLoad,
-    IWineD3DBaseTextureImpl_UnLoad,
-    IWineD3DBaseTextureImpl_GetType,
-    /*IWineD3DBaseTexture*/
-    IWineD3DBaseTextureImpl_SetLOD,
-    IWineD3DBaseTextureImpl_GetLOD,
-    IWineD3DBaseTextureImpl_GetLevelCount,
-    IWineD3DBaseTextureImpl_SetAutoGenFilterType,
-    IWineD3DBaseTextureImpl_GetAutoGenFilterType,
-    IWineD3DBaseTextureImpl_GenerateMipSubLevels,
-    IWineD3DBaseTextureImpl_SetDirty,
-    IWineD3DBaseTextureImpl_GetDirty,
-    /* internal */
-    IWineD3DBaseTextureImpl_BindTexture,
-    IWineD3DBaseTextureImpl_GetTextureDimensions,
-    IWineD3DBaseTextureImpl_IsCondNP2,
-    IWineD3DBaseTextureImpl_ApplyStateChanges
-
-};
index feb6e23..2d3184f 100644 (file)
@@ -96,7 +96,8 @@ static HRESULT WINAPI IWineD3DClipperImpl_SetHwnd(IWineD3DClipper *iface, DWORD
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, RECT *Rect, RGNDATA *ClipList, DWORD *Size)
+static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, const RECT *Rect,
+        RGNDATA *ClipList, DWORD *Size)
 {
     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
     TRACE("(%p,%p,%p,%p)\n", This, Rect, ClipList, Size);
@@ -140,7 +141,7 @@ static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, RE
     }
 }
 
-static HRESULT WINAPI IWineD3DClipperImpl_SetClipList(IWineD3DClipper *iface, RGNDATA *rgn, DWORD Flags)
+static HRESULT WINAPI IWineD3DClipperImpl_SetClipList(IWineD3DClipper *iface, const RGNDATA *rgn, DWORD Flags)
 {
     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
     static int warned = 0;
index acfe36b..05afe5d 100644 (file)
@@ -1253,7 +1253,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
      * the alpha blend state changes with different render target formats
      */
     if(oldFmt != newFmt) {
-        const GlPixelFormatDesc *glDesc;
+        const struct GlPixelFormatDesc *glDesc;
         const StaticPixelFormatDesc *old = getFormatDescEntry(oldFmt, NULL, NULL);
         const StaticPixelFormatDesc *new = getFormatDescEntry(newFmt, &GLINFO_LOCATION, &glDesc);
 
index 9ccb2d1..90b1221 100644 (file)
@@ -68,27 +68,27 @@ static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface)
    IWineD3DCubeTexture IWineD3DResource parts follow
    **************************************************** */
 static HRESULT WINAPI IWineD3DCubeTextureImpl_GetDevice(IWineD3DCubeTexture *iface, IWineD3DDevice** ppDevice) {
-    return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
+    return resource_get_device((IWineD3DResource *)iface, ppDevice);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_SetPrivateData(IWineD3DCubeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
+    return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_GetPrivateData(IWineD3DCubeTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
+    return resource_get_private_data((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_FreePrivateData(IWineD3DCubeTexture *iface, REFGUID refguid) {
-    return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
+    return resource_free_private_data((IWineD3DResource *)iface, refguid);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_SetPriority(IWineD3DCubeTexture *iface, DWORD PriorityNew) {
-    return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
+    return resource_set_priority((IWineD3DResource *)iface, PriorityNew);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_GetPriority(IWineD3DCubeTexture *iface) {
-    return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
+    return resource_get_priority((IWineD3DResource *)iface);
 }
 
 static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
@@ -176,52 +176,52 @@ static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) {
         }
     }
 
-    IWineD3DBaseTextureImpl_UnLoad((IWineD3DBaseTexture *) iface);
+    basetexture_unload((IWineD3DBaseTexture *)iface);
 }
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DCubeTextureImpl_GetType(IWineD3DCubeTexture *iface) {
-    return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
+    return resource_get_type((IWineD3DResource *)iface);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_GetParent(IWineD3DCubeTexture *iface, IUnknown **pParent) {
-    return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
+    return resource_get_parent((IWineD3DResource *)iface, pParent);
 }
 
 /* ******************************************************
    IWineD3DCubeTexture IWineD3DBaseTexture parts follow
    ****************************************************** */
 static DWORD WINAPI IWineD3DCubeTextureImpl_SetLOD(IWineD3DCubeTexture *iface, DWORD LODNew) {
-    return IWineD3DBaseTextureImpl_SetLOD((IWineD3DBaseTexture *)iface, LODNew);
+    return basetexture_set_lod((IWineD3DBaseTexture *)iface, LODNew);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_GetLOD(IWineD3DCubeTexture *iface) {
-    return IWineD3DBaseTextureImpl_GetLOD((IWineD3DBaseTexture *)iface);
+    return basetexture_get_lod((IWineD3DBaseTexture *)iface);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_GetLevelCount(IWineD3DCubeTexture *iface) {
-    return IWineD3DBaseTextureImpl_GetLevelCount((IWineD3DBaseTexture *)iface);
+    return basetexture_get_level_count((IWineD3DBaseTexture *)iface);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_SetAutoGenFilterType(IWineD3DCubeTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
-  return IWineD3DBaseTextureImpl_SetAutoGenFilterType((IWineD3DBaseTexture *)iface, FilterType);
+  return basetexture_set_autogen_filter_type((IWineD3DBaseTexture *)iface, FilterType);
 }
 
 static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DCubeTextureImpl_GetAutoGenFilterType(IWineD3DCubeTexture *iface) {
-  return IWineD3DBaseTextureImpl_GetAutoGenFilterType((IWineD3DBaseTexture *)iface);
+  return basetexture_get_autogen_filter_type((IWineD3DBaseTexture *)iface);
 }
 
 static void WINAPI IWineD3DCubeTextureImpl_GenerateMipSubLevels(IWineD3DCubeTexture *iface) {
-    IWineD3DBaseTextureImpl_GenerateMipSubLevels((IWineD3DBaseTexture *)iface);
+    basetexture_generate_mipmaps((IWineD3DBaseTexture *)iface);
 }
 
 /* Internal function, No d3d mapping */
 static BOOL WINAPI IWineD3DCubeTextureImpl_SetDirty(IWineD3DCubeTexture *iface, BOOL dirty) {
-    return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty);
+    return basetexture_set_dirty((IWineD3DBaseTexture *)iface, dirty);
 }
 
 /* Internal function, No d3d mapping */
 static BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface) {
-    return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface);
+    return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface) {
@@ -231,7 +231,7 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *i
 
     TRACE("(%p) : relay to BaseTexture\n", This);
 
-    hr = IWineD3DBaseTextureImpl_BindTexture((IWineD3DBaseTexture *)iface);
+    hr = basetexture_bind((IWineD3DBaseTexture *)iface);
     if (set_gl_texture_desc && SUCCEEDED(hr)) {
         UINT i, j;
         for (i = 0; i < This->baseTexture.levels; ++i) {
@@ -262,7 +262,7 @@ static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture
                                                         const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], 
                                                         const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
     TRACE("(%p) : relay to BaseTexture\n", iface);
-    IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
+    basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
 }
 
 
@@ -286,7 +286,7 @@ static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D
             }
         }
     }
-    IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface);
+    basetexture_cleanup((IWineD3DBaseTexture *)iface);
     /* finally delete the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
index 0cb539b..836ad3b 100644 (file)
@@ -52,7 +52,7 @@ const WINED3DLIGHT WINED3D_default_light = {
 };
 
 /* static function declarations */
-static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
+static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
 
 /* helper macros */
 #define D3DMEMCHECK(object, ppResult) if(NULL == object) { *ppResult = NULL; WARN("Out of memory\n"); return WINED3DERR_OUTOFVIDEOMEMORY;}
@@ -457,12 +457,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
         object->num_contained_ps_consts_f = GL_LIMITS(pshader_constantsF);
         for (i = 0; i < MAX_CONST_B; ++i) {
             object->contained_ps_consts_b[i] = i;
-            object->changed.pixelShaderConstantsB[i] = TRUE;
+            object->changed.pixelShaderConstantsB |= (1 << i);
         }
         object->num_contained_ps_consts_b = MAX_CONST_B;
         for (i = 0; i < MAX_CONST_I; ++i) {
             object->contained_ps_consts_i[i] = i;
-            object->changed.pixelShaderConstantsI[i] = TRUE;
+            object->changed.pixelShaderConstantsI |= (1 << i);
         }
         object->num_contained_ps_consts_i = MAX_CONST_I;
 
@@ -514,13 +514,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
         }
         object->num_contained_vs_consts_f = GL_LIMITS(vshader_constantsF);
         for (i = 0; i < MAX_CONST_B; ++i) {
-            object->changed.vertexShaderConstantsB[i] = TRUE;
             object->contained_vs_consts_b[i] = i;
+            object->changed.vertexShaderConstantsB |= (1 << i);
         }
         object->num_contained_vs_consts_b = MAX_CONST_B;
         for (i = 0; i < MAX_CONST_I; ++i) {
-            object->changed.vertexShaderConstantsI[i] = TRUE;
             object->contained_vs_consts_i[i] = i;
+            object->changed.vertexShaderConstantsI |= (1 << i);
         }
         object->num_contained_vs_consts_i = MAX_CONST_I;
         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
@@ -587,7 +587,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;    
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
     unsigned int Size       = 1;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
     UINT mul_4w, mul_4h;
     TRACE("(%p) Create surface\n",This);
@@ -759,7 +759,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
     HRESULT hr;
     unsigned int pow2Width;
     unsigned int pow2Height;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
 
     TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
@@ -779,11 +779,11 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
     object->height = Height;
 
     if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING) {
-        object->baseTexture.minMipLookup = &minMipLookup;
-        object->baseTexture.magLookup    = &magLookup;
+        object->baseTexture.minMipLookup = minMipLookup;
+        object->baseTexture.magLookup    = magLookup;
     } else {
-        object->baseTexture.minMipLookup = &minMipLookup_noFilter;
-        object->baseTexture.magLookup    = &magLookup_noFilter;
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
+        object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
     /** Non-power2 support **/
@@ -821,7 +821,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
         object->baseTexture.pow2Matrix[15] = 1.0;
         object->target = GL_TEXTURE_2D;
         object->cond_np2 = TRUE;
-        object->baseTexture.minMipLookup = &minMipLookup_noFilter;
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
     } else if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE) &&
        (Width != pow2Width || Height != pow2Height) &&
        !((Format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE) && (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
@@ -832,7 +832,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
         object->baseTexture.pow2Matrix[15] = 1.0;
         object->target = GL_TEXTURE_RECTANGLE_ARB;
         object->cond_np2 = TRUE;
-        object->baseTexture.minMipLookup = &minMipLookup_noFilter;
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
     } else {
         object->baseTexture.pow2Matrix[0] =  (((float)Width)  / ((float)pow2Width));
         object->baseTexture.pow2Matrix[5] =  (((float)Height) / ((float)pow2Height));
@@ -891,7 +891,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
         tmpW = max(1, tmpW >> 1);
         tmpH = max(1, tmpH >> 1);
     }
-    object->baseTexture.shader_conversion_group = glDesc->conversion_group;
+    object->baseTexture.shader_color_fixup = glDesc->color_fixup;
 
     TRACE("(%p) : Created  texture %p\n", This, object);
     return WINED3D_OK;
@@ -911,7 +911,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     UINT                       tmpW;
     UINT                       tmpH;
     UINT                       tmpD;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
 
     getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
 
@@ -932,10 +932,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
           Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
 
-    object->width  = Width;
-    object->height = Height;
-    object->depth  = Depth;
-
     /* Is NP2 support for volumes needed? */
     object->baseTexture.pow2Matrix[ 0] = 1.0;
     object->baseTexture.pow2Matrix[ 5] = 1.0;
@@ -943,11 +939,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     object->baseTexture.pow2Matrix[15] = 1.0;
 
     if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING) {
-        object->baseTexture.minMipLookup = &minMipLookup;
-        object->baseTexture.magLookup    = &magLookup;
+        object->baseTexture.minMipLookup = minMipLookup;
+        object->baseTexture.magLookup    = magLookup;
     } else {
-        object->baseTexture.minMipLookup = &minMipLookup_noFilter;
-        object->baseTexture.magLookup    = &magLookup_noFilter;
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
+        object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
     /* Calculate levels for mip mapping */
@@ -1002,7 +998,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
         tmpH = max(1, tmpH >> 1);
         tmpD = max(1, tmpD >> 1);
     }
-    object->baseTexture.shader_conversion_group = glDesc->conversion_group;
+    object->baseTexture.shader_color_fixup = glDesc->color_fixup;
 
     *ppVolumeTexture = (IWineD3DVolumeTexture *) object;
     TRACE("(%p) : Created volume texture %p\n", This, object);
@@ -1057,7 +1053,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
     UINT                     tmpW;
     HRESULT                  hr;
     unsigned int pow2EdgeLength;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
 
     /* TODO: It should only be possible to create textures for formats 
@@ -1081,8 +1077,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
     pow2EdgeLength = 1;
     while (pow2EdgeLength < EdgeLength) pow2EdgeLength <<= 1;
 
-    object->edgeLength           = EdgeLength;
-
     if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
         /* Precalculated scaling for 'faked' non power of two texture coords */
         object->baseTexture.pow2Matrix[ 0] = 1.0;
@@ -1098,11 +1092,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
     }
 
     if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING) {
-        object->baseTexture.minMipLookup = &minMipLookup;
-        object->baseTexture.magLookup    = &magLookup;
+        object->baseTexture.minMipLookup = minMipLookup;
+        object->baseTexture.magLookup    = magLookup;
     } else {
-        object->baseTexture.minMipLookup = &minMipLookup_noFilter;
-        object->baseTexture.magLookup    = &magLookup_noFilter;
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
+        object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
     /* Calculate levels for mip mapping */
@@ -1174,7 +1168,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
         }
         tmpW = max(1, tmpW >> 1);
     }
-    object->baseTexture.shader_conversion_group = glDesc->conversion_group;
+    object->baseTexture.shader_color_fixup = glDesc->color_fixup;
 
     TRACE("(%p) : Created Cube Texture %p\n", This, object);
     *ppCubeTexture = (IWineD3DCubeTexture *) object;
@@ -1243,13 +1237,19 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
 
         if(GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
             TRACE("(%p) Allocating data for an occlusion query\n", This);
+
+            ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            ENTER_GL();
             GL_EXTCALL(glGenQueriesARB(1, &((WineQueryOcclusionData *)(object->extendedData))->queryId));
+            LEAVE_GL();
             break;
         }
     case WINED3DQUERYTYPE_EVENT:
         object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
         ((WineQueryEventData *)(object->extendedData))->ctx = This->activeContext;
 
+        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ENTER_GL();
         if(GL_SUPPORT(APPLE_FENCE)) {
             GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
             checkGLcall("glGenFencesAPPLE");
@@ -1257,6 +1257,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
             GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
             checkGLcall("glGenFencesNV");
         }
+        LEAVE_GL();
         break;
 
     case WINED3DQUERYTYPE_VCACHE:
@@ -1311,7 +1312,7 @@ static LONG fullscreen_exStyle(LONG orig_exStyle) {
     return exStyle;
 }
 
-static void WINAPI IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *iface, HWND window, UINT w, UINT h) {
+static void IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *iface, HWND window, UINT w, UINT h) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     LONG style, exStyle;
@@ -1355,7 +1356,7 @@ static void WINAPI IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *ifac
  *  window: Window to setup
  *
  *****************************************************************************/
-static void WINAPI IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window) {
+static void IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     LONG style, exStyle;
 
@@ -1934,7 +1935,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface
     return hr;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DWORD Flags, PALETTEENTRY *PalEnt, IWineD3DPalette **Palette, IUnknown *Parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DWORD Flags,
+        const PALETTEENTRY *PalEnt, IWineD3DPalette **Palette, IUnknown *Parent)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DPaletteImpl *object;
     HRESULT hr;
@@ -2478,7 +2481,8 @@ static void WINAPI IWineD3DDeviceImpl_SetMultithreaded(IWineD3DDevice *iface) {
     return;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, WINED3DDISPLAYMODE* pMode) {
+static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain,
+        const WINED3DDISPLAYMODE* pMode) {
     DEVMODEW devmode;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     LONG ret;
@@ -2772,7 +2776,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetTransform(IWineD3DDevice *iface, WIN
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_MultiplyTransform(IWineD3DDevice *iface, WINED3DTRANSFORMSTATETYPE State, CONST WINED3DMATRIX* pMatrix) {
-    WINED3DMATRIX *mat = NULL;
+    const WINED3DMATRIX *mat = NULL;
     WINED3DMATRIX temp;
 
     /* Note: Using 'updateStateBlock' rather than 'stateblock' in the code
@@ -3541,7 +3545,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB(
         TRACE("Set BOOL constant %u to %s\n", start + i, srcData[i]? "true":"false");
 
     for (i = start; i < cnt + start; ++i) {
-        This->updateStateBlock->changed.vertexShaderConstantsB[i] = TRUE;
+        This->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
@@ -3589,7 +3593,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI(
            srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
 
     for (i = start; i < cnt + start; ++i) {
-        This->updateStateBlock->changed.vertexShaderConstantsI[i] = TRUE;
+        This->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
@@ -3806,7 +3810,8 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
 }
 
 static void device_map_psamplers(IWineD3DDeviceImpl *This) {
-    DWORD *sampler_tokens = ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.samplers;
+    const DWORD *sampler_tokens =
+            ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.samplers;
     int i;
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
@@ -3820,7 +3825,9 @@ static void device_map_psamplers(IWineD3DDeviceImpl *This) {
     }
 }
 
-static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, DWORD *pshader_sampler_tokens, DWORD *vshader_sampler_tokens, int unit) {
+static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshader_sampler_tokens,
+        const DWORD *vshader_sampler_tokens, int unit)
+{
     int current_mapping = This->rev_tex_unit_map[unit];
 
     if (current_mapping == -1) {
@@ -3845,8 +3852,9 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, DWORD *pshader_sam
 }
 
 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
-    DWORD *vshader_sampler_tokens = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.samplers;
-    DWORD *pshader_sampler_tokens = NULL;
+    const DWORD *vshader_sampler_tokens =
+            ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.samplers;
+    const DWORD *pshader_sampler_tokens = NULL;
     int start = GL_LIMITS(combined_samplers) - 1;
     int i;
 
@@ -3854,7 +3862,7 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
         IWineD3DPixelShaderImpl *pshader = (IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader;
 
         /* Make sure the shader's reg_maps are up to date. This is only relevant for 1.x pixelshaders. */
-        IWineD3DPixelShader_CompileShader((IWineD3DPixelShader *)pshader);
+        IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *)pshader);
         pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
     }
 
@@ -3970,7 +3978,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(
         TRACE("Set BOOL constant %u to %s\n", start + i, srcData[i]? "true":"false");
 
     for (i = start; i < cnt + start; ++i) {
-        This->updateStateBlock->changed.pixelShaderConstantsB[i] = TRUE;
+        This->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
@@ -4018,7 +4026,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(
            srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
 
     for (i = start; i < cnt + start; ++i) {
-        This->updateStateBlock->changed.pixelShaderConstantsI[i] = TRUE;
+        This->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
@@ -4140,8 +4148,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
 }
 
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
-static HRESULT
-process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, WineDirect3DVertexStridedData *lpStrideData, IWineD3DVertexBufferImpl *dest, DWORD dwFlags) {
+static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount,
+        const WineDirect3DVertexStridedData *lpStrideData, IWineD3DVertexBufferImpl *dest, DWORD dwFlags)
+{
     char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL;
     unsigned int i;
     DWORD DestFVF = dest->fvf;
@@ -4173,7 +4182,7 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
             return E_OUTOFMEMORY;
         }
         if(dest->vbo) {
-            void *src;
+            const void *src;
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->vbo));
             checkGLcall("glBindBufferARB");
             src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB));
@@ -4274,8 +4283,8 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
         if ( ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) ||
              ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) {
             /* The position first */
-            float *p =
-              (float *) (((char *) lpStrideData->u.s.position.lpData) + i * lpStrideData->u.s.position.dwStride);
+            const float *p =
+                    (const float *)(lpStrideData->u.s.position.lpData + i * lpStrideData->u.s.position.dwStride);
             float x, y, z, rhw;
             TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
 
@@ -4390,8 +4399,8 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
             if(dest_conv) dest_conv += sizeof(DWORD);
         }
         if (DestFVF & WINED3DFVF_NORMAL) {
-            float *normal =
-              (float *) (((float *) lpStrideData->u.s.normal.lpData) + i * lpStrideData->u.s.normal.dwStride);
+            const float *normal =
+                    (const float *)(lpStrideData->u.s.normal.lpData + i * lpStrideData->u.s.normal.dwStride);
             /* AFAIK this should go into the lighting information */
             FIXME("Didn't expect the destination to have a normal\n");
             copy_and_next(dest_ptr, normal, 3 * sizeof(float));
@@ -4401,8 +4410,8 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
         }
 
         if (DestFVF & WINED3DFVF_DIFFUSE) {
-            DWORD *color_d = 
-              (DWORD *) (((char *) lpStrideData->u.s.diffuse.lpData) + i * lpStrideData->u.s.diffuse.dwStride);
+            const DWORD *color_d =
+                    (const DWORD *)(lpStrideData->u.s.diffuse.lpData + i * lpStrideData->u.s.diffuse.dwStride);
             if(!color_d) {
                 static BOOL warned = FALSE;
 
@@ -4432,8 +4441,8 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
 
         if (DestFVF & WINED3DFVF_SPECULAR) { 
             /* What's the color value in the feedback buffer? */
-            DWORD *color_s = 
-              (DWORD *) (((char *) lpStrideData->u.s.specular.lpData) + i * lpStrideData->u.s.specular.dwStride);
+            const DWORD *color_s =
+                    (const DWORD *)(lpStrideData->u.s.specular.lpData + i * lpStrideData->u.s.specular.dwStride);
             if(!color_s) {
                 static BOOL warned = FALSE;
 
@@ -4462,8 +4471,8 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
         }
 
         for (tex_index = 0; tex_index < numTextures; tex_index++) {
-            float *tex_coord =
-              (float *) (((char *) lpStrideData->u.s.texCoords[tex_index].lpData) + 
+            const float *tex_coord =
+                    (const float *)(lpStrideData->u.s.texCoords[tex_index].lpData +
                             i * lpStrideData->u.s.texCoords[tex_index].dwStride);
             if(!tex_coord) {
                 ERR("No source texture, but destination requests one\n");
@@ -4901,25 +4910,29 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW
         }
     }
     for(i = 0; i < MAX_CONST_I; i++) {
-        if(object->changed.vertexShaderConstantsI[i]) {
+        if (object->changed.vertexShaderConstantsI & (1 << i))
+        {
             object->contained_vs_consts_i[object->num_contained_vs_consts_i] = i;
             object->num_contained_vs_consts_i++;
         }
     }
     for(i = 0; i < MAX_CONST_B; i++) {
-        if(object->changed.vertexShaderConstantsB[i]) {
+        if (object->changed.vertexShaderConstantsB & (1 << i))
+        {
             object->contained_vs_consts_b[object->num_contained_vs_consts_b] = i;
             object->num_contained_vs_consts_b++;
         }
     }
     for(i = 0; i < MAX_CONST_I; i++) {
-        if(object->changed.pixelShaderConstantsI[i]) {
+        if (object->changed.pixelShaderConstantsI & (1 << i))
+        {
             object->contained_ps_consts_i[object->num_contained_ps_consts_i] = i;
             object->num_contained_ps_consts_i++;
         }
     }
     for(i = 0; i < MAX_CONST_B; i++) {
-        if(object->changed.pixelShaderConstantsB[i]) {
+        if (object->changed.pixelShaderConstantsB & (1 << i))
+        {
             object->contained_ps_consts_b[object->num_contained_ps_consts_b] = i;
             object->num_contained_ps_consts_b++;
         }
@@ -5018,7 +5031,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
     unsigned int   i;
     WINED3DRECT curRect;
     RECT vp_rect;
-    WINED3DVIEWPORT *vp = &This->stateBlock->viewport;
+    const WINED3DVIEWPORT *vp = &This->stateBlock->viewport;
     UINT drawable_width, drawable_height;
     IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
     IWineD3DSwapChainImpl *swapchain = NULL;
@@ -5131,7 +5144,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
         /* Now process each rect in turn */
         for (i = 0; i < Count; i++) {
             /* Note gl uses lower left, width/height */
-            IntersectRect((RECT *) &curRect, &vp_rect, (RECT *) &pRects[i]);
+            IntersectRect((RECT *)&curRect, &vp_rect, (const RECT *)&pRects[i]);
             if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
                 IntersectRect((RECT *) &curRect, (RECT *) &curRect, &This->stateBlock->scissorRect);
             }
@@ -5399,7 +5412,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided (IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData) {
+static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided(IWineD3DDevice *iface,
+        WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
+        const WineDirect3DVertexStridedData *DrawPrimStrideData)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
 
     /* Mark the state dirty until we have nicer tracking
@@ -5415,7 +5431,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided (IWineD3DDevice *i
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData, UINT NumVertices, CONST void *pIndexData, WINED3DFORMAT IndexDataFormat) {
+static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDevice *iface,
+        WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
+        const WineDirect3DVertexStridedData *DrawPrimStrideData, UINT NumVertices, const void *pIndexData,
+        WINED3DFORMAT IndexDataFormat)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     DWORD idxSize = (IndexDataFormat == WINED3DFMT_INDEX32 ? 4 : 2);
 
@@ -5607,7 +5627,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetFrontBufferData(IWineD3DDevice *if
 static HRESULT  WINAPI  IWineD3DDeviceImpl_ValidateDevice(IWineD3DDevice *iface, DWORD* pNumPasses) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DBaseTextureImpl *texture;
-    const GlPixelFormatDesc *gl_info;
+    const struct GlPixelFormatDesc *gl_info;
     DWORD i;
 
     TRACE("(%p) : %p\n", This, pNumPasses);
@@ -5759,10 +5779,11 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetCurrentTexturePalette(IWineD3DDevi
 
 static HRESULT  WINAPI  IWineD3DDeviceImpl_SetSoftwareVertexProcessing(IWineD3DDevice *iface, BOOL bSoftware) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    static BOOL showFixmes = TRUE;
-    if (showFixmes) {
+    static BOOL warned;
+    if (!warned)
+    {
         FIXME("(%p) : stub\n", This);
-        showFixmes = FALSE;
+        warned = TRUE;
     }
 
     This->softwareVertexProcessing = bSoftware;
@@ -5772,10 +5793,11 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetSoftwareVertexProcessing(IWineD3DD
 
 static BOOL     WINAPI  IWineD3DDeviceImpl_GetSoftwareVertexProcessing(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    static BOOL showFixmes = TRUE;
-    if (showFixmes) {
+    static BOOL warned;
+    if (!warned)
+    {
         FIXME("(%p) : stub\n", This);
-        showFixmes = FALSE;
+        warned = TRUE;
     }
     return This->softwareVertexProcessing;
 }
@@ -5801,11 +5823,12 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetRasterStatus(IWineD3DDevice *iface
 
 static HRESULT  WINAPI  IWineD3DDeviceImpl_SetNPatchMode(IWineD3DDevice *iface, float nSegments) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    static BOOL showfixmes = TRUE;
+    static BOOL warned;
     if(nSegments != 0.0f) {
-        if( showfixmes) {
+        if (!warned)
+        {
             FIXME("(%p) : stub nSegments(%f)\n", This, nSegments);
-            showfixmes = FALSE;
+            warned = TRUE;
         }
     }
     return WINED3D_OK;
@@ -5813,10 +5836,11 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetNPatchMode(IWineD3DDevice *iface,
 
 static float    WINAPI  IWineD3DDeviceImpl_GetNPatchMode(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    static BOOL showfixmes = TRUE;
-    if( showfixmes) {
+    static BOOL warned;
+    if (!warned)
+    {
         FIXME("(%p) : stub returning(%f)\n", This, 0.0f);
-        showfixmes = FALSE;
+        warned = TRUE;
     }
     return 0.0f;
 }
@@ -5875,7 +5899,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
         return IWineD3DSurface_BltFast(pDestinationSurface,
                                         pDestPoint  ? pDestPoint->x : 0,
                                         pDestPoint  ? pDestPoint->y : 0,
-                                        pSourceSurface, (RECT *) pSourceRect, 0);
+                                        pSourceSurface, pSourceRect, 0);
     }
 
     if (destFormat == WINED3DFMT_UNKNOWN) {
@@ -6319,7 +6343,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD
         memset(&BltFx, 0, sizeof(BltFx));
         BltFx.dwSize = sizeof(BltFx);
         BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format);
-        return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+        return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
+                WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
     }
 }
 
@@ -6443,7 +6468,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
 }
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
-        IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
+        IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
     IWineD3DSwapChain *src_swapchain, *dst_swapchain;
@@ -6736,7 +6762,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
             This->cursorHeight = pSur->currentDesc.Height;
             if (SUCCEEDED(IWineD3DSurface_LockRect(pCursorBitmap, &rect, NULL, WINED3DLOCK_READONLY)))
             {
-                const GlPixelFormatDesc *glDesc;
+                const struct GlPixelFormatDesc *glDesc;
                 const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &GLINFO_LOCATION, &glDesc);
                 char *mem, *bits = (char *)rect.pBits;
                 GLint intfmt = glDesc->glInternal;
@@ -6914,7 +6940,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice*
     return WINED3D_OK;
 }
 
-static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
+static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT_PARAMETERS* pPresentationParameters)
+{
     IWineD3DDeviceImpl *This = surface->resource.wineD3DDevice; /* for GL_SUPPORT */
 
     /* Reallocate proper memory for the front and back buffer and adjust their sizes */
@@ -6977,7 +7004,8 @@ static HRESULT WINAPI reset_unload_resources(IWineD3DResource *resource, void *d
     return S_OK;
 }
 
-static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, WINED3DPRESENT_PARAMETERS *pp) {
+static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRESENT_PARAMETERS *pp)
+{
     UINT i, count;
     WINED3DDISPLAYMODE m;
     HRESULT hr;
@@ -7291,7 +7319,7 @@ static void WINAPI IWineD3DDeviceImpl_SetGammaRamp(IWineD3DDevice * iface, UINT
     TRACE("Relaying  to swapchain\n");
 
     if (IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, &swapchain) == WINED3D_OK) {
-        IWineD3DSwapChain_SetGammaRamp(swapchain, Flags, (WINED3DGAMMARAMP *)pRamp);
+        IWineD3DSwapChain_SetGammaRamp(swapchain, Flags, pRamp);
         IWineD3DSwapChain_Release(swapchain);
     }
     return;
@@ -7318,14 +7346,14 @@ static void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT i
 * any handles to other resource held by the caller must be closed
 * (e.g. a texture should release all held surfaces because telling the device that it's been released.)
  *****************************************************/
-static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){
+static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     TRACE("(%p) : Adding Resource %p\n", This, resource);
     list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
-static void WINAPI IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){
+static void IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     TRACE("(%p) : Removing resource %p\n", This, resource);
index 4a1846a..253860f 100644 (file)
@@ -154,20 +154,30 @@ static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYP
 static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType);
 
 /* lookup tables */
-int minLookup[MAX_LOOKUPS];
-int maxLookup[MAX_LOOKUPS];
+const int minLookup[MAX_LOOKUPS] =
+{
+    WINED3DTADDRESS_WRAP, /* WINELOOKUP_WARPPARAM */
+};
+
+const int maxLookup[MAX_LOOKUPS] =
+{
+    WINED3DTADDRESS_MIRRORONCE, /* WINELOOKUP_WARPPARAM */
+};
+
 DWORD *stateLookup[MAX_LOOKUPS];
 
-DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
-DWORD minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1] = {
-    {GL_NEAREST, GL_NEAREST, GL_NEAREST},
-    {GL_NEAREST, GL_NEAREST, GL_NEAREST},
-    {GL_NEAREST, GL_NEAREST, GL_NEAREST},
-    {GL_NEAREST, GL_NEAREST, GL_NEAREST},
+struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+{
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
 };
 
-DWORD magLookup[WINED3DTEXF_ANISOTROPIC + 1];
-DWORD magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] = {
+GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+{
     GL_NEAREST, GL_NEAREST, GL_NEAREST, GL_NEAREST
 };
 
@@ -367,12 +377,8 @@ static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
 /* Set the shader type for this device, depending on the given capabilities,
  * the device type, and the user preferences in wined3d_settings */
 
-void select_shader_mode(
-    WineD3D_GL_Info *gl_info,
-    WINED3DDEVTYPE DeviceType,
-    int* ps_selected,
-    int* vs_selected) {
-
+static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
+{
     if (wined3d_settings.vs_mode == VS_NONE) {
         *vs_selected = SHADER_NONE;
     } else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
@@ -450,7 +456,8 @@ static void select_shader_max_constants(
  **********************************************************/
 
 #define GLINFO_LOCATION (*gl_info)
-static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) {
+static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
+{
     GLuint prog;
     BOOL ret = FALSE;
     const char *testcode =
@@ -494,7 +501,7 @@ static DWORD ver_for_ext(GL_SupportedExt ext)
     return 0;
 }
 
-BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
+static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     const char *GL_Extensions    = NULL;
     const char *WGL_Extensions   = NULL;
     const char *gl_string        = NULL;
@@ -1075,8 +1082,13 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
              */
             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
+                /* Geforce GTX - highend */
+                if(strstr(gl_info->gl_renderer, "GTX 280")) {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280;
+                    vidmem = 1024;
+                }
                 /* Geforce9 - highend */
-                if(strstr(gl_info->gl_renderer, "9800")) {
+                else if(strstr(gl_info->gl_renderer, "9800")) {
                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT;
                     vidmem = 512;
                 }
@@ -1336,11 +1348,7 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     else
         gl_info->vidmem = WINE_DEFAULT_VIDMEM;
 
-    /* Load all the lookup tables
-    TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
-    minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
-    maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
-
+    /* Load all the lookup tables */
     for (i = 0; i < MAX_LOOKUPS; i++) {
         stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
     }
@@ -1363,19 +1371,21 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
              gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
 
 
-    minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE]     = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT]    = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR]   = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE]    = GL_NEAREST;
-    minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
-    minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
-    minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE]   = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
-    minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE]   = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
-    GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT]  = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
+    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_NONE]     = GL_LINEAR;
+    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_POINT]    = GL_LINEAR;
+    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_LINEAR]   = GL_LINEAR;
+    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_NONE]    = GL_NEAREST;
+    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
+    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
+    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_NONE]   = GL_LINEAR;
+    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
+    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
+    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_NONE]
+            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
+    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_POINT]
+            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
+    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_LINEAR]
+            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
 
 /* TODO: config lookups */
 
@@ -1527,7 +1537,7 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
     if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
         DEVMODEW DevModeW;
         int ModeIdx = 0;
-        int i = 0;
+        UINT i = 0;
         int j = 0;
 
         ZeroMemory(&DevModeW, sizeof(DevModeW));
@@ -1665,6 +1675,18 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad
     *(pIdentifier->Revision) = 0;
     *pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
 
+    if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
+    {
+        TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
+        *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
+    }
+
+    if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
+    {
+        TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
+        *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
+    }
+
     if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
         *(pIdentifier->WHQLLevel) = 0;
     } else {
@@ -1755,7 +1777,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT
                                                    WINED3DFORMAT DepthStencilFormat) {
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
     int nCfgs;
-    WineD3D_PixelFormat *cfgs;
+    const WineD3D_PixelFormat *cfgs;
     int it;
 
     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
@@ -1790,7 +1812,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
                                                        BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
 
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *desc;
 
     TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
@@ -1823,7 +1845,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
 
     if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
         int i, nCfgs;
-        WineD3D_PixelFormat *cfgs;
+        const WineD3D_PixelFormat *cfgs;
 
         cfgs = Adapters[Adapter].cfgs;
         nCfgs = Adapters[Adapter].nCfgs;
@@ -1844,7 +1866,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
     else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
         short redSize, greenSize, blueSize, alphaSize, colorBits;
         int i, nCfgs;
-        WineD3D_PixelFormat *cfgs;
+        const WineD3D_PixelFormat *cfgs;
 
         if(!getColorBits(SurfaceFormat, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
             ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
@@ -1965,7 +1987,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter
 static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
 {
     const struct fragment_pipeline *fp;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
 
     switch(CheckFormat) {
         case WINED3DFMT_V8U8:
@@ -1973,24 +1995,18 @@ static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
         case WINED3DFMT_L6V5U5:
         case WINED3DFMT_X8L8V8U8:
         case WINED3DFMT_Q8W8V8U8:
+            /* Ask the fixed function pipeline implementation if it can deal
+             * with the conversion. If we've got a GL extension giving native
+             * support this will be an identity conversion. */
             getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
-            if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
-                /* We have a GL extension giving native support */
-                TRACE_(d3d_caps)("[OK]\n");
-                return TRUE;
-            }
-
-            /* No native support: Ask the fixed function pipeline implementation if it
-             * can deal with the conversion
-             */
             fp = select_fragment_implementation(Adapter, DeviceType);
-            if(fp->conv_supported(CheckFormat)) {
+            if (fp->color_fixup_supported(glDesc->color_fixup))
+            {
                 TRACE_(d3d_caps)("[OK]\n");
                 return TRUE;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return FALSE;
             }
+            TRACE_(d3d_caps)("[FAILED]\n");
+            return FALSE;
 
         default:
             TRACE_(d3d_caps)("[FAILED]\n");
@@ -2002,7 +2018,7 @@ static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
 static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayFormat, WINED3DFORMAT DepthStencilFormat)
 {
     int it=0;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *desc = getFormatDescEntry(DepthStencilFormat, &GLINFO_LOCATION, &glDesc);
 
     /* Fail if we weren't able to get a description of the format */
@@ -2028,7 +2044,7 @@ static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayForma
 
 static BOOL CheckFilterCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
 {
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
 
     /* Fail if we weren't able to get a description of the format */
@@ -2046,7 +2062,7 @@ static BOOL CheckFilterCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
 static BOOL CheckRenderTargetCapability(WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat)
 {
     UINT Adapter = 0;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
 
     /* Fail if we weren't able to get a description of the format */
@@ -2153,7 +2169,7 @@ static BOOL CheckSrgbWriteCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WI
 /* Check if a format support blending in combination with pixel shaders */
 static BOOL CheckPostPixelShaderBlendingCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
 {
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
 
     /* Fail if we weren't able to get a description of the format */
@@ -2185,7 +2201,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
 {
     const shader_backend_t *shader_backend;
     const struct fragment_pipeline *fp;
-    const GlPixelFormatDesc *glDesc;
+    const struct GlPixelFormatDesc *glDesc;
 
     switch (CheckFormat) {
 
@@ -2260,25 +2276,18 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
         case WINED3DFMT_L6V5U5:
         case WINED3DFMT_Q8W8V8U8:
         case WINED3DFMT_V16U16:
-        case WINED3DFMT_W11V11U10:
+            /* Ask the shader backend if it can deal with the conversion. If
+             * we've got a GL extension giving native support this will be an
+             * identity conversion. */
             getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
-            if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
-                /* We have a GL extension giving native support */
-                TRACE_(d3d_caps)("[OK]\n");
-                return TRUE;
-            }
-
-            /* No native support: Ask the fixed function pipeline implementation if it
-             * can deal with the conversion
-             */
             shader_backend = select_shader_backend(Adapter, DeviceType);
-            if(shader_backend->shader_conv_supported(CheckFormat)) {
+            if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup))
+            {
                 TRACE_(d3d_caps)("[OK]\n");
                 return TRUE;
-            } else {
-                TRACE_(d3d_caps)("[FAILED]\n");
-                return FALSE;
             }
+            TRACE_(d3d_caps)("[FAILED]\n");
+            return FALSE;
 
         case WINED3DFMT_DXT1:
         case WINED3DFMT_DXT2:
@@ -2301,6 +2310,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
         case WINED3DFMT_INDEX32:
         case WINED3DFMT_Q16W16V16U16:
         case WINED3DFMT_A2W10V10U10:
+        case WINED3DFMT_W11V11U10:
             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
             return FALSE;
 
@@ -2383,10 +2393,12 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
         /* Vendor specific formats */
         case WINED3DFMT_ATI2N:
             if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
+                getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
                 shader_backend = select_shader_backend(Adapter, DeviceType);
                 fp = select_fragment_implementation(Adapter, DeviceType);
-                if(shader_backend->shader_conv_supported(CheckFormat) &&
-                   fp->conv_supported(CheckFormat)) {
+                if (shader_backend->shader_color_fixup_supported(glDesc->color_fixup)
+                        && fp->color_fixup_supported(glDesc->color_fixup))
+                {
                     TRACE_(d3d_caps)("[OK]\n");
                     return TRUE;
                 }
@@ -2419,6 +2431,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
 }
 
 static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) {
+    const struct GlPixelFormatDesc *format_desc;
     const struct blit_shader *blitter;
 
     if(SurfaceType == SURFACE_GDI) {
@@ -2455,8 +2468,10 @@ static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WI
     if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE;
 
     /* If opengl can't process the format natively, the blitter may be able to convert it */
+    getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &format_desc);
     blitter = select_blit_implementation(Adapter, DeviceType);
-    if(blitter->conv_supported(CheckFormat)) {
+    if (blitter->color_fixup_supported(format_desc->color_fixup))
+    {
         TRACE_(d3d_caps)("[OK]\n");
         return TRUE;
     }
@@ -3726,7 +3741,8 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
     return IUnknown_Release(volumeParent);
 }
 
-static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
+static BOOL implementation_is_apple(const WineD3D_GL_Info *gl_info)
+{
     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
@@ -3848,6 +3864,7 @@ static const struct driver_version_information driver_version_table[] = {
     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    7,  15, 11, 7341   },
     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     7,  15, 11, 7341    },
     {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     7,  15, 11, 7341    },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     7,  15, 11, 7341    },
 
     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
     {VENDOR_ATI,        CARD_ATI_RADEON_9500,           6,  14, 10, 6764    },
@@ -3964,12 +3981,14 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
     }
 }
 
-static void WINE_GLAPI invalid_func(void *data) {
+static void WINE_GLAPI invalid_func(const void *data)
+{
     ERR("Invalid vertex attribute function called\n");
     DebugBreak();
 }
 
-static void WINE_GLAPI invalid_texcoord_func(GLenum unit, void * data) {
+static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
+{
     ERR("Invalid texcoord function called\n");
     DebugBreak();
 }
@@ -3979,8 +3998,9 @@ static void WINE_GLAPI invalid_texcoord_func(GLenum unit, void * data) {
 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
  * the extension detection and are used in drawStridedSlow
  */
-static void WINE_GLAPI position_d3dcolor(void *data) {
-    DWORD pos = *((DWORD *) data);
+static void WINE_GLAPI position_d3dcolor(const void *data)
+{
+    DWORD pos = *((const DWORD *)data);
 
     FIXME("Add a test for fixed function position from d3dcolor type\n");
     glVertex4s(D3DCOLOR_B_R(pos),
@@ -3988,8 +4008,10 @@ static void WINE_GLAPI position_d3dcolor(void *data) {
                D3DCOLOR_B_B(pos),
                D3DCOLOR_B_A(pos));
 }
-static void WINE_GLAPI position_float4(void *data) {
-    GLfloat *pos = (float *) data;
+
+static void WINE_GLAPI position_float4(const void *data)
+{
+    const GLfloat *pos = data;
 
     if (pos[3] < eps && pos[3] > -eps)
         glVertex3fv(pos);
@@ -4000,8 +4022,9 @@ static void WINE_GLAPI position_float4(void *data) {
     }
 }
 
-static void WINE_GLAPI diffuse_d3dcolor(void *data) {
-    DWORD diffuseColor = *((DWORD *) data);
+static void WINE_GLAPI diffuse_d3dcolor(const void *data)
+{
+    DWORD diffuseColor = *((const DWORD *)data);
 
     glColor4ub(D3DCOLOR_B_R(diffuseColor),
                D3DCOLOR_B_G(diffuseColor),
@@ -4009,148 +4032,152 @@ static void WINE_GLAPI diffuse_d3dcolor(void *data) {
                D3DCOLOR_B_A(diffuseColor));
 }
 
-static void WINE_GLAPI specular_d3dcolor(void *data) {
-    DWORD specularColor = *((DWORD *) data);
+static void WINE_GLAPI specular_d3dcolor(const void *data)
+{
+    DWORD specularColor = *((const DWORD *)data);
 
     GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
                                        D3DCOLOR_B_G(specularColor),
                                        D3DCOLOR_B_B(specularColor));
 }
-static void WINE_GLAPI warn_no_specular_func(void *data) {
+
+static void WINE_GLAPI warn_no_specular_func(const void *data)
+{
     WARN("GL_EXT_secondary_color not supported\n");
 }
 
-void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) {
-    position_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) glVertex3fv;
-    position_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) position_float4;
-    position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) position_d3dcolor;
-    position_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) glVertex2sv;
-    position_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
-    position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
-
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (void *) glColor3fv;
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (void *) glColor4fv;
-    diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = (void *) diffuse_d3dcolor;
-    diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (void *) glColor4ubv;
-    diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (void *) glColor4sv;
-    diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (void *) glColor4usv;
-    diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = (void *) invalid_func;
-    diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = (void *) invalid_func;
+static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
+{
+    position_funcs[WINED3DDECLTYPE_FLOAT1]      = invalid_func;
+    position_funcs[WINED3DDECLTYPE_FLOAT2]      = invalid_func;
+    position_funcs[WINED3DDECLTYPE_FLOAT3]      = (glAttribFunc)glVertex3fv;
+    position_funcs[WINED3DDECLTYPE_FLOAT4]      = position_float4;
+    position_funcs[WINED3DDECLTYPE_D3DCOLOR]    = position_d3dcolor;
+    position_funcs[WINED3DDECLTYPE_UBYTE4]      = invalid_func;
+    position_funcs[WINED3DDECLTYPE_SHORT2]      = invalid_func;
+    position_funcs[WINED3DDECLTYPE_SHORT4]      = (glAttribFunc)glVertex2sv;
+    position_funcs[WINED3DDECLTYPE_UBYTE4N]     = invalid_func;
+    position_funcs[WINED3DDECLTYPE_SHORT2N]     = invalid_func;
+    position_funcs[WINED3DDECLTYPE_SHORT4N]     = invalid_func;
+    position_funcs[WINED3DDECLTYPE_USHORT2N]    = invalid_func;
+    position_funcs[WINED3DDECLTYPE_USHORT4N]    = invalid_func;
+    position_funcs[WINED3DDECLTYPE_UDEC3]       = invalid_func;
+    position_funcs[WINED3DDECLTYPE_DEC3N]       = invalid_func;
+    position_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
+    position_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
+
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT1]       = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT2]       = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT3]       = (glAttribFunc)glColor3fv;
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT4]       = (glAttribFunc)glColor4fv;
+    diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR]     = diffuse_d3dcolor;
+    diffuse_funcs[WINED3DDECLTYPE_UBYTE4]       = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_SHORT2]       = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_SHORT4]       = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_UBYTE4N]      = (glAttribFunc)glColor4ubv;
+    diffuse_funcs[WINED3DDECLTYPE_SHORT2N]      = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_SHORT4N]      = (glAttribFunc)glColor4sv;
+    diffuse_funcs[WINED3DDECLTYPE_USHORT2N]     = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_USHORT4N]     = (glAttribFunc)glColor4usv;
+    diffuse_funcs[WINED3DDECLTYPE_UDEC3]        = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_DEC3N]        = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2]    = invalid_func;
+    diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4]    = invalid_func;
 
     /* No 4 component entry points here */
-    specular_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) invalid_func;
+    specular_funcs[WINED3DDECLTYPE_FLOAT1]      = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_FLOAT2]      = invalid_func;
     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
-        specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) GL_EXTCALL(glSecondaryColor3fvEXT);
+        specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
     } else {
-        specular_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) warn_no_specular_func;
+        specular_funcs[WINED3DDECLTYPE_FLOAT3]      = warn_no_specular_func;
     }
-    specular_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) invalid_func;
+    specular_funcs[WINED3DDECLTYPE_FLOAT4]      = invalid_func;
     if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
-        specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) specular_d3dcolor;
+        specular_funcs[WINED3DDECLTYPE_D3DCOLOR]    = specular_d3dcolor;
     } else {
-        specular_funcs[WINED3DDECLTYPE_D3DCOLOR]      = (void *) warn_no_specular_func;
+        specular_funcs[WINED3DDECLTYPE_D3DCOLOR]      = warn_no_specular_func;
     }
-    specular_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
-    specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
+    specular_funcs[WINED3DDECLTYPE_UBYTE4]      = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_SHORT2]      = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_SHORT4]      = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_UBYTE4N]     = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_SHORT2N]     = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_SHORT4N]     = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_USHORT2N]    = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_USHORT4N]    = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_UDEC3]       = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_DEC3N]       = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
+    specular_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
 
     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
      */
-    normal_funcs[WINED3DDECLTYPE_FLOAT1]         = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_FLOAT2]         = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (void *) glNormal3fv;
-    normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (void *) glNormal3fv; /* Just ignore the 4th value */
-    normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_UBYTE4]         = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_SHORT2]         = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_SHORT4]         = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_SHORT2N]        = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_SHORT4N]        = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_USHORT2N]       = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_USHORT4N]       = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_UDEC3]          = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_DEC3N]          = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = (void *) invalid_func;
-    normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = (void *) invalid_func;
-
-    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT1]    = (void *) GL_EXTCALL(glMultiTexCoord1fvARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT2]    = (void *) GL_EXTCALL(glMultiTexCoord2fvARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT3]    = (void *) GL_EXTCALL(glMultiTexCoord3fvARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT4]    = (void *) GL_EXTCALL(glMultiTexCoord4fvARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR]  = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4]    = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2]    = (void *) GL_EXTCALL(glMultiTexCoord2svARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4]    = (void *) GL_EXTCALL(glMultiTexCoord4svARB);
-    multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4N]   = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2N]   = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4N]   = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_USHORT2N]  = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_USHORT4N]  = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_UDEC3]     = (void *) invalid_texcoord_func;
-    multi_texcoord_funcs[WINED3DDECLTYPE_DEC3N]     = (void *) invalid_texcoord_func;
+    normal_funcs[WINED3DDECLTYPE_FLOAT1]         = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_FLOAT2]         = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_FLOAT3]         = (glAttribFunc)glNormal3fv;
+    normal_funcs[WINED3DDECLTYPE_FLOAT4]         = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
+    normal_funcs[WINED3DDECLTYPE_D3DCOLOR]       = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_UBYTE4]         = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_SHORT2]         = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_SHORT4]         = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_UBYTE4N]        = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_SHORT2N]        = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_SHORT4N]        = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_USHORT2N]       = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_USHORT4N]       = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_UDEC3]          = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_DEC3N]          = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_FLOAT16_2]      = invalid_func;
+    normal_funcs[WINED3DDECLTYPE_FLOAT16_4]      = invalid_func;
+
+    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT1]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT3]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR]  = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4]    = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
+    multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4N]   = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2N]   = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4N]   = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_USHORT2N]  = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_USHORT4N]  = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_UDEC3]     = invalid_texcoord_func;
+    multi_texcoord_funcs[WINED3DDECLTYPE_DEC3N]     = invalid_texcoord_func;
     if (GL_SUPPORT(NV_HALF_FLOAT))
     {
-        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) GL_EXTCALL(glMultiTexCoord2hvNV);
-        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) GL_EXTCALL(glMultiTexCoord4hvNV);
+        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
+        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
     } else {
-        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_texcoord_func;
-        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_texcoord_func;
+        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_texcoord_func;
+        multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = invalid_texcoord_func;
     }
 
-    texcoord_funcs[WINED3DDECLTYPE_FLOAT1]      = (void *) glTexCoord1fv;
-    texcoord_funcs[WINED3DDECLTYPE_FLOAT2]      = (void *) glTexCoord2fv;
-    texcoord_funcs[WINED3DDECLTYPE_FLOAT3]      = (void *) glTexCoord3fv;
-    texcoord_funcs[WINED3DDECLTYPE_FLOAT4]      = (void *) glTexCoord4fv;
-    texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR]    = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_UBYTE4]      = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_SHORT2]      = (void *) glTexCoord2sv;
-    texcoord_funcs[WINED3DDECLTYPE_SHORT4]      = (void *) glTexCoord4sv;
-    texcoord_funcs[WINED3DDECLTYPE_UBYTE4N]     = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_SHORT2N]     = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_SHORT4N]     = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_USHORT2N]    = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_USHORT4N]    = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_UDEC3]       = (void *) invalid_func;
-    texcoord_funcs[WINED3DDECLTYPE_DEC3N]       = (void *) invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_FLOAT1]      = (glAttribFunc)glTexCoord1fv;
+    texcoord_funcs[WINED3DDECLTYPE_FLOAT2]      = (glAttribFunc)glTexCoord2fv;
+    texcoord_funcs[WINED3DDECLTYPE_FLOAT3]      = (glAttribFunc)glTexCoord3fv;
+    texcoord_funcs[WINED3DDECLTYPE_FLOAT4]      = (glAttribFunc)glTexCoord4fv;
+    texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR]    = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_UBYTE4]      = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_SHORT2]      = (glAttribFunc)glTexCoord2sv;
+    texcoord_funcs[WINED3DDECLTYPE_SHORT4]      = (glAttribFunc)glTexCoord4sv;
+    texcoord_funcs[WINED3DDECLTYPE_UBYTE4N]     = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_SHORT2N]     = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_SHORT4N]     = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_USHORT2N]    = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_USHORT4N]    = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_UDEC3]       = invalid_func;
+    texcoord_funcs[WINED3DDECLTYPE_DEC3N]       = invalid_func;
     if (GL_SUPPORT(NV_HALF_FLOAT))
     {
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) GL_EXTCALL(glTexCoord2hvNV);
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) GL_EXTCALL(glTexCoord4hvNV);
+        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (glAttribFunc)GL_EXTCALL(glTexCoord2hvNV);
+        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (glAttribFunc)GL_EXTCALL(glTexCoord4hvNV);
     } else {
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2]   = (void *) invalid_func;
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (void *) invalid_func;
+        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
+        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
     }
 }
 
index 545bad1..7603103 100644 (file)
@@ -142,14 +142,14 @@ void primitiveDeclarationConvertToStridedData(
 
      /* We need to deal with frequency data!*/
 
-    BYTE  *data    = NULL;
+    const BYTE *data = NULL;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
-    int i;
-    WINED3DVERTEXELEMENT *element;
+    unsigned int i;
+    const WINED3DVERTEXELEMENT *element;
     DWORD stride;
     DWORD numPreloadStreams = This->stateBlock->streamIsUP ? 0 : vertexDeclaration->num_streams;
-    DWORD *streams = vertexDeclaration->streams;
+    const DWORD *streams = vertexDeclaration->streams;
 
     /* Check for transformed vertices, disable vertex shader if present */
     strided->u.s.position_transformed = vertexDeclaration->position_transformed;
@@ -164,7 +164,7 @@ void primitiveDeclarationConvertToStridedData(
         unsigned int idx;
 
         element = vertexDeclaration->pDeclarationWine + i;
-        TRACE("%p Element %p (%d of %d)\n", vertexDeclaration->pDeclarationWine,
+        TRACE("%p Element %p (%u of %u)\n", vertexDeclaration->pDeclarationWine,
             element,  i + 1, vertexDeclaration->declarationWNumElements - 1);
 
         if (This->stateBlock->streamSource[element->Stream] == NULL)
@@ -286,21 +286,22 @@ static void drawStridedFast(IWineD3DDevice *iface,UINT numberOfVertices, GLenum
  * Slower GL version which extracts info about each vertex in turn
  */
 
-static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
-                     UINT NumVertexes, GLenum glPrimType,
-                     const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex) {
-
+static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT NumVertexes,
+        GLenum glPrimType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex)
+{
     unsigned int               textureNo    = 0;
     const WORD                *pIdxBufS     = NULL;
     const DWORD               *pIdxBufL     = NULL;
-    LONG                       vx_index;
+    ULONG                      vx_index;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    UINT *streamOffset = This->stateBlock->streamOffset;
+    const UINT *streamOffset = This->stateBlock->streamOffset;
     long                      SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
     BOOL                      pixelShader = use_ps(This);
-
-    BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
-    BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
+    BOOL specular_fog = FALSE;
+    UINT texture_stages = GL_LIMITS(texture_stages);
+    const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
+    const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
+    DWORD tex_mask = 0;
 
     TRACE("Using slow vertex array code\n");
 
@@ -321,56 +322,92 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
         return;
     }
 
-    /* Adding the stream offset once is cheaper than doing it every iteration. Do not modify the strided data, it is a pointer
-     * to the strided Data in the device and might be needed intact on the next draw
-     */
-    for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
-        if(sd->u.s.texCoords[textureNo].lpData) {
-            texCoords[textureNo] = sd->u.s.texCoords[textureNo].lpData + streamOffset[sd->u.s.texCoords[textureNo].streamNo];
-        } else {
-            texCoords[textureNo] = NULL;
-        }
-    }
-    if(sd->u.s.diffuse.lpData) {
-        diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo];
-    }
-    if(sd->u.s.specular.lpData) {
+    /* Start drawing in GL */
+    VTRACE(("glBegin(%x)\n", glPrimType));
+    glBegin(glPrimType);
+
+    if (sd->u.s.position.lpData) position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo];
+
+    if (sd->u.s.normal.lpData) normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo];
+    else glNormal3f(0, 0, 0);
+
+    if (sd->u.s.diffuse.lpData) diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo];
+    else glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    if (This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR)
+        FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType));
+
+    if (sd->u.s.specular.lpData)
+    {
         specular = sd->u.s.specular.lpData + streamOffset[sd->u.s.specular.streamNo];
-    }
-    if(sd->u.s.normal.lpData) {
-        normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo];
-    }
-    if(sd->u.s.position.lpData) {
-        position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo];
-    }
 
-    if(FIXME_ON(d3d_draw)) {
-        if(specular && This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
-           (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position_transformed )&&
-           This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
-            if(GL_SUPPORT(EXT_FOG_COORD) && sd->u.s.specular.dwType != WINED3DDECLTYPE_D3DCOLOR) {
-                FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType));
+        /* special case where the fog density is stored in the specular alpha channel */
+        if (This->stateBlock->renderState[WINED3DRS_FOGENABLE]
+                && (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE
+                    || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4)
+                && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
+        {
+            if (GL_SUPPORT(EXT_FOG_COORD))
+            {
+                if (sd->u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR) specular_fog = TRUE;
+                else FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType));
+            }
+            else
+            {
+                static BOOL warned;
+
+                if (!warned)
+                {
+                    /* TODO: Use the fog table code from old ddraw */
+                    FIXME("Implement fog for transformed vertices in software\n");
+                    warned = TRUE;
+                }
             }
         }
-        if(This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR) {
-            FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType));
-        }
+    }
+    else if (GL_SUPPORT(EXT_SECONDARY_COLOR))
+    {
+        GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
     }
 
-    /* Start drawing in GL */
-    VTRACE(("glBegin(%x)\n", glPrimType));
-    glBegin(glPrimType);
+    for (textureNo = 0; textureNo < texture_stages; ++textureNo)
+    {
+        int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
+        int texture_idx = This->texUnitMap[textureNo];
 
-    /* Default settings for data that is not passed */
-    if (sd->u.s.normal.lpData == NULL) {
-        glNormal3f(0, 0, 0);
-    }
-    if(sd->u.s.diffuse.lpData == NULL) {
-        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-    }
-    if(sd->u.s.specular.lpData == NULL) {
-        if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
-            GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+        if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
+        {
+            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+            continue;
+        }
+
+        if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
+
+        if (texture_idx == -1) continue;
+
+        if (coordIdx > 7)
+        {
+            TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo);
+            continue;
+        }
+        else if (coordIdx < 0)
+        {
+            FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
+            continue;
+        }
+
+        if(sd->u.s.texCoords[coordIdx].lpData)
+        {
+            texCoords[coordIdx] =
+                    sd->u.s.texCoords[coordIdx].lpData + streamOffset[sd->u.s.texCoords[coordIdx].streamNo];
+            tex_mask |= (1 << textureNo);
+        }
+        else
+        {
+            TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
+            if (GL_SUPPORT(ARB_MULTITEXTURE))
+                GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
+            else
+                glTexCoord4f(0, 0, 0, 1);
         }
     }
 
@@ -380,6 +417,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
 
     /* For each primitive */
     for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
+        UINT texture, tmp_tex_mask;
         /* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
          * function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
          */
@@ -389,63 +427,43 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
 
             /* Indexed so work out the number of strides to skip */
             if (idxSize == 2) {
-                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+                VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufS[startIdx+vx_index]));
                 SkipnStrides = pIdxBufS[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
             } else {
-                VTRACE(("Idx for vertex %d = %d\n", vx_index, pIdxBufL[startIdx+vx_index]));
+                VTRACE(("Idx for vertex %u = %u\n", vx_index, pIdxBufL[startIdx+vx_index]));
                 SkipnStrides = pIdxBufL[startIdx + vx_index] + This->stateBlock->loadBaseVertexIndex;
             }
         }
 
-        /* Texture coords --------------------------- */
-        for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
-
-            if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
-                FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-                continue ;
-            }
-
-            /* Query tex coords */
-            if (This->stateBlock->textures[textureNo] != NULL || pixelShader) {
-                int    coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
-                int texture_idx = This->texUnitMap[textureNo];
-                void *ptrToCoords;
-
-                if (coordIdx > 7) {
-                    VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
-                    continue;
-                } else if (coordIdx < 0) {
-                    FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
-                    continue;
-                }
+        tmp_tex_mask = tex_mask;
+        for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture)
+        {
+            int coord_idx;
+            const void *ptr;
 
-                if (texture_idx == -1) continue;
+            if (!(tmp_tex_mask & 1)) continue;
 
-                if (texCoords[coordIdx] == NULL) {
-                    TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
-                    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-                        GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
-                    } else {
-                        glTexCoord4f(0, 0, 0, 1);
-                    }
-                    continue;
-                }
+            coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX];
+            ptr = texCoords[coord_idx] + (SkipnStrides * sd->u.s.texCoords[coord_idx].dwStride);
 
-                ptrToCoords = texCoords[coordIdx] + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride);
-                if (GL_SUPPORT(ARB_MULTITEXTURE))
-                    multi_texcoord_funcs[sd->u.s.texCoords[coordIdx].dwType](GL_TEXTURE0_ARB + texture_idx, ptrToCoords);
-                else
-                    texcoord_funcs[sd->u.s.texCoords[coordIdx].dwType](ptrToCoords);
+            if (GL_SUPPORT(ARB_MULTITEXTURE))
+            {
+                int texture_idx = This->texUnitMap[texture];
+                multi_texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](GL_TEXTURE0_ARB + texture_idx, ptr);
             }
-        } /* End of textures */
+            else
+            {
+                texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](ptr);
+            }
+        }
 
         /* Diffuse -------------------------------- */
         if (diffuse) {
-            DWORD *ptrToCoords = (DWORD *)(diffuse + (SkipnStrides * sd->u.s.diffuse.dwStride));
+            const void *ptrToCoords = diffuse + SkipnStrides * sd->u.s.diffuse.dwStride;
 
-            diffuse_funcs[sd->u.s.diffuse.dwType]((void *) ptrToCoords);
+            diffuse_funcs[sd->u.s.diffuse.dwType](ptrToCoords);
             if(This->activeContext->num_untracked_materials) {
-                DWORD diffuseColor = ptrToCoords[0];
+                DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
                 unsigned char i;
                 float color[4];
 
@@ -462,37 +480,26 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
 
         /* Specular ------------------------------- */
         if (specular) {
-            DWORD *ptrToCoords = (DWORD *)(specular + (SkipnStrides * sd->u.s.specular.dwStride));
-
-            /* special case where the fog density is stored in the specular alpha channel */
-            if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
-              (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 )&&
-              This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
-                if(GL_SUPPORT(EXT_FOG_COORD)) {
-                    DWORD specularColor = ptrToCoords[0];
-                    GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
-                } else {
-                    static BOOL warned = FALSE;
-                    if(!warned) {
-                        /* TODO: Use the fog table code from old ddraw */
-                        FIXME("Implement fog for transformed vertices in software\n");
-                        warned = TRUE;
-                    }
-                }
-            }
+            const void *ptrToCoords = specular + SkipnStrides * sd->u.s.specular.dwStride;
 
-            specular_funcs[sd->u.s.specular.dwType]((void *) ptrToCoords);
+            specular_funcs[sd->u.s.specular.dwType](ptrToCoords);
+
+            if (specular_fog)
+            {
+                DWORD specularColor = *(const DWORD *)ptrToCoords;
+                GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
+            }
         }
 
         /* Normal -------------------------------- */
         if (normal != NULL) {
-            float *ptrToCoords = (float *)(normal + (SkipnStrides * sd->u.s.normal.dwStride));
+            const void *ptrToCoords = normal + SkipnStrides * sd->u.s.normal.dwStride;
             normal_funcs[sd->u.s.normal.dwType](ptrToCoords);
         }
 
         /* Position -------------------------------- */
         if (position) {
-            float *ptrToCoords = (float *)(position + (SkipnStrides * sd->u.s.position.dwStride));
+            const void *ptrToCoords = position + SkipnStrides * sd->u.s.position.dwStride;
             position_funcs[sd->u.s.position.dwType](ptrToCoords);
         }
 
@@ -509,16 +516,16 @@ static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData
 static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, const UINT index, const void *ptr) {
     switch(type) {
         case WINED3DDECLTYPE_FLOAT1:
-            GL_EXTCALL(glVertexAttrib1fvARB(index, (float *) ptr));
+            GL_EXTCALL(glVertexAttrib1fvARB(index, (const float *)ptr));
             break;
         case WINED3DDECLTYPE_FLOAT2:
-            GL_EXTCALL(glVertexAttrib2fvARB(index, (float *) ptr));
+            GL_EXTCALL(glVertexAttrib2fvARB(index, (const float *)ptr));
             break;
         case WINED3DDECLTYPE_FLOAT3:
-            GL_EXTCALL(glVertexAttrib3fvARB(index, (float *) ptr));
+            GL_EXTCALL(glVertexAttrib3fvARB(index, (const float *)ptr));
             break;
         case WINED3DDECLTYPE_FLOAT4:
-            GL_EXTCALL(glVertexAttrib4fvARB(index, (float *) ptr));
+            GL_EXTCALL(glVertexAttrib4fvARB(index, (const float *)ptr));
             break;
 
         case WINED3DDECLTYPE_UBYTE4:
@@ -530,29 +537,29 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
             break;
 
         case WINED3DDECLTYPE_SHORT2:
-            GL_EXTCALL(glVertexAttrib4svARB(index, (GLshort *) ptr));
+            GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
             break;
         case WINED3DDECLTYPE_SHORT4:
-            GL_EXTCALL(glVertexAttrib4svARB(index, (GLshort *) ptr));
+            GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
             break;
 
         case WINED3DDECLTYPE_SHORT2N:
         {
-            GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
+            GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
             GL_EXTCALL(glVertexAttrib4NsvARB(index, s));
             break;
         }
         case WINED3DDECLTYPE_USHORT2N:
         {
-            GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
+            GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
             GL_EXTCALL(glVertexAttrib4NusvARB(index, s));
             break;
         }
         case WINED3DDECLTYPE_SHORT4N:
-            GL_EXTCALL(glVertexAttrib4NsvARB(index, (GLshort *) ptr));
+            GL_EXTCALL(glVertexAttrib4NsvARB(index, (const GLshort *)ptr));
             break;
         case WINED3DDECLTYPE_USHORT4N:
-            GL_EXTCALL(glVertexAttrib4NusvARB(index, (GLushort *) ptr));
+            GL_EXTCALL(glVertexAttrib4NusvARB(index, (const GLushort *)ptr));
             break;
 
         case WINED3DDECLTYPE_UDEC3:
@@ -569,21 +576,21 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
              * byte float according to the IEEE standard
              */
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
-                GL_EXTCALL(glVertexAttrib2hvNV(index, (GLhalfNV *)ptr));
+                GL_EXTCALL(glVertexAttrib2hvNV(index, (const GLhalfNV *)ptr));
             } else {
-                float x = float_16_to_32(((unsigned short *) ptr) + 0);
-                float y = float_16_to_32(((unsigned short *) ptr) + 1);
+                float x = float_16_to_32(((const unsigned short *)ptr) + 0);
+                float y = float_16_to_32(((const unsigned short *)ptr) + 1);
                 GL_EXTCALL(glVertexAttrib2fARB(index, x, y));
             }
             break;
         case WINED3DDECLTYPE_FLOAT16_4:
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
-                GL_EXTCALL(glVertexAttrib4hvNV(index, (GLhalfNV *)ptr));
+                GL_EXTCALL(glVertexAttrib4hvNV(index, (const GLhalfNV *)ptr));
             } else {
-                float x = float_16_to_32(((unsigned short *) ptr) + 0);
-                float y = float_16_to_32(((unsigned short *) ptr) + 1);
-                float z = float_16_to_32(((unsigned short *) ptr) + 2);
-                float w = float_16_to_32(((unsigned short *) ptr) + 3);
+                float x = float_16_to_32(((const unsigned short *)ptr) + 0);
+                float y = float_16_to_32(((const unsigned short *)ptr) + 1);
+                float z = float_16_to_32(((const unsigned short *)ptr) + 2);
+                float w = float_16_to_32(((const unsigned short *)ptr) + 3);
                 GL_EXTCALL(glVertexAttrib4fARB(index, x, y, z, w));
             }
             break;
@@ -595,18 +602,17 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
     }
 }
 
-static void drawStridedSlowVs(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd, UINT numberOfVertices,
-                              GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx,
-                              ULONG startVertex) {
-
+static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT numberOfVertices,
+        GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     long                      SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
     const WORD                *pIdxBufS     = NULL;
     const DWORD               *pIdxBufL     = NULL;
-    LONG                       vx_index;
+    ULONG                      vx_index;
     int i;
     IWineD3DStateBlockImpl *stateblock = This->stateBlock;
-    BYTE *ptr;
+    const BYTE *ptr;
 
     if (idxSize != 0) {
         /* Immediate mode drawing can't make use of indices in a vbo - get the data from the index buffer.
@@ -656,11 +662,12 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, WineDirect3DVertexStridedDa
     glEnd();
 }
 
-static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd, UINT numberOfVertices,
-                                 GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex,
-                                 ULONG startIdx, ULONG startVertex) {
-    UINT numInstances = 0;
-    int numInstancedAttribs = 0, i, j;
+static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd,
+        UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex,
+        ULONG startIdx, ULONG startVertex)
+{
+    UINT numInstances = 0, i;
+    int numInstancedAttribs = 0, j;
     UINT instancedData[sizeof(sd->u.input) / sizeof(sd->u.input[0]) /* 16 */];
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DStateBlockImpl *stateblock = This->stateBlock;
@@ -704,7 +711,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, WineDirect3DVerte
     for(i = 0; i < numInstances; i++) {
         /* Specify the instanced attributes using immediate mode calls */
         for(j = 0; j < numInstancedAttribs; j++) {
-            BYTE *ptr = sd->u.input[instancedData[j]].lpData +
+            const BYTE *ptr = sd->u.input[instancedData[j]].lpData +
                         sd->u.input[instancedData[j]].dwStride * i +
                         stateblock->streamOffset[sd->u.input[instancedData[j]].streamNo];
             if(sd->u.input[instancedData[j]].VBO) {
@@ -823,7 +830,7 @@ void drawPrimitive(IWineD3DDevice *iface,
 
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl          *target;
-    int i;
+    unsigned int i;
 
     if (NumPrimitives == 0) return;
 
@@ -854,7 +861,7 @@ void drawPrimitive(IWineD3DDevice *iface,
     {
         GLenum glPrimType;
         BOOL emulation = FALSE;
-        WineDirect3DVertexStridedData *strided = &This->strided_streams;
+        const WineDirect3DVertexStridedData *strided = &This->strided_streams;
         WineDirect3DVertexStridedData stridedlcl;
         /* Ok, Work out which primitive is requested and how many vertexes that
            will be                                                              */
@@ -865,10 +872,10 @@ void drawPrimitive(IWineD3DDevice *iface,
         if(!use_vs(This)) {
             if(!This->strided_streams.u.s.position_transformed && This->activeContext->num_untracked_materials &&
                 This->stateBlock->renderState[WINED3DRS_LIGHTING]) {
-                static BOOL first = TRUE;
-                if(first) {
+                static BOOL warned;
+                if (!warned) {
                     FIXME("Using software emulation because not all material properties could be tracked\n");
-                    first = FALSE;
+                    warned = TRUE;
                 } else {
                     TRACE("Using software emulation because not all material properties could be tracked\n");
                 }
@@ -878,10 +885,10 @@ void drawPrimitive(IWineD3DDevice *iface,
                 /* Either write a pipeline replacement shader or convert the specular alpha from unsigned byte
                  * to a float in the vertex buffer
                  */
-                static BOOL first = TRUE;
-                if(first) {
+                static BOOL warned;
+                if (!warned) {
                     FIXME("Using software emulation because manual fog coordinates are provided\n");
-                    first = FALSE;
+                    warned = TRUE;
                 } else {
                     TRACE("Using software emulation because manual fog coordinates are provided\n");
                 }
@@ -898,10 +905,10 @@ void drawPrimitive(IWineD3DDevice *iface,
         if (This->useDrawStridedSlow || emulation) {
             /* Immediate mode drawing */
             if(use_vs(This)) {
-                static BOOL first = TRUE;
-                if(first) {
+                static BOOL warned;
+                if (!warned) {
                     FIXME("Using immediate mode with vertex shaders for half float emulation\n");
-                    first = FALSE;
+                    warned = TRUE;
                 } else {
                     TRACE("Using immediate mode with vertex shaders for half float emulation\n");
                 }
@@ -1005,8 +1012,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     unsigned int i, j, num_quads, out_vertex_size, buffer_size, d3d_out_vertex_size;
     float max_x = 0.0, max_y = 0.0, max_z = 0.0, neg_z = 0.0;
     WineDirect3DVertexStridedData strided;
-    BYTE *data;
-    WINED3DRECTPATCH_INFO *info = &patch->RectPatchInfo;
+    const BYTE *data;
+    const WINED3DRECTPATCH_INFO *info = &patch->RectPatchInfo;
     DWORD vtxStride;
     GLenum feedback_type;
     GLfloat *feedbuffer;
@@ -1048,7 +1055,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     /* First, get the boundary cube of the input data */
     for(j = 0; j < info->Height; j++) {
         for(i = 0; i < info->Width; i++) {
-            float *v = (float *) (data + vtxStride * i + vtxStride * info->Stride * j);
+            const float *v = (const float *)(data + vtxStride * i + vtxStride * info->Stride * j);
             if(fabs(v[0]) > max_x) max_x = fabs(v[0]);
             if(fabs(v[1]) > max_y) max_y = fabs(v[1]);
             if(fabs(v[2]) > max_z) max_z = fabs(v[2]);
@@ -1085,11 +1092,11 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FILLMODE));
     if(patch->has_normals) {
-        float black[4] = {0, 0, 0, 0};
-        float red[4]   = {1, 0, 0, 0};
-        float green[4] = {0, 1, 0, 0};
-        float blue[4]  = {0, 0, 1, 0};
-        float white[4] = {1, 1, 1, 1};
+        const GLfloat black[4] = {0, 0, 0, 0};
+        const GLfloat red[4]   = {1, 0, 0, 0};
+        const GLfloat green[4] = {0, 1, 0, 0};
+        const GLfloat blue[4]  = {0, 0, 1, 0};
+        const GLfloat white[4] = {1, 1, 1, 1};
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
@@ -1172,13 +1179,13 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     glMap2f(GL_MAP2_VERTEX_3,
             0, 1, vtxStride / sizeof(float), info->Width,
             0, 1, info->Stride * vtxStride / sizeof(float), info->Height,
-            (float *) data);
+            (const GLfloat *)data);
     checkGLcall("glMap2f");
     if(patch->has_texcoords) {
         glMap2f(GL_MAP2_TEXTURE_COORD_4,
                 0, 1, vtxStride / sizeof(float), info->Width,
                 0, 1, info->Stride * vtxStride / sizeof(float), info->Height,
-                (float *) data);
+                (const GLfloat *)data);
         checkGLcall("glMap2f");
     }
     glMapGrid2f(ceilf(patch->numSegs[0]), 0.0, 1.0, ceilf(patch->numSegs[1]), 0.0, 1.0);
@@ -1256,9 +1263,9 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
 
     if(patch->has_normals) {
         /* Now do the same with reverse light directions */
-        float x[4] = {-1,  0,  0, 0};
-        float y[4] = { 0, -1,  0, 0};
-        float z[4] = { 0,  0, -1, 0};
+        const GLfloat x[4] = {-1,  0,  0, 0};
+        const GLfloat y[4] = { 0, -1,  0, 0};
+        const GLfloat z[4] = { 0,  0, -1, 0};
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
index bb9a871..4c1d223 100644 (file)
@@ -35,6 +35,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_constants);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION      (*gl_info)
 
@@ -56,42 +57,43 @@ typedef struct {
 /* GLSL shader private data */
 struct shader_glsl_priv {
     struct hash_table_t *glsl_program_lookup;
-    struct glsl_shader_prog_link *glsl_program;
+    const struct glsl_shader_prog_link *glsl_program;
     GLhandleARB depth_blt_program[tex_type_count];
 };
 
 /* Struct to maintain data about a linked GLSL program */
 struct glsl_shader_prog_link {
-    struct list             vshader_entry;
-    struct list             pshader_entry;
-    GLhandleARB             programId;
-    GLhandleARB             *vuniformF_locations;
-    GLhandleARB             *puniformF_locations;
-    GLhandleARB             vuniformI_locations[MAX_CONST_I];
-    GLhandleARB             puniformI_locations[MAX_CONST_I];
-    GLhandleARB             posFixup_location;
-    GLhandleARB             bumpenvmat_location[MAX_TEXTURES];
-    GLhandleARB             luminancescale_location[MAX_TEXTURES];
-    GLhandleARB             luminanceoffset_location[MAX_TEXTURES];
-    GLhandleARB             srgb_comparison_location;
-    GLhandleARB             srgb_mul_low_location;
-    GLhandleARB             ycorrection_location;
-    GLenum                  vertex_color_clamp;
-    GLhandleARB             vshader;
-    GLhandleARB             pshader;
+    struct list                 vshader_entry;
+    struct list                 pshader_entry;
+    GLhandleARB                 programId;
+    GLhandleARB                 *vuniformF_locations;
+    GLhandleARB                 *puniformF_locations;
+    GLhandleARB                 vuniformI_locations[MAX_CONST_I];
+    GLhandleARB                 puniformI_locations[MAX_CONST_I];
+    GLhandleARB                 posFixup_location;
+    GLhandleARB                 bumpenvmat_location[MAX_TEXTURES];
+    GLhandleARB                 luminancescale_location[MAX_TEXTURES];
+    GLhandleARB                 luminanceoffset_location[MAX_TEXTURES];
+    GLhandleARB                 ycorrection_location;
+    GLenum                      vertex_color_clamp;
+    GLhandleARB                 vshader;
+    IWineD3DPixelShader         *pshader;
+    struct ps_compile_args      ps_args;
 };
 
 typedef struct {
-    GLhandleARB vshader;
-    GLhandleARB pshader;
+    GLhandleARB                 vshader;
+    IWineD3DPixelShader         *pshader;
+    struct ps_compile_args      ps_args;
 } glsl_program_key_t;
 
 
 /** Prints the GLSL info log which will contain error messages if they exist */
-static void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) {
+static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
+{
     int infologLength = 0;
     char *infoLog;
-    int i;
+    unsigned int i;
     BOOL is_spam;
 
     const char *spam[] = {
@@ -140,11 +142,8 @@ static void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) {
 /**
  * Loads (pixel shader) samplers
  */
-static void shader_glsl_load_psamplers(
-    WineD3D_GL_Info *gl_info,
-    IWineD3DStateBlock* iface,
-    GLhandleARB programId) {
-
+static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, IWineD3DStateBlock *iface, GLhandleARB programId)
+{
     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
     GLhandleARB name_loc;
     int i;
@@ -166,7 +165,8 @@ static void shader_glsl_load_psamplers(
     }
 }
 
-static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBlock* iface, GLhandleARB programId) {
+static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, IWineD3DStateBlock *iface, GLhandleARB programId)
+{
     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
     GLhandleARB name_loc;
     char sampler_name[20];
@@ -192,14 +192,15 @@ static void shader_glsl_load_vsamplers(WineD3D_GL_Info *gl_info, IWineD3DStateBl
  * Loads floating point constants (aka uniforms) into the currently set GLSL program.
  * When constant_list == NULL, it will load all the constants.
  */
-static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info,
-        unsigned int max_constants, float* constants, GLhandleARB *constant_locations,
-        struct list *constant_list) {
-    constants_entry *constant;
-    local_constant* lconst;
+static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+        unsigned int max_constants, const float *constants, const GLhandleARB *constant_locations,
+        const struct list *constant_list)
+{
+    const constants_entry *constant;
+    const local_constant *lconst;
     GLhandleARB tmp_loc;
     DWORD i, j, k;
-    DWORD *idx;
+    const DWORD *idx;
 
     if (TRACE_ON(d3d_shader)) {
         LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) {
@@ -274,7 +275,7 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
             tmp_loc = constant_locations[lconst->idx];
             if (tmp_loc != -1) {
-                GLfloat* values = (GLfloat*)lconst->value;
+                const GLfloat *values = (const GLfloat *)lconst->value;
                 TRACE_(d3d_constants)("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
                         values[0], values[1], values[2], values[3]);
             }
@@ -285,46 +286,37 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL
         tmp_loc = constant_locations[lconst->idx];
         if (tmp_loc != -1) {
             /* We found this uniform name in the program - go ahead and send the data */
-            GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, (GLfloat*)lconst->value));
+            GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, (const GLfloat *)lconst->value));
         }
     }
     checkGLcall("glUniform4fvARB()");
 }
 
-/** 
- * Loads integer constants (aka uniforms) into the currently set GLSL program.
- * When @constants_set == NULL, it will load all the constants.
- */
-static void shader_glsl_load_constantsI(
-    IWineD3DBaseShaderImpl* This,
-    WineD3D_GL_Info *gl_info,
-    GLhandleARB programId,
-    GLhandleARB locations[MAX_CONST_I],
-    unsigned max_constants,
-    int* constants,
-    BOOL* constants_set) {
-    
-    int i;
+/* Loads integer constants (aka uniforms) into the currently set GLSL program. */
+static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+        const GLhandleARB locations[MAX_CONST_I], const int *constants, WORD constants_set)
+{
+    unsigned int i;
     struct list* ptr;
 
-    for (i=0; i<max_constants; ++i) {
-        if (NULL == constants_set || constants_set[i]) {
+    for (i = 0; constants_set; constants_set >>= 1, ++i)
+    {
+        if (!(constants_set & 1)) continue;
 
-            TRACE_(d3d_constants)("Loading constants %i: %i, %i, %i, %i\n",
-                  i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
+        TRACE_(d3d_constants)("Loading constants %u: %i, %i, %i, %i\n",
+                i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
 
-            /* We found this uniform name in the program - go ahead and send the data */
-            GL_EXTCALL(glUniform4ivARB(locations[i], 1, &constants[i*4]));
-            checkGLcall("glUniform4ivARB");
-        }
+        /* We found this uniform name in the program - go ahead and send the data */
+        GL_EXTCALL(glUniform4ivARB(locations[i], 1, &constants[i*4]));
+        checkGLcall("glUniform4ivARB");
     }
 
     /* Load immediate constants */
     ptr = list_head(&This->baseShader.constantsI);
     while (ptr) {
-        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        const struct local_constant *lconst = LIST_ENTRY(ptr, const struct local_constant, entry);
         unsigned int idx = lconst->idx;
-        GLint* values = (GLint*) lconst->value;
+        const GLint *values = (const GLint *)lconst->value;
 
         TRACE_(d3d_constants)("Loading local constants %i: %i, %i, %i, %i\n", idx,
             values[0], values[1], values[2], values[3]);
@@ -336,48 +328,43 @@ static void shader_glsl_load_constantsI(
     }
 }
 
-/** 
- * Loads boolean constants (aka uniforms) into the currently set GLSL program.
- * When @constants_set == NULL, it will load all the constants.
- */
-static void shader_glsl_load_constantsB(
-    IWineD3DBaseShaderImpl* This,
-    WineD3D_GL_Info *gl_info,
-    GLhandleARB programId,
-    unsigned max_constants,
-    BOOL* constants,
-    BOOL* constants_set) {
-    
+/* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
+static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+        GLhandleARB programId, const BOOL *constants, WORD constants_set)
+{
     GLhandleARB tmp_loc;
-    int i;
+    unsigned int i;
     char tmp_name[8];
     char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
     const char* prefix = is_pshader? "PB":"VB";
     struct list* ptr;
 
-    for (i=0; i<max_constants; ++i) {
-        if (NULL == constants_set || constants_set[i]) {
+    /* TODO: Benchmark and see if it would be beneficial to store the
+     * locations of the constants to avoid looking up each time */
+    for (i = 0; constants_set; constants_set >>= 1, ++i)
+    {
+        if (!(constants_set & 1)) continue;
 
-            TRACE_(d3d_constants)("Loading constants %i: %i;\n", i, constants[i]);
+        TRACE_(d3d_constants)("Loading constants %i: %i;\n", i, constants[i]);
 
-            /* TODO: Benchmark and see if it would be beneficial to store the 
-             * locations of the constants to avoid looking up each time */
-            snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
-            tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
-            if (tmp_loc != -1) {
-                /* We found this uniform name in the program - go ahead and send the data */
-                GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
-                checkGLcall("glUniform1ivARB");
-            }
+        /* TODO: Benchmark and see if it would be beneficial to store the
+         * locations of the constants to avoid looking up each time */
+        snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
+        tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+        if (tmp_loc != -1)
+        {
+            /* We found this uniform name in the program - go ahead and send the data */
+            GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
+            checkGLcall("glUniform1ivARB");
         }
     }
 
     /* Load immediate constants */
     ptr = list_head(&This->baseShader.constantsB);
     while (ptr) {
-        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        const struct local_constant *lconst = LIST_ENTRY(ptr, const struct local_constant, entry);
         unsigned int idx = lconst->idx;
-        GLint* values = (GLint*) lconst->value;
+        const GLint *values = (const GLint *)lconst->value;
 
         TRACE_(d3d_constants)("Loading local constants %i: %i\n", idx, values[0]);
 
@@ -403,15 +390,15 @@ static void shader_glsl_load_constants(
     char useVertexShader) {
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv;
+    const struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv;
     IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
-    WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
 
-    GLhandleARB *constant_locations;
-    struct list *constant_list;
+    const GLhandleARB *constant_locations;
+    const struct list *constant_list;
     GLhandleARB programId;
-    struct glsl_shader_prog_link *prog = priv->glsl_program;
-    unsigned int i;
+    const struct glsl_shader_prog_link *prog = priv->glsl_program;
+    int i;
 
     if (!prog) {
         /* No GLSL program set - nothing to do. */
@@ -430,15 +417,12 @@ static void shader_glsl_load_constants(
                 stateBlock->vertexShaderConstantF, constant_locations, constant_list);
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
-        shader_glsl_load_constantsI(vshader, gl_info, programId,
-                                    prog->vuniformI_locations, MAX_CONST_I,
-                                    stateBlock->vertexShaderConstantI,
-                                    stateBlock->changed.vertexShaderConstantsI);
+        shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations,
+                stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI);
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
-        shader_glsl_load_constantsB(vshader, gl_info, programId, MAX_CONST_B,
-                                    stateBlock->vertexShaderConstantB,
-                                    stateBlock->changed.vertexShaderConstantsB);
+        shader_glsl_load_constantsB(vshader, gl_info, programId,
+                stateBlock->vertexShaderConstantB, stateBlock->changed.vertexShaderConstantsB);
 
         /* Upload the position fixup params */
         GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
@@ -457,15 +441,12 @@ static void shader_glsl_load_constants(
                 stateBlock->pixelShaderConstantF, constant_locations, constant_list);
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
-        shader_glsl_load_constantsI(pshader, gl_info, programId,
-                                    prog->puniformI_locations, MAX_CONST_I,
-                                    stateBlock->pixelShaderConstantI, 
-                                    stateBlock->changed.pixelShaderConstantsI);
+        shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations,
+                stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI);
 
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
-        shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
-                                    stateBlock->pixelShaderConstantB, 
-                                    stateBlock->changed.pixelShaderConstantsB);
+        shader_glsl_load_constantsB(pshader, gl_info, programId,
+                stateBlock->pixelShaderConstantB, stateBlock->changed.pixelShaderConstantsB);
 
         /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
          * It can't be 0 for a valid texbem instruction.
@@ -474,7 +455,7 @@ static void shader_glsl_load_constants(
             IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pshader;
             int stage = ps->luminanceconst[i].texunit;
 
-            float *data = (float *) &stateBlock->textureState[(int) ps->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
+            const float *data = (const float *)&stateBlock->textureState[(int)ps->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
             GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location[i], 1, 0, data));
             checkGLcall("glUniformMatrix2fvARB");
 
@@ -482,8 +463,8 @@ static void shader_glsl_load_constants(
              * is set too, so we can check that in the needsbumpmat check
              */
             if(ps->baseShader.reg_maps.luminanceparams[stage]) {
-                GLfloat *scale = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
-                GLfloat *offset = (GLfloat *) &stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
+                const GLfloat *scale = (const GLfloat *)&stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
+                const GLfloat *offset = (const GLfloat *)&stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
 
                 GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
                 checkGLcall("glUniform1fvARB");
@@ -492,28 +473,6 @@ static void shader_glsl_load_constants(
             }
         }
 
-        if(((IWineD3DPixelShaderImpl *) pshader)->srgb_enabled &&
-                  !((IWineD3DPixelShaderImpl *) pshader)->srgb_mode_hardcoded) {
-            float comparison[4];
-            float mul_low[4];
-
-            if(stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
-                comparison[0] = srgb_cmp; comparison[1] = srgb_cmp;
-                comparison[2] = srgb_cmp; comparison[3] = srgb_cmp;
-
-                mul_low[0] = srgb_mul_low; mul_low[1] = srgb_mul_low;
-                mul_low[2] = srgb_mul_low; mul_low[3] = srgb_mul_low;
-            } else {
-                comparison[0] = 1.0 / 0.0; comparison[1] = 1.0 / 0.0;
-                comparison[2] = 1.0 / 0.0; comparison[3] = 1.0 / 0.0;
-
-                mul_low[0] = 1.0; mul_low[1] = 1.0;
-                mul_low[2] = 1.0; mul_low[3] = 1.0;
-            }
-
-            GL_EXTCALL(glUniform4fvARB(prog->srgb_comparison_location, 1, comparison));
-            GL_EXTCALL(glUniform4fvARB(prog->srgb_mul_low_location, 1, mul_low));
-        }
         if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
             float correction_params[4];
             if(deviceImpl->render_offscreen) {
@@ -530,17 +489,13 @@ static void shader_glsl_load_constants(
 }
 
 /** Generate the variable & register declarations for the GLSL output target */
-static void shader_generate_glsl_declarations(
-    IWineD3DBaseShader *iface,
-    shader_reg_maps* reg_maps,
-    SHADER_BUFFER* buffer,
-    WineD3D_GL_Info* gl_info) {
-
+static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
+        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
+{
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
-    int i;
-    unsigned int extra_constants_needed = 0;
-    local_constant* lconst;
+    unsigned int i, extra_constants_needed = 0;
+    const local_constant *lconst;
 
     /* There are some minor differences between pixel and vertex shaders */
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
@@ -608,27 +563,10 @@ static void shader_generate_glsl_declarations(
         }
 
         if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
-            ps_impl->srgb_enabled = 1;
-            if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) {
-                shader_addline(buffer, "uniform vec4 srgb_mul_low;\n");
-                shader_addline(buffer, "uniform vec4 srgb_comparison;\n");
-                ps_impl->srgb_mode_hardcoded = 0;
-                extra_constants_needed++;
-            } else {
-                ps_impl->srgb_mode_hardcoded = 1;
-                shader_addline(buffer, "const vec4 srgb_mul_low = vec4(%f, %f, %f, %f);\n",
-                               srgb_mul_low, srgb_mul_low, srgb_mul_low, srgb_mul_low);
-                shader_addline(buffer, "const vec4 srgb_comparison = vec4(%f, %f, %f, %f);\n",
-                               srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
-            }
-        } else {
-            IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
-
-            /* Do not write any srgb fixup into the shader to save shader size and processing time.
-             * As a consequence, we can't toggle srgb write on without recompilation
-             */
-            ps_impl->srgb_enabled = 0;
-            ps_impl->srgb_mode_hardcoded = 1;
+            shader_addline(buffer, "const vec4 srgb_mul_low = vec4(%f, %f, %f, %f);\n",
+                            srgb_mul_low, srgb_mul_low, srgb_mul_low, srgb_mul_low);
+            shader_addline(buffer, "const vec4 srgb_comparison = vec4(%f, %f, %f, %f);\n",
+                            srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
         }
         if(reg_maps->vpos || reg_maps->usesdsy) {
             if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) {
@@ -772,7 +710,7 @@ static void shader_generate_glsl_declarations(
  ****************************************************************************/
 
 /* Prototypes */
-static void shader_glsl_add_src_param(SHADER_OPCODE_ARG* arg, const DWORD param,
+static void shader_glsl_add_src_param(const SHADER_OPCODE_ARG *arg, const DWORD param,
         const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param);
 
 /** Used for opcode modifiers - They multiply the result by the specified amount */
@@ -854,13 +792,9 @@ static void shader_glsl_gen_modifier (
 
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
-static void shader_glsl_get_register_name(
-    const DWORD param,
-    const DWORD addr_token,
-    char* regstr,
-    BOOL* is_color,
-    SHADER_OPCODE_ARG* arg) {
-
+static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_token,
+        char *regstr, BOOL *is_color, const SHADER_OPCODE_ARG *arg)
+{
     /* oPos, oFog and oPts in D3D */
     static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
 
@@ -868,7 +802,7 @@ static void shader_glsl_get_register_name(
     DWORD regtype = shader_get_regtype(param);
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-    WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+    const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
 
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
     char tmpStr[150];
@@ -1103,8 +1037,9 @@ static void shader_glsl_get_swizzle(const DWORD param, BOOL fixup, DWORD mask, c
 /* From a given parameter token, generate the corresponding GLSL string.
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
-static void shader_glsl_add_src_param(SHADER_OPCODE_ARG* arg, const DWORD param,
-        const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param) {
+static void shader_glsl_add_src_param(const SHADER_OPCODE_ARG *arg, const DWORD param,
+        const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param)
+{
     BOOL is_color = FALSE;
     char swizzle_str[6];
 
@@ -1121,8 +1056,9 @@ static void shader_glsl_add_src_param(SHADER_OPCODE_ARG* arg, const DWORD param,
 /* From a given parameter token, generate the corresponding GLSL string.
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
-static DWORD shader_glsl_add_dst_param(SHADER_OPCODE_ARG* arg, const DWORD param,
-        const DWORD addr_token, glsl_dst_param_t *dst_param) {
+static DWORD shader_glsl_add_dst_param(const SHADER_OPCODE_ARG* arg, const DWORD param,
+        const DWORD addr_token, glsl_dst_param_t *dst_param)
+{
     BOOL is_color = FALSE;
 
     dst_param->mask_str[0] = '\0';
@@ -1133,7 +1069,8 @@ static DWORD shader_glsl_add_dst_param(SHADER_OPCODE_ARG* arg, const DWORD param
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
-static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer, SHADER_OPCODE_ARG *arg, const DWORD param) {
+static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer, const SHADER_OPCODE_ARG *arg, const DWORD param)
+{
     glsl_dst_param_t dst_param;
     DWORD mask;
     int shift;
@@ -1149,13 +1086,14 @@ static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer, SHADER_OPCODE_ARG
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
-static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, SHADER_OPCODE_ARG *arg) {
+static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const SHADER_OPCODE_ARG *arg)
+{
     return shader_glsl_append_dst_ext(buffer, arg, arg->dst);
 }
 
 /** Process GLSL instruction modifiers */
-void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG* arg) {
-    
+void shader_glsl_add_instruction_modifiers(const SHADER_OPCODE_ARG* arg)
+{
     DWORD mask = arg->dst & WINED3DSP_DSTMOD_MASK;
  
     if (arg->opcode->dst_token && mask != 0) {
@@ -1225,198 +1163,112 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, BOOL projected,
     }
 }
 
-static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {
-    IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
-    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) shader->baseShader.device;
-    WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
-    glsl_dst_param_t dst_param;
-    glsl_dst_param_t dst_param2;
-    WINED3DFORMAT fmt;
-    WINED3DFORMAT conversion_group;
-    IWineD3DBaseTextureImpl *texture;
-    DWORD mask, mask_size;
-    UINT i;
-    BOOL recorded = FALSE;
-    DWORD sampler_idx;
-    DWORD hex_version = shader->baseShader.hex_version;
-
-    switch(arg->opcode->opcode) {
-        case WINED3DSIO_TEX:
-            if (hex_version < WINED3DPS_VERSION(2,0)) {
-                sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
-            } else {
-                sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
-            }
+static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name,
+        BOOL sign_fixup, enum fixup_channel_source channel_source)
+{
+    switch(channel_source)
+    {
+        case CHANNEL_SOURCE_ZERO:
+            strcat(arguments, "0.0");
             break;
 
-        case WINED3DSIO_TEXLDL:
-            FIXME("Add color fixup for vertex texture WINED3DSIO_TEXLDL\n");
-            return;
-
-        case WINED3DSIO_TEXDP3TEX:
-        case WINED3DSIO_TEXM3x3TEX:
-        case WINED3DSIO_TEXM3x3SPEC:
-        case WINED3DSIO_TEXM3x3VSPEC:
-        case WINED3DSIO_TEXBEM:
-        case WINED3DSIO_TEXREG2AR:
-        case WINED3DSIO_TEXREG2GB:
-        case WINED3DSIO_TEXREG2RGB:
-            sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
+        case CHANNEL_SOURCE_ONE:
+            strcat(arguments, "1.0");
             break;
 
-        default:
-            /* Not a texture sampling instruction, nothing to do */
-            return;
-    };
-
-    texture = (IWineD3DBaseTextureImpl *) deviceImpl->stateBlock->textures[sampler_idx];
-    if(texture) {
-        fmt = texture->resource.format;
-        conversion_group = texture->baseTexture.shader_conversion_group;
-    } else {
-        fmt = WINED3DFMT_UNKNOWN;
-        conversion_group = WINED3DFMT_UNKNOWN;
-    }
-
-    /* before doing anything, record the sampler with the format in the format conversion list,
-     * but check if it's not there already
-     */
-    for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
-        if(shader->baseShader.sampled_samplers[i] == sampler_idx) {
-            recorded = TRUE;
-            break;
-        }
-    }
-    if(!recorded) {
-        shader->baseShader.sampled_samplers[shader->baseShader.num_sampled_samplers] = sampler_idx;
-        shader->baseShader.num_sampled_samplers++;
-        shader->baseShader.sampled_format[sampler_idx] = conversion_group;
-    }
-
-    switch(fmt) {
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER) && fmt == WINED3DFMT_V8U8) {
-                /* The 3rd channel returns 1.0 in d3d, but 0.0 in gl. Fix this while we're at it :-) */
-                mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_2, &dst_param);
-                mask_size = shader_glsl_get_write_mask_size(mask);
-                if(mask_size >= 3) {
-                    shader_addline(arg->buffer, "%s.%c = 1.0;\n", dst_param.reg_name, dst_param.mask_str[3]);
-                }
-            } else {
-                /* Correct the sign, but leave the blue as it is - it was loaded correctly already */
-                mask = shader_glsl_add_dst_param(arg, arg->dst,
-                                          WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1,
-                                          &dst_param);
-                mask_size = shader_glsl_get_write_mask_size(mask);
-                if(mask_size >= 2) {
-                    shader_addline(arg->buffer, "%s.%c%c = %s.%c%c * 2.0 - 1.0;\n",
-                    dst_param.reg_name, dst_param.mask_str[1], dst_param.mask_str[2],
-                    dst_param.reg_name, dst_param.mask_str[1], dst_param.mask_str[2]);
-                } else if(mask_size == 1) {
-                    shader_addline(arg->buffer, "%s.%c = %s.%c * 2.0 - 1.0;\n", dst_param.reg_name, dst_param.mask_str[1],
-                    dst_param.reg_name, dst_param.mask_str[1]);
-                }
-            }
+        case CHANNEL_SOURCE_X:
+            strcat(arguments, reg_name);
+            strcat(arguments, ".x");
             break;
 
-        case WINED3DFMT_X8L8V8U8:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                /* Red and blue are the signed channels, fix them up; Blue(=L) is correct already,
-                 * and a(X) is always 1.0
-                 */
-                mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);
-                mask_size = shader_glsl_get_write_mask_size(mask);
-                if(mask_size >= 2) {
-                    shader_addline(arg->buffer, "%s.%c%c = %s.%c%c * 2.0 - 1.0;\n",
-                                   dst_param.reg_name, dst_param.mask_str[1], dst_param.mask_str[2],
-                                   dst_param.reg_name, dst_param.mask_str[1], dst_param.mask_str[2]);
-                } else if(mask_size == 1) {
-                    shader_addline(arg->buffer, "%s.%c = %s.%c * 2.0 - 1.0;\n",
-                                   dst_param.reg_name, dst_param.mask_str[1],
-                                   dst_param.reg_name, dst_param.mask_str[1]);
-                }
-            }
+        case CHANNEL_SOURCE_Y:
+            strcat(arguments, reg_name);
+            strcat(arguments, ".y");
             break;
 
-        case WINED3DFMT_L6V5U5:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);
-                mask_size = shader_glsl_get_write_mask_size(mask);
-                shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_2, &dst_param2);
-                if(mask_size >= 3) {
-                    /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
-                    shader_addline(arg->buffer, "tmp0.g = %s.%c;\n",
-                                   dst_param.reg_name, dst_param.mask_str[2]);
-                    shader_addline(arg->buffer, "%s.%c%c = %s.%c%c * 2.0 - 1.0;\n",
-                                   dst_param.reg_name, dst_param.mask_str[2], dst_param.mask_str[1],
-                                   dst_param2.reg_name, dst_param.mask_str[1], dst_param.mask_str[3]);
-                    shader_addline(arg->buffer, "%s.%c = tmp0.g;\n", dst_param.reg_name,
-                                   dst_param.mask_str[3]);
-                } else if(mask_size == 2) {
-                    /* This is bad: We have VL, but we need VU */
-                    FIXME("2 components sampled from a converted L6V5U5 texture\n");
-                } else {
-                    shader_addline(arg->buffer, "%s.%c = %s.%c * 2.0 - 1.0;\n",
-                                   dst_param.reg_name, dst_param.mask_str[1],
-                                   dst_param2.reg_name, dst_param.mask_str[1]);
-                }
-            }
-            break;
-
-        case WINED3DFMT_Q8W8V8U8:
-            if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                /* Correct the sign in all channels. The writemask just applies as-is, no
-                 * need for checking the mask size
-                 */
-                shader_glsl_add_dst_param(arg, arg->dst,
-                                          WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 |
-                                          WINED3DSP_WRITEMASK_2 | WINED3DSP_WRITEMASK_3,
-                                          &dst_param);
-                shader_addline(arg->buffer, "%s%s = %s%s * 2.0 - 1.0;\n", dst_param.reg_name, dst_param.mask_str,
-                               dst_param.reg_name, dst_param.mask_str);
-            }
+        case CHANNEL_SOURCE_Z:
+            strcat(arguments, reg_name);
+            strcat(arguments, ".z");
             break;
 
-        case WINED3DFMT_ATI2N:
-            /* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
-             * which means the first one is replicated across .rgb, and the 2nd one is in
-             * .a. We need the 2nd in .g
-             *
-             * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they
-             * are swapped compared to d3d. So swap red and green.
-             */
-            mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);
-            mask_size = shader_glsl_get_write_mask_size(mask);
-            if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
-                if(mask_size >= 2) {
-                    shader_addline(arg->buffer, "%s.%c%c = %s.%c%c;\n",
-                                dst_param.reg_name, dst_param.mask_str[1],
-                                                    dst_param.mask_str[2],
-                                dst_param.reg_name, dst_param.mask_str[2],
-                                                    dst_param.mask_str[1]);
-                } else {
-                    FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
-                }
-            } else {
-                if(mask_size == 4) {
-                    /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
-                    shader_addline(arg->buffer, "%s.%c = %s.%c;\n",
-                                dst_param.reg_name, dst_param.mask_str[2],
-                                dst_param.reg_name, dst_param.mask_str[4]);
-                } else if(mask_size == 1) {
-                    /* Nothing to do */
-                } else {
-                    FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
-                    /* This is bad: We have .r[gb], but we need .ra */
-                }
-            }
+        case CHANNEL_SOURCE_W:
+            strcat(arguments, reg_name);
+            strcat(arguments, ".w");
             break;
 
-            /* stupid compiler */
         default:
+            FIXME("Unhandled channel source %#x\n", channel_source);
+            strcat(arguments, "undefined");
             break;
     }
+
+    if (sign_fixup) strcat(arguments, " * 2.0 - 1.0");
+}
+
+static void shader_glsl_color_correction(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup)
+{
+    unsigned int mask_size, remaining;
+    glsl_dst_param_t dst_param;
+    char arguments[256];
+    DWORD mask;
+    BOOL dummy;
+
+    mask = 0;
+    if (fixup.x_sign_fixup || fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0;
+    if (fixup.y_sign_fixup || fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1;
+    if (fixup.z_sign_fixup || fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2;
+    if (fixup.w_sign_fixup || fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3;
+    mask &= arg->dst;
+
+    if (!mask) return; /* Nothing to do */
+
+    if (is_yuv_fixup(fixup))
+    {
+        enum yuv_fixup yuv_fixup = get_yuv_fixup(fixup);
+        FIXME("YUV fixup (%#x) not supported\n", yuv_fixup);
+        return;
+    }
+
+    mask_size = shader_glsl_get_write_mask_size(mask);
+
+    dst_param.mask_str[0] = '\0';
+    shader_glsl_get_write_mask(mask, dst_param.mask_str);
+
+    dst_param.reg_name[0] = '\0';
+    shader_glsl_get_register_name(arg->dst, arg->dst_addr, dst_param.reg_name, &dummy, arg);
+
+    arguments[0] = '\0';
+    remaining = mask_size;
+    if (mask & WINED3DSP_WRITEMASK_0)
+    {
+        shader_glsl_append_fixup_arg(arguments, dst_param.reg_name, fixup.x_sign_fixup, fixup.x_source);
+        if (--remaining) strcat(arguments, ", ");
+    }
+    if (mask & WINED3DSP_WRITEMASK_1)
+    {
+        shader_glsl_append_fixup_arg(arguments, dst_param.reg_name, fixup.y_sign_fixup, fixup.y_source);
+        if (--remaining) strcat(arguments, ", ");
+    }
+    if (mask & WINED3DSP_WRITEMASK_2)
+    {
+        shader_glsl_append_fixup_arg(arguments, dst_param.reg_name, fixup.z_sign_fixup, fixup.z_source);
+        if (--remaining) strcat(arguments, ", ");
+    }
+    if (mask & WINED3DSP_WRITEMASK_3)
+    {
+        shader_glsl_append_fixup_arg(arguments, dst_param.reg_name, fixup.w_sign_fixup, fixup.w_source);
+        if (--remaining) strcat(arguments, ", ");
+    }
+
+    if (mask_size > 1)
+    {
+        shader_addline(arg->buffer, "%s%s = vec%u(%s);\n",
+                dst_param.reg_name, dst_param.mask_str, mask_size, arguments);
+    }
+    else
+    {
+        shader_addline(arg->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
+    }
 }
 
 /*****************************************************************************
@@ -1426,7 +1278,8 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {
  ****************************************************************************/
 
 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
-static void shader_glsl_arith(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_arith(const SHADER_OPCODE_ARG *arg)
+{
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src0_param;
@@ -1452,7 +1305,8 @@ static void shader_glsl_arith(SHADER_OPCODE_ARG* arg) {
 }
 
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
-static void shader_glsl_mov(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src0_param;
@@ -1487,7 +1341,8 @@ static void shader_glsl_mov(SHADER_OPCODE_ARG* arg) {
 }
 
 /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
-static void shader_glsl_dot(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_dot(const SHADER_OPCODE_ARG *arg)
+{
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src0_param;
@@ -1517,7 +1372,8 @@ static void shader_glsl_dot(SHADER_OPCODE_ARG* arg) {
 
 /* Note that this instruction has some restrictions. The destination write mask
  * can't contain the w component, and the source swizzles have to be .xyzw */
-static void shader_glsl_cross(SHADER_OPCODE_ARG *arg) {
+static void shader_glsl_cross(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
@@ -1533,7 +1389,8 @@ static void shader_glsl_cross(SHADER_OPCODE_ARG *arg) {
 /* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
  * Src0 and src1 are scalars. Note that D3D uses the absolute of src0, while
  * GLSL uses the value as-is. */
-static void shader_glsl_pow(SHADER_OPCODE_ARG *arg) {
+static void shader_glsl_pow(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER *buffer = arg->buffer;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
@@ -1556,7 +1413,8 @@ static void shader_glsl_pow(SHADER_OPCODE_ARG *arg) {
 /* Process the WINED3DSIO_LOG instruction in GLSL (dst = log2(|src0|))
  * Src0 is a scalar. Note that D3D uses the absolute of src0, while
  * GLSL uses the value as-is. */
-static void shader_glsl_log(SHADER_OPCODE_ARG *arg) {
+static void shader_glsl_log(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER *buffer = arg->buffer;
     glsl_src_param_t src0_param;
     DWORD dst_write_mask;
@@ -1575,7 +1433,8 @@ static void shader_glsl_log(SHADER_OPCODE_ARG *arg) {
 }
 
 /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
-static void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg)
+{
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src_param;
@@ -1626,7 +1485,8 @@ static void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
  * For 2.0 shaders, just do this (honoring writemask and swizzle):
  *   dst = 2^src;    (partial precision is allowed, but optional)
  */
-static void shader_glsl_expp(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_expp(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
     glsl_src_param_t src_param;
 
@@ -1659,7 +1519,8 @@ static void shader_glsl_expp(SHADER_OPCODE_ARG* arg) {
 }
 
 /** Process the RCP (reciprocal or inverse) opcode in GLSL (dst = 1 / src) */
-static void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_rcp(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src_param;
     DWORD write_mask;
     unsigned int mask_size;
@@ -1675,7 +1536,8 @@ static void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_rsq(const SHADER_OPCODE_ARG *arg)
+{
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src_param;
     DWORD write_mask;
@@ -1694,7 +1556,8 @@ static void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) {
 }
 
 /** Process signed comparison opcodes in GLSL. */
-static void shader_glsl_compare(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_compare(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD write_mask;
@@ -1741,7 +1604,8 @@ static void shader_glsl_compare(SHADER_OPCODE_ARG* arg) {
 }
 
 /** Process CMP instruction in GLSL (dst = src0 >= 0.0 ? src1 : src2), per channel */
-static void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_cmp(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
@@ -1817,7 +1681,8 @@ static void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) {
 /** Process the CND opcode in GLSL (dst = (src0 > 0.5) ? src1 : src2) */
 /* For ps 1.1-1.3, only a single component of src0 is used. For ps 1.4
  * the compare is done per component of src0. */
-static void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_cnd(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
@@ -1863,7 +1728,8 @@ static void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) {
 }
 
 /** GLSL code generation for WINED3DSIO_MAD: Multiply the first 2 opcodes, then add the last */
-static void shader_glsl_mad(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_mad(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
@@ -1879,7 +1745,11 @@ static void shader_glsl_mad(SHADER_OPCODE_ARG* arg) {
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for 
     Vertex shaders to GLSL codes */
-static void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_mnxn(const SHADER_OPCODE_ARG *arg)
+{
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
+    const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
+    DWORD shader_version = shader->baseShader.hex_version;
     int i;
     int nComponents = 0;
     SHADER_OPCODE_ARG tmpArg;
@@ -1897,23 +1767,23 @@ static void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) {
     switch(arg->opcode->opcode) {
         case WINED3DSIO_M4x4:
             nComponents = 4;
-            tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP4);
+            tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP4);
             break;
         case WINED3DSIO_M4x3:
             nComponents = 3;
-            tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP4);
+            tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP4);
             break;
         case WINED3DSIO_M3x4:
             nComponents = 4;
-            tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+            tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
             break;
         case WINED3DSIO_M3x3:
             nComponents = 3;
-            tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+            tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
             break;
         case WINED3DSIO_M3x2:
             nComponents = 2;
-            tmpArg.opcode = shader_get_opcode(arg->shader, WINED3DSIO_DP3);
+            tmpArg.opcode = shader_get_opcode(opcode_table, shader_version, WINED3DSIO_DP3);
             break;
         default:
             break;
@@ -1932,7 +1802,8 @@ static void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) {
     blend factor.  Equation:  (dst = src2 + src0 * (src1 - src2))
     This is equivalent to mix(src2, src1, src0);
 */
-static void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_lrp(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
@@ -1954,7 +1825,8 @@ static void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) {
  * dst.z = (src0.x > 0) ? ((src0.y > 0) ? pow(src0.y, src.w) : 0) : 0
  *                                        where src.w is clamped at +- 128
  */
-static void shader_glsl_lit(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_lit(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src3_param;
@@ -1998,7 +1870,8 @@ static void shader_glsl_lit(SHADER_OPCODE_ARG* arg) {
  * dst.z = src0.z
  * dst.w = src1.w
  */
-static void shader_glsl_dst(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_dst(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0y_param;
     glsl_src_param_t src0z_param;
     glsl_src_param_t src1y_param;
@@ -2026,7 +1899,8 @@ static void shader_glsl_dst(SHADER_OPCODE_ARG* arg) {
  * dst.z = dst.z
  * dst.w = dst.w
  */
-static void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_sincos(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
@@ -2058,13 +1932,14 @@ static void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
  *  Need to use a temporary variable for this operation.
  */
 /* FIXME: I don't think nested loops will work correctly this way. */
-static void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_loop(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src1_param;
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
     DWORD regtype = shader_get_regtype(arg->src[1]);
     DWORD reg = arg->src[1] & WINED3DSP_REGNUM_MASK;
     const DWORD *control_values = NULL;
-    local_constant *constant;
+    const local_constant *constant;
 
     shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
 
@@ -2110,7 +1985,8 @@ static void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
     shader->baseShader.cur_loop_regno++;
 }
 
-static void shader_glsl_end(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_end(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
 
     shader_addline(arg->buffer, "}\n");
@@ -2124,7 +2000,8 @@ static void shader_glsl_end(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void shader_glsl_rep(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_rep(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
     glsl_src_param_t src0_param;
 
@@ -2135,14 +2012,16 @@ static void shader_glsl_rep(SHADER_OPCODE_ARG* arg) {
     shader->baseShader.cur_loop_depth++;
 }
 
-static void shader_glsl_if(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_if(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
 
     shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
     shader_addline(arg->buffer, "if (%s) {\n", src0_param.param_str);
 }
 
-static void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_ifc(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
 
@@ -2153,16 +2032,19 @@ static void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) {
             src0_param.param_str, shader_get_comp_op(arg->opcode_token), src1_param.param_str);
 }
 
-static void shader_glsl_else(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_else(const SHADER_OPCODE_ARG *arg)
+{
     shader_addline(arg->buffer, "} else {\n");
 }
 
-static void shader_glsl_break(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_break(const SHADER_OPCODE_ARG *arg)
+{
     shader_addline(arg->buffer, "break;\n");
 }
 
 /* FIXME: According to MSDN the compare is done per component. */
-static void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_breakc(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
 
@@ -2173,19 +2055,22 @@ static void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) {
             src0_param.param_str, shader_get_comp_op(arg->opcode_token), src1_param.param_str);
 }
 
-static void shader_glsl_label(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_label(const SHADER_OPCODE_ARG *arg)
+{
 
     DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK;
     shader_addline(arg->buffer, "}\n");
     shader_addline(arg->buffer, "void subroutine%u () {\n",  snum);
 }
 
-static void shader_glsl_call(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_call(const SHADER_OPCODE_ARG *arg)
+{
     DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK;
     shader_addline(arg->buffer, "subroutine%u();\n", snum);
 }
 
-static void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_callnz(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src1_param;
 
     DWORD snum = (arg->src[0]) & WINED3DSP_REGNUM_MASK;
@@ -2196,7 +2081,8 @@ static void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) {
 /*********************************************
  * Pixel Shader Specific Code begins here
  ********************************************/
-static void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD hex_version = This->baseShader.hex_version;
@@ -2295,7 +2181,8 @@ static void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) {
+static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*)arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     glsl_sample_function_t sample_function;
@@ -2330,8 +2217,8 @@ static void shader_glsl_texldl(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg)
+{
     /* FIXME: Make this work for more than just 2D textures */
     
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
@@ -2382,7 +2269,8 @@ static void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
 /** Process the WINED3DSIO_TEXDP3TEX instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src,
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
-static void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texdp3tex(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     char dst_mask[6];
     glsl_sample_function_t sample_function;
@@ -2424,7 +2312,8 @@ static void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXDP3 instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
-static void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texdp3(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@@ -2444,7 +2333,8 @@ static void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXDEPTH instruction in GLSL:
  * Calculate the depth as dst.x / dst.y   */
-static void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texdepth(const SHADER_OPCODE_ARG *arg)
+{
     glsl_dst_param_t dst_param;
 
     shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
@@ -2463,7 +2353,8 @@ static void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) {
  * Calculate tmp0.y = TexCoord[dstreg] . src.xyz;  (tmp0.x has already been calculated)
  * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
  */
-static void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texm3x2depth(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK;
     glsl_src_param_t src0_param;
@@ -2476,7 +2367,8 @@ static void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
  * Calculate the 1st of a 2-row matrix multiplication. */
-static void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texm3x2pad(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -2488,8 +2380,8 @@ static void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3PAD instruction in GLSL
  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
-static void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_glsl_texm3x3pad(const SHADER_OPCODE_ARG* arg)
+{
     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
@@ -2502,7 +2394,8 @@ static void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) {
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
-static void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texm3x2tex(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -2521,7 +2414,8 @@ static void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */
-static void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texm3x3tex(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
     char dst_mask[6];
@@ -2547,7 +2441,8 @@ static void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply */
-static void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texm3x3(const SHADER_OPCODE_ARG *arg)
+{
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
     char dst_mask[6];
@@ -2566,8 +2461,8 @@ static void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL 
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
-static void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_glsl_texm3x3spec(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     glsl_src_param_t src0_param;
@@ -2600,8 +2495,8 @@ static void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL 
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
-static void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_glsl_texm3x3vspec(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = arg->buffer;
@@ -2637,7 +2532,8 @@ static void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
  * Apply a fake bump map transform.
  * texbem is pshader <= 1.3 only, this saves a few version checks
  */
-static void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texbem(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     char dst_swizzle[6];
@@ -2692,7 +2588,8 @@ static void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_bem(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param, src1_param;
     DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
 
@@ -2706,8 +2603,8 @@ static void pshader_glsl_bem(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
-static void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) {
-
+static void pshader_glsl_texreg2ar(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
     char dst_mask[6];
@@ -2721,7 +2618,8 @@ static void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXREG2GB instruction in GLSL
  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
-static void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texreg2gb(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
     char dst_mask[6];
@@ -2735,7 +2633,8 @@ static void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL
  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
-static void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     char dst_mask[6];
     DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
@@ -2753,7 +2652,8 @@ static void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_TEXKILL instruction in GLSL.
  * If any of the first 3 components are < 0, discard this pixel */
-static void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_texkill(const SHADER_OPCODE_ARG *arg)
+{
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     DWORD hex_version = This->baseShader.hex_version;
     glsl_dst_param_t dst_param;
@@ -2774,7 +2674,8 @@ static void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) {
 
 /** Process the WINED3DSIO_DP2ADD instruction in GLSL.
  * dst = dot2(src0, src1) + src2 */
-static void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) {
+static void pshader_glsl_dp2add(const SHADER_OPCODE_ARG *arg)
+{
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
@@ -2795,11 +2696,9 @@ static void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) {
     }
 }
 
-static void pshader_glsl_input_pack(
-   SHADER_BUFFER* buffer,
-   semantic* semantics_in,
-   IWineD3DPixelShader *iface) {
-
+static void pshader_glsl_input_pack(SHADER_BUFFER* buffer, const struct semantic* semantics_in,
+        IWineD3DPixelShader *iface, enum vertexprocessing_mode vertexprocessing)
+{
    unsigned int i;
    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
 
@@ -2819,7 +2718,7 @@ static void pshader_glsl_input_pack(
        switch(usage) {
 
            case WINED3DDECLUSAGE_TEXCOORD:
-               if(usage_idx < 8 && This->vertexprocessing == pretransformed) {
+               if(usage_idx < 8 && vertexprocessing == pretransformed) {
                    shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
                                   This->input_reg_map[i], reg_mask, usage_idx, reg_mask);
                } else {
@@ -2857,26 +2756,31 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
+    key->ps_args = entry->ps_args;
 
     hash_table_put(priv->glsl_program_lookup, key, entry);
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
-        GLhandleARB vshader, GLhandleARB pshader) {
+        GLhandleARB vshader, IWineD3DPixelShader *pshader, struct ps_compile_args *ps_args) {
     glsl_program_key_t key;
 
     key.vshader = vshader;
     key.pshader = pshader;
+    key.ps_args = *ps_args;
 
     return (struct glsl_shader_prog_link *)hash_table_get(priv->glsl_program_lookup, &key);
 }
 
-static void delete_glsl_program_entry(struct shader_glsl_priv *priv, WineD3D_GL_Info *gl_info, struct glsl_shader_prog_link *entry) {
+static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info,
+        struct glsl_shader_prog_link *entry)
+{
     glsl_program_key_t *key;
 
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
+    key->ps_args = entry->ps_args;
     hash_table_remove(priv->glsl_program_lookup, key);
 
     GL_EXTCALL(glDeleteObjectARB(entry->programId));
@@ -2887,7 +2791,9 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, WineD3D_GL_
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
-static void handle_ps3_input(SHADER_BUFFER *buffer, semantic *semantics_in, semantic *semantics_out, WineD3D_GL_Info *gl_info, DWORD *map) {
+static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *semantics_in,
+        const struct semantic *semantics_out, const WineD3D_GL_Info *gl_info, const DWORD *map)
+{
     unsigned int i, j;
     DWORD usage_token, usage_token_out;
     DWORD register_token, register_token_out;
@@ -3036,8 +2942,8 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, semantic *semantics_in, sema
 }
 
 static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexshader,
-        IWineD3DPixelShader *pixelshader,
-        WineD3D_GL_Info *gl_info) {
+        IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info)
+{
     GLhandleARB ret = 0;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
     IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
@@ -3050,7 +2956,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     DWORD register_token;
     DWORD usage, usage_idx, writemask;
     char reg_mask[6];
-    semantic *semantics_out, *semantics_in;
+    const struct semantic *semantics_out, *semantics_in;
 
     buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
     buffer.bsize = 0;
@@ -3191,14 +3097,16 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     return ret;
 }
 
-static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, WineD3D_GL_Info *gl_info, GLhandleARB programId, char prefix) {
-    local_constant* lconst;
+static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD3D_GL_Info *gl_info,
+        GLhandleARB programId, char prefix)
+{
+    const local_constant *lconst;
     GLuint tmp_loc;
-    float *value;
+    const float *value;
     char glsl_name[8];
 
     LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry) {
-        value = (float *) lconst->value;
+        value = (const float *)lconst->value;
         snprintf(glsl_name, sizeof(glsl_name), "%cLC%u", prefix, lconst->idx);
         tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
         GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
@@ -3217,7 +3125,7 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, WineD3D_GL_
 static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
     IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
     struct shader_glsl_priv *priv          = (struct shader_glsl_priv *)This->shader_priv;
-    WineD3D_GL_Info *gl_info               = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info         = &This->adapter->gl_info;
     IWineD3DPixelShader  *pshader          = This->stateBlock->pixelShader;
     IWineD3DVertexShader *vshader          = This->stateBlock->vertexShader;
     struct glsl_shader_prog_link *entry    = NULL;
@@ -3225,10 +3133,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     GLhandleARB reorder_shader_id          = 0;
     int i;
     char glsl_name[8];
+    GLhandleARB vshader_id, pshader_id;
+    struct ps_compile_args compile_args;
 
-    GLhandleARB vshader_id = use_vs ? ((IWineD3DBaseShaderImpl*)vshader)->baseShader.prgId : 0;
-    GLhandleARB pshader_id = use_ps ? ((IWineD3DBaseShaderImpl*)pshader)->baseShader.prgId : 0;
-    entry = get_glsl_program_entry(priv, vshader_id, pshader_id);
+    if(use_vs) {
+        IWineD3DVertexShaderImpl_CompileShader(vshader);
+        vshader_id = ((IWineD3DVertexShaderImpl*)vshader)->prgId;
+    } else {
+        vshader_id = 0;
+    }
+    if(use_ps) {
+        find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &compile_args);
+    } else {
+        /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
+        memset(&compile_args, 0, sizeof(compile_args));
+    }
+    entry = get_glsl_program_entry(priv, vshader_id, pshader, &compile_args);
     if (entry) {
         priv->glsl_program = entry;
         return;
@@ -3242,7 +3162,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
     entry->programId = programId;
     entry->vshader = vshader_id;
-    entry->pshader = pshader_id;
+    entry->pshader = pshader;
+    entry->ps_args = compile_args;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
 
@@ -3287,6 +3208,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
         list_add_head(&((IWineD3DBaseShaderImpl *)vshader)->baseShader.linked_programs, &entry->vshader_entry);
     }
 
+    if(use_ps) {
+        pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &compile_args);
+    } else {
+        pshader_id = 0;
+    }
+
     /* Attach GLSL pshader */
     if (pshader_id) {
         TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId);
@@ -3334,8 +3261,6 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
 
 
     entry->posFixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup"));
-    entry->srgb_comparison_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_comparison"));
-    entry->srgb_mul_low_location = GL_EXTCALL(glGetUniformLocationARB(programId, "srgb_mul_low"));
     entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
     checkGLcall("Find glsl program uniform locations");
 
@@ -3380,7 +3305,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     }
 }
 
-static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info, enum tex_types tex_type) {
+static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
+{
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
     const char *blt_vshader[] = {
@@ -3454,7 +3380,7 @@ static GLhandleARB create_glsl_blt_shader(WineD3D_GL_Info *gl_info, enum tex_typ
 static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
 
@@ -3482,7 +3408,7 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
 
 static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv;
     GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
 
@@ -3499,7 +3425,7 @@ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types t
 
 static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv;
     GLhandleARB program_id;
 
@@ -3512,23 +3438,32 @@ static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
 
 static void shader_glsl_cleanup(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     GL_EXTCALL(glUseProgramObjectARB(0));
 }
 
 static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
-    struct list *linked_programs;
+    const struct list *linked_programs;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     struct shader_glsl_priv *priv = (struct shader_glsl_priv *)device->shader_priv;
-    WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
+    IWineD3DPixelShaderImpl *ps = NULL;
+    IWineD3DVertexShaderImpl *vs = NULL;
 
     /* Note: Do not use QueryInterface here to find out which shader type this is because this code
      * can be called from IWineD3DBaseShader::Release
      */
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
 
-    if(This->baseShader.prgId == 0) return;
+    if(pshader) {
+        ps = (IWineD3DPixelShaderImpl *) This;
+        if(ps->num_gl_shaders == 0) return;
+    } else {
+        vs = (IWineD3DVertexShaderImpl *) This;
+        if(vs->prgId == 0) return;
+    }
+
     linked_programs = &This->baseShader.linked_programs;
 
     TRACE("Deleting linked programs\n");
@@ -3546,17 +3481,35 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
         }
     }
 
-    TRACE("Deleting shader object %u\n", This->baseShader.prgId);
-    GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
-    checkGLcall("glDeleteObjectARB");
-    This->baseShader.prgId = 0;
-    This->baseShader.is_compiled = FALSE;
+    if(pshader) {
+        UINT i;
+
+        ENTER_GL();
+        for(i = 0; i < ps->num_gl_shaders; i++) {
+            TRACE("deleting pshader %u\n", ps->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(ps->gl_shaders[i].prgId));
+            checkGLcall("glDeleteObjectARB");
+        }
+        LEAVE_GL();
+        HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
+        ps->gl_shaders = NULL;
+        ps->num_gl_shaders = 0;
+    } else {
+        TRACE("Deleting shader object %u\n", vs->prgId);
+        ENTER_GL();
+        GL_EXTCALL(glDeleteObjectARB(vs->prgId));
+        checkGLcall("glDeleteObjectARB");
+        LEAVE_GL();
+        vs->prgId = 0;
+        vs->baseShader.is_compiled = FALSE;
+    }
 }
 
-static unsigned int glsl_program_key_hash(void *key) {
-    glsl_program_key_t *k = (glsl_program_key_t *)key;
+static unsigned int glsl_program_key_hash(const void *key)
+{
+    const glsl_program_key_t *k = (const glsl_program_key_t *)key;
 
-    unsigned int hash = k->vshader | k->pshader << 16;
+    unsigned int hash = k->vshader | ((DWORD_PTR) k->pshader) << 16;
     hash += ~(hash << 15);
     hash ^=  (hash >> 10);
     hash +=  (hash << 3);
@@ -3567,11 +3520,13 @@ static unsigned int glsl_program_key_hash(void *key) {
     return hash;
 }
 
-static BOOL glsl_program_key_compare(void *keya, void *keyb) {
-    glsl_program_key_t *ka = (glsl_program_key_t *)keya;
-    glsl_program_key_t *kb = (glsl_program_key_t *)keyb;
+static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
+{
+    const glsl_program_key_t *ka = (const glsl_program_key_t *)keya;
+    const glsl_program_key_t *kb = (const glsl_program_key_t *)keyb;
 
-    return ka->vshader == kb->vshader && ka->pshader == kb->pshader;
+    return ka->vshader == kb->vshader && ka->pshader == kb->pshader &&
+           (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0);
 }
 
 static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
@@ -3584,7 +3539,7 @@ static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
 
 static void shader_glsl_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
     int i;
 
@@ -3607,14 +3562,14 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
     return FALSE;
 }
 
-static void shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
+    const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     const char *fragcolor;
-    WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
 
-    /* Create the hw GLSL shader object and assign it as the baseShader.prgId */
+    /* Create the hw GLSL shader object and assign it as the shader->prgId */
     GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
 
     shader_addline(buffer, "#version 120\n");
@@ -3636,13 +3591,9 @@ static void shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFF
     if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
 
         if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) {
-            This->vertexprocessing = pretransformed;
-            pshader_glsl_input_pack(buffer, This->semantics_in, iface);
+            pshader_glsl_input_pack(buffer, This->semantics_in, iface, pretransformed);
         } else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device)) {
-            This->vertexprocessing = fixedfunction;
-            pshader_glsl_input_pack(buffer, This->semantics_in, iface);
-        } else {
-            This->vertexprocessing = vertexshader;
+            pshader_glsl_input_pack(buffer, This->semantics_in, iface, fixedfunction);
         }
     }
 
@@ -3663,7 +3614,7 @@ static void shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFF
     } else {
         fragcolor = "gl_FragColor";
     }
-    if(This->srgb_enabled) {
+    if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
         shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(%f, %f, %f)) * vec3(%f, %f, %f) - vec3(%f, %f, %f);\n",
                         fragcolor, srgb_pow, srgb_pow, srgb_pow, srgb_mul_high, srgb_mul_high, srgb_mul_high,
                         srgb_sub_high, srgb_sub_high, srgb_sub_high);
@@ -3692,16 +3643,16 @@ static void shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFF
     print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
 
     /* Store the shader object */
-    This->baseShader.prgId = shader_obj;
+    return shader_obj;
 }
 
 static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
+    const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
-    WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
 
-    /* Create the hw GLSL shader program and assign it as the baseShader.prgId */
+    /* Create the hw GLSL shader program and assign it as the shader->prgId */
     GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
 
     shader_addline(buffer, "#version 120\n");
@@ -3749,10 +3700,11 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
     print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
 
     /* Store the shader object */
-    This->baseShader.prgId = shader_obj;
+    This->prgId = shader_obj;
 }
 
-static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) {
+static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
+{
     /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
      * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
      * vs_nv_version which is based on NV_vertex_program.
@@ -3800,21 +3752,23 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_inf
     TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (pCaps->PixelShaderVersion >> 8) & 0xff, pCaps->PixelShaderVersion & 0xff);
 }
 
-static BOOL shader_glsl_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking shader format support for format %s:", debug_d3dformat(fmt));
-    switch(fmt) {
-        case WINED3DFMT_V8U8:
-        case WINED3DFMT_V16U16:
-        case WINED3DFMT_X8L8V8U8:
-        case WINED3DFMT_L6V5U5:
-        case WINED3DFMT_Q8W8V8U8:
-        case WINED3DFMT_ATI2N:
-            TRACE("[OK]\n");
-            return TRUE;
-        default:
-            TRACE("[FAILED\n");
-            return FALSE;
+static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+    {
+        TRACE("Checking support for fixup:\n");
+        dump_color_fixup_desc(fixup);
+    }
+
+    /* We support everything except YUV conversions. */
+    if (!is_yuv_fixup(fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
     }
+
+    TRACE("[FAILED]\n");
+    return FALSE;
 }
 
 static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
@@ -3919,5 +3873,5 @@ const shader_backend_t glsl_shader_backend = {
     shader_glsl_generate_pshader,
     shader_glsl_generate_vshader,
     shader_glsl_get_caps,
-    shader_glsl_conv_supported,
+    shader_glsl_color_fixup_supported,
 };
index 79423a1..0737892 100644 (file)
@@ -74,7 +74,7 @@ static ULONG WINAPI IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface)
             LEAVE_GL();
         }
 
-        IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
+        resource_cleanup((IWineD3DResource *)iface);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -84,31 +84,31 @@ static ULONG WINAPI IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface)
    IWineD3DIndexBuffer IWineD3DResource parts follow
    **************************************************** */
 static HRESULT WINAPI IWineD3DIndexBufferImpl_GetDevice(IWineD3DIndexBuffer *iface, IWineD3DDevice** ppDevice) {
-    return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
+    return resource_get_device((IWineD3DResource *)iface, ppDevice);
 }
 
 static HRESULT WINAPI IWineD3DIndexBufferImpl_SetPrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
+    return resource_set_private_data((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
 }
 
 static HRESULT WINAPI IWineD3DIndexBufferImpl_GetPrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
+    return resource_get_private_data((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
 }
 
 static HRESULT WINAPI IWineD3DIndexBufferImpl_FreePrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid) {
-    return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
+    return resource_free_private_data((IWineD3DResource *)iface, refguid);
 }
 
 static DWORD WINAPI IWineD3DIndexBufferImpl_SetPriority(IWineD3DIndexBuffer *iface, DWORD PriorityNew) {
-    return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
+    return resource_set_priority((IWineD3DResource *)iface, PriorityNew);
 }
 
 static DWORD WINAPI IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *iface) {
-    return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
+    return resource_get_priority((IWineD3DResource *)iface);
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface) {
-    IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
+    FIXME("iface %p stub!\n", iface);
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface) {
@@ -133,11 +133,11 @@ static void WINAPI IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface) {
 }
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DIndexBufferImpl_GetType(IWineD3DIndexBuffer *iface) {
-    return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
+    return resource_get_type((IWineD3DResource *)iface);
 }
 
 static HRESULT WINAPI IWineD3DIndexBufferImpl_GetParent(IWineD3DIndexBuffer *iface, IUnknown **pParent) {
-    return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
+    return resource_get_parent((IWineD3DResource *)iface, pParent);
 }
 
 /* ******************************************************
index 29c4e98..77f5365 100644 (file)
@@ -29,7 +29,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
-void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     BOOL bumpmap = FALSE;
 
     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
@@ -548,7 +548,7 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
     }
 }
 
-void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
 
@@ -610,7 +610,8 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
     }
 }
 
-static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps) {
+static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps)
+{
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD                        |
                             WINED3DTEXOPCAPS_ADDSIGNED                  |
                             WINED3DTEXOPCAPS_ADDSIGNED2X                |
@@ -672,12 +673,26 @@ static void nvrc_fragment_free(IWineD3DDevice *iface) {}
  * register combiners extension(Pre-GF3).
  */
 
-static BOOL nvts_conv_supported(WINED3DFORMAT fmt) {
-    TRACE("Checking shader format support for format %s: [FAILED]\n", debug_d3dformat(fmt));
+static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
+{
+    if (TRACE_ON(d3d))
+    {
+        TRACE("Checking support for fixup:\n");
+        dump_color_fixup_desc(fixup);
+    }
+
+    /* We only support identity conversions. */
+    if (is_identity_fixup(fixup))
+    {
+        TRACE("[OK]\n");
+        return TRUE;
+    }
+
+    TRACE("[FAILED]\n");
     return FALSE;
 }
 
-const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
+static const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
@@ -809,7 +824,7 @@ const struct fragment_pipeline nvts_fragment_pipeline = {
     nvrc_fragment_get_caps,
     nvrc_fragment_alloc,
     nvrc_fragment_free,
-    nvts_conv_supported,
+    nvts_color_fixup_supported,
     nvrc_fragmentstate_template,
     FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
 };
@@ -819,7 +834,7 @@ const struct fragment_pipeline nvrc_fragment_pipeline = {
     nvrc_fragment_get_caps,
     nvrc_fragment_alloc,