- sync wined3d with wine HEAD
authorKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 18 Jan 2009 21:09:22 +0000 (21:09 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 18 Jan 2009 21:09:22 +0000 (21:09 +0000)
svn path=/trunk/; revision=38914

34 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/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/gl_compat.c [new file with mode: 0644]
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/query.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/texture.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexbuffer.c
reactos/dll/directx/wine/wined3d/vertexdeclaration.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.rbuild
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_main.c
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/include/reactos/wine/wined3d.idl

index 9d51250..7ff3cd4 100644 (file)
@@ -70,6 +70,7 @@ struct shader_arb_priv {
 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)
 {
 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)
 {
+    DWORD shader_version = This->baseShader.reg_maps.shader_version;
     local_constant* lconst;
     DWORD i, j;
     unsigned int ret;
     local_constant* lconst;
     DWORD i, j;
     unsigned int ret;
@@ -83,8 +84,8 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con
         }
     }
     /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
         }
     }
     /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
-    if(target_type == GL_FRAGMENT_PROGRAM_ARB &&
-       WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) {
+    if (target_type == GL_FRAGMENT_PROGRAM_ARB && WINED3DSHADER_VERSION_MAJOR(shader_version) == 1)
+    {
         float lcl_const[4];
         for(i = 0; i < max_constants; i++) {
             if(!dirty_consts[i]) continue;
         float lcl_const[4];
         for(i = 0; i < max_constants; i++) {
             if(!dirty_consts[i]) continue;
@@ -225,6 +226,28 @@ static void shader_arb_load_constants(
     }
 }
 
     }
 }
 
+static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
+     * context. On a context switch the old context will be fully dirtified */
+    memset(This->activeContext->vshader_const_dirty + start, 1,
+            sizeof(*This->activeContext->vshader_const_dirty) * count);
+    This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count + 1);
+}
+
+static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
+     * context. On a context switch the old context will be fully dirtified */
+    memset(This->activeContext->pshader_const_dirty + start, 1,
+            sizeof(*This->activeContext->pshader_const_dirty) * count);
+    This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
+}
+
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
 static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
         SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
 static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
         SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
@@ -232,7 +255,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     DWORD i, cur;
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     DWORD i, cur;
-    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+    char pshader = shader_is_pshader_version(reg_maps->shader_version);
     unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
             (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
     UINT extra_constants_needed = 0;
     unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
             (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
     UINT extra_constants_needed = 0;
@@ -291,7 +314,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
                 FIXME("No free constant to load the luminance parameters\n");
             }
         } else {
                 FIXME("No free constant to load the luminance parameters\n");
             }
         } else {
-            FIXME("No free constant found to load environemnt bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
+            FIXME("No free constant found to load environment bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
         }
 
         ps->numbumpenvmatconsts = cur + 1;
         }
 
         ps->numbumpenvmatconsts = cur + 1;
@@ -360,9 +383,8 @@ static const char * const shift_tab[] = {
 
 static void shader_arb_get_write_mask(const 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 *ptr = write_mask;
-    char vshader = shader_is_vshader_version(This->baseShader.hex_version);
+    char vshader = shader_is_vshader_version(arg->reg_maps->shader_version);
 
     if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) {
         *ptr++ = '.';
 
     if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) {
         *ptr++ = '.';
@@ -488,8 +510,7 @@ static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD
     break;
   case WINED3DSPR_INPUT:
 
     break;
   case WINED3DSPR_INPUT:
 
-    if (vshader_input_is_color((IWineD3DVertexShader*) This, reg))
-        is_color = TRUE;
+    if (This->swizzle_map & (1 << reg)) is_color = TRUE;
 
     sprintf(tmpReg, "vertex.attrib[%u]", reg);
     strcat(hwLine, tmpReg);
 
     sprintf(tmpReg, "vertex.attrib[%u]", reg);
     strcat(hwLine, tmpReg);
@@ -787,7 +808,6 @@ static void pshader_hw_bem(const SHADER_OPCODE_ARG *arg)
 
 static void pshader_hw_cnd(const 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];
     char dst_name[50];
     SHADER_BUFFER* buffer = arg->buffer;
     char dst_wmask[20];
     char dst_name[50];
@@ -807,8 +827,8 @@ static void pshader_hw_cnd(const SHADER_OPCODE_ARG *arg)
     pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[2], 2, src_name[2]);
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
     pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[2], 2, src_name[2]);
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
-    if (shader->baseShader.hex_version <= WINED3DPS_VERSION(1, 3) &&
-        arg->opcode_token & WINED3DSI_COISSUE) {
+    if (arg->reg_maps->shader_version <= WINED3DPS_VERSION(1, 3) && arg->opcode_token & WINED3DSI_COISSUE)
+    {
         shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
     } else {
         shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
         shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
     } else {
         shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
@@ -877,15 +897,45 @@ static void pshader_hw_dp2add(const SHADER_OPCODE_ARG *arg)
 /* Map the opcode 1-to-1 to the GL code */
 static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
 {
 /* Map the opcode 1-to-1 to the GL code */
 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;
     const DWORD *src = arg->src;
     CONST SHADER_OPCODE* curOpcode = arg->opcode;
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD dst = arg->dst;
     const DWORD *src = arg->src;
+    const char *instruction;
     char arguments[256];
     unsigned int i;
 
     char arguments[256];
     unsigned int i;
 
-    if (shader_is_pshader_version(shader->baseShader.hex_version))
+    switch (curOpcode->opcode)
+    {
+        case WINED3DSIO_ABS: instruction = "ABS"; break;
+        case WINED3DSIO_ADD: instruction = "ADD"; break;
+        case WINED3DSIO_CRS: instruction = "XPD"; break;
+        case WINED3DSIO_DP3: instruction = "DP3"; break;
+        case WINED3DSIO_DP4: instruction = "DP4"; break;
+        case WINED3DSIO_DST: instruction = "DST"; break;
+        case WINED3DSIO_EXP: instruction = "EX2"; break;
+        case WINED3DSIO_EXPP: instruction = "EXP"; break;
+        case WINED3DSIO_FRC: instruction = "FRC"; break;
+        case WINED3DSIO_LIT: instruction = "LIT"; break;
+        case WINED3DSIO_LOG: instruction = "LG2"; break;
+        case WINED3DSIO_LOGP: instruction = "LOG"; break;
+        case WINED3DSIO_LRP: instruction = "LRP"; break;
+        case WINED3DSIO_MAD: instruction = "MAD"; break;
+        case WINED3DSIO_MAX: instruction = "MAX"; break;
+        case WINED3DSIO_MIN: instruction = "MIN"; break;
+        case WINED3DSIO_MOV: instruction = "MOV"; break;
+        case WINED3DSIO_MUL: instruction = "MUL"; break;
+        case WINED3DSIO_NOP: instruction = "NOP"; break;
+        case WINED3DSIO_POW: instruction = "POW"; break;
+        case WINED3DSIO_SGE: instruction = "SGE"; break;
+        case WINED3DSIO_SLT: instruction = "SLT"; break;
+        case WINED3DSIO_SUB: instruction = "SUB"; break;
+        default: instruction = "";
+            FIXME("Unhandled opcode %s\n", curOpcode->name);
+            break;
+    }
+
+    if (shader_is_pshader_version(arg->reg_maps->shader_version))
     {
         /* Output token related */
         char output_rname[256];
     {
         /* Output token related */
         char output_rname[256];
@@ -938,7 +988,7 @@ static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
             strcat(arguments, ", ");
             strcat(arguments, operands[i]);
         }
             strcat(arguments, ", ");
             strcat(arguments, operands[i]);
         }
-        shader_addline(buffer, "%s%s %s;\n", curOpcode->glname, modifier, arguments);
+        shader_addline(buffer, "%s%s %s;\n", instruction, modifier, arguments);
 
         /* A shift requires another line. */
         if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname);
 
         /* A shift requires another line. */
         if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname);
@@ -955,7 +1005,7 @@ static void shader_hw_map2gl(const SHADER_OPCODE_ARG *arg)
                 vshader_program_add_param(arg, src[i-1], TRUE, arguments);
             }
         }
                 vshader_program_add_param(arg, src[i-1], TRUE, arguments);
             }
         }
-        shader_addline(buffer, "%s%s;\n", curOpcode->glname, arguments);
+        shader_addline(buffer, "%s%s;\n", instruction, arguments);
     }
 }
 
     }
 }
 
@@ -963,8 +1013,8 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
 
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl*)arg->shader;
 
-    if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1
-            && !shader_is_pshader_version(shader->baseShader.hex_version)
+    if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1
+            && !shader_is_pshader_version(arg->reg_maps->shader_version)
             && shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)
             || arg->opcode->opcode == WINED3DSIO_MOVA)
     {
             && shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)
             || arg->opcode->opcode == WINED3DSIO_MOVA)
     {
@@ -1008,8 +1058,7 @@ static void shader_hw_mov(const SHADER_OPCODE_ARG *arg)
 
 static void pshader_hw_texkill(const 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;
+    DWORD shader_version = arg->reg_maps->shader_version;
     SHADER_BUFFER* buffer = arg->buffer;
     char reg_dest[40];
 
     SHADER_BUFFER* buffer = arg->buffer;
     char reg_dest[40];
 
@@ -1018,7 +1067,8 @@ static void pshader_hw_texkill(const SHADER_OPCODE_ARG *arg)
      */
     pshader_get_register_name(arg->shader, arg->dst, reg_dest);
 
      */
     pshader_get_register_name(arg->shader, arg->dst, reg_dest);
 
-    if(hex_version >= WINED3DPS_VERSION(2,0)) {
+    if (shader_version >= WINED3DPS_VERSION(2,0))
+    {
         /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
         shader_addline(buffer, "KIL %s;\n", reg_dest);
     } else {
         /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
         shader_addline(buffer, "KIL %s;\n", reg_dest);
     } else {
@@ -1039,7 +1089,7 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
     DWORD dst = arg->dst;
     const DWORD *src = arg->src;
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD dst = arg->dst;
     const DWORD *src = arg->src;
     SHADER_BUFFER* buffer = arg->buffer;
-    DWORD hex_version = This->baseShader.hex_version;
+    DWORD shader_version = arg->reg_maps->shader_version;
     BOOL projected = FALSE, bias = FALSE;
 
     char reg_dest[40];
     BOOL projected = FALSE, bias = FALSE;
 
     char reg_dest[40];
@@ -1053,14 +1103,14 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
-   if (hex_version < WINED3DPS_VERSION(1,4))
+   if (shader_version < WINED3DPS_VERSION(1,4))
       strcpy(reg_coord, reg_dest);
    else
       pshader_gen_input_modifier_line(arg->shader, buffer, src[0], 0, reg_coord);
 
   /* 1.0-1.4: Use destination register number as texture code.
      2.0+: Use provided sampler number as texure code. */
       strcpy(reg_coord, reg_dest);
    else
       pshader_gen_input_modifier_line(arg->shader, buffer, src[0], 0, reg_coord);
 
   /* 1.0-1.4: Use destination register number as texture code.
      2.0+: Use provided sampler number as texure code. */
-  if (hex_version < WINED3DPS_VERSION(2,0))
+  if (shader_version < WINED3DPS_VERSION(2,0))
      reg_sampler_code = reg_dest_code;
   else
      reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
      reg_sampler_code = reg_dest_code;
   else
      reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
@@ -1070,7 +1120,8 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
    * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
    * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
    */
    * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
    * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
    */
-  if(hex_version < WINED3DPS_VERSION(1,4)) {
+  if (shader_version < WINED3DPS_VERSION(1,4))
+  {
       DWORD flags = 0;
       if(reg_sampler_code < MAX_TEXTURES) {
         flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
       DWORD flags = 0;
       if(reg_sampler_code < MAX_TEXTURES) {
         flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
@@ -1078,7 +1129,9 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
       if (flags & WINED3DTTFF_PROJECTED) {
           projected = TRUE;
       }
       if (flags & WINED3DTTFF_PROJECTED) {
           projected = TRUE;
       }
-  } else if(hex_version < WINED3DPS_VERSION(2,0)) {
+  }
+  else if (shader_version < WINED3DPS_VERSION(2,0))
+  {
       DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
       if (src_mod == WINED3DSPSM_DZ) {
           projected = TRUE;
       DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
       if (src_mod == WINED3DSPSM_DZ) {
           projected = TRUE;
@@ -1098,14 +1151,13 @@ static void pshader_hw_tex(const SHADER_OPCODE_ARG *arg)
 
 static void pshader_hw_texcoord(const 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;
     DWORD dst = arg->dst;
     SHADER_BUFFER* buffer = arg->buffer;
-    DWORD hex_version = This->baseShader.hex_version;
 
     char tmp[20];
     shader_arb_get_write_mask(arg, dst, tmp);
 
     char tmp[20];
     shader_arb_get_write_mask(arg, dst, tmp);
-    if (hex_version != WINED3DPS_VERSION(1,4)) {
+    if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+    {
         DWORD reg = dst & WINED3DSP_REGNUM_MASK;
         shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
     } else {
         DWORD reg = dst & WINED3DSP_REGNUM_MASK;
         shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
     } else {
@@ -1130,8 +1182,8 @@ static void pshader_hw_texreg2ar(const SHADER_OPCODE_ARG *arg)
 
      sprintf(dst_str, "T%u", reg1);
      pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[0], 0, src_str);
 
      sprintf(dst_str, "T%u", reg1);
      pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[0], 0, src_str);
-     shader_addline(buffer, "MOV TMP.r, %s.a;\n", src_str);
-     shader_addline(buffer, "MOV TMP.g, %s.r;\n", src_str);
+     shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str);
+     shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str);
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
      shader_hw_sample(arg, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
      shader_hw_sample(arg, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
@@ -1146,8 +1198,8 @@ static void pshader_hw_texreg2gb(const SHADER_OPCODE_ARG *arg)
 
      sprintf(dst_str, "T%u", reg1);
      pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[0], 0, src_str);
 
      sprintf(dst_str, "T%u", reg1);
      pshader_gen_input_modifier_line(arg->shader, buffer, arg->src[0], 0, src_str);
-     shader_addline(buffer, "MOV TMP.r, %s.g;\n", src_str);
-     shader_addline(buffer, "MOV TMP.g, %s.b;\n", src_str);
+     shader_addline(buffer, "MOV TMP.x, %s.y;\n", src_str);
+     shader_addline(buffer, "MOV TMP.y, %s.z;\n", src_str);
      shader_hw_sample(arg, reg1, dst_str, "TMP", FALSE, FALSE);
 }
 
      shader_hw_sample(arg, reg1, dst_str, "TMP", FALSE, FALSE);
 }
 
@@ -1199,20 +1251,20 @@ static void pshader_hw_texbem(const SHADER_OPCODE_ARG *arg)
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
-        shader_addline(buffer, "DP3 TMP.r, TMP2, T%u;\n", src);
+        shader_addline(buffer, "DP3 TMP.x, TMP2, T%u;\n", src);
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
-        shader_addline(buffer, "DP3 TMP.g, TMP2, T%u;\n", src);
+        shader_addline(buffer, "DP3 TMP.y, TMP2, T%u;\n", src);
 
         /* with projective textures, texbem only divides the static texture coord, not the displacement,
          * so we can't let the GL handle this.
          */
         if (((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
               & WINED3DTTFF_PROJECTED) {
 
         /* with projective textures, texbem only divides the static texture coord, not the displacement,
          * so we can't let the GL handle this.
          */
         if (((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
               & WINED3DTTFF_PROJECTED) {
-            shader_addline(buffer, "RCP TMP2.a, %s.a;\n", reg_coord);
-            shader_addline(buffer, "MUL TMP2.rg, %s, TMP2.a;\n", reg_coord);
-            shader_addline(buffer, "ADD TMP.rg, TMP, TMP2;\n");
+            shader_addline(buffer, "RCP TMP2.w, %s.w;\n", reg_coord);
+            shader_addline(buffer, "MUL TMP2.xy, %s, TMP2.w;\n", reg_coord);
+            shader_addline(buffer, "ADD TMP.xy, TMP, TMP2;\n");
         } else {
         } else {
-            shader_addline(buffer, "ADD TMP.rg, TMP, %s;\n", reg_coord);
+            shader_addline(buffer, "ADD TMP.xy, TMP, %s;\n", reg_coord);
         }
 
         shader_hw_sample(arg, reg_dest_code, reg_coord, "TMP", FALSE, FALSE);
         }
 
         shader_hw_sample(arg, reg_dest_code, reg_coord, "TMP", FALSE, FALSE);
@@ -1384,15 +1436,15 @@ static void pshader_hw_texdepth(const SHADER_OPCODE_ARG *arg)
     /* According to the msdn, the source register(must be r5) is unusable after
      * the texdepth instruction, so we're free to modify it
      */
     /* According to the msdn, the source register(must be r5) is unusable after
      * the texdepth instruction, so we're free to modify it
      */
-    shader_addline(buffer, "MIN %s.g, %s.g, one.g;\n", dst_name, dst_name);
+    shader_addline(buffer, "MIN %s.y, %s.y, one.y;\n", dst_name, dst_name);
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
      * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
      * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
-    shader_addline(buffer, "RCP %s.g, %s.g;\n", dst_name, dst_name);
-    shader_addline(buffer, "MUL TMP.x, %s.r, %s.g;\n", dst_name, dst_name);
-    shader_addline(buffer, "MIN TMP.x, TMP.x, one.r;\n");
+    shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
+    shader_addline(buffer, "MUL TMP.x, %s.x, %s.y;\n", dst_name, dst_name);
+    shader_addline(buffer, "MIN TMP.x, TMP.x, one.x;\n");
     shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
 }
 
     shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
 }
 
@@ -1474,7 +1526,7 @@ static void pshader_hw_texm3x2depth(const SHADER_OPCODE_ARG *arg)
      */
     shader_addline(buffer, "RCP TMP.y, TMP.y;\n");
     shader_addline(buffer, "MUL TMP.x, TMP.x, TMP.y;\n");
      */
     shader_addline(buffer, "RCP TMP.y, TMP.y;\n");
     shader_addline(buffer, "MUL TMP.x, TMP.x, TMP.y;\n");
-    shader_addline(buffer, "MIN TMP.x, TMP.x, one.r;\n");
+    shader_addline(buffer, "MIN TMP.x, TMP.x, one.x;\n");
     shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
 }
 
     shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
 }
 
@@ -1487,7 +1539,7 @@ static void shader_hw_mnxn(const SHADER_OPCODE_ARG *arg)
     SHADER_OPCODE_ARG tmpArg;
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
     const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
     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;
+    DWORD shader_version = arg->reg_maps->shader_version;
 
     memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG));
 
 
     memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG));
 
@@ -1538,10 +1590,20 @@ static void vshader_hw_rsq_rcp(const SHADER_OPCODE_ARG *arg)
     DWORD dst = arg->dst;
     DWORD src = arg->src[0];
     DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     DWORD dst = arg->dst;
     DWORD src = arg->src[0];
     DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+    const char *instruction;
 
     char tmpLine[256];
 
 
     char tmpLine[256];
 
-    strcpy(tmpLine, curOpcode->glname); /* Opcode */
+    switch(curOpcode->opcode)
+    {
+        case WINED3DSIO_RSQ: instruction = "RSQ"; break;
+        case WINED3DSIO_RCP: instruction = "RCP"; break;
+        default: instruction = "";
+            FIXME("Unhandled opcode %s\n", curOpcode->name);
+            break;
+    }
+
+    strcpy(tmpLine, instruction);
     vshader_program_add_param(arg, dst, FALSE, tmpLine); /* Destination */
     strcat(tmpLine, ",");
     vshader_program_add_param(arg, src, TRUE, tmpLine);
     vshader_program_add_param(arg, dst, FALSE, tmpLine); /* Destination */
     strcat(tmpLine, ",");
     vshader_program_add_param(arg, src, TRUE, tmpLine);
@@ -1631,7 +1693,7 @@ static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
 static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
 {
     GLuint program_id = 0;
 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] =
+    static const char * const blt_fprograms[tex_type_count] =
     {
         /* tex_1d */
         NULL,
     {
         /* tex_1d */
         NULL,
@@ -1777,19 +1839,12 @@ static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     }
 }
 
     }
 }
 
-static void shader_arb_cleanup(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    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 *baseShader = (IWineD3DBaseShaderImpl *) iface;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
 static void shader_arb_destroy(IWineD3DBaseShader *iface) {
     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);
 
 
-    if(pshader) {
+    if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version))
+    {
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
         UINT i;
 
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
         UINT i;
 
@@ -1864,18 +1919,35 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
     /* [0.0;1.0] clamping. Not needed, this is done implicitly */
 }
 
     /* [0.0;1.0] clamping. Not needed, this is done implicitly */
 }
 
-static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
-    const char *fragcolor;
+    DWORD shader_version = reg_maps->shader_version;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
     const local_constant *lconst;
     GLuint retval;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
     const local_constant *lconst;
     GLuint retval;
+    const char *fragcolor;
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBfp1.0\n");
 
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBfp1.0\n");
 
+    if (shader_version < WINED3DPS_VERSION(3,0)) {
+        switch(args->fog) {
+            case FOG_OFF:
+                break;
+            case FOG_LINEAR:
+                shader_addline(buffer, "OPTION ARB_fog_linear;\n");
+                break;
+            case FOG_EXP:
+                shader_addline(buffer, "OPTION ARB_fog_exp;\n");
+                break;
+            case FOG_EXP2:
+                shader_addline(buffer, "OPTION ARB_fog_exp2;\n");
+                break;
+        }
+    }
+
     shader_addline(buffer, "TEMP TMP;\n");     /* Used in matrix ops */
     shader_addline(buffer, "TEMP TMP2;\n");    /* Used in matrix ops */
     shader_addline(buffer, "TEMP TA;\n");      /* Used for modifiers */
     shader_addline(buffer, "TEMP TMP;\n");     /* Used in matrix ops */
     shader_addline(buffer, "TEMP TMP2;\n");    /* Used in matrix ops */
     shader_addline(buffer, "TEMP TA;\n");      /* Used for modifiers */
@@ -1885,37 +1957,23 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
     shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
     shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
     shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
     shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
-    /* Base Declarations */
-    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
-
-    /* We need two variables for fog blending */
-    shader_addline(buffer, "TEMP TMP_FOG;\n");
-    if (This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) {
+    if (shader_version < WINED3DPS_VERSION(2,0)) {
+        fragcolor = "R0";
+    } else {
         shader_addline(buffer, "TEMP TMP_COLOR;\n");
         shader_addline(buffer, "TEMP TMP_COLOR;\n");
+        fragcolor = "TMP_COLOR";
     }
 
     }
 
+    /* Base Declarations */
+    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
-    /* calculate fog and blend it
-     * NOTE: state.fog.params.y and state.fog.params.z don't hold fog start s and end e but
-     * -1/(e-s) and e/(e-s) respectively.
-     */
-    shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
-
-    if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
-        fragcolor = "R0";
-    } else {
-        fragcolor = "TMP_COLOR";
-    }
-    if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
+    if(args->srgb_correction) {
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
     }
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
     }
-    if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
-        shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor);
-        shader_addline(buffer, "MOV result.color.a, %s.a;\n", fragcolor);
-    }
-
+    shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
@@ -2185,8 +2243,9 @@ const shader_backend_t arb_program_shader_backend = {
     shader_arb_select,
     shader_arb_select_depth_blt,
     shader_arb_deselect_depth_blt,
     shader_arb_select,
     shader_arb_select_depth_blt,
     shader_arb_deselect_depth_blt,
+    shader_arb_update_float_vertex_constants,
+    shader_arb_update_float_pixel_constants,
     shader_arb_load_constants,
     shader_arb_load_constants,
-    shader_arb_cleanup,
     shader_arb_color_correction,
     shader_arb_destroy,
     shader_arb_alloc,
     shader_arb_color_correction,
     shader_arb_destroy,
     shader_arb_alloc,
@@ -2310,7 +2369,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
      * application provided constants
      */
     if(device->shader_backend == &arb_program_shader_backend) {
      * application provided constants
      */
     if(device->shader_backend == &arb_program_shader_backend) {
-        if(use_ps(device)) return;
+        if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
         device->activeContext->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
 
         device = stateblock->wineD3DDevice;
         device->activeContext->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
@@ -2331,7 +2390,7 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb
      * application provided constants
      */
     if(device->shader_backend == &arb_program_shader_backend) {
      * application provided constants
      */
     if(device->shader_backend == &arb_program_shader_backend) {
-        if(use_ps(device)) return;
+        if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
         device->activeContext->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
 
         device = stateblock->wineD3DDevice;
         device->activeContext->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
@@ -2351,11 +2410,12 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb
 }
 
 static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float mat[2][2];
 
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float mat[2][2];
 
-    if(use_ps(device)) {
+    if (use_ps(stateblock))
+    {
         if(stage != 0 &&
            ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
         if(stage != 0 &&
            ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
@@ -2385,11 +2445,12 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, W
 }
 
 static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float param[4];
 
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float param[4];
 
-    if(use_ps(device)) {
+    if (use_ps(stateblock))
+    {
         if(stage != 0 &&
            ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
             /* The pixel shader has to know the luminance offset. Do a constants update if it
         if(stage != 0 &&
            ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
             /* The pixel shader has to know the luminance offset. Do a constants update if it
@@ -2481,7 +2542,7 @@ static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int
         if(argnum == 2) ret = "arg2";
     }
     if(arg & WINED3DTA_ALPHAREPLICATE) {
         if(argnum == 2) ret = "arg2";
     }
     if(arg & WINED3DTA_ALPHAREPLICATE) {
-        shader_addline(buffer, "MOV arg%u, %s.a;\n", argnum, ret);
+        shader_addline(buffer, "MOV arg%u, %s.w;\n", argnum, ret);
         if(argnum == 0) ret = "arg0";
         if(argnum == 1) ret = "arg1";
         if(argnum == 2) ret = "arg2";
         if(argnum == 0) ret = "arg0";
         if(argnum == 1) ret = "arg1";
         if(argnum == 2) ret = "arg2";
@@ -2496,8 +2557,8 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
     BOOL mul_final_dest = FALSE;
 
     if(color && alpha) dstmask = "";
     BOOL mul_final_dest = FALSE;
 
     if(color && alpha) dstmask = "";
-    else if(color) dstmask = ".rgb";
-    else dstmask = ".a";
+    else if(color) dstmask = ".xyz";
+    else dstmask = ".w";
 
     if(dst == tempreg) dstreg = "tempreg";
     else dstreg = "ret";
 
     if(dst == tempreg) dstreg = "tempreg";
     else dstreg = "ret";
@@ -2508,7 +2569,7 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
 
     switch(op) {
         case WINED3DTOP_DISABLE:
 
     switch(op) {
         case WINED3DTOP_DISABLE:
-            if(stage == 1) shader_addline(buffer, "MOV %s%s, fragment.color.primary;\n", dstreg, dstmask);
+            if(stage == 0) shader_addline(buffer, "MOV %s%s, fragment.color.primary;\n", dstreg, dstmask);
             break;
 
         case WINED3DTOP_SELECTARG2:
             break;
 
         case WINED3DTOP_SELECTARG2:
@@ -2553,42 +2614,42 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
 
         case WINED3DTOP_BLENDCURRENTALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_CURRENT);
 
         case WINED3DTOP_BLENDCURRENTALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_CURRENT);
-            shader_addline(buffer, "LRP %s%s, %s.a, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+            shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
             break;
         case WINED3DTOP_BLENDFACTORALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TFACTOR);
             break;
         case WINED3DTOP_BLENDFACTORALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TFACTOR);
-            shader_addline(buffer, "LRP %s%s, %s.a, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+            shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
             break;
         case WINED3DTOP_BLENDTEXTUREALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
             break;
         case WINED3DTOP_BLENDTEXTUREALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
-            shader_addline(buffer, "LRP %s%s, %s.a, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+            shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
             break;
         case WINED3DTOP_BLENDDIFFUSEALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_DIFFUSE);
             break;
         case WINED3DTOP_BLENDDIFFUSEALPHA:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_DIFFUSE);
-            shader_addline(buffer, "LRP %s%s, %s.a, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+            shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
             break;
 
         case WINED3DTOP_BLENDTEXTUREALPHAPM:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
             break;
 
         case WINED3DTOP_BLENDTEXTUREALPHAPM:
             arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
-            shader_addline(buffer, "SUB arg0.a, const.x, %s.a;\n", arg0);
-            shader_addline(buffer, "MAD_SAT %s%s, %s, arg0.a, %s;\n", dstreg, dstmask, arg2, arg1);
+            shader_addline(buffer, "SUB arg0.w, const.x, %s.w;\n", arg0);
+            shader_addline(buffer, "MAD_SAT %s%s, %s, arg0.w, %s;\n", dstreg, dstmask, arg2, arg1);
             break;
 
         /* D3DTOP_PREMODULATE ???? */
 
         case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
             break;
 
         /* D3DTOP_PREMODULATE ???? */
 
         case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
-            shader_addline(buffer, "SUB arg0.a, const.x, %s;\n", arg1);
-            shader_addline(buffer, "MAD_SAT %s%s, arg0.a, %s, %s;\n", dstreg, dstmask, arg2, arg1);
+            shader_addline(buffer, "SUB arg0.w, const.x, %s;\n", arg1);
+            shader_addline(buffer, "MAD_SAT %s%s, arg0.w, %s, %s;\n", dstreg, dstmask, arg2, arg1);
             break;
         case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
             break;
         case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
-            shader_addline(buffer, "MAD_SAT %s%s, %s.a, %s, %s;\n", dstreg, dstmask, arg1, arg2, arg1);
+            shader_addline(buffer, "MAD_SAT %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg1, arg2, arg1);
             break;
         case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
             shader_addline(buffer, "SUB arg0, const.x, %s;\n", arg1);
             break;
         case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
             shader_addline(buffer, "SUB arg0, const.x, %s;\n", arg1);
-            shader_addline(buffer, "MAD_SAT %s%s, arg0, %s, %s.a;\n", dstreg, dstmask, arg2, arg1);
+            shader_addline(buffer, "MAD_SAT %s%s, arg0, %s, %s.w;\n", dstreg, dstmask, arg2, arg1);
             break;
         case WINED3DTOP_MODULATECOLOR_ADDALPHA:
             break;
         case WINED3DTOP_MODULATECOLOR_ADDALPHA:
-            shader_addline(buffer, "MAD_SAT %s%s, %s, %s, %s.a;\n", dstreg, dstmask, arg1, arg2, arg1);
+            shader_addline(buffer, "MAD_SAT %s%s, %s, %s, %s.w;\n", dstreg, dstmask, arg1, arg2, arg1);
             break;
 
         case WINED3DTOP_DOTPRODUCT3:
             break;
 
         case WINED3DTOP_DOTPRODUCT3:
@@ -2694,10 +2755,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
     }
 
     /* Shader header */
     }
 
     /* Shader header */
-    buffer.bsize = 0;
-    buffer.lineNo = 0;
-    buffer.newline = TRUE;
-    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
+    shader_buffer_init(&buffer);
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
@@ -2776,20 +2834,20 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
            (settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAP ||
             settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAPLUMINANCE)) {
             shader_addline(&buffer, "SWZ arg1, bumpmat%u, x, z, 0, 0;\n", stage - 1);
            (settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAP ||
             settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAPLUMINANCE)) {
             shader_addline(&buffer, "SWZ arg1, bumpmat%u, x, z, 0, 0;\n", stage - 1);
-            shader_addline(&buffer, "DP3 ret.r, arg1, tex%u;\n", stage - 1);
+            shader_addline(&buffer, "DP3 ret.x, arg1, tex%u;\n", stage - 1);
             shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1);
             shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1);
-            shader_addline(&buffer, "DP3 ret.g, arg1, tex%u;\n", stage - 1);
+            shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1);
 
             /* with projective textures, texbem only divides the static texture coord, not the displacement,
              * so multiply the displacement with the dividing parameter before passing it to TXP
              */
             if (settings->op[stage].projected != proj_none) {
                 if(settings->op[stage].projected == proj_count4) {
 
             /* with projective textures, texbem only divides the static texture coord, not the displacement,
              * so multiply the displacement with the dividing parameter before passing it to TXP
              */
             if (settings->op[stage].projected != proj_none) {
                 if(settings->op[stage].projected == proj_count4) {
-                    shader_addline(&buffer, "MOV ret.a, fragment.texcoord[%u].a;\n", stage);
-                    shader_addline(&buffer, "MUL ret.rgb, ret, fragment.texcoord[%u].a, fragment.texcoord[%u];\n", stage, stage);
+                    shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage);
+                    shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage);
                 } else {
                 } else {
-                    shader_addline(&buffer, "MOV ret.a, fragment.texcoord[%u].b;\n", stage);
-                    shader_addline(&buffer, "MAD ret.rgb, ret, fragment.texcoord[%u].b, fragment.texcoord[%u];\n", stage, stage);
+                    shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage);
+                    shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage);
                 }
             } else {
                 shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage);
                 }
             } else {
                 shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage);
@@ -2798,13 +2856,13 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
             shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
                            instr, sat, stage, stage, textype);
             if(settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAPLUMINANCE) {
             shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
                            instr, sat, stage, stage, textype);
             if(settings->op[stage - 1].cop == WINED3DTOP_BUMPENVMAPLUMINANCE) {
-                shader_addline(&buffer, "MAD_SAT ret.r, tex%u.b, luminance%u.r, luminance%u.g;\n",
+                shader_addline(&buffer, "MAD_SAT ret.x, tex%u.z, luminance%u.x, luminance%u.y;\n",
                                stage - 1, stage - 1, stage - 1);
                                stage - 1, stage - 1, stage - 1);
-                shader_addline(&buffer, "MUL tex%u, tex%u, ret.r;\n", stage, stage);
+                shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage);
             }
         } else if(settings->op[stage].projected == proj_count3) {
             shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage);
             }
         } else if(settings->op[stage].projected == proj_count3) {
             shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage);
-            shader_addline(&buffer, "MOV ret.a, ret.b;\n");
+            shader_addline(&buffer, "MOV ret.w, ret.z;\n");
             shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
                             instr, sat, stage, stage, textype);
         } else {
             shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
                             instr, sat, stage, stage, textype);
         } else {
@@ -2814,7 +2872,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
 
         sprintf(colorcor_dst, "tex%u", stage);
         gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y",
 
         sprintf(colorcor_dst, "tex%u", stage);
         gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y",
-                settings->op[stage].color_correction);
+                settings->op[stage].color_fixup);
     }
 
     /* Generate the main shader */
     }
 
     /* Generate the main shader */
@@ -2850,7 +2908,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
                           settings->op[stage].cop, settings->op[stage].carg0,
                           settings->op[stage].carg1, settings->op[stage].carg2);
             if(stage == 0) {
                           settings->op[stage].cop, settings->op[stage].carg0,
                           settings->op[stage].carg1, settings->op[stage].carg2);
             if(stage == 0) {
-                shader_addline(&buffer, "MOV ret.a, fragment.color.primary.a;\n");
+                shader_addline(&buffer, "MOV ret.w, fragment.color.primary.w;\n");
             }
         } else if(op_equal) {
             gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
             }
         } else if(op_equal) {
             gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
@@ -2869,7 +2927,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
     if(settings->sRGB_write) {
         shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
         arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
     if(settings->sRGB_write) {
         shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
         arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
-        shader_addline(&buffer, "MOV result.color.a, ret.a;\n");
+        shader_addline(&buffer, "MOV result.color.w, ret.w;\n");
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
@@ -2888,15 +2946,15 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
         FIXME("Fragment program error at position %d: %s\n", pos,
               debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
     }
         FIXME("Fragment program error at position %d: %s\n", pos,
               debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
     }
-    HeapFree(GetProcessHeap(), 0, buffer.buffer);
+    shader_buffer_free(&buffer);
     return ret;
 }
 
 static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) device->fragment_priv;
     return ret;
 }
 
 static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     struct shader_arb_priv *priv = (struct shader_arb_priv *) device->fragment_priv;
-    BOOL use_pshader = use_ps(device);
-    BOOL use_vshader = use_vs(device);
+    BOOL use_pshader = use_ps(stateblock);
+    BOOL use_vshader = use_vs(stateblock);
     struct ffp_frag_settings settings;
     const struct arbfp_ffp_desc *desc;
     unsigned int i;
     struct ffp_frag_settings settings;
     const struct arbfp_ffp_desc *desc;
     unsigned int i;
@@ -2909,6 +2967,8 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
             }
             state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context);
             state_arb_specularenable(STATE_RENDER(WINED3DRS_SPECULARENABLE), stateblock, context);
             }
             state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context);
             state_arb_specularenable(STATE_RENDER(WINED3DRS_SPECULARENABLE), stateblock, context);
+        } else if(use_pshader && !isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
+            device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
         }
         return;
     }
         }
         return;
     }
@@ -2983,9 +3043,36 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
  * fragment_prog_arbfp function being called because FOGENABLE is dirty, which calls this function here
  */
 static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
  * fragment_prog_arbfp function being called because FOGENABLE is dirty, which calls this function here
  */
 static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    enum fogsource new_source;
+
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
+
+    if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
+
+    if(use_vs(stateblock)
+       && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
+        if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
+            FIXME("vertex shader with table fog used\n");
+        }
+        context->last_was_foggy_shader = TRUE;
+        new_source = FOGSOURCE_VS;
+    } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
+        context->last_was_foggy_shader = FALSE;
+        if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
+            new_source = FOGSOURCE_COORD;
+        } else {
+            new_source = FOGSOURCE_FFP;
+        }
+    } else {
+        context->last_was_foggy_shader = FALSE;
+        new_source = FOGSOURCE_FFP;
+    }
+    if(new_source != context->fog_source) {
+        context->fog_source = new_source;
+        state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
+    }
 }
 
 static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@@ -3130,7 +3217,11 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
     {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
@@ -3191,11 +3282,11 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup,
     const char *tex, *texinstr;
 
     if (yuv_fixup == YUV_FIXUP_UYVY) {
     const char *tex, *texinstr;
 
     if (yuv_fixup == YUV_FIXUP_UYVY) {
-        chroma = 'r';
-        *luminance = 'a';
+        chroma = 'x';
+        *luminance = 'w';
     } else {
     } else {
-        chroma = 'a';
-        *luminance = 'r';
+        chroma = 'w';
+        *luminance = 'x';
     }
     switch(textype) {
         case GL_TEXTURE_2D:             tex = "2D";     texinstr = "TXP"; break;
     }
     switch(textype) {
         case GL_TEXTURE_2D:             tex = "2D";     texinstr = "TXP"; break;
@@ -3221,8 +3312,8 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup,
      * So we have to get the sampling x position in non-normalized coordinates in integers
      */
     if(textype != GL_TEXTURE_RECTANGLE_ARB) {
      * So we have to get the sampling x position in non-normalized coordinates in integers
      */
     if(textype != GL_TEXTURE_RECTANGLE_ARB) {
-        shader_addline(buffer, "MUL texcrd.rg, fragment.texcoord[0], size.x;\n");
-        shader_addline(buffer, "MOV texcrd.a, size.x;\n");
+        shader_addline(buffer, "MUL texcrd.xy, fragment.texcoord[0], size.x;\n");
+        shader_addline(buffer, "MOV texcrd.w, size.x;\n");
     } else {
         shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
     }
     } else {
         shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
     }
@@ -3244,9 +3335,9 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup,
 
     /* Put the value into either of the chroma values */
     shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
 
     /* Put the value into either of the chroma values */
     shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
-    shader_addline(buffer, "MUL chroma.r, luminance.%c, temp.x;\n", chroma);
+    shader_addline(buffer, "MUL chroma.x, luminance.%c, temp.x;\n", chroma);
     shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
     shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
-    shader_addline(buffer, "MUL chroma.g, luminance.%c, temp.x;\n", chroma);
+    shader_addline(buffer, "MUL chroma.y, luminance.%c, temp.x;\n", chroma);
 
     /* Sample pixel 2. If we read an even pixel(SLT above returned 1), sample
      * the pixel right to the current one. Otherwise, sample the left pixel.
 
     /* Sample pixel 2. If we read an even pixel(SLT above returned 1), sample
      * the pixel right to the current one. Otherwise, sample the left pixel.
@@ -3258,9 +3349,9 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup,
 
     /* Put the value into the other chroma */
     shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
 
     /* Put the value into the other chroma */
     shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
-    shader_addline(buffer, "MAD chroma.g, luminance.%c, temp.x, chroma.g;\n", chroma);
+    shader_addline(buffer, "MAD chroma.y, luminance.%c, temp.x, chroma.y;\n", chroma);
     shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
     shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
-    shader_addline(buffer, "MAD chroma.r, luminance.%c, temp.x, chroma.r;\n", chroma);
+    shader_addline(buffer, "MAD chroma.x, luminance.%c, temp.x, chroma.x;\n", chroma);
 
     /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
      * the current one and lerp the two U and V values
 
     /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
      * the current one and lerp the two U and V values
@@ -3380,7 +3471,7 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance
     }
     /* Read the texture, put the result into the output register */
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
     }
     /* Read the texture, put the result into the output register */
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
-    shader_addline(buffer, "MOV chroma.r, temp.a;\n");
+    shader_addline(buffer, "MOV chroma.x, temp.w;\n");
 
     /* The other chroma value is 1/6th of the texture lower, from 5/6th to 6/6th
      * No need to clamp because we're just reusing the already clamped value from above
 
     /* The other chroma value is 1/6th of the texture lower, from 5/6th to 6/6th
      * No need to clamp because we're just reusing the already clamped value from above
@@ -3391,7 +3482,7 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance
         shader_addline(buffer, "MAD texcrd.y, size.y, coef.w, texcrd.y;\n");
     }
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
         shader_addline(buffer, "MAD texcrd.y, size.y, coef.w, texcrd.y;\n");
     }
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
-    shader_addline(buffer, "MOV chroma.g, temp.a;\n");
+    shader_addline(buffer, "MOV chroma.y, temp.w;\n");
 
     /* Sample the luminance value. It is in the top 2/3rd of the texture, so scale the y coordinate.
      * Clamp the y coordinate to prevent the chroma values from bleeding into the sampled luminance
 
     /* Sample the luminance value. It is in the top 2/3rd of the texture, so scale the y coordinate.
      * Clamp the y coordinate to prevent the chroma values from bleeding into the sampled luminance
@@ -3405,7 +3496,7 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance
         shader_addline(buffer, "MIN texcrd.y, temp.y, texcrd.y;\n");
         shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
     } else {
         shader_addline(buffer, "MIN texcrd.y, temp.y, texcrd.y;\n");
         shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
     } else {
-        /* Reading from texture_rectangles is pretty streightforward, just use the unmodified
+        /* Reading from texture_rectangles is pretty straightforward, just use the unmodified
          * texture coordinate. It is still a good idea to clamp it though, since the opengl texture
          * is bigger
          */
          * texture coordinate. It is still a good idea to clamp it though, since the opengl texture
          * is bigger
          */
@@ -3426,10 +3517,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
     struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
 
     /* Shader header */
     struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
 
     /* Shader header */
-    buffer.bsize = 0;
-    buffer.lineNo = 0;
-    buffer.newline = TRUE;
-    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
+    shader_buffer_init(&buffer);
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
@@ -3438,7 +3526,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
     checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)");
     LEAVE_GL();
     if(!shader) {
     checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)");
     LEAVE_GL();
     if(!shader) {
-        HeapFree(GetProcessHeap(), 0, buffer.buffer);
+        shader_buffer_free(&buffer);
         return 0;
     }
 
         return 0;
     }
 
@@ -3452,7 +3540,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
      * contains the luminance and alpha the chroma. With UYVY it is vice versa. Thus
      * take the format into account when generating the read swizzles
      *
      * contains the luminance and alpha the chroma. With UYVY it is vice versa. Thus
      * take the format into account when generating the read swizzles
      *
-     * Reading the Y value is streightforward - just sample the texture. The hardware
+     * Reading the Y value is straightforward - just sample the texture. The hardware
      * takes care of filtering in the horizontal and vertical direction.
      *
      * Reading the U and V values is harder. We have to avoid filtering horizontally,
      * takes care of filtering in the horizontal and vertical direction.
      *
      * Reading the U and V values is harder. We have to avoid filtering horizontally,
@@ -3493,7 +3581,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
         case YUV_FIXUP_YUY2:
             if (!gen_planar_yuv_read(&buffer, yuv_fixup, textype, &luminance_component))
             {
         case YUV_FIXUP_YUY2:
             if (!gen_planar_yuv_read(&buffer, yuv_fixup, textype, &luminance_component))
             {
-                HeapFree(GetProcessHeap(), 0, buffer.buffer);
+                shader_buffer_free(&buffer);
                 return 0;
             }
             break;
                 return 0;
             }
             break;
@@ -3501,14 +3589,14 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
         case YUV_FIXUP_YV12:
             if (!gen_yv12_read(&buffer, textype, &luminance_component))
             {
         case YUV_FIXUP_YV12:
             if (!gen_yv12_read(&buffer, textype, &luminance_component))
             {
-                HeapFree(GetProcessHeap(), 0, buffer.buffer);
+                shader_buffer_free(&buffer);
                 return 0;
             }
             break;
 
         default:
             FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
                 return 0;
             }
             break;
 
         default:
             FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
-            HeapFree(GetProcessHeap(), 0, buffer.buffer);
+            shader_buffer_free(&buffer);
             return 0;
     }
 
             return 0;
     }
 
@@ -3516,12 +3604,12 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
      * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
      * ranges from -0.5 to 0.5
      */
      * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
      * ranges from -0.5 to 0.5
      */
-    shader_addline(&buffer, "SUB chroma.rg, chroma, coef.y;\n");
+    shader_addline(&buffer, "SUB chroma.xy, chroma, coef.y;\n");
 
 
-    shader_addline(&buffer, "MAD result.color.r, chroma.r, yuv_coef.x, luminance.%c;\n", luminance_component);
-    shader_addline(&buffer, "MAD temp.r, -chroma.g, yuv_coef.y, luminance.%c;\n", luminance_component);
-    shader_addline(&buffer, "MAD result.color.g, -chroma.r, yuv_coef.z, temp.r;\n");
-    shader_addline(&buffer, "MAD result.color.b, chroma.g, yuv_coef.w, luminance.%c;\n", luminance_component);
+    shader_addline(&buffer, "MAD result.color.x, chroma.x, yuv_coef.x, luminance.%c;\n", luminance_component);
+    shader_addline(&buffer, "MAD temp.x, -chroma.y, yuv_coef.y, luminance.%c;\n", luminance_component);
+    shader_addline(&buffer, "MAD result.color.y, -chroma.x, yuv_coef.z, temp.x;\n");
+    shader_addline(&buffer, "MAD result.color.z, chroma.y, yuv_coef.w, luminance.%c;\n", luminance_component);
     shader_addline(&buffer, "END\n");
 
     ENTER_GL();
     shader_addline(&buffer, "END\n");
 
     ENTER_GL();
@@ -3533,7 +3621,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
         FIXME("Fragment program error at position %d: %s\n", pos,
               debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
     }
         FIXME("Fragment program error at position %d: %s\n", pos,
               debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
     }
-    HeapFree(GetProcessHeap(), 0, buffer.buffer);
+    shader_buffer_free(&buffer);
     LEAVE_GL();
 
     switch (yuv_fixup)
     LEAVE_GL();
 
     switch (yuv_fixup)
index 90ca192..c01ec1a 100644 (file)
@@ -159,7 +159,96 @@ static const char *debug_rep(GLuint rep) {
     }
 }
 
     }
 }
 
+static const char *debug_op(GLuint op) {
+    switch(op) {
+        case GL_MOV_ATI:                return "GL_MOV_ATI";
+        case GL_ADD_ATI:                return "GL_ADD_ATI";
+        case GL_MUL_ATI:                return "GL_MUL_ATI";
+        case GL_SUB_ATI:                return "GL_SUB_ATI";
+        case GL_DOT3_ATI:               return "GL_DOT3_ATI";
+        case GL_DOT4_ATI:               return "GL_DOT4_ATI";
+        case GL_MAD_ATI:                return "GL_MAD_ATI";
+        case GL_LERP_ATI:               return "GL_LERP_ATI";
+        case GL_CND_ATI:                return "GL_CND_ATI";
+        case GL_CND0_ATI:               return "GL_CND0_ATI";
+        case GL_DOT2_ADD_ATI:           return "GL_DOT2_ADD_ATI";
+        default:                        return "unexpected op";
+    }
+}
+
+static const char *debug_mask(GLuint mask) {
+    switch(mask) {
+        case GL_NONE:                           return "GL_NONE";
+        case GL_RED_BIT_ATI:                    return "GL_RED_BIT_ATI";
+        case GL_GREEN_BIT_ATI:                  return "GL_GREEN_BIT_ATI";
+        case GL_BLUE_BIT_ATI:                   return "GL_BLUE_BIT_ATI";
+        case GL_RED_BIT_ATI | GL_GREEN_BIT_ATI: return "GL_RED_BIT_ATI | GL_GREEN_BIT_ATI";
+        case GL_RED_BIT_ATI | GL_BLUE_BIT_ATI:  return "GL_RED_BIT_ATI | GL_BLUE_BIT_ATI";
+        case GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI:return "GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI";
+        case GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI:return "GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI";
+        default:                                return "Unexpected writemask";
+    }
+}
 #define GLINFO_LOCATION (*gl_info)
 #define GLINFO_LOCATION (*gl_info)
+
+static void wrap_op1(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) {
+    if(dstMask == GL_ALPHA) {
+        TRACE("glAlphaFragmentOp1ATI(%s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
+        GL_EXTCALL(glAlphaFragmentOp1ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod));
+    } else {
+        TRACE("glColorFragmentOp1ATI(%s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+              debug_mask(dstMask), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
+        GL_EXTCALL(glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod));
+    }
+}
+
+static void wrap_op2(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
+                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) {
+    if(dstMask == GL_ALPHA) {
+        TRACE("glAlphaFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+              debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod));
+        GL_EXTCALL(glAlphaFragmentOp2ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));
+    } else {
+        TRACE("glColorFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+              debug_mask(dstMask), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+              debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod));
+        GL_EXTCALL(glColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));
+    }
+}
+
+static void wrap_op3(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
+                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod,
+                     GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) {
+    if(dstMask == GL_ALPHA) {
+        /* Leave some free space to fit "GL_NONE, " in to align most alpha and color op lines */
+        TRACE("glAlphaFragmentOp3ATI(%s, %s,          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+              debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod),
+              debug_register(arg3), debug_rep(arg3Rep), debug_argmod(arg3Mod));
+        GL_EXTCALL(glAlphaFragmentOp3ATI(op, dst, dstMod,
+                                         arg1, arg1Rep, arg1Mod,
+                                         arg2, arg2Rep, arg2Mod,
+                                         arg3, arg3Rep, arg3Mod));
+    } else {
+        TRACE("glColorFragmentOp3ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+              debug_mask(dstMask), debug_dstmod(dstMod),
+              debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+              debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod),
+              debug_register(arg3), debug_rep(arg3Rep), debug_argmod(arg3Mod));
+        GL_EXTCALL(glColorFragmentOp3ATI(op, dst, dstMask, dstMod,
+                                         arg1, arg1Rep, arg1Mod,
+                                         arg2, arg2Rep, arg2Mod,
+                                         arg3, arg3Rep, arg3Mod));
+    }
+}
+
 static GLuint register_for_arg(DWORD arg, const 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)
 {
@@ -351,6 +440,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
         if(op[stage].cop != WINED3DTOP_BUMPENVMAP &&
            op[stage].cop != WINED3DTOP_BUMPENVMAPLUMINANCE) continue;
 
         if(op[stage].cop != WINED3DTOP_BUMPENVMAP &&
            op[stage].cop != WINED3DTOP_BUMPENVMAPLUMINANCE) continue;
 
+        fixup = op[stage].color_fixup;
         if (fixup.x_source != CHANNEL_SOURCE_X || fixup.y_source != CHANNEL_SOURCE_Y)
         {
             FIXME("Swizzles not implemented\n");
         if (fixup.x_source != CHANNEL_SOURCE_X || fixup.y_source != CHANNEL_SOURCE_Y)
         {
             FIXME("Swizzles not implemented\n");
@@ -364,12 +454,10 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
             argmodextra_y = fixup.y_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_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_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));
+        wrap_op3(gl_info, GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_RED_BIT_ATI, GL_NONE,
+                 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);
 
         /* FIXME: How can I make GL_DOT2_ADD_ATI read the factors from blue and alpha? It defaults to red and green,
          * and it is fairly easy to make it read GL_BLUE or BL_ALPHA, but I can't get an R * B + G * A. So we're wasting
 
         /* FIXME: How can I make GL_DOT2_ADD_ATI read the factors from blue and alpha? It defaults to red and green,
          * and it is fairly easy to make it read GL_BLUE or BL_ALPHA, but I can't get an R * B + G * A. So we're wasting
@@ -379,18 +467,14 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
          * NOTE: GL_BLUE | GL_ALPHA is not possible. It doesn't throw a compilation error, but an OR operation on the
          * constants doesn't make sense, considering their values.
          */
          * NOTE: GL_BLUE | GL_ALPHA is not possible. It doesn't throw a compilation error, but an OR operation on the
          * constants doesn't make sense, considering their values.
          */
-        TRACE("glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_5_ATI, GL_RED_BIT_ATI, GL_NONE, ATI_FFP_CONST_BUMPMAT(%d), GL_BLUE, GL_NONE)\n", stage);
-        GL_EXTCALL(glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_5_ATI, GL_RED_BIT_ATI, GL_NONE,
-                                         ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_NONE));
-        TRACE("glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE, ATI_FFP_CONST_BUMPMAT(%d), GL_ALPHA, GL_NONE)\n", stage);
-        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_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_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));
+        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_RED_BIT_ATI, GL_NONE,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_NONE);
+        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE);
+        wrap_op3(gl_info, GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
+                 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);
     }
 
     /* Pass 3: Generate sampling instructions for regular textures */
     }
 
     /* Pass 3: Generate sampling instructions for regular textures */
@@ -438,12 +522,10 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
         if(op[stage].cop == WINED3DTOP_DISABLE) {
             if(stage == 0) {
                 /* Handle complete texture disabling gracefully */
         if(op[stage].cop == WINED3DTOP_DISABLE) {
             if(stage == 0) {
                 /* Handle complete texture disabling gracefully */
-                TRACE("glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_PRIMARY_COLOR, GL_NONE, GL_NONE)\n");
-                GL_EXTCALL(glColorFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
-                                                 GL_PRIMARY_COLOR, GL_NONE, GL_NONE));
-                TRACE("glAlphaFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_PRIMARY_COLOR, GL_NONE, GL_NONE)\n");
-                GL_EXTCALL(glAlphaFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE,
-                                                 GL_PRIMARY_COLOR, GL_NONE, GL_NONE));
+                wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
+                         GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
+                wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
+                         GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
             }
             break;
         }
             }
             break;
         }
@@ -472,10 +554,8 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 argmod1 = argmod2;
                 rep1 = rep2;
             case WINED3DTOP_SELECTARG1:
                 argmod1 = argmod2;
                 rep1 = rep2;
             case WINED3DTOP_SELECTARG1:
-                TRACE("glColorFragmentOp1ATI(GL_MOV_ATI, %s, GL_NONE, GL_NONE, %s, %s, %s)\n",
-                      debug_register(dstreg), debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1));
-                GL_EXTCALL(glColorFragmentOp1ATI(GL_MOV_ATI, dstreg, GL_NONE, GL_NONE,
-                                                 arg1, rep1, argmod1));
+                wrap_op1(gl_info, GL_MOV_ATI, dstreg, GL_NONE, GL_NONE,
+                         arg1, rep1, argmod1);
                 break;
 
             case WINED3DTOP_MODULATE4X:
                 break;
 
             case WINED3DTOP_MODULATE4X:
@@ -484,13 +564,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 if(dstmod == GL_NONE) dstmod = GL_2X_BIT_ATI;
                 dstmod |= GL_SATURATE_BIT_ATI;
             case WINED3DTOP_MODULATE:
                 if(dstmod == GL_NONE) dstmod = GL_2X_BIT_ATI;
                 dstmod |= GL_SATURATE_BIT_ATI;
             case WINED3DTOP_MODULATE:
-                TRACE("glColorFragmentOp2ATI(GL_MUL_ATI, %s, GL_NONE, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2));
-                GL_EXTCALL(glColorFragmentOp2ATI(GL_MUL_ATI, dstreg, GL_NONE, dstmod,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmod2));
+                wrap_op2(gl_info, GL_MUL_ATI, dstreg, GL_NONE, dstmod,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmod2);
                 break;
 
             case WINED3DTOP_ADDSIGNED2X:
                 break;
 
             case WINED3DTOP_ADDSIGNED2X:
@@ -499,40 +575,27 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 argmodextra = GL_BIAS_BIT_ATI;
             case WINED3DTOP_ADD:
                 dstmod |= GL_SATURATE_BIT_ATI;
                 argmodextra = GL_BIAS_BIT_ATI;
             case WINED3DTOP_ADD:
                 dstmod |= GL_SATURATE_BIT_ATI;
-                TRACE("glColorFragmentOp2ATI(GL_ADD_ATI, %s, GL_NONE, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmodextra | argmod2));
-                GL_EXTCALL(glColorFragmentOp2ATI(GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, dstmod,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmodextra | argmod2));
+                wrap_op2(gl_info, GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, dstmod,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmodextra | argmod2);
                 break;
 
             case WINED3DTOP_SUBTRACT:
                 dstmod |= GL_SATURATE_BIT_ATI;
                 break;
 
             case WINED3DTOP_SUBTRACT:
                 dstmod |= GL_SATURATE_BIT_ATI;
-                TRACE("glColorFragmentOp2ATI(GL_SUB_ATI, %s, GL_NONE, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2));
-                GL_EXTCALL(glColorFragmentOp2ATI(GL_SUB_ATI, dstreg, GL_NONE, dstmod,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmod2));
+                wrap_op2(gl_info, GL_SUB_ATI, dstreg, GL_NONE, dstmod,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmod2);
                 break;
 
             case WINED3DTOP_ADDSMOOTH:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
                 break;
 
             case WINED3DTOP_ADDSMOOTH:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
-                TRACE("glColorFragmentOp3ATI(GL_MAD_ATI, %s, GL_NONE, GL_SATURATE_BIT_ATI, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmodextra),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1));
                 /* Dst = arg1 + * arg2(1 -arg 1)
                  *     = arg2 * (1 - arg1) + arg1
                  */
                 /* Dst = arg1 + * arg2(1 -arg 1)
                  *     = arg2 * (1 - arg1) + arg1
                  */
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
-                                                 arg2, rep2, argmod2,
-                                                 arg1, rep1, argmodextra,
-                                                 arg1, rep1, argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+                         arg2, rep2, argmod2,
+                         arg1, rep1, argmodextra,
+                         arg1, rep1, argmod1);
                 break;
 
             case WINED3DTOP_BLENDCURRENTALPHA:
                 break;
 
             case WINED3DTOP_BLENDCURRENTALPHA:
@@ -543,28 +606,18 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
             case WINED3DTOP_BLENDDIFFUSEALPHA:
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
             case WINED3DTOP_BLENDDIFFUSEALPHA:
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
-                TRACE("glColorFragmentOp3ATI(GL_LERP_ATI, %s, GL_NONE, GL_NONE, %s, GL_ALPHA, GL_NONE, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(extrarg),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
-                                                 extrarg, GL_ALPHA, GL_NONE,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmod2));
+                wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
+                         extrarg, GL_ALPHA, GL_NONE,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmod2);
                 break;
 
             case WINED3DTOP_BLENDTEXTUREALPHAPM:
                 arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
                 break;
 
             case WINED3DTOP_BLENDTEXTUREALPHAPM:
                 arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
-                TRACE("glColorFragmentOp3ATI(GL_MAD_ATI, %s, GL_NONE, GL_NONE, %s, %s, %s, %s, GL_ALPHA, GL_COMP_BIT_ATI, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg0),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE, GL_NONE,
-                                                 arg2, rep2,  argmod2,
-                                                 arg0, GL_ALPHA, GL_COMP_BIT_ATI,
-                                                 arg1, rep1,  argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_NONE,
+                         arg2, rep2,  argmod2,
+                         arg0, GL_ALPHA, GL_COMP_BIT_ATI,
+                         arg1, rep1,  argmod1);
                 break;
 
             /* D3DTOP_PREMODULATE ???? */
                 break;
 
             /* D3DTOP_PREMODULATE ???? */
@@ -573,63 +626,40 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
             case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
                 if(!argmodextra) argmodextra = argmod1;
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
             case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
                 if(!argmodextra) argmodextra = argmod1;
-                TRACE("glColorFragmentOp3ATI(GL_MAD_ATI, %s, GL_NONE, GL_SATURATE_BIT_ATI, %s, %s, %s, %s, GL_ALPHA, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg1), debug_argmod(argmodextra), debug_register(arg1), debug_rep(rep1), debug_argmod(arg1));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
-                                                 arg2, rep2,  argmod2,
-                                                 arg1, GL_ALPHA, argmodextra,
-                                                 arg1, rep1,  argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+                         arg2, rep2,  argmod2,
+                         arg1, GL_ALPHA, argmodextra,
+                         arg1, rep1,  argmod1);
                 break;
 
             case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
             case WINED3DTOP_MODULATECOLOR_ADDALPHA:
                 if(!argmodextra) argmodextra = argmod1;
                 break;
 
             case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
             case WINED3DTOP_MODULATECOLOR_ADDALPHA:
                 if(!argmodextra) argmodextra = argmod1;
-                TRACE("glColorFragmentOp3ATI(GL_MAD_ATI, %s, GL_NONE, GL_SATURATE_BIT_ATI, %s, %s, %s, %s, %s, %s, %s, GL_ALPHA, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmodextra),
-                      debug_register(arg1), debug_argmod(argmod1));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
-                                                 arg2, rep2,  argmod2,
-                                                 arg1, rep1,  argmodextra,
-                                                 arg1, GL_ALPHA, argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+                         arg2, rep2,  argmod2,
+                         arg1, rep1,  argmodextra,
+                         arg1, GL_ALPHA, argmod1);
                 break;
 
             case WINED3DTOP_DOTPRODUCT3:
                 break;
 
             case WINED3DTOP_DOTPRODUCT3:
-                TRACE("glColorFragmentOp2ATI(GL_DOT3_ATI, %s, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1 | GL_BIAS_BIT_ATI),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2 | GL_BIAS_BIT_ATI));
-                GL_EXTCALL(glColorFragmentOp2ATI(GL_DOT3_ATI, dstreg, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
-                                                 arg1, rep1, argmod1 | GL_BIAS_BIT_ATI,
-                                                 arg2, rep2, argmod2 | GL_BIAS_BIT_ATI));
+                wrap_op2(gl_info, GL_DOT3_ATI, dstreg, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
+                         arg1, rep1, argmod1 | GL_BIAS_BIT_ATI,
+                         arg2, rep2, argmod2 | GL_BIAS_BIT_ATI);
                 break;
 
             case WINED3DTOP_MULTIPLYADD:
                 break;
 
             case WINED3DTOP_MULTIPLYADD:
-                TRACE("glColorFragmentOp3ATI(GL_MAD_ATI, %s, GL_NONE, GL_SATURATE_BIT_ATI, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg0), debug_rep(rep0), debug_argmod(argmod0));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmod2,
-                                                 arg0, rep0, argmod0));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmod2,
+                         arg0, rep0, argmod0);
                 break;
 
             case WINED3DTOP_LERP:
                 break;
 
             case WINED3DTOP_LERP:
-                TRACE("glColorFragmentOp3ATI(GL_LERP_ATI, %s, GL_NONE, GL_NONE, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_rep(rep1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_rep(rep2), debug_argmod(argmod2),
-                      debug_register(arg0), debug_rep(rep0), debug_argmod(argmod0));
-                GL_EXTCALL(glColorFragmentOp3ATI(GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
-                                                 arg0, rep0, argmod0,
-                                                 arg1, rep1, argmod1,
-                                                 arg2, rep2, argmod2));
+                wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
+                         arg0, rep0, argmod0,
+                         arg1, rep1, argmod1,
+                         arg2, rep2, argmod2);
                 break;
 
             case WINED3DTOP_BUMPENVMAP:
                 break;
 
             case WINED3DTOP_BUMPENVMAP:
@@ -651,9 +681,8 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
             case WINED3DTOP_DISABLE:
                 /* Get the primary color to the output if on stage 0, otherwise leave register 0 untouched */
                 if(stage == 0) {
             case WINED3DTOP_DISABLE:
                 /* Get the primary color to the output if on stage 0, otherwise leave register 0 untouched */
                 if(stage == 0) {
-                    TRACE("glAlphaFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_PRIMARY_COLOR, GL_NONE, GL_NONE)\n");
-                    GL_EXTCALL(glAlphaFragmentOp1ATI(GL_MOV_ATI, GL_REG_0_ATI, GL_NONE,
-                               GL_PRIMARY_COLOR, GL_NONE, GL_NONE));
+                    wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
+                             GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
                 }
                 break;
 
                 }
                 break;
 
@@ -661,11 +690,8 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 arg1 = arg2;
                 argmod1 = argmod2;
             case WINED3DTOP_SELECTARG1:
                 arg1 = arg2;
                 argmod1 = argmod2;
             case WINED3DTOP_SELECTARG1:
-                TRACE("glAlphaFragmentOp1ATI(GL_MOV_ATI, %s,          GL_NONE, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_argmod(argmod1));
-                GL_EXTCALL(glAlphaFragmentOp1ATI(GL_MOV_ATI, dstreg, GL_NONE,
-                                                 arg1, GL_NONE, argmod1));
+                wrap_op1(gl_info, GL_MOV_ATI, dstreg, GL_ALPHA, GL_NONE,
+                         arg1, GL_NONE, argmod1);
                 break;
 
             case WINED3DTOP_MODULATE4X:
                 break;
 
             case WINED3DTOP_MODULATE4X:
@@ -674,13 +700,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 if(dstmod == GL_NONE) dstmod = GL_2X_BIT_ATI;
                 dstmod |= GL_SATURATE_BIT_ATI;
             case WINED3DTOP_MODULATE:
                 if(dstmod == GL_NONE) dstmod = GL_2X_BIT_ATI;
                 dstmod |= GL_SATURATE_BIT_ATI;
             case WINED3DTOP_MODULATE:
-                TRACE("glAlphaFragmentOp2ATI(GL_MUL_ATI, %s,          %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmod2));
-                GL_EXTCALL(glAlphaFragmentOp2ATI(GL_MUL_ATI, dstreg, dstmod,
-                                                 arg1, GL_NONE, argmod1,
-                                                 arg2, GL_NONE, argmod2));
+                wrap_op2(gl_info, GL_MUL_ATI, dstreg, GL_ALPHA, dstmod,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmod2);
                 break;
 
             case WINED3DTOP_ADDSIGNED2X:
                 break;
 
             case WINED3DTOP_ADDSIGNED2X:
@@ -689,40 +711,27 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 argmodextra = GL_BIAS_BIT_ATI;
             case WINED3DTOP_ADD:
                 dstmod |= GL_SATURATE_BIT_ATI;
                 argmodextra = GL_BIAS_BIT_ATI;
             case WINED3DTOP_ADD:
                 dstmod |= GL_SATURATE_BIT_ATI;
-                TRACE("glAlphaFragmentOp2ATI(GL_ADD_ATI, %s,          %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmodextra | argmod2));
-                GL_EXTCALL(glAlphaFragmentOp2ATI(GL_ADD_ATI, dstreg, dstmod,
-                                                 arg1, GL_NONE, argmod1,
-                                                 arg2, GL_NONE, argmodextra | argmod2));
+                wrap_op2(gl_info, GL_ADD_ATI, dstreg, GL_ALPHA, dstmod,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmodextra | argmod2);
                 break;
 
             case WINED3DTOP_SUBTRACT:
                 dstmod |= GL_SATURATE_BIT_ATI;
                 break;
 
             case WINED3DTOP_SUBTRACT:
                 dstmod |= GL_SATURATE_BIT_ATI;
-                TRACE("glAlphaFragmentOp2ATI(GL_SUB_ATI, %s, GL_NONE, %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg), debug_dstmod(dstmod),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmod2));
-                GL_EXTCALL(glAlphaFragmentOp2ATI(GL_SUB_ATI, dstreg, dstmod,
-                                                 arg1, GL_NONE, argmod1,
-                                                 arg2, GL_NONE, argmod2));
+                wrap_op2(gl_info, GL_SUB_ATI, dstreg, GL_ALPHA, dstmod,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmod2);
                 break;
 
             case WINED3DTOP_ADDSMOOTH:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
                 break;
 
             case WINED3DTOP_ADDSMOOTH:
                 argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
-                TRACE("glAlphaFragmentOp3ATI(GL_MAD_ATI, %s,          GL_SATURATE_BIT_ATI, %s, GL_NONE, %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_argmod(argmod2),
-                      debug_register(arg1), debug_argmod(argmodextra),
-                      debug_register(arg1), debug_argmod(argmod1));
                 /* Dst = arg1 + * arg2(1 -arg 1)
                  *     = arg2 * (1 - arg1) + arg1
                  */
                 /* Dst = arg1 + * arg2(1 -arg 1)
                  *     = arg2 * (1 - arg1) + arg1
                  */
-                GL_EXTCALL(glAlphaFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_SATURATE_BIT_ATI,
-                                                 arg2, GL_NONE, argmod2,
-                                                 arg1, GL_NONE, argmodextra,
-                                                 arg1, GL_NONE, argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+                         arg2, GL_NONE, argmod2,
+                         arg1, GL_NONE, argmodextra,
+                         arg1, GL_NONE, argmod1);
                 break;
 
             case WINED3DTOP_BLENDCURRENTALPHA:
                 break;
 
             case WINED3DTOP_BLENDCURRENTALPHA:
@@ -733,64 +742,40 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
             case WINED3DTOP_BLENDDIFFUSEALPHA:
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
             case WINED3DTOP_BLENDDIFFUSEALPHA:
                 if(extrarg == GL_NONE) extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
-                TRACE("glAlphaFragmentOp3ATI(GL_LERP_ATI, %s,          GL_NONE, %s, GL_ALPHA, GL_NONE, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(extrarg),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmod2));
-                GL_EXTCALL(glAlphaFragmentOp3ATI(GL_LERP_ATI, dstreg, GL_NONE,
-                                                 extrarg, GL_ALPHA, GL_NONE,
-                                                 arg1, GL_NONE, argmod1,
-                                                 arg2, GL_NONE, argmod2));
+                wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_ALPHA, GL_NONE,
+                         extrarg, GL_ALPHA, GL_NONE,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmod2);
                 break;
 
             case WINED3DTOP_BLENDTEXTUREALPHAPM:
                 arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
                 break;
 
             case WINED3DTOP_BLENDTEXTUREALPHAPM:
                 arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
-                TRACE("glAlphaFragmentOp3ATI(GL_MAD_ATI, %s,          GL_NONE, %s, GL_NONE, %s, %s, GL_ALPHA, GL_COMP_BIT_ATI, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg2), debug_argmod(argmod2),
-                      debug_register(arg0),
-                      debug_register(arg1), debug_argmod(argmod1));
-                GL_EXTCALL(glAlphaFragmentOp3ATI(GL_MAD_ATI, dstreg, GL_NONE,
-                                                 arg2, GL_NONE,  argmod2,
-                                                 arg0, GL_ALPHA, GL_COMP_BIT_ATI,
-                                                 arg1, GL_NONE,  argmod1));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_NONE,
+                         arg2, GL_NONE,  argmod2,
+                         arg0, GL_ALPHA, GL_COMP_BIT_ATI,
+                         arg1, GL_NONE,  argmod1);
                 break;
 
             /* D3DTOP_PREMODULATE ???? */
 
             case WINED3DTOP_DOTPRODUCT3:
                 break;
 
             /* D3DTOP_PREMODULATE ???? */
 
             case WINED3DTOP_DOTPRODUCT3:
-                TRACE("glAlphaFragmentOp2ATI(GL_DOT3_ATI, %s,          GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_argmod(argmod1 | GL_BIAS_BIT_ATI),
-                      debug_register(arg2), debug_argmod(argmod2 | GL_BIAS_BIT_ATI));
-                GL_EXTCALL(glAlphaFragmentOp2ATI(GL_DOT3_ATI, dstreg, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
-                                                 arg1, GL_NONE, argmod1 | GL_BIAS_BIT_ATI,
-                                                 arg2, GL_NONE, argmod2 | GL_BIAS_BIT_ATI));
+                wrap_op2(gl_info, GL_DOT3_ATI, dstreg, GL_ALPHA, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
+                         arg1, GL_NONE, argmod1 | GL_BIAS_BIT_ATI,
+                         arg2, GL_NONE, argmod2 | GL_BIAS_BIT_ATI);
                 break;
 
             case WINED3DTOP_MULTIPLYADD:
                 break;
 
             case WINED3DTOP_MULTIPLYADD:
-                TRACE("glAlphaFragmentOp3ATI(GL_MAD_ATI, %s,          GL_SATURATE_BIT_ATI, %s, GL_NONE, %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmod2),
-                      debug_register(arg0), debug_argmod(argmod0));
-                GL_EXTCALL(glAlphaFragmentOp3ATI(GL_MAD_ATI, dstreg,          GL_SATURATE_BIT_ATI,
-                           arg1, GL_NONE, argmod1,
-                           arg2, GL_NONE, argmod2,
-                           arg0, GL_NONE, argmod0));
+                wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmod2,
+                         arg0, GL_NONE, argmod0);
                 break;
 
             case WINED3DTOP_LERP:
                 break;
 
             case WINED3DTOP_LERP:
-                TRACE("glAlphaFragmentOp3ATI(GL_LERP_ATI, %s,          GL_SATURATE_BIT_ATI, %s, GL_NONE, %s, %s, GL_NONE, %s, %s, GL_NONE, %s)\n",
-                      debug_register(dstreg),
-                      debug_register(arg1), debug_argmod(argmod1),
-                      debug_register(arg2), debug_argmod(argmod2),
-                      debug_register(arg0), debug_argmod(argmod0));
-                GL_EXTCALL(glAlphaFragmentOp3ATI(GL_LERP_ATI, dstreg, GL_SATURATE_BIT_ATI,
-                                                 arg1, GL_NONE, argmod1,
-                                                 arg2, GL_NONE, argmod2,
-                                                 arg0, GL_NONE, argmod0));
+                wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+                         arg1, GL_NONE, argmod1,
+                         arg2, GL_NONE, argmod2,
+                         arg0, GL_NONE, argmod0);
                 break;
 
             case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
                 break;
 
             case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
@@ -868,7 +853,7 @@ static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *statebloc
 }
 
 static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     float mat[2][2];
 
     mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]);
     float mat[2][2];
 
     mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]);
@@ -896,10 +881,41 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
     }
 }
 
     }
 }
 
+static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
+    BOOL use_vshader = use_vs(stateblock);
+
+    /* The ATIFS code does not support pixel shaders currently, but we have to provide a state handler
+     * to call shader_select to select a vertex shader if one is applied because the vertex shader state
+     * may defer calling the shader backend if the pshader state is dirty.
+     *
+     * In theory the application should not be able to mark the pixel shader dirty because it cannot
+     * create a shader, and thus has no way to set the state to something != NULL. However, a different
+     * pipeline part may link a different state to its pixelshader handler, thus a pshader state exists
+     * and can be dirtified. Also the pshader is always dirtified at startup, and blitting disables all
+     * shaders and dirtifies all shader states. If atifs can deal with this it keeps the rest of the code
+     * simpler.
+     */
+    if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
+        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, use_vshader);
+
+        if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
+            device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
+        }
+    }
+}
+
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
     {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_atifs   }, 0                               },
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
     {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_atifs   }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor          }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity        }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGSTART),                    { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
+    {STATE_RENDER(WINED3DRS_FOGEND),                      { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
     {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
@@ -1020,6 +1036,7 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
     {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
     {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
+    {STATE_PIXELSHADER,                                   { STATE_PIXELSHADER,                                  atifs_apply_pixelshader }, 0                               },
     {0 /* Terminate */,                                   { 0,                                                  0                       }, 0                               },
 };
 
     {0 /* Terminate */,                                   { 0,                                                  0                       }, 0                               },
 };
 
index c0b149f..a270b0c 100644 (file)
@@ -40,6 +40,20 @@ static inline BOOL shader_is_version_token(DWORD token) {
            shader_is_vshader_version(token);
 }
 
            shader_is_vshader_version(token);
 }
 
+void shader_buffer_init(struct SHADER_BUFFER *buffer)
+{
+    buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
+    buffer->buffer[0] = '\0';
+    buffer->bsize = 0;
+    buffer->lineNo = 0;
+    buffer->newline = TRUE;
+}
+
+void shader_buffer_free(struct SHADER_BUFFER *buffer)
+{
+    HeapFree(GetProcessHeap(), 0, buffer->buffer);
+}
+
 int shader_addline(
     SHADER_BUFFER* buffer,  
     const char *format, ...) {
 int shader_addline(
     SHADER_BUFFER* buffer,  
     const char *format, ...) {
@@ -76,6 +90,15 @@ int shader_addline(
     return 0;
 }
 
     return 0;
 }
 
+void shader_init(struct IWineD3DBaseShaderClass *shader,
+        IWineD3DDevice *device, const SHADER_OPCODE *instruction_table)
+{
+    shader->ref = 1;
+    shader->device = device;
+    shader->shader_ins = instruction_table;
+    list_init(&shader->linked_programs);
+}
+
 const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code)
 {
     DWORD i = 0;
 const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code)
 {
     DWORD i = 0;
@@ -117,17 +140,12 @@ static int shader_get_param(const DWORD *pToken, DWORD shader_version, DWORD *pa
 }
 
 /* Return the number of parameters to skip for an opcode */
 }
 
 /* Return the number of parameters to skip for an opcode */
-static inline int shader_skip_opcode(
-    IWineD3DBaseShaderImpl* This,
-    const SHADER_OPCODE* curOpcode,
-    DWORD opcode_token) {
-
+static inline int shader_skip_opcode(const SHADER_OPCODE *curOpcode, DWORD opcode_token, DWORD shader_version)
+{
    /* Shaders >= 2.0 may contain address tokens, but fortunately they
     * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
    /* Shaders >= 2.0 may contain address tokens, but fortunately they
     * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
-
-    return (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2)?
-        ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT):
-        curOpcode->num_params;
+    return (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
+            ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : curOpcode->num_params;
 }
 
 /* Read the parameters of an unrecognized opcode from the input stream
 }
 
 /* Read the parameters of an unrecognized opcode from the input stream
@@ -192,28 +210,21 @@ static void shader_delete_constant_list(struct list* clist) {
 /* Note that this does not count the loop register
  * as an address register. */
 
 /* Note that this does not count the loop register
  * as an address register. */
 
-HRESULT shader_get_registers_used(
-    IWineD3DBaseShader *iface,
-    shader_reg_maps* reg_maps,
-    semantic* semantics_in,
-    semantic* semantics_out,
-    CONST DWORD* pToken,
-    IWineD3DStateBlockImpl *stateBlock) {
-
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
+        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code)
+{
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
-    DWORD shader_version = This->baseShader.hex_version;
+    DWORD shader_version;
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
+    const DWORD* pToken = byte_code;
+    char pshader;
 
     /* There are some minor differences between pixel and vertex shaders */
 
     /* There are some minor differences between pixel and vertex shaders */
-    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
 
     memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
     memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
 
 
     memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
     memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
 
-    if (pToken == NULL)
-        return WINED3D_OK;
-
     /* get_registers_used is called on every compile on some 1.x shaders, which can result
      * in stacking up a collection of local constants. Delete the old constants if existing
      */
     /* get_registers_used is called on every compile on some 1.x shaders, which can result
      * in stacking up a collection of local constants. Delete the old constants if existing
      */
@@ -221,17 +232,22 @@ HRESULT shader_get_registers_used(
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
 
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
 
+    /* The version token is supposed to be the first token */
+    if (!shader_is_version_token(*pToken))
+    {
+        FIXME("First token is not a version token, invalid shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+    reg_maps->shader_version = shader_version = *pToken++;
+    pshader = shader_is_pshader_version(shader_version);
+
     while (WINED3DVS_END() != *pToken) {
         CONST SHADER_OPCODE* curOpcode;
         DWORD opcode_token;
 
     while (WINED3DVS_END() != *pToken) {
         CONST SHADER_OPCODE* curOpcode;
         DWORD opcode_token;
 
-        /* Skip version */
-        if (shader_is_version_token(*pToken)) {
-             ++pToken;
-             continue;
-
         /* Skip comments */
         /* Skip comments */
-        } else if (shader_is_comment(*pToken)) {
+        if (shader_is_comment(*pToken))
+        {
              DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
              ++pToken;
              pToken += comment_len;
              DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
              ++pToken;
              pToken += comment_len;
@@ -287,7 +303,8 @@ HRESULT shader_get_registers_used(
             memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
             memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
-            if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 && pshader) {
+            if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 && pshader)
+            {
                 float *value = (float *) lconst->value;
                 if(value[0] < -1.0) value[0] = -1.0;
                 else if(value[0] >  1.0) value[0] =  1.0;
                 float *value = (float *) lconst->value;
                 if(value[0] < -1.0) value[0] = -1.0;
                 else if(value[0] >  1.0) value[0] =  1.0;
@@ -328,6 +345,8 @@ HRESULT shader_get_registers_used(
                 max_loop_depth = cur_loop_depth;
             pToken += curOpcode->num_params;
 
                 max_loop_depth = cur_loop_depth;
             pToken += curOpcode->num_params;
 
+            /* Rep and Loop always use an integer constant for the control parameters */
+            This->baseShader.uses_int_consts = TRUE;
         } else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
                    WINED3DSIO_ENDREP == curOpcode->opcode) {
             cur_loop_depth--;
         } else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
                    WINED3DSIO_ENDREP == curOpcode->opcode) {
             cur_loop_depth--;
@@ -344,50 +363,25 @@ HRESULT shader_get_registers_used(
             int i, limit;
 
             /* Declare 1.X samplers implicitly, based on the destination reg. number */
             int i, limit;
 
             /* Declare 1.X samplers implicitly, based on the destination reg. number */
-            if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 &&
-                pshader /* Filter different instructions with the same enum values in VS */ &&
-                (WINED3DSIO_TEX == curOpcode->opcode ||
-                 WINED3DSIO_TEXBEM == curOpcode->opcode ||
-                 WINED3DSIO_TEXBEML == curOpcode->opcode ||
-                 WINED3DSIO_TEXDP3TEX == curOpcode->opcode ||
-                 WINED3DSIO_TEXM3x2TEX == curOpcode->opcode ||
-                 WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode ||
-                 WINED3DSIO_TEXM3x3TEX == curOpcode->opcode ||
-                 WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode ||
-                 WINED3DSIO_TEXREG2AR == curOpcode->opcode ||
-                 WINED3DSIO_TEXREG2GB == curOpcode->opcode ||
-                 WINED3DSIO_TEXREG2RGB == curOpcode->opcode)) {
-
+            if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1
+                    && pshader /* Filter different instructions with the same enum values in VS */
+                    && (WINED3DSIO_TEX == curOpcode->opcode
+                        || WINED3DSIO_TEXBEM == curOpcode->opcode
+                        || WINED3DSIO_TEXBEML == curOpcode->opcode
+                        || WINED3DSIO_TEXDP3TEX == curOpcode->opcode
+                        || WINED3DSIO_TEXM3x2TEX == curOpcode->opcode
+                        || WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode
+                        || WINED3DSIO_TEXM3x3TEX == curOpcode->opcode
+                        || WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode
+                        || WINED3DSIO_TEXREG2AR == curOpcode->opcode
+                        || WINED3DSIO_TEXREG2GB == curOpcode->opcode
+                        || WINED3DSIO_TEXREG2RGB == curOpcode->opcode))
+            {
                 /* Fake sampler usage, only set reserved bit and ttype */
                 DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
 
                 /* Fake sampler usage, only set reserved bit and ttype */
                 DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
 
-                if(!stateBlock->textures[sampler_code]) {
-                    ERR("No texture bound to sampler %d\n", sampler_code);
-                    reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                } else {
-                    int texType = IWineD3DBaseTexture_GetTextureDimensions(stateBlock->textures[sampler_code]);
-                    switch(texType) {
-                        /* We have to select between texture rectangles and 2D textures later because 2.0 and
-                         * 3.0 shaders only have WINED3DSTT_2D as well
-                         */
-                        case GL_TEXTURE_RECTANGLE_ARB:
-                        case GL_TEXTURE_2D:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                            break;
-
-                        case GL_TEXTURE_3D:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_VOLUME;
-                            break;
-
-                        case GL_TEXTURE_CUBE_MAP_ARB:
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_CUBE;
-                            break;
-
-                        default:
-                            ERR("Unexpected gl texture type found: %d\n", texType);
-                            reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-                    }
-                }
+                TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
+                reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
 
                 /* texbem is only valid with < 1.4 pixel shaders */
                 if(WINED3DSIO_TEXBEM  == curOpcode->opcode ||
 
                 /* texbem is only valid with < 1.4 pixel shaders */
                 if(WINED3DSIO_TEXBEM  == curOpcode->opcode ||
@@ -473,20 +467,30 @@ HRESULT shader_get_registers_used(
                         reg_maps->usesrelconstF = TRUE;
                     }
                 }
                         reg_maps->usesrelconstF = TRUE;
                     }
                 }
+                else if(WINED3DSPR_CONSTINT == regtype) {
+                    This->baseShader.uses_int_consts = TRUE;
+                }
+                else if(WINED3DSPR_CONSTBOOL == regtype) {
+                    This->baseShader.uses_bool_consts = TRUE;
+                }
 
                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used
                  * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT
                  * isn't used in them, but future register types might cause issues
                  */
 
                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used
                  * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT
                  * isn't used in them, but future register types might cause issues
                  */
-                else if(WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ &&
-                        !pshader && WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) < 3) {
+                else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */
+                        && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3)
+                {
                     reg_maps->texcoord_mask[reg] |= shader_get_writemask(param);
                 }
             }
         }
     }
                     reg_maps->texcoord_mask[reg] |= shader_get_writemask(param);
                 }
             }
         }
     }
+    ++pToken;
     reg_maps->loop_depth = max_loop_depth;
 
     reg_maps->loop_depth = max_loop_depth;
 
+    This->baseShader.functionLength = ((char *)pToken - (char *)byte_code);
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -593,7 +597,7 @@ static void shader_dump_param(const DWORD param, const DWORD addr_token, int inp
 {
     static const char * const rastout_reg_names[] = { "oPos", "oFog", "oPts" };
     static const char * const misctype_reg_names[] = { "vPos", "vFace"};
 {
     static const char * const rastout_reg_names[] = { "oPos", "oFog", "oPts" };
     static const char * const misctype_reg_names[] = { "vPos", "vFace"};
-    char swizzle_reg_chars[4];
+    const char *swizzle_reg_chars = "xyzw";
 
     DWORD reg = param & WINED3DSP_REGNUM_MASK;
     DWORD regtype = shader_get_regtype(param);
 
     DWORD reg = param & WINED3DSP_REGNUM_MASK;
     DWORD regtype = shader_get_regtype(param);
@@ -602,14 +606,6 @@ static void shader_dump_param(const DWORD param, const DWORD addr_token, int inp
     /* There are some minor differences between pixel and vertex shaders */
     char pshader = shader_is_pshader_version(shader_version);
 
     /* There are some minor differences between pixel and vertex shaders */
     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 */
-
-    swizzle_reg_chars[0] = pshader? 'r': 'x';
-    swizzle_reg_chars[1] = pshader? 'g': 'y';
-    swizzle_reg_chars[2] = pshader? 'b': 'z';
-    swizzle_reg_chars[3] = pshader? 'a': 'w';
-
     if (input) {
         if ( (modifier == WINED3DSPSM_NEG) ||
              (modifier == WINED3DSPSM_BIASNEG) ||
     if (input) {
         if ( (modifier == WINED3DSPSM_NEG) ||
              (modifier == WINED3DSPSM_BIASNEG) ||
@@ -714,10 +710,10 @@ static void shader_dump_param(const DWORD param, const DWORD addr_token, int inp
    } else {
         /** operand input */
         DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
    } else {
         /** operand input */
         DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
-        DWORD swizzle_r = swizzle & 0x03;
-        DWORD swizzle_g = (swizzle >> 2) & 0x03;
-        DWORD swizzle_b = (swizzle >> 4) & 0x03;
-        DWORD swizzle_a = (swizzle >> 6) & 0x03;
+        DWORD swizzle_x = swizzle & 0x03;
+        DWORD swizzle_y = (swizzle >> 2) & 0x03;
+        DWORD swizzle_z = (swizzle >> 4) & 0x03;
+        DWORD swizzle_w = (swizzle >> 6) & 0x03;
 
         if (0 != modifier) {
             switch (modifier) {
 
         if (0 != modifier) {
             switch (modifier) {
@@ -745,25 +741,24 @@ static void shader_dump_param(const DWORD param, const DWORD addr_token, int inp
         *  RRGGBBAA
         */
         if ((WINED3DVS_NOSWIZZLE >> WINED3DVS_SWIZZLE_SHIFT) != swizzle) {
         *  RRGGBBAA
         */
         if ((WINED3DVS_NOSWIZZLE >> WINED3DVS_SWIZZLE_SHIFT) != swizzle) {
-            if (swizzle_r == swizzle_g &&
-                swizzle_r == swizzle_b &&
-                swizzle_r == swizzle_a) {
-                    TRACE(".%c", swizzle_reg_chars[swizzle_r]);
+            if (swizzle_x == swizzle_y &&
+                swizzle_x == swizzle_z &&
+                swizzle_x == swizzle_w) {
+                    TRACE(".%c", swizzle_reg_chars[swizzle_x]);
             } else {
                 TRACE(".%c%c%c%c",
             } else {
                 TRACE(".%c%c%c%c",
-                swizzle_reg_chars[swizzle_r],
-                swizzle_reg_chars[swizzle_g],
-                swizzle_reg_chars[swizzle_b],
-                swizzle_reg_chars[swizzle_a]);
+                swizzle_reg_chars[swizzle_x],
+                swizzle_reg_chars[swizzle_y],
+                swizzle_reg_chars[swizzle_z],
+                swizzle_reg_chars[swizzle_w]);
             }
         }
     }
 }
 
 static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
             }
         }
     }
 }
 
 static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
-        IWineD3DDeviceImpl *device, const struct SHADER_OPCODE_ARG *arg)
+        IWineD3DDeviceImpl *device, const struct SHADER_OPCODE_ARG *arg, DWORD shader_version)
 {
 {
-    DWORD hex_version = shader->baseShader.hex_version;
     IWineD3DBaseTextureImpl *texture;
     struct color_fixup_desc fixup;
     BOOL recorded = FALSE;
     IWineD3DBaseTextureImpl *texture;
     struct color_fixup_desc fixup;
     BOOL recorded = FALSE;
@@ -773,7 +768,7 @@ static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
     switch(arg->opcode->opcode)
     {
         case WINED3DSIO_TEX:
     switch(arg->opcode->opcode)
     {
         case WINED3DSIO_TEX:
-            if (hex_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
+            if (WINED3DSHADER_VERSION_MAJOR(shader_version) < 2) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
             else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
             break;
 
             else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
             break;
 
@@ -821,10 +816,8 @@ static void shader_color_correction(IWineD3DBaseShaderImpl *shader,
     device->shader_backend->shader_color_correction(arg, fixup);
 }
 
     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 */
+/* Shared code in order to generate the bulk of the shader string.
+ * NOTE: A description of how to parse tokens can be found on msdn */
 void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
         const 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)
 {
@@ -832,10 +825,10 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
     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;
     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;
+    DWORD shader_version = reg_maps->shader_version;
     const DWORD *pToken = pFunction;
     const DWORD *pToken = pFunction;
-    const SHADER_OPCODE *curOpcode = NULL;
-    SHADER_HANDLER hw_fct = NULL;
+    const SHADER_OPCODE *curOpcode;
+    SHADER_HANDLER hw_fct;
     DWORD i;
     SHADER_OPCODE_ARG hw_arg;
 
     DWORD i;
     SHADER_OPCODE_ARG hw_arg;
 
@@ -845,99 +838,92 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
     hw_arg.reg_maps = reg_maps;
     This->baseShader.parse_state.current_row = 0;
 
     hw_arg.reg_maps = reg_maps;
     This->baseShader.parse_state.current_row = 0;
 
-    /* Second pass, process opcodes */
-    if (NULL != pToken) {
-        while (WINED3DPS_END() != *pToken) {
-
-            /* Skip version token */
-            if (shader_is_version_token(*pToken)) {
-                ++pToken;
-                continue;
-            }
-
-            /* Skip comment tokens */
-            if (shader_is_comment(*pToken)) {
-                DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
-                ++pToken;
-                TRACE("#%s\n", (const char*)pToken);
-                pToken += comment_len;
-                continue;
-            }
-
-            /* Read opcode */
-            hw_arg.opcode_token = *pToken++;
-            curOpcode = shader_get_opcode(opcode_table, shader_version, hw_arg.opcode_token);
-
-            /* Select handler */
-            if (curOpcode == NULL)
-                hw_fct = NULL;
-            else
-                hw_fct = handler_table[curOpcode->handler_idx];
-
-            /* Unknown opcode and its parameters */
-            if (NULL == curOpcode) {
-                FIXME("Unrecognized opcode: token=0x%08x\n", hw_arg.opcode_token);
-                pToken += shader_skip_unrecognized(pToken, shader_version);
-
-            /* Nothing to do */
-            } else if (WINED3DSIO_DCL == curOpcode->opcode ||
-                       WINED3DSIO_NOP == curOpcode->opcode ||
-                       WINED3DSIO_DEF == curOpcode->opcode ||
-                       WINED3DSIO_DEFI == curOpcode->opcode ||
-                       WINED3DSIO_DEFB == curOpcode->opcode ||
-                       WINED3DSIO_PHASE == curOpcode->opcode ||
-                       WINED3DSIO_RET == curOpcode->opcode) {
-
-                pToken += shader_skip_opcode(This, curOpcode, hw_arg.opcode_token);
+    while (WINED3DPS_END() != *pToken)
+    {
+        /* Skip version token */
+        if (shader_is_version_token(*pToken))
+        {
+            ++pToken;
+            continue;
+        }
 
 
-            /* If a generator function is set for current shader target, use it */
-            } else if (hw_fct != NULL) {
+        /* Skip comment tokens */
+        if (shader_is_comment(*pToken))
+        {
+            pToken += (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
+            ++pToken;
+            continue;
+        }
 
 
-                hw_arg.opcode = curOpcode;
+        /* Read opcode */
+        hw_arg.opcode_token = *pToken++;
+        curOpcode = shader_get_opcode(opcode_table, shader_version, hw_arg.opcode_token);
 
 
-                /* Destination token */
-                if (curOpcode->dst_token) {
+        /* Unknown opcode and its parameters */
+        if (!curOpcode)
+        {
+            FIXME("Unrecognized opcode: token=0x%08x\n", hw_arg.opcode_token);
+            pToken += shader_skip_unrecognized(pToken, shader_version);
+            continue;
+        }
 
 
-                    DWORD param, addr_token = 0;
-                    pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
-                    hw_arg.dst = param;
-                    hw_arg.dst_addr = addr_token;
-                }
+        /* Nothing to do */
+        if (WINED3DSIO_DCL == curOpcode->opcode
+                || WINED3DSIO_NOP == curOpcode->opcode
+                || WINED3DSIO_DEF == curOpcode->opcode
+                || WINED3DSIO_DEFI == curOpcode->opcode
+                || WINED3DSIO_DEFB == curOpcode->opcode
+                || WINED3DSIO_PHASE == curOpcode->opcode
+                || WINED3DSIO_RET == curOpcode->opcode)
+        {
+            pToken += shader_skip_opcode(curOpcode, hw_arg.opcode_token, shader_version);
+            continue;
+        }
 
 
-                /* Predication token */
-                if (hw_arg.opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) 
-                    hw_arg.predicate = *pToken++;
+        /* Select handler */
+        hw_fct = handler_table[curOpcode->handler_idx];
 
 
-                /* Other source tokens */
-                for (i = 0; i < (curOpcode->num_params - curOpcode->dst_token); i++) {
+        /* Unhandled opcode */
+        if (!hw_fct)
+        {
+            FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
+            pToken += shader_skip_opcode(curOpcode, hw_arg.opcode_token, shader_version);
+            continue;
+        }
 
 
-                    DWORD param, addr_token = 0; 
-                    pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
-                    hw_arg.src[i] = param;
-                    hw_arg.src_addr[i] = addr_token;
-                }
+        hw_arg.opcode = curOpcode;
 
 
-                /* Call appropriate function for output target */
-                hw_fct(&hw_arg);
+        /* Destination token */
+        if (curOpcode->dst_token)
+        {
+            DWORD param, addr_token = 0;
+            pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
+            hw_arg.dst = param;
+            hw_arg.dst_addr = addr_token;
+        }
 
 
-                /* Add color correction if needed */
-                shader_color_correction(This, device, &hw_arg);
+        /* Predication token */
+        if (hw_arg.opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) hw_arg.predicate = *pToken++;
 
 
-                /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
-                /* FIXME: This should be internal to the shader backend.
-                 * Also, right now this is the only reason "shader_mode" exists. */
-                if (This->baseShader.shader_mode == SHADER_GLSL)
-                    shader_glsl_add_instruction_modifiers(&hw_arg);
+        /* Other source tokens */
+        for (i = 0; i < (curOpcode->num_params - curOpcode->dst_token); ++i)
+        {
+            DWORD param, addr_token = 0;
+            pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
+            hw_arg.src[i] = param;
+            hw_arg.src_addr[i] = addr_token;
+        }
 
 
-            /* Unhandled opcode */
-            } else {
+        /* Call appropriate function for output target */
+        hw_fct(&hw_arg);
 
 
-                FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
-                pToken += shader_skip_opcode(This, curOpcode, hw_arg.opcode_token);
-            }
-        }
-        /* TODO: What about result.depth? */
+        /* Add color correction if needed */
+        shader_color_correction(This, device, &hw_arg, shader_version);
 
 
+        /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
+        /* FIXME: This should be internal to the shader backend.
+         * Also, right now this is the only reason "shader_mode" exists. */
+        if (This->baseShader.shader_mode == SHADER_GLSL) shader_glsl_add_instruction_modifiers(&hw_arg);
     }
 }
 
     }
 }
 
@@ -966,60 +952,45 @@ static void shader_dump_ins_modifiers(const DWORD output)
         FIXME("_unrecognized_modifier(%#x)", mmask >> WINED3DSP_DSTMOD_SHIFT);
 }
 
         FIXME("_unrecognized_modifier(%#x)", mmask >> WINED3DSP_DSTMOD_SHIFT);
 }
 
-/* First pass: trace shader, initialize length and version */
-void shader_trace_init(
-    IWineD3DBaseShader *iface,
-    const DWORD* pFunction) {
-
-    IWineD3DBaseShaderImpl *This =(IWineD3DBaseShaderImpl *)iface;
-
+void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table)
+{
     const DWORD* pToken = pFunction;
     const SHADER_OPCODE* curOpcode = NULL;
     const DWORD* pToken = pFunction;
     const SHADER_OPCODE* curOpcode = NULL;
+    DWORD shader_version;
     DWORD opcode_token;
     DWORD opcode_token;
-    unsigned int len = 0;
     DWORD i;
 
     DWORD i;
 
-    TRACE("(%p) : Parsing program\n", This);
+    TRACE("Parsing %p\n", pFunction);
 
 
-    if (!pFunction)
+    /* The version token is supposed to be the first token */
+    if (!shader_is_version_token(*pToken))
     {
     {
-        WARN("Got a NULL pFunction, returning.\n");
-        This->baseShader.functionLength = 1; /* no Function defined use fixed function vertex processing */
+        FIXME("First token is not a version token, invalid shader.\n");
         return;
     }
         return;
     }
+    shader_version = *pToken++;
+    TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version) ? "ps": "vs",
+            WINED3DSHADER_VERSION_MAJOR(shader_version), WINED3DSHADER_VERSION_MINOR(shader_version));
 
     while (WINED3DVS_END() != *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 (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;
         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++;
             continue;
         }
         opcode_token = *pToken++;
-        curOpcode = shader_get_opcode(This->baseShader.shader_ins, This->baseShader.hex_version, opcode_token);
-        len++;
+        curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token);
 
         if (!curOpcode)
         {
             int tokens_read;
             FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
 
         if (!curOpcode)
         {
             int tokens_read;
             FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
-            tokens_read = shader_skip_unrecognized(pToken, This->baseShader.hex_version);
+            tokens_read = shader_skip_unrecognized(pToken, shader_version);
             pToken += tokens_read;
             pToken += tokens_read;
-            len += tokens_read;
         }
         else
         {
         }
         else
         {
@@ -1028,12 +999,11 @@ void shader_trace_init(
                 DWORD usage = *pToken;
                 DWORD param = *(pToken + 1);
 
                 DWORD usage = *pToken;
                 DWORD param = *(pToken + 1);
 
-                shader_dump_decl_usage(usage, param, This->baseShader.hex_version);
+                shader_dump_decl_usage(usage, param, shader_version);
                 shader_dump_ins_modifiers(param);
                 TRACE(" ");
                 shader_dump_ins_modifiers(param);
                 TRACE(" ");
-                shader_dump_param(param, 0, 0, This->baseShader.hex_version);
+                shader_dump_param(param, 0, 0, shader_version);
                 pToken += 2;
                 pToken += 2;
-                len += 2;
             }
             else if (curOpcode->opcode == WINED3DSIO_DEF)
             {
             }
             else if (curOpcode->opcode == WINED3DSIO_DEF)
             {
@@ -1045,7 +1015,6 @@ void shader_trace_init(
                         *(const float *)(pToken + 3),
                         *(const float *)(pToken + 4));
                 pToken += 5;
                         *(const float *)(pToken + 3),
                         *(const float *)(pToken + 4));
                 pToken += 5;
-                len += 5;
             }
             else if (curOpcode->opcode == WINED3DSIO_DEFI)
             {
             }
             else if (curOpcode->opcode == WINED3DSIO_DEFI)
             {
@@ -1055,14 +1024,12 @@ void shader_trace_init(
                         *(pToken + 3),
                         *(pToken + 4));
                 pToken += 5;
                         *(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;
             }
             else if (curOpcode->opcode == WINED3DSIO_DEFB)
             {
                 TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
                         *(pToken + 1)? "true": "false");
                 pToken += 2;
-                len += 2;
             }
             else
             {
             }
             else
             {
@@ -1074,7 +1041,7 @@ void shader_trace_init(
                 if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
                 {
                     TRACE("(");
                 if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
                 {
                     TRACE("(");
-                    shader_dump_param(*(pToken + 2), 0, 1, This->baseShader.hex_version);
+                    shader_dump_param(*(pToken + 2), 0, 1, shader_version);
                     TRACE(") ");
                 }
                 if (opcode_token & WINED3DSI_COISSUE)
                     TRACE(") ");
                 }
                 if (opcode_token & WINED3DSI_COISSUE)
@@ -1102,7 +1069,7 @@ void shader_trace_init(
                     }
                 }
                 else if (curOpcode->opcode == WINED3DSIO_TEX
                     }
                 }
                 else if (curOpcode->opcode == WINED3DSIO_TEX
-                        && This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)
+                        && shader_version >= WINED3DPS_VERSION(2,0)
                         && (opcode_token & WINED3DSI_TEXLD_PROJECT))
                 {
                     TRACE("p");
                         && (opcode_token & WINED3DSI_TEXLD_PROJECT))
                 {
                     TRACE("p");
@@ -1111,51 +1078,60 @@ void shader_trace_init(
                 /* Destination token */
                 if (curOpcode->dst_token)
                 {
                 /* Destination token */
                 if (curOpcode->dst_token)
                 {
-                    tokens_read = shader_get_param(pToken, This->baseShader.hex_version, &param, &addr_token);
+                    tokens_read = shader_get_param(pToken, shader_version, &param, &addr_token);
                     pToken += tokens_read;
                     pToken += tokens_read;
-                    len += tokens_read;
 
                     shader_dump_ins_modifiers(param);
                     TRACE(" ");
 
                     shader_dump_ins_modifiers(param);
                     TRACE(" ");
-                    shader_dump_param(param, addr_token, 0, This->baseShader.hex_version);
+                    shader_dump_param(param, addr_token, 0, shader_version);
                 }
 
                 /* Predication token - already printed out, just skip it */
                 if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
                 {
                     pToken++;
                 }
 
                 /* Predication token - already printed out, just skip it */
                 if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
                 {
                     pToken++;
-                    len++;
                 }
 
                 /* Other source tokens */
                 for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i)
                 {
                 }
 
                 /* 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);
+                    tokens_read = shader_get_param(pToken, shader_version, &param, &addr_token);
                     pToken += tokens_read;
                     pToken += tokens_read;
-                    len += tokens_read;
 
                     TRACE((i == 0)? " " : ", ");
 
                     TRACE((i == 0)? " " : ", ");
-                    shader_dump_param(param, addr_token, 1, This->baseShader.hex_version);
+                    shader_dump_param(param, addr_token, 1, shader_version);
                 }
             }
             TRACE("\n");
         }
     }
                 }
             }
             TRACE("\n");
         }
     }
-    This->baseShader.functionLength = (len + 1) * sizeof(DWORD);
+}
+
+void shader_cleanup(IWineD3DBaseShader *iface)
+{
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
+
+    ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
+    HeapFree(GetProcessHeap(), 0, This->baseShader.function);
+    shader_delete_constant_list(&This->baseShader.constantsF);
+    shader_delete_constant_list(&This->baseShader.constantsB);
+    shader_delete_constant_list(&This->baseShader.constantsI);
+    list_remove(&This->baseShader.shader_list_entry);
 }
 
 static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
 static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 }
 
 static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
 static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
+static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
+static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 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(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_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 GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
     FIXME("NONE shader backend asked to generate a pixel shader\n");
     return 0;
 }
     FIXME("NONE shader backend asked to generate a pixel shader\n");
     return 0;
 }
@@ -1196,8 +1172,9 @@ const shader_backend_t none_shader_backend = {
     shader_none_select,
     shader_none_select_depth_blt,
     shader_none_deselect_depth_blt,
     shader_none_select,
     shader_none_select_depth_blt,
     shader_none_deselect_depth_blt,
+    shader_none_update_float_vertex_constants,
+    shader_none_update_float_pixel_constants,
     shader_none_load_constants,
     shader_none_load_constants,
-    shader_none_cleanup,
     shader_none_color_correction,
     shader_none_destroy,
     shader_none_alloc,
     shader_none_color_correction,
     shader_none_destroy,
     shader_none_alloc,
@@ -1208,46 +1185,3 @@ const shader_backend_t none_shader_backend = {
     shader_none_get_caps,
     shader_none_color_fixup_supported,
 };
     shader_none_get_caps,
     shader_none_color_fixup_supported,
 };
-
-/* *******************************************
-   IWineD3DPixelShader IUnknown parts follow
-   ******************************************* */
-HRESULT  WINAPI IWineD3DBaseShaderImpl_QueryInterface(IWineD3DBaseShader *iface, REFIID riid, LPVOID *ppobj)
-{
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IWineD3DBase)
-        || IsEqualGUID(riid, &IID_IWineD3DBaseShader)
-        || IsEqualGUID(riid, &IID_IWineD3DPixelShader)) {
-        IUnknown_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-ULONG  WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface) {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    TRACE("(%p) : AddRef increasing from %d\n", This, This->baseShader.ref);
-    return InterlockedIncrement(&This->baseShader.ref);
-}
-
-ULONG  WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface) {
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
-    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
-    ULONG ref;
-    TRACE("(%p) : Releasing from %d\n", This, This->baseShader.ref);
-    ref = InterlockedDecrement(&This->baseShader.ref);
-    if (ref == 0) {
-        deviceImpl->shader_backend->shader_destroy(iface);
-        HeapFree(GetProcessHeap(), 0, This->baseShader.function);
-        shader_delete_constant_list(&This->baseShader.constantsF);
-        shader_delete_constant_list(&This->baseShader.constantsB);
-        shader_delete_constant_list(&This->baseShader.constantsI);
-        list_remove(&This->baseShader.shader_list_entry);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
index 158650e..f6189b6 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
+void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage)
+{
+    texture->levels = levels;
+    texture->filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
+    texture->LOD = 0;
+    texture->dirty = TRUE;
+    texture->is_srgb = FALSE;
+    texture->srgb_mode_change_count = 0;
+}
+
 void basetexture_cleanup(IWineD3DBaseTexture *iface)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 void basetexture_cleanup(IWineD3DBaseTexture *iface)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
@@ -249,7 +259,6 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface)
                 glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
             }
         }
                 glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
             }
         }
-               
     } else { /* this only happened if we've run out of openGL textures */
         WARN("This texture doesn't have an openGL texture assigned to it\n");
         hr =  WINED3DERR_INVALIDCALL;
     } else { /* this only happened if we've run out of openGL textures */
         WARN("This texture doesn't have an openGL texture assigned to it\n");
         hr =  WINED3DERR_INVALIDCALL;
index 05afe5d..da3053a 100644 (file)
@@ -839,12 +839,6 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
 
     checkGLcall("glClear");
 
 
     checkGLcall("glClear");
 
-    glColor3f(1.0, 1.0, 1.0);
-    checkGLcall("glColor3f");
-
-    glEnable(GL_LIGHTING);
-    checkGLcall("glEnable");
-
     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
 
     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
 
@@ -1053,7 +1047,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     /* TODO: Use a display list */
 
     /* Disable shaders */
     /* TODO: Use a display list */
 
     /* Disable shaders */
-    This->shader_backend->shader_cleanup((IWineD3DDevice *) This);
+    This->shader_backend->shader_select((IWineD3DDevice *)This, FALSE, FALSE);
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
@@ -1066,42 +1060,40 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
 
     /* Disable all textures. The caller can then bind a texture it wants to blit
      * from
 
     /* Disable all textures. The caller can then bind a texture it wants to blit
      * from
+     *
+     * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
+     * function texture unit. No need to care for higher samplers
      */
      */
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        /* The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
-         * function texture unit. No need to care for higher samplers
-         */
-        for(i = GL_LIMITS(textures) - 1; i > 0 ; i--) {
-            sampler = This->rev_tex_unit_map[i];
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
-            checkGLcall("glActiveTextureARB");
-
-            if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
-                glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
-            }
-            glDisable(GL_TEXTURE_3D);
-            checkGLcall("glDisable GL_TEXTURE_3D");
-            if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-                glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
-            }
-            glDisable(GL_TEXTURE_2D);
-            checkGLcall("glDisable GL_TEXTURE_2D");
+    for(i = GL_LIMITS(textures) - 1; i > 0 ; i--) {
+        sampler = This->rev_tex_unit_map[i];
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+        checkGLcall("glActiveTextureARB");
 
 
-            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
+        if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+            glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+            checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+        }
+        glDisable(GL_TEXTURE_3D);
+        checkGLcall("glDisable GL_TEXTURE_3D");
+        if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+            glDisable(GL_TEXTURE_RECTANGLE_ARB);
+            checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+        }
+        glDisable(GL_TEXTURE_2D);
+        checkGLcall("glDisable GL_TEXTURE_2D");
 
 
-            if (sampler != -1) {
-                if (sampler < MAX_TEXTURES) {
-                    Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
-                }
-                Context_MarkStateDirty(context, STATE_SAMPLER(sampler), StateTable);
+        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
+
+        if (sampler != -1) {
+            if (sampler < MAX_TEXTURES) {
+                Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
             }
             }
+            Context_MarkStateDirty(context, STATE_SAMPLER(sampler), StateTable);
         }
         }
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
-        checkGLcall("glActiveTextureARB");
     }
     }
+    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
+    checkGLcall("glActiveTextureARB");
 
     sampler = This->rev_tex_unit_map[0];
 
 
     sampler = This->rev_tex_unit_map[0];
 
@@ -1150,7 +1142,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     glDisable(GL_DEPTH_TEST);
     checkGLcall("glDisable GL_DEPTH_TEST");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE), StateTable);
     glDisable(GL_DEPTH_TEST);
     checkGLcall("glDisable GL_DEPTH_TEST");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE), StateTable);
-    glDisable(GL_FOG);
+    glDisableWINE(GL_FOG);
     checkGLcall("glDisable GL_FOG");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE), StateTable);
     glDisable(GL_BLEND);
     checkGLcall("glDisable GL_FOG");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE), StateTable);
     glDisable(GL_BLEND);
@@ -1623,3 +1615,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
             FIXME("Unexpected context usage requested\n");
     }
 }
             FIXME("Unexpected context usage requested\n");
     }
 }
+
+WineD3DContext *getActiveContext(void) {
+    return last_device->activeContext;
+}
index 90b1221..c7de212 100644 (file)
@@ -136,9 +136,8 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
             }
         }
     } else if (srgb_was_toggled) {
             }
         }
     } else if (srgb_was_toggled) {
-        /* Loop is repeated in the else block with the extra AddDirtyRect line to avoid the alternative of
-         * checking srgb_was_toggled in every iteration, even when the texture is just dirty
-         */
+        /* Loop is repeated in the else block with the extra surface_add_dirty_rect() line to avoid the
+         * alternative of checking srgb_was_toggled in every iteration, even when the texture is just dirty */
         if (This->baseTexture.srgb_mode_change_count < 20)
             ++This->baseTexture.srgb_mode_change_count;
         else
         if (This->baseTexture.srgb_mode_change_count < 20)
             ++This->baseTexture.srgb_mode_change_count;
         else
@@ -146,7 +145,7 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
 
         for (i = 0; i < This->baseTexture.levels; i++) {
             for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
 
         for (i = 0; i < This->baseTexture.levels; i++) {
             for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
-                IWineD3DSurface_AddDirtyRect(This->surfaces[j][i], NULL);
+                surface_add_dirty_rect(This->surfaces[j][i], NULL);
                 surface_force_reload(This->surfaces[j][i]);
                 IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
             }
                 surface_force_reload(This->surfaces[j][i]);
                 IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
             }
@@ -298,7 +297,7 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *
         TRACE("(%p) level (%d)\n", This, Level);
         return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc);
     }
         TRACE("(%p) level (%d)\n", This, Level);
         return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc);
     }
-    FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
+    WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
     return WINED3DERR_INVALIDCALL;
 }
 
     return WINED3DERR_INVALIDCALL;
 }
 
@@ -360,7 +359,8 @@ static HRESULT  WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
     if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
     if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
-        hr = IWineD3DSurface_AddDirtyRect(This->surfaces[FaceType][0], pDirtyRect);
+        surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect);
+        hr = WINED3D_OK;
     } else {
         WARN("(%p) overflow FaceType(%d)\n", This, FaceType);
     }
     } else {
         WARN("(%p) overflow FaceType(%d)\n", This, FaceType);
     }
index 836ad3b..d4a57c9 100644 (file)
@@ -54,76 +54,6 @@ const WINED3DLIGHT WINED3D_default_light = {
 /* static function declarations */
 static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
 
 /* static function declarations */
 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;}
-
-#define D3DCREATEOBJECTINSTANCE(object, type) { \
-    object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
-    D3DMEMCHECK(object, pp##type); \
-    object->lpVtbl = &IWineD3D##type##_Vtbl;  \
-    object->wineD3DDevice = This; \
-    object->parent       = parent; \
-    object->ref          = 1; \
-    *pp##type = (IWineD3D##type *) object; \
-}
-
-#define D3DCREATESHADEROBJECTINSTANCE(object, type) { \
-    object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
-    D3DMEMCHECK(object, pp##type); \
-    object->lpVtbl = &IWineD3D##type##_Vtbl;  \
-    object->parent          = parent; \
-    object->baseShader.ref  = 1; \
-    object->baseShader.device = (IWineD3DDevice*) This; \
-    list_init(&object->baseShader.linked_programs); \
-    *pp##type = (IWineD3D##type *) object; \
-}
-
-#define  D3DCREATERESOURCEOBJECTINSTANCE(object, type, d3dtype, _size){ \
-    object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3D##type##Impl)); \
-    D3DMEMCHECK(object, pp##type); \
-    object->lpVtbl = &IWineD3D##type##_Vtbl;  \
-    object->resource.wineD3DDevice   = This; \
-    object->resource.parent          = parent; \
-    object->resource.resourceType    = d3dtype; \
-    object->resource.ref             = 1; \
-    object->resource.pool            = Pool; \
-    object->resource.format          = Format; \
-    object->resource.usage           = Usage; \
-    object->resource.size            = _size; \
-    object->resource.priority        = 0; \
-    list_init(&object->resource.privateData); \
-    /* Check that we have enough video ram left */ \
-    if (Pool == WINED3DPOOL_DEFAULT) { \
-        if (IWineD3DDevice_GetAvailableTextureMem(iface) <= _size) { \
-            WARN("Out of 'bogus' video memory\n"); \
-            HeapFree(GetProcessHeap(), 0, object); \
-            *pp##type = NULL; \
-            return WINED3DERR_OUTOFVIDEOMEMORY; \
-        } \
-        WineD3DAdapterChangeGLRam(This, _size); \
-    } \
-    object->resource.heapMemory = (0 == _size ? NULL : HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, _size + RESOURCE_ALIGNMENT)); \
-    if (object->resource.heapMemory == NULL && _size != 0) { \
-        FIXME("Out of memory!\n"); \
-        HeapFree(GetProcessHeap(), 0, object); \
-        *pp##type = NULL; \
-        return WINED3DERR_OUTOFVIDEOMEMORY; \
-    } \
-    object->resource.allocatedMemory = (BYTE *)(((ULONG_PTR) object->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); \
-    *pp##type = (IWineD3D##type *) object; \
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object) ;\
-    TRACE("(%p) : Created resource %p\n", This, object); \
-}
-
-#define D3DINITIALIZEBASETEXTURE(_basetexture) { \
-    _basetexture.levels     = Levels; \
-    _basetexture.filterType = (Usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; \
-    _basetexture.LOD        = 0; \
-    _basetexture.dirty      = TRUE; \
-    _basetexture.is_srgb = FALSE; \
-    _basetexture.srgb_mode_change_count = 0; \
-}
-
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
@@ -164,6 +94,13 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
 
     if (!refCount) {
     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
 
     if (!refCount) {
+        UINT i;
+
+        for (i = 0; i < sizeof(This->multistate_funcs)/sizeof(This->multistate_funcs[0]); ++i) {
+            HeapFree(GetProcessHeap(), 0, This->multistate_funcs[i]);
+            This->multistate_funcs[i] = NULL;
+        }
+
         /* TODO: Clean up all the surfaces and textures! */
         /* NOTE: You must release the parent if the object was created via a callback
         ** ***************************/
         /* TODO: Clean up all the surfaces and textures! */
         /* NOTE: You must release the parent if the object was created via a callback
         ** ***************************/
@@ -203,6 +140,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     IWineD3DVertexBufferImpl *object;
     WINED3DFORMAT Format = WINED3DFMT_VERTEXDATA; /* Dummy format for now */
     int dxVersion = ( (IWineD3DImpl *) This->wineD3D)->dxVersion;
     IWineD3DVertexBufferImpl *object;
     WINED3DFORMAT Format = WINED3DFMT_VERTEXDATA; /* Dummy format for now */
     int dxVersion = ( (IWineD3DImpl *) This->wineD3D)->dxVersion;
+    HRESULT hr;
     BOOL conv;
 
     if(Size == 0) {
     BOOL conv;
 
     if(Size == 0) {
@@ -218,7 +156,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    D3DCREATERESOURCEOBJECTINSTANCE(object, VertexBuffer, WINED3DRTYPE_VERTEXBUFFER, Size)
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppVertexBuffer = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DVertexBuffer_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_VERTEXBUFFER, This, Size, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppVertexBuffer = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
 
     TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
     *ppVertexBuffer = (IWineD3DVertexBuffer *)object;
 
     TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
     *ppVertexBuffer = (IWineD3DVertexBuffer *)object;
@@ -310,10 +268,32 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
                                                     HANDLE *sharedHandle, IUnknown *parent) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DIndexBufferImpl *object;
                                                     HANDLE *sharedHandle, IUnknown *parent) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DIndexBufferImpl *object;
+    HRESULT hr;
+
     TRACE("(%p) Creating index buffer\n", This);
 
     /* Allocate the storage for the device */
     TRACE("(%p) Creating index buffer\n", This);
 
     /* Allocate the storage for the device */
-    D3DCREATERESOURCEOBJECTINSTANCE(object,IndexBuffer,WINED3DRTYPE_INDEXBUFFER, Length)
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppIndexBuffer = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DIndexBuffer_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_INDEXBUFFER, This, Length, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppIndexBuffer = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
 
     if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
         CreateIndexBufferVBO(This, object);
 
     if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
         CreateIndexBufferVBO(This, object);
@@ -333,24 +313,41 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
     int i, j;
     HRESULT temp_result;
 
     int i, j;
     HRESULT temp_result;
 
-    D3DCREATEOBJECTINSTANCE(object, StateBlock)
-    object->blockType     = Type;
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if(!object)
+    {
+        ERR("Out of memory\n");
+        *ppStateBlock = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DStateBlock_Vtbl;
+    object->wineD3DDevice = This;
+    object->parent = parent;
+    object->ref = 1;
+    object->blockType = Type;
+
+    *ppStateBlock = (IWineD3DStateBlock *)object;
 
     for(i = 0; i < LIGHTMAP_SIZE; i++) {
         list_init(&object->lightMap[i]);
     }
 
 
     for(i = 0; i < LIGHTMAP_SIZE; i++) {
         list_init(&object->lightMap[i]);
     }
 
+    temp_result = allocate_shader_constants(object);
+    if (FAILED(temp_result))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        return temp_result;
+    }
+
     /* Special case - Used during initialization to produce a placeholder stateblock
           so other functions called can update a state block                         */
     /* Special case - Used during initialization to produce a placeholder stateblock
           so other functions called can update a state block                         */
-    if (Type == WINED3DSBT_INIT) {
+    if (Type == WINED3DSBT_INIT || Type == WINED3DSBT_RECORDED)
+    {
         /* Don't bother increasing the reference count otherwise a device will never
            be freed due to circular dependencies                                   */
         return WINED3D_OK;
     }
         /* Don't bother increasing the reference count otherwise a device will never
            be freed due to circular dependencies                                   */
         return WINED3D_OK;
     }
-    
-    temp_result = allocate_shader_constants(object);
-    if (WINED3D_OK != temp_result)
-        return temp_result;
 
     /* Otherwise, might as well set the whole state block to the appropriate values  */
     if (This->stateBlock != NULL)
 
     /* Otherwise, might as well set the whole state block to the appropriate values  */
     if (This->stateBlock != NULL)
@@ -413,7 +410,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
         }
         object->num_contained_ps_consts_b = MAX_CONST_B;
         for(i = 0; i < MAX_TEXTURES; i++) {
         }
         object->num_contained_ps_consts_b = MAX_CONST_B;
         for(i = 0; i < MAX_TEXTURES; i++) {
-            for(j = 1; j <= WINED3D_HIGHEST_TEXTURE_STATE; j++) {
+            for (j = 0; j <= WINED3D_HIGHEST_TEXTURE_STATE; ++j)
+            {
                 object->contained_tss_states[object->num_contained_tss_states].stage = i;
                 object->contained_tss_states[object->num_contained_tss_states].state = j;
                 object->num_contained_tss_states++;
                 object->contained_tss_states[object->num_contained_tss_states].stage = i;
                 object->contained_tss_states[object->num_contained_tss_states].state = j;
                 object->num_contained_tss_states++;
@@ -467,23 +465,26 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
         object->num_contained_ps_consts_i = MAX_CONST_I;
 
         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
         object->num_contained_ps_consts_i = MAX_CONST_I;
 
         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
-            object->changed.renderState[SavedPixelStates_R[i]] = TRUE;
-            object->contained_render_states[i] = SavedPixelStates_R[i];
+            DWORD rs = SavedPixelStates_R[i];
+            object->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
+            object->contained_render_states[i] = rs;
         }
         object->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
         }
         object->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
-                object->changed.textureState[j][SavedPixelStates_T[i]] = TRUE;
+                DWORD state = SavedPixelStates_T[i];
+                object->changed.textureState[j] |= 1 << state;
                 object->contained_tss_states[object->num_contained_tss_states].stage = j;
                 object->contained_tss_states[object->num_contained_tss_states].stage = j;
-                object->contained_tss_states[object->num_contained_tss_states].state = SavedPixelStates_T[i];
+                object->contained_tss_states[object->num_contained_tss_states].state = state;
                 object->num_contained_tss_states++;
             }
         }
         for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++) {
             for (i =0; i < NUM_SAVEDPIXELSTATES_S;i++) {
                 object->num_contained_tss_states++;
             }
         }
         for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++) {
             for (i =0; i < NUM_SAVEDPIXELSTATES_S;i++) {
-                object->changed.samplerState[j][SavedPixelStates_S[i]] = TRUE;
+                DWORD state = SavedPixelStates_S[i];
+                object->changed.samplerState[j] |= 1 << state;
                 object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
                 object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
-                object->contained_sampler_states[object->num_contained_sampler_states].state = SavedPixelStates_S[i];
+                object->contained_sampler_states[object->num_contained_sampler_states].state = state;
                 object->num_contained_sampler_states++;
             }
         }
                 object->num_contained_sampler_states++;
             }
         }
@@ -524,23 +525,26 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
         }
         object->num_contained_vs_consts_i = MAX_CONST_I;
         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
         }
         object->num_contained_vs_consts_i = MAX_CONST_I;
         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
-            object->changed.renderState[SavedVertexStates_R[i]] = TRUE;
-            object->contained_render_states[i] = SavedVertexStates_R[i];
+            DWORD rs = SavedVertexStates_R[i];
+            object->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
+            object->contained_render_states[i] = rs;
         }
         object->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
         }
         object->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
         for (j = 0; j < MAX_TEXTURES; j++) {
             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
-                object->changed.textureState[j][SavedVertexStates_T[i]] = TRUE;
+                DWORD state = SavedVertexStates_T[i];
+                object->changed.textureState[j] |= 1 << state;
                 object->contained_tss_states[object->num_contained_tss_states].stage = j;
                 object->contained_tss_states[object->num_contained_tss_states].stage = j;
-                object->contained_tss_states[object->num_contained_tss_states].state = SavedVertexStates_T[i];
+                object->contained_tss_states[object->num_contained_tss_states].state = state;
                 object->num_contained_tss_states++;
             }
         }
         for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
             for (i =0; i < NUM_SAVEDVERTEXSTATES_S;i++) {
                 object->num_contained_tss_states++;
             }
         }
         for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
             for (i =0; i < NUM_SAVEDVERTEXSTATES_S;i++) {
-                object->changed.samplerState[j][SavedVertexStates_S[i]] = TRUE;
+                DWORD state = SavedVertexStates_S[i];
+                object->changed.samplerState[j] |= 1 << state;
                 object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
                 object->contained_sampler_states[object->num_contained_sampler_states].stage = j;
-                object->contained_sampler_states[object->num_contained_sampler_states].state = SavedVertexStates_S[i];
+                object->contained_sampler_states[object->num_contained_sampler_states].state = state;
                 object->num_contained_sampler_states++;
             }
         }
                 object->num_contained_sampler_states++;
             }
         }
@@ -572,17 +576,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-/* ************************************
-MSDN:
-[in] Render targets are not lockable unless the application specifies TRUE for Lockable. Note that lockable render targets reduce performance on some graphics hardware.
-
-Discard
- [in] Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise. 
-
-If this flag is set, the contents of the depth stencil buffer will be invalid after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
-
-******************************** */
 static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) {
     IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;    
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
 static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) {
     IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;    
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
@@ -590,29 +583,9 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
     UINT mul_4w, mul_4h;
     const struct GlPixelFormatDesc *glDesc;
     const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
     UINT mul_4w, mul_4h;
-    TRACE("(%p) Create surface\n",This);
-    
-    /** FIXME: Check ranges on the inputs are valid 
-     * MSDN
-     *   MultisampleQuality
-     *    [in] Quality level. The valid range is between zero and one less than the level
-     *    returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. 
-     *    Passing a larger value returns the error WINED3DERR_INVALIDCALL. The MultisampleQuality
-     *    values of paired render targets, depth stencil surfaces, and the MultiSample type
-     *    must all match.
-      *******************************/
-
+    HRESULT hr;
 
 
-    /**
-    * TODO: Discard MSDN
-    * [in] Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
-    *
-    * If this flag is set, the contents of the depth stencil buffer will be
-    * invalid after calling either IDirect3DDevice9::Present or  * IDirect3DDevice9::SetDepthStencilSurface
-    * with a different depth surface.
-    *
-    *This flag has the same behavior as the constant, D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL, in D3DPRESENTFLAG.
-    ***************************/
+    TRACE("(%p) Create surface\n",This);
 
     if(MultisampleQuality > 0) {
         FIXME("MultisampleQuality set to %d, substituting 0\n", MultisampleQuality);
 
     if(MultisampleQuality > 0) {
         FIXME("MultisampleQuality set to %d, substituting 0\n", MultisampleQuality);
@@ -648,7 +621,54 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     if(glDesc->heightscale != 0.0) Size *= glDesc->heightscale;
 
     /** Create and initialise the surface resource **/
     if(glDesc->heightscale != 0.0) Size *= glDesc->heightscale;
 
     /** Create and initialise the surface resource **/
-    D3DCREATERESOURCEOBJECTINSTANCE(object,Surface,WINED3DRTYPE_SURFACE, Size)
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppSurface = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    /* Look at the implementation and set the correct Vtable */
+    switch(Impl)
+    {
+        case SURFACE_OPENGL:
+            /* Check if a 3D adapter is available when creating gl surfaces */
+            if (!This->adapter)
+            {
+                ERR("OpenGL surfaces are not available without opengl\n");
+                HeapFree(GetProcessHeap(), 0, object);
+                return WINED3DERR_NOTAVAILABLE;
+            }
+            object->lpVtbl = &IWineD3DSurface_Vtbl;
+            break;
+
+        case SURFACE_GDI:
+            object->lpVtbl = &IWineGDISurface_Vtbl;
+            break;
+
+        default:
+            /* To be sure to catch this */
+            ERR("Unknown requested surface implementation %d!\n", Impl);
+            HeapFree(GetProcessHeap(), 0, object);
+            return WINED3DERR_INVALIDCALL;
+    }
+
+    hr = resource_init(&object->resource, WINED3DRTYPE_SURFACE, This, Size, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppSurface = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+
+    *ppSurface = (IWineD3DSurface *)object;
+
     /* "Standalone" surface */
     IWineD3DSurface_SetContainer((IWineD3DSurface *)object, NULL);
 
     /* "Standalone" surface */
     IWineD3DSurface_SetContainer((IWineD3DSurface *)object, NULL);
 
@@ -711,46 +731,30 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     }
 
     /* mark the texture as dirty so that it gets loaded first time around*/
     }
 
     /* mark the texture as dirty so that it gets loaded first time around*/
-    IWineD3DSurface_AddDirtyRect(*ppSurface, NULL);
+    surface_add_dirty_rect(*ppSurface, NULL);
     TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
            This, Width, Height, Format, debug_d3dformat(Format),
            (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size);
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
            This, Width, Height, Format, debug_d3dformat(Format),
            (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size);
 
-    /* Look at the implementation and set the correct Vtable */
-    switch(Impl) {
-        case SURFACE_OPENGL:
-            /* Check if a 3D adapter is available when creating gl surfaces */
-            if(!This->adapter) {
-                ERR("OpenGL surfaces are not available without opengl\n");
-                HeapFree(GetProcessHeap(), 0, object->resource.allocatedMemory);
-                HeapFree(GetProcessHeap(), 0, object);
-                return WINED3DERR_NOTAVAILABLE;
-            }
-            break;
-
-        case SURFACE_GDI:
-            object->lpVtbl = &IWineGDISurface_Vtbl;
-            break;
-
-        default:
-            /* To be sure to catch this */
-            ERR("Unknown requested surface implementation %d!\n", Impl);
-            IWineD3DSurface_Release((IWineD3DSurface *) object);
-            return WINED3DERR_INVALIDCALL;
-    }
-
     list_init(&object->renderbuffers);
 
     /* Call the private setup routine */
     list_init(&object->renderbuffers);
 
     /* Call the private setup routine */
-    return IWineD3DSurface_PrivateSetup( (IWineD3DSurface *) object );
+    hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)object);
+    if (FAILED(hr))
+    {
+        ERR("Private setup failed, returning %#x\n", hr);
+        IWineD3DSurface_Release(*ppSurface);
+        *ppSurface = NULL;
+        return hr;
+    }
 
 
+    return hr;
 }
 
 }
 
-static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, UINT Width, UINT Height, UINT Levels,
-                                                 DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
-                                                 IWineD3DTexture** ppTexture, HANDLE* pSharedHandle, IUnknown *parent,
-                                                 D3DCB_CREATESURFACEFN D3DCB_CreateSurface) {
-
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
+        UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
+        IWineD3DTexture **ppTexture, HANDLE *pSharedHandle, IUnknown *parent)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DTextureImpl *object;
     unsigned int i;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DTextureImpl *object;
     unsigned int i;
@@ -773,41 +777,89 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    D3DCREATERESOURCEOBJECTINSTANCE(object, Texture, WINED3DRTYPE_TEXTURE, 0);
-    D3DINITIALIZEBASETEXTURE(object->baseTexture);    
-    object->width  = Width;
-    object->height = Height;
-
-    if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING) {
-        object->baseTexture.minMipLookup = minMipLookup;
-        object->baseTexture.magLookup    = magLookup;
-    } else {
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-        object->baseTexture.magLookup    = magLookup_noFilter;
-    }
-
-    /** Non-power2 support **/
-    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {
+    /* Non-power2 support */
+    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO))
+    {
         pow2Width = Width;
         pow2Height = Height;
         pow2Width = Width;
         pow2Height = Height;
-    } else {
+    }
+    else
+    {
         /* Find the nearest pow2 match */
         pow2Width = pow2Height = 1;
         while (pow2Width < Width) pow2Width <<= 1;
         while (pow2Height < Height) pow2Height <<= 1;
 
         /* Find the nearest pow2 match */
         pow2Width = pow2Height = 1;
         while (pow2Width < Width) pow2Width <<= 1;
         while (pow2Height < Height) pow2Height <<= 1;
 
-        if(pow2Width != Width || pow2Height != Height) {
-            if(Levels > 1) {
+        if (pow2Width != Width || pow2Height != Height)
+        {
+            if (Levels > 1)
+            {
                 WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support\n");
                 WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support\n");
-                HeapFree(GetProcessHeap(), 0, object);
-                *ppTexture = NULL;
                 return WINED3DERR_INVALIDCALL;
                 return WINED3DERR_INVALIDCALL;
-            } else {
-                Levels = 1;
             }
             }
+            Levels = 1;
         }
     }
 
         }
     }
 
+    /* Calculate levels for mip mapping */
+    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (Levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        Levels = 1;
+    }
+    else if (!Levels)
+    {
+        Levels = wined3d_log2i(max(Width, Height)) + 1;
+        TRACE("Calculated levels = %d\n", Levels);
+    }
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppTexture = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DTexture_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_TEXTURE, This, 0, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppTexture = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+
+    *ppTexture = (IWineD3DTexture *)object;
+
+    basetexture_init(&object->baseTexture, Levels, Usage);
+    object->width  = Width;
+    object->height = Height;
+
+    if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING) {
+        object->baseTexture.minMipLookup = minMipLookup;
+        object->baseTexture.magLookup    = magLookup;
+    } else {
+        object->baseTexture.minMipLookup = minMipLookup_noFilter;
+        object->baseTexture.magLookup    = magLookup_noFilter;
+    }
+
     /** FIXME: add support for real non-power-two if it's provided by the video card **/
     /* Precalculated scaling for 'faked' non power of two texture coords.
        Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
     /** FIXME: add support for real non-power-two if it's provided by the video card **/
     /* Precalculated scaling for 'faked' non power of two texture coords.
        Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
@@ -843,37 +895,14 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
     }
     TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]);
 
     }
     TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]);
 
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
-        if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-        if(Levels > 1) {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-        object->baseTexture.levels = 1;
-    } else if (Levels == 0) {
-        TRACE("calculating levels %d\n", object->baseTexture.levels);
-        object->baseTexture.levels++;
-        tmpW = Width;
-        tmpH = Height;
-        while (tmpW > 1 || tmpH > 1) {
-            tmpW = max(1, tmpW >> 1);
-            tmpH = max(1, tmpH >> 1);
-            object->baseTexture.levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->baseTexture.levels);
-    }
-
     /* Generate all the surfaces */
     tmpW = Width;
     tmpH = Height;
     for (i = 0; i < object->baseTexture.levels; i++)
     {
         /* use the callback to create the texture surface */
     /* Generate all the surfaces */
     tmpW = Width;
     tmpH = Height;
     for (i = 0; i < object->baseTexture.levels; i++)
     {
         /* use the callback to create the texture surface */
-        hr = D3DCB_CreateSurface(This->parent, parent, tmpW, tmpH, Format, Usage, Pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &object->surfaces[i],NULL);
+        hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpH, Format,
+                Usage, Pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &object->surfaces[i]);
         if (hr!= WINED3D_OK || ( (IWineD3DSurfaceImpl *) object->surfaces[i])->Flags & SFLAG_OVERSIZE) {
             FIXME("Failed to create surface  %p\n", object);
             /* clean up */
         if (hr!= WINED3D_OK || ( (IWineD3DSurfaceImpl *) object->surfaces[i])->Flags & SFLAG_OVERSIZE) {
             FIXME("Failed to create surface  %p\n", object);
             /* clean up */
@@ -898,13 +927,9 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface,
-                                                      UINT Width, UINT Height, UINT Depth,
-                                                      UINT Levels, DWORD Usage,
-                                                      WINED3DFORMAT Format, WINED3DPOOL Pool,
-                                                      IWineD3DVolumeTexture **ppVolumeTexture,
-                                                      HANDLE *pSharedHandle, IUnknown *parent,
-                                                      D3DCB_CREATEVOLUMEFN D3DCB_CreateVolume) {
-
+        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
+        IWineD3DVolumeTexture **ppVolumeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+{
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeTextureImpl *object;
     unsigned int               i;
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeTextureImpl *object;
     unsigned int               i;
@@ -912,6 +937,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     UINT                       tmpH;
     UINT                       tmpD;
     const struct GlPixelFormatDesc *glDesc;
     UINT                       tmpH;
     UINT                       tmpD;
     const struct GlPixelFormatDesc *glDesc;
+    HRESULT hr;
 
     getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
 
 
     getFormatDescEntry(Format, &GLINFO_LOCATION, &glDesc);
 
@@ -926,8 +952,52 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    D3DCREATERESOURCEOBJECTINSTANCE(object, VolumeTexture, WINED3DRTYPE_VOLUMETEXTURE, 0);
-    D3DINITIALIZEBASETEXTURE(object->baseTexture);
+    /* Calculate levels for mip mapping */
+    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (Levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        Levels = 1;
+    }
+    else if (!Levels)
+    {
+        Levels = wined3d_log2i(max(max(Width, Height), Depth)) + 1;
+        TRACE("Calculated levels = %d\n", Levels);
+    }
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppVolumeTexture = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_VOLUMETEXTURE, This, 0, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppVolumeTexture = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+
+    basetexture_init(&object->baseTexture, Levels, Usage);
 
     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));
 
     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));
@@ -946,31 +1016,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
         object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
         object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
-        if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-        if(Levels > 1) {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-        object->baseTexture.levels = 1;
-    } else if (Levels == 0) {
-        object->baseTexture.levels++;
-        tmpW = Width;
-        tmpH = Height;
-        tmpD = Depth;
-        while (tmpW > 1 || tmpH > 1 || tmpD > 1) {
-            tmpW = max(1, tmpW >> 1);
-            tmpH = max(1, tmpH >> 1);
-            tmpD = max(1, tmpD >> 1);
-            object->baseTexture.levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->baseTexture.levels);
-    }
-
     /* Generate all the surfaces */
     tmpW = Width;
     tmpH = Height;
     /* Generate all the surfaces */
     tmpW = Width;
     tmpH = Height;
@@ -980,9 +1025,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     {
         HRESULT hr;
         /* Create the volume */
     {
         HRESULT hr;
         /* Create the volume */
-        hr = D3DCB_CreateVolume(This->parent, parent, tmpW, tmpH, tmpD, Format, Pool, Usage,
-                                &object->volumes[i], pSharedHandle);
-
+        hr = IWineD3DDeviceParent_CreateVolume(This->device_parent, parent,
+                tmpW, tmpH, tmpD, Format, Pool, Usage, &object->volumes[i]);
         if(FAILED(hr)) {
             ERR("Creating a volume for the volume texture failed(%08x)\n", hr);
             IWineD3DVolumeTexture_Release((IWineD3DVolumeTexture *) object);
         if(FAILED(hr)) {
             ERR("Creating a volume for the volume texture failed(%08x)\n", hr);
             IWineD3DVolumeTexture_Release((IWineD3DVolumeTexture *) object);
@@ -1015,13 +1059,37 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeImpl        *object; /** NOTE: impl ref allowed since this is a create function **/
     const StaticPixelFormatDesc *formatDesc  = getFormatDescEntry(Format, NULL, NULL);
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeImpl        *object; /** NOTE: impl ref allowed since this is a create function **/
     const StaticPixelFormatDesc *formatDesc  = getFormatDescEntry(Format, NULL, NULL);
+    HRESULT hr;
 
     if(!GL_SUPPORT(EXT_TEXTURE3D)) {
         WARN("(%p) : Volume cannot be created - no volume texture support\n", This);
         return WINED3DERR_INVALIDCALL;
     }
 
 
     if(!GL_SUPPORT(EXT_TEXTURE3D)) {
         WARN("(%p) : Volume cannot be created - no volume texture support\n", This);
         return WINED3DERR_INVALIDCALL;
     }
 
-    D3DCREATERESOURCEOBJECTINSTANCE(object, Volume, WINED3DRTYPE_VOLUME, ((Width * formatDesc->bpp) * Height * Depth))
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppVolume = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DVolume_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_VOLUME, This,
+            Width * Height * Depth * formatDesc->bpp, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppVolume = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+
+    *ppVolume = (IWineD3DVolume *)object;
 
     TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
           Depth, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
 
     TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
           Depth, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
@@ -1037,16 +1105,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
     memset(&object->lockedBox, 0, sizeof(WINED3DBOX));
     object->dirty               = TRUE;
 
     memset(&object->lockedBox, 0, sizeof(WINED3DBOX));
     object->dirty               = TRUE;
 
-    return IWineD3DVolume_AddDirtyBox((IWineD3DVolume *) object, NULL);
-}
+    volume_add_dirty_box((IWineD3DVolume *)object, NULL);
 
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, UINT EdgeLength,
-                                                    UINT Levels, DWORD Usage,
-                                                    WINED3DFORMAT Format, WINED3DPOOL Pool,
-                                                    IWineD3DCubeTexture **ppCubeTexture,
-                                                    HANDLE *pSharedHandle, IUnknown *parent,
-                                                    D3DCB_CREATESURFACEFN D3DCB_CreateSurface) {
+    return WINED3D_OK;
+}
 
 
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface,
+        UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
+        IWineD3DCubeTexture **ppCubeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+{
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
     unsigned int             i, j;
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
     unsigned int             i, j;
@@ -1068,8 +1135,52 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    D3DCREATERESOURCEOBJECTINSTANCE(object, CubeTexture, WINED3DRTYPE_CUBETEXTURE, 0);
-    D3DINITIALIZEBASETEXTURE(object->baseTexture);
+    /* Calculate levels for mip mapping */
+    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (Levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        Levels = 1;
+    }
+    else if (!Levels)
+    {
+        Levels = wined3d_log2i(EdgeLength) + 1;
+        TRACE("Calculated levels = %d\n", Levels);
+    }
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppCubeTexture = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_CUBETEXTURE, This, 0, Usage, Format, Pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppCubeTexture = NULL;
+        return hr;
+    }
+
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+
+    basetexture_init(&object->baseTexture, Levels, Usage);
 
     TRACE("(%p) Create Cube Texture\n", This);
 
 
     TRACE("(%p) Create Cube Texture\n", This);
 
@@ -1099,33 +1210,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
         object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
         object->baseTexture.magLookup    = magLookup_noFilter;
     }
 
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
-        if(!GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            HeapFree(GetProcessHeap(), 0, object);
-            *ppCubeTexture = NULL;
-
-            return WINED3DERR_INVALIDCALL;
-        }
-        if(Levels > 1) {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            HeapFree(GetProcessHeap(), 0, object);
-            *ppCubeTexture = NULL;
-
-            return WINED3DERR_INVALIDCALL;
-        }
-        object->baseTexture.levels = 1;
-    } else if (Levels == 0) {
-        object->baseTexture.levels++;
-        tmpW = EdgeLength;
-        while (tmpW > 1) {
-            tmpW = max(1, tmpW >> 1);
-            object->baseTexture.levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->baseTexture.levels);
-    }
-
     /* Generate all the surfaces */
     tmpW = EdgeLength;
     for (i = 0; i < object->baseTexture.levels; i++) {
     /* Generate all the surfaces */
     tmpW = EdgeLength;
     for (i = 0; i < object->baseTexture.levels; i++) {
@@ -1141,24 +1225,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
             };
 
                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
             };
 
-            hr=D3DCB_CreateSurface(This->parent, parent, tmpW, tmpW, Format, Usage, Pool,
-                                   i /* Level */, j, &object->surfaces[j][i],pSharedHandle);
-
-            if(hr!= WINED3D_OK) {
-                /* clean up */
-                unsigned int k;
-                unsigned int l;
-                for (l = 0; l < j; l++) {
-                    IWineD3DSurface_Release(object->surfaces[l][i]);
-                }
-                for (k = 0; k < i; k++) {
-                    for (l = 0; l < 6; l++) {
-                        IWineD3DSurface_Release(object->surfaces[l][k]);
-                    }
-                }
-
+            hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpW,
+                    Format, Usage, Pool, i /* Level */, j, &object->surfaces[j][i]);
+            if (FAILED(hr))
+            {
                 FIXME("(%p) Failed to create surface\n",object);
                 FIXME("(%p) Failed to create surface\n",object);
-                HeapFree(GetProcessHeap(),0,object);
+                IWineD3DCubeTexture_Release((IWineD3DCubeTexture *)object);
                 *ppCubeTexture = NULL;
                 return hr;
             }
                 *ppCubeTexture = NULL;
                 return hr;
             }
@@ -1225,10 +1297,23 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
         return hr;
     }
 
         return hr;
     }
 
-    D3DCREATEOBJECTINSTANCE(object, Query)
-    object->lpVtbl       = vtable;
-    object->type         = Type;
-    object->state        = QUERY_CREATED;
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if(!object)
+    {
+        ERR("Out of memory\n");
+        *ppQuery = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = vtable;
+    object->type = Type;
+    object->state = QUERY_CREATED;
+    object->wineD3DDevice = This;
+    object->parent = parent;
+    object->ref = 1;
+
+    *ppQuery = (IWineD3DQuery *)object;
+
     /* allocated the 'extended' data based on the type of query requested */
     switch(Type){
     case WINED3DQUERYTYPE_OCCLUSION:
     /* allocated the 'extended' data based on the type of query requested */
     switch(Type){
     case WINED3DQUERYTYPE_OCCLUSION:
@@ -1392,10 +1477,9 @@ static void IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window)
 }
 
 /* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
 }
 
 /* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
-        WINED3DPRESENT_PARAMETERS* pPresentationParameters, IWineD3DSwapChain** ppSwapChain,
-        IUnknown* parent, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget,
-        D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil, WINED3DSURFTYPE surface_type)
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
+        WINED3DPRESENT_PARAMETERS *pPresentationParameters, IWineD3DSwapChain **ppSwapChain,
+        IUnknown *parent, WINED3DSURFTYPE surface_type)
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
 
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
 
@@ -1422,7 +1506,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
         FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n");
     }
 
         FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n");
     }
 
-    D3DCREATEOBJECTINSTANCE(object, SwapChain)
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if(!object)
+    {
+        ERR("Out of memory\n");
+        *ppSwapChain = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
     switch(surface_type) {
         case SURFACE_GDI:
             object->lpVtbl = &IWineGDISwapChain_Vtbl;
     switch(surface_type) {
         case SURFACE_GDI:
             object->lpVtbl = &IWineGDISwapChain_Vtbl;
@@ -1432,8 +1523,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
             break;
         case SURFACE_UNKNOWN:
             FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain\n");
             break;
         case SURFACE_UNKNOWN:
             FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain\n");
+            HeapFree(GetProcessHeap(), 0, object);
             return WINED3DERR_INVALIDCALL;
     }
             return WINED3DERR_INVALIDCALL;
     }
+    object->wineD3DDevice = This;
+    object->parent = parent;
+    object->ref = 1;
+
+    *ppSwapChain = (IWineD3DSwapChain *)object;
 
     /*********************
     * Lookup the window Handle and the relating X window handle
 
     /*********************
     * Lookup the window Handle and the relating X window handle
@@ -1465,11 +1562,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
     object->orig_fmt = Mode.Format;
     formatDesc  = getFormatDescEntry(Mode.Format, NULL, NULL);
 
     object->orig_fmt = Mode.Format;
     formatDesc  = getFormatDescEntry(Mode.Format, NULL, NULL);
 
-    /** MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
-     *  then the corresponding dimension of the client area of the hDeviceWindow
-     *  (or the focus window, if hDeviceWindow is NULL) is taken.
-      **********************/
-
     if (pPresentationParameters->Windowed &&
         ((pPresentationParameters->BackBufferWidth == 0) ||
          (pPresentationParameters->BackBufferHeight == 0) ||
     if (pPresentationParameters->Windowed &&
         ((pPresentationParameters->BackBufferWidth == 0) ||
          (pPresentationParameters->BackBufferHeight == 0) ||
@@ -1497,16 +1589,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
     object->presentParms = *pPresentationParameters;
 
     TRACE("calling rendertarget CB\n");
     object->presentParms = *pPresentationParameters;
 
     TRACE("calling rendertarget CB\n");
-    hr = D3DCB_CreateRenderTarget(This->parent,
-                             parent,
-                             object->presentParms.BackBufferWidth,
-                             object->presentParms.BackBufferHeight,
-                             object->presentParms.BackBufferFormat,
-                             object->presentParms.MultiSampleType,
-                             object->presentParms.MultiSampleQuality,
-                             TRUE /* Lockable */,
-                             &object->frontBuffer,
-                             NULL /* pShared (always null)*/);
+    hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent,
+            object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
+            object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType,
+            object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->frontBuffer);
     if (SUCCEEDED(hr)) {
         IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
         if(surface_type == SURFACE_OPENGL) {
     if (SUCCEEDED(hr)) {
         IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
         if(surface_type == SURFACE_OPENGL) {
@@ -1585,16 +1671,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
 
         for(i = 0; i < object->presentParms.BackBufferCount; i++) {
             TRACE("calling rendertarget CB\n");
 
         for(i = 0; i < object->presentParms.BackBufferCount; i++) {
             TRACE("calling rendertarget CB\n");
-            hr = D3DCB_CreateRenderTarget(This->parent,
-                                    parent,
-                                    object->presentParms.BackBufferWidth,
-                                    object->presentParms.BackBufferHeight,
-                                    object->presentParms.BackBufferFormat,
-                                    object->presentParms.MultiSampleType,
-                                    object->presentParms.MultiSampleQuality,
-                                    TRUE /* Lockable */,
-                                    &object->backBuffer[i],
-                                    NULL /* pShared (always null)*/);
+            hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent,
+                    object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
+                    object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType,
+                    object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->backBuffer[i]);
             if(SUCCEEDED(hr)) {
                 IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object);
             } else {
             if(SUCCEEDED(hr)) {
                 IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object);
             } else {
@@ -1624,16 +1704,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice* iface,
     if (pPresentationParameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) {
         TRACE("Creating depth stencil buffer\n");
         if (This->auto_depth_stencil_buffer == NULL ) {
     if (pPresentationParameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) {
         TRACE("Creating depth stencil buffer\n");
         if (This->auto_depth_stencil_buffer == NULL ) {
-            hr = D3DCB_CreateDepthStencil(This->parent,
-                                    parent,
-                                    object->presentParms.BackBufferWidth,
-                                    object->presentParms.BackBufferHeight,
-                                    object->presentParms.AutoDepthStencilFormat,
-                                    object->presentParms.MultiSampleType,
-                                    object->presentParms.MultiSampleQuality,
-                                    FALSE /* FIXME: Discard */,
-                                    &This->auto_depth_stencil_buffer,
-                                    NULL /* pShared (always null)*/  );
+            hr = IWineD3DDeviceParent_CreateDepthStencilSurface(This->device_parent, parent,
+                    object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
+                    object->presentParms.AutoDepthStencilFormat, object->presentParms.MultiSampleType,
+                    object->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */,
+                    &This->auto_depth_stencil_buffer);
             if (SUCCEEDED(hr)) {
                 IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0);
             } else {
             if (SUCCEEDED(hr)) {
                 IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0);
             } else {
@@ -1730,7 +1805,20 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice*
     TRACE("(%p) : directXVersion %u, elements %p, element_count %d, ppDecl=%p\n",
             This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, elements, element_count, ppVertexDeclaration);
 
     TRACE("(%p) : directXVersion %u, elements %p, element_count %d, ppDecl=%p\n",
             This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, elements, element_count, ppVertexDeclaration);
 
-    D3DCREATEOBJECTINSTANCE(object, VertexDeclaration)
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if(!object)
+    {
+        ERR("Out of memory\n");
+        *ppVertexDeclaration = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
+    object->wineD3DDevice = This;
+    object->parent = parent;
+    object->ref = 1;
+
+    *ppVertexDeclaration = (IWineD3DVertexDeclaration *)object;
 
     hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, elements, element_count);
     if(FAILED(hr)) {
 
     hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, elements, element_count);
     if(FAILED(hr)) {
@@ -1783,6 +1871,10 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the
             elements[idx].Type = WINED3DDECLTYPE_FLOAT4;
             elements[idx].Usage = WINED3DDECLUSAGE_POSITIONT;
         }
             elements[idx].Type = WINED3DDECLTYPE_FLOAT4;
             elements[idx].Usage = WINED3DDECLUSAGE_POSITIONT;
         }
+        else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW) {
+            elements[idx].Type = WINED3DDECLTYPE_FLOAT4;
+            elements[idx].Usage = WINED3DDECLUSAGE_POSITION;
+        }
         else {
             elements[idx].Type = WINED3DDECLTYPE_FLOAT3;
             elements[idx].Usage = WINED3DDECLUSAGE_POSITION;
         else {
             elements[idx].Type = WINED3DDECLTYPE_FLOAT3;
             elements[idx].Usage = WINED3DDECLUSAGE_POSITION;
@@ -1896,25 +1988,39 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
-    D3DCREATESHADEROBJECTINSTANCE(object, VertexShader)
-    object->baseShader.shader_ins = IWineD3DVertexShaderImpl_shader_ins;
 
 
-    TRACE("(%p) : Created Vertex shader %p\n", This, *ppVertexShader);
+    if (!pFunction) return WINED3DERR_INVALIDCALL;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppVertexShader = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DVertexShader_Vtbl;
+    object->parent = parent;
+    shader_init(&object->baseShader, iface, IWineD3DVertexShaderImpl_shader_ins);
+    list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
+    *ppVertexShader = (IWineD3DVertexShader *)object;
+
+    TRACE("(%p) : Created vertex shader %p\n", This, *ppVertexShader);
 
     if (vertex_declaration) {
         IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
     }
 
     hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
 
     if (vertex_declaration) {
         IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
     }
 
     hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
-
-    if (WINED3D_OK != hr) {
-        FIXME("(%p) : Failed to set the function, returning WINED3DERR_INVALIDCALL\n", iface);
+    if (FAILED(hr))
+    {
+        WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
         IWineD3DVertexShader_Release(*ppVertexShader);
         IWineD3DVertexShader_Release(*ppVertexShader);
-        return WINED3DERR_INVALIDCALL;
+        *ppVertexShader = NULL;
+        return hr;
     }
     }
-    list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
 
 
-    return WINED3D_OK;
+    return hr;
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DPixelShader **ppPixelShader, IUnknown *parent) {
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DPixelShader **ppPixelShader, IUnknown *parent) {
@@ -1922,14 +2028,31 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
 
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
 
-    D3DCREATESHADEROBJECTINSTANCE(object, PixelShader)
-    object->baseShader.shader_ins = IWineD3DPixelShaderImpl_shader_ins;
+    if (!pFunction) return WINED3DERR_INVALIDCALL;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Out of memory\n");
+        *ppPixelShader = NULL;
+        return WINED3DERR_OUTOFVIDEOMEMORY;
+    }
+
+    object->lpVtbl = &IWineD3DPixelShader_Vtbl;
+    object->parent = parent;
+    shader_init(&object->baseShader, iface, IWineD3DPixelShaderImpl_shader_ins);
+    list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
+    *ppPixelShader = (IWineD3DPixelShader *)object;
+
+    TRACE("(%p) : Created pixel shader %p\n", This, *ppPixelShader);
+
     hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);
     hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);
-    if (WINED3D_OK == hr) {
-        TRACE("(%p) : Created Pixel shader %p\n", This, *ppPixelShader);
-        list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
-    } else {
-        WARN("(%p) : Failed to create pixel shader\n", This);
+    if (FAILED(hr))
+    {
+        WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
+        IWineD3DPixelShader_Release(*ppPixelShader);
+        *ppPixelShader = NULL;
+        return hr;
     }
 
     return hr;
     }
 
     return hr;
@@ -1956,7 +2079,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePalette(IWineD3DDevice *iface, DW
     object->parent = Parent;
     object->wineD3DDevice = This;
     object->palNumEntries = IWineD3DPaletteImpl_Size(Flags);
     object->parent = Parent;
     object->wineD3DDevice = This;
     object->palNumEntries = IWineD3DPaletteImpl_Size(Flags);
-       
     object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion));
 
     if(!object->hpal) {
     object->hpal = CreatePalette((const LOGPALETTE*)&(object->palVersion));
 
     if(!object->hpal) {
@@ -2050,12 +2172,8 @@ static void create_dummy_textures(IWineD3DDeviceImpl *This) {
         GLubyte white = 255;
 
         /* Make appropriate texture active */
         GLubyte white = 255;
 
         /* Make appropriate texture active */
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
-            checkGLcall("glActiveTextureARB");
-        } else if (i > 0) {
-            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-        }
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+        checkGLcall("glActiveTextureARB");
 
         /* Generate an opengl texture name */
         glGenTextures(1, &This->dummyTextureName[i]);
 
         /* Generate an opengl texture name */
         glGenTextures(1, &This->dummyTextureName[i]);
@@ -2064,7 +2182,6 @@ static void create_dummy_textures(IWineD3DDeviceImpl *This) {
 
         /* Generate a dummy 2d texture (not using 1d because they cause many
         * DRI drivers fall back to sw) */
 
         /* Generate a dummy 2d texture (not using 1d because they cause many
         * DRI drivers fall back to sw) */
-        This->stateBlock->textureDimensions[i] = GL_TEXTURE_2D;
         glBindTexture(GL_TEXTURE_2D, This->dummyTextureName[i]);
         checkGLcall("glBindTexture");
 
         glBindTexture(GL_TEXTURE_2D, This->dummyTextureName[i]);
         checkGLcall("glBindTexture");
 
@@ -2080,14 +2197,17 @@ static void create_dummy_textures(IWineD3DDeviceImpl *This) {
     LEAVE_GL();
 }
 
     LEAVE_GL();
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATESWAPCHAIN D3DCB_CreateSwapChain) {
+static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
+        WINED3DPRESENT_PARAMETERS *pPresentationParameters)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain = NULL;
     HRESULT hr;
     DWORD state;
     unsigned int i;
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain = NULL;
     HRESULT hr;
     DWORD state;
     unsigned int i;
 
-    TRACE("(%p)->(%p,%p)\n", This, pPresentationParameters, D3DCB_CreateSwapChain);
+    TRACE("(%p)->(%p)\n", This, pPresentationParameters);
+
     if(This->d3d_initialized) return WINED3DERR_INVALIDCALL;
     if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL;
 
     if(This->d3d_initialized) return WINED3DERR_INVALIDCALL;
     if(!This->adapter->opengl) return WINED3DERR_INVALIDCALL;
 
@@ -2107,11 +2227,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
     This->updateStateBlock = This->stateBlock;
     IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock);
 
     This->updateStateBlock = This->stateBlock;
     IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock);
 
-    hr = allocate_shader_constants(This->updateStateBlock);
-    if (WINED3D_OK != hr) {
-        goto err_out;
-    }
-
     This->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
     This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
 
     This->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
     This->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
 
@@ -2147,8 +2262,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
 
     /* Setup the implicit swapchain */
     TRACE("Creating implicit swapchain\n");
 
     /* Setup the implicit swapchain */
     TRACE("Creating implicit swapchain\n");
-    hr=D3DCB_CreateSwapChain(This->parent, pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
-    if (FAILED(hr) || !swapchain) {
+    hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
+            pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
+    if (FAILED(hr))
+    {
         WARN("Failed to create implicit swapchain\n");
         goto err_out;
     }
         WARN("Failed to create implicit swapchain\n");
         goto err_out;
     }
@@ -2205,17 +2322,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
 
     ENTER_GL();
 
 
     ENTER_GL();
 
-    { /* Set a default viewport */
-        WINED3DVIEWPORT vp;
-        vp.X      = 0;
-        vp.Y      = 0;
-        vp.Width  = pPresentationParameters->BackBufferWidth;
-        vp.Height = pPresentationParameters->BackBufferHeight;
-        vp.MinZ   = 0.0f;
-        vp.MaxZ   = 1.0f;
-        IWineD3DDevice_SetViewport((IWineD3DDevice *)This, &vp);
-    }
-
     /* Initialize the current view state */
     This->view_ident = 1;
     This->contexts[0]->last_was_rhw = 0;
     /* Initialize the current view state */
     This->view_ident = 1;
     This->contexts[0]->last_was_rhw = 0;
@@ -2286,15 +2392,19 @@ err_out:
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_InitGDI(IWineD3DDevice *iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATESWAPCHAIN D3DCB_CreateSwapChain) {
+static HRESULT WINAPI IWineD3DDeviceImpl_InitGDI(IWineD3DDevice *iface,
+        WINED3DPRESENT_PARAMETERS *pPresentationParameters)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain = NULL;
     HRESULT hr;
 
     /* Setup the implicit swapchain */
     TRACE("Creating implicit swapchain\n");
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain = NULL;
     HRESULT hr;
 
     /* Setup the implicit swapchain */
     TRACE("Creating implicit swapchain\n");
-    hr=D3DCB_CreateSwapChain(This->parent, pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
-    if (FAILED(hr) || !swapchain) {
+    hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
+            pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
+    if (FAILED(hr))
+    {
         WARN("Failed to create implicit swapchain\n");
         goto err_out;
     }
         WARN("Failed to create implicit swapchain\n");
         goto err_out;
     }
@@ -2560,36 +2670,6 @@ static UINT WINAPI IWineD3DDeviceImpl_GetAvailableTextureMem(IWineD3DDevice *ifa
     return (This->adapter->TextureRam - This->adapter->UsedTextureRam);
 }
 
     return (This->adapter->TextureRam - This->adapter->UsedTextureRam);
 }
 
-
-
-/*****
- * Get / Set FVF
- *****/
-static HRESULT WINAPI IWineD3DDeviceImpl_SetFVF(IWineD3DDevice *iface, DWORD fvf) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-    /* Update the current state block */
-    This->updateStateBlock->changed.fvf      = TRUE;
-
-    if(This->updateStateBlock->fvf == fvf) {
-        TRACE("Application is setting the old fvf over, nothing to do\n");
-        return WINED3D_OK;
-    }
-
-    This->updateStateBlock->fvf              = fvf;
-    TRACE("(%p) : FVF Shader FVF set to %x\n", This, fvf);
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
-    return WINED3D_OK;
-}
-
-
-static HRESULT WINAPI IWineD3DDeviceImpl_GetFVF(IWineD3DDevice *iface, DWORD *pfvf) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    TRACE("(%p) : GetFVF returning %x\n", This, This->stateBlock->fvf);
-    *pfvf = This->stateBlock->fvf;
-    return WINED3D_OK;
-}
-
 /*****
  * Get / Set Stream Source
  *****/
 /*****
  * Get / Set Stream Source
  *****/
@@ -2608,7 +2688,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface,
     oldSrc = This->updateStateBlock->streamSource[StreamNumber];
     TRACE("(%p) : StreamNo: %u, OldStream (%p), NewStream (%p), OffsetInBytes %u, NewStride %u\n", This, StreamNumber, oldSrc, pStreamData, OffsetInBytes, Stride);
 
     oldSrc = This->updateStateBlock->streamSource[StreamNumber];
     TRACE("(%p) : StreamNo: %u, OldStream (%p), NewStream (%p), OffsetInBytes %u, NewStride %u\n", This, StreamNumber, oldSrc, pStreamData, OffsetInBytes, Stride);
 
-    This->updateStateBlock->changed.streamSource[StreamNumber] = TRUE;
+    This->updateStateBlock->changed.streamSource |= 1 << StreamNumber;
 
     if(oldSrc == pStreamData &&
        This->updateStateBlock->streamStride[StreamNumber] == Stride &&
 
     if(oldSrc == pStreamData &&
        This->updateStateBlock->streamStride[StreamNumber] == Stride &&
@@ -2631,10 +2711,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface,
         return WINED3D_OK;
     }
 
         return WINED3D_OK;
     }
 
-    /* Need to do a getParent and pass the references up */
-    /* MSDN says ..... When an application no longer holds a reference to this interface, the interface will automatically be freed.
-    which suggests that we shouldn't be ref counting? and do need a _release on the stream source to reset the stream source
-    so for now, just count internally   */
     if (pStreamData != NULL) {
         IWineD3DVertexBufferImpl *vbImpl = (IWineD3DVertexBufferImpl *) pStreamData;
         InterlockedIncrement(&vbImpl->bindCount);
     if (pStreamData != NULL) {
         IWineD3DVertexBufferImpl *vbImpl = (IWineD3DVertexBufferImpl *) pStreamData;
         InterlockedIncrement(&vbImpl->bindCount);
@@ -2696,7 +2772,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSourceFreq(IWineD3DDevice *ifa
     TRACE("(%p) StreamNumber(%d), Divider(%d)\n", This, StreamNumber, Divider);
     This->updateStateBlock->streamFlags[StreamNumber] = Divider & (WINED3DSTREAMSOURCE_INSTANCEDATA  | WINED3DSTREAMSOURCE_INDEXEDDATA );
 
     TRACE("(%p) StreamNumber(%d), Divider(%d)\n", This, StreamNumber, Divider);
     This->updateStateBlock->streamFlags[StreamNumber] = Divider & (WINED3DSTREAMSOURCE_INSTANCEDATA  | WINED3DSTREAMSOURCE_INDEXEDDATA );
 
-    This->updateStateBlock->changed.streamFreq[StreamNumber]  = TRUE;
+    This->updateStateBlock->changed.streamFreq |= 1 << StreamNumber;
     This->updateStateBlock->streamFreq[StreamNumber]          = Divider & 0x7FFFFF;
 
     if(This->updateStateBlock->streamFreq[StreamNumber] != oldFreq ||
     This->updateStateBlock->streamFreq[StreamNumber]          = Divider & 0x7FFFFF;
 
     if(This->updateStateBlock->streamFreq[StreamNumber] != oldFreq ||
@@ -2730,7 +2806,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetTransform(IWineD3DDevice *iface, W
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
         TRACE("Recording... not performing anything\n");
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
         TRACE("Recording... not performing anything\n");
-        This->updateStateBlock->changed.transform[d3dts] = TRUE;
+        This->updateStateBlock->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f);
         This->updateStateBlock->transforms[d3dts] = *lpmatrix;
         return WINED3D_OK;
     }
         This->updateStateBlock->transforms[d3dts] = *lpmatrix;
         return WINED3D_OK;
     }
@@ -2787,7 +2863,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_MultiplyTransform(IWineD3DDevice *iface
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     TRACE("(%p) : For state %s\n", This, debug_d3dtstype(State));
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     TRACE("(%p) : For state %s\n", This, debug_d3dtstype(State));
 
-    if (State < HIGHEST_TRANSFORMSTATE)
+    if (State <= HIGHEST_TRANSFORMSTATE)
     {
         mat = &This->updateStateBlock->transforms[State];
     } else {
     {
         mat = &This->updateStateBlock->transforms[State];
     } else {
@@ -2933,9 +3009,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
             if (rho < 0.0001) rho = 0.0001f;
             object->exponent = -0.3/log(cos(rho/2));
         }
             if (rho < 0.0001) rho = 0.0001f;
             object->exponent = -0.3/log(cos(rho/2));
         }
-       if (object->exponent > 128.0) {
-               object->exponent = 128.0;
-       }
+        if (object->exponent > 128.0) {
+            object->exponent = 128.0;
+        }
         object->cutoff = pLight->Phi*90/M_PI;
 
         /* FIXME: Range */
         object->cutoff = pLight->Phi*90/M_PI;
 
         /* FIXME: Range */
@@ -3049,7 +3125,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLightEnable(IWineD3DDevice *iface, D
                  *
                  * TODO: Test how this affects rendering
                  */
                  *
                  * TODO: Test how this affects rendering
                  */
-                FIXME("Too many concurrently active lights\n");
+                WARN("Too many concurrently active lights\n");
                 return WINED3D_OK;
             }
 
                 return WINED3D_OK;
             }
 
@@ -3099,7 +3175,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetClipPlane(IWineD3DDevice *iface, DWO
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    This->updateStateBlock->changed.clipplane[Index] = TRUE;
+    This->updateStateBlock->changed.clipplane |= 1 << Index;
 
     if(This->updateStateBlock->clipplane[Index][0] == pPlane[0] &&
        This->updateStateBlock->clipplane[Index][1] == pPlane[1] &&
 
     if(This->updateStateBlock->clipplane[Index][0] == pPlane[0] &&
        This->updateStateBlock->clipplane[Index][1] == pPlane[1] &&
@@ -3323,7 +3399,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, W
 
     TRACE("(%p)->state = %s(%d), value = %d\n", This, debug_d3drenderstate(State), State, Value);
 
 
     TRACE("(%p)->state = %s(%d), value = %d\n", This, debug_d3drenderstate(State), State, Value);
 
-    This->updateStateBlock->changed.renderState[State] = TRUE;
+    This->updateStateBlock->changed.renderState[State >> 5] |= 1 << (State & 0x1f);
     This->updateStateBlock->renderState[State] = Value;
 
     /* Handle recording of state blocks */
     This->updateStateBlock->renderState[State] = Value;
 
     /* Handle recording of state blocks */
@@ -3386,7 +3462,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface,
 
     oldValue = This->stateBlock->samplerState[Sampler][Type];
     This->updateStateBlock->samplerState[Sampler][Type]         = Value;
 
     oldValue = This->stateBlock->samplerState[Sampler][Type];
     This->updateStateBlock->samplerState[Sampler][Type]         = Value;
-    This->updateStateBlock->changed.samplerState[Sampler][Type] = Value;
+    This->updateStateBlock->changed.samplerState[Sampler] |= 1 << Type;
 
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
 
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
@@ -3548,7 +3624,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB(
         This->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
     }
 
         This->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
     }
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+    if (!This->isRecordingState) IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -3596,7 +3672,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI(
         This->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
     }
 
         This->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
     }
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+    if (!This->isRecordingState) IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -3607,64 +3683,24 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI(
     int *dstData,
     UINT count) {
 
     int *dstData,
     UINT count) {
 
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    int cnt = min(count, MAX_CONST_I - start);
-
-    TRACE("(iface %p, dstData %p, start %d, count %d)\n",
-            iface, dstData, start, count);
-
-    if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0)
-        return WINED3DERR_INVALIDCALL;
-
-    memcpy(dstData, &This->stateBlock->vertexShaderConstantI[start * 4], cnt * sizeof(int) * 4);
-    return WINED3D_OK;
-}
-
-static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(
-    IWineD3DDevice *iface,
-    UINT start,
-    CONST float *srcData,
-    UINT count) {
-
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    UINT i;
-
-    TRACE("(iface %p, srcData %p, start %d, count %d)\n",
-            iface, srcData, start, count);
-
-    /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
-    if (srcData == NULL || start + count > GL_LIMITS(vshader_constantsF) || start > GL_LIMITS(vshader_constantsF))
-        return WINED3DERR_INVALIDCALL;
-
-    memcpy(&This->updateStateBlock->vertexShaderConstantF[start * 4], srcData, count * sizeof(float) * 4);
-    if(TRACE_ON(d3d)) {
-        for (i = 0; i < count; i++)
-            TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i,
-                srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
-    }
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    int cnt = min(count, MAX_CONST_I - start);
 
 
-    for (i = start; i < count + start; ++i) {
-        if (!This->updateStateBlock->changed.vertexShaderConstantsF[i]) {
-            constants_entry *ptr = LIST_ENTRY(list_head(&This->updateStateBlock->set_vconstantsF), constants_entry, entry);
-            if (!ptr || ptr->count >= sizeof(ptr->idx) / sizeof(*ptr->idx)) {
-                ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(constants_entry));
-                list_add_head(&This->updateStateBlock->set_vconstantsF, &ptr->entry);
-            }
-            ptr->idx[ptr->count++] = i;
-            This->updateStateBlock->changed.vertexShaderConstantsF[i] = TRUE;
-        }
-    }
+    TRACE("(iface %p, dstData %p, start %d, count %d)\n",
+            iface, dstData, start, count);
 
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+    if (dstData == NULL || ((signed int) MAX_CONST_I - (signed int) start) <= (signed int) 0)
+        return WINED3DERR_INVALIDCALL;
 
 
+    memcpy(dstData, &This->stateBlock->vertexShaderConstantI[start * 4], cnt * sizeof(int) * 4);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF_DirtyConst(
-IWineD3DDevice *iface,
-UINT start,
-CONST float *srcData,
-UINT count) {
+static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(
+    IWineD3DDevice *iface,
+    UINT start,
+    CONST float *srcData,
+    UINT count) {
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     UINT i;
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     UINT i;
@@ -3680,17 +3716,17 @@ UINT count) {
     if(TRACE_ON(d3d)) {
         for (i = 0; i < count; i++)
             TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i,
     if(TRACE_ON(d3d)) {
         for (i = 0; i < count; i++)
             TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i,
-                    srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
+                srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
     }
 
     }
 
-    /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
-     * context. On a context switch the old context will be fully dirtified
-     */
-    memset(This->activeContext->vshader_const_dirty + start, 1,
-           sizeof(*This->activeContext->vshader_const_dirty) * count);
-    This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start+count+1);
+    if (!This->isRecordingState)
+    {
+        This->shader_backend->shader_update_float_vertex_constants(iface, start, count);
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+    }
 
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VERTEXSHADERCONSTANT);
+    memset(This->updateStateBlock->changed.vertexShaderConstantsF + start, 1,
+            sizeof(*This->updateStateBlock->changed.vertexShaderConstantsF) * count);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -3716,7 +3752,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(
 
 static inline void markTextureStagesDirty(IWineD3DDeviceImpl *This, DWORD stage) {
     DWORD i;
 
 static inline void markTextureStagesDirty(IWineD3DDeviceImpl *This, DWORD stage) {
     DWORD i;
-    for(i = 0; i < WINED3D_HIGHEST_TEXTURE_STATE; i++) {
+    for(i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
+    {
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, i));
     }
 }
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, i));
     }
 }
@@ -3739,6 +3776,7 @@ static void device_map_stage(IWineD3DDeviceImpl *This, int stage, int unit) {
 static void device_update_fixed_function_usage_map(IWineD3DDeviceImpl *This) {
     int i;
 
 static void device_update_fixed_function_usage_map(IWineD3DDeviceImpl *This) {
     int i;
 
+    This->fixed_function_usage_map = 0;
     for (i = 0; i < MAX_TEXTURES; ++i) {
         WINED3DTEXTUREOP color_op = This->stateBlock->textureState[i][WINED3DTSS_COLOROP];
         WINED3DTEXTUREOP alpha_op = This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP];
     for (i = 0; i < MAX_TEXTURES; ++i) {
         WINED3DTEXTUREOP color_op = This->stateBlock->textureState[i][WINED3DTSS_COLOROP];
         WINED3DTEXTUREOP alpha_op = This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP];
@@ -3751,10 +3789,6 @@ static void device_update_fixed_function_usage_map(IWineD3DDeviceImpl *This) {
 
         if (color_op == WINED3DTOP_DISABLE) {
             /* Not used, and disable higher stages */
 
         if (color_op == WINED3DTOP_DISABLE) {
             /* Not used, and disable higher stages */
-            while (i < MAX_TEXTURES) {
-                This->fixed_function_usage_map[i] = FALSE;
-                ++i;
-            }
             break;
         }
 
             break;
         }
 
@@ -3764,26 +3798,27 @@ static void device_update_fixed_function_usage_map(IWineD3DDeviceImpl *This) {
                 || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3DTOP_SELECTARG2)
                 || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3DTOP_SELECTARG1)
                 || ((alpha_arg3 == WINED3DTA_TEXTURE) && (alpha_op == WINED3DTOP_MULTIPLYADD || alpha_op == WINED3DTOP_LERP))) {
                 || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3DTOP_SELECTARG2)
                 || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3DTOP_SELECTARG1)
                 || ((alpha_arg3 == WINED3DTA_TEXTURE) && (alpha_op == WINED3DTOP_MULTIPLYADD || alpha_op == WINED3DTOP_LERP))) {
-            This->fixed_function_usage_map[i] = TRUE;
-        } else {
-            This->fixed_function_usage_map[i] = FALSE;
+            This->fixed_function_usage_map |= (1 << i);
         }
 
         if ((color_op == WINED3DTOP_BUMPENVMAP || color_op == WINED3DTOP_BUMPENVMAPLUMINANCE) && i < MAX_TEXTURES - 1) {
         }
 
         if ((color_op == WINED3DTOP_BUMPENVMAP || color_op == WINED3DTOP_BUMPENVMAPLUMINANCE) && i < MAX_TEXTURES - 1) {
-            This->fixed_function_usage_map[i+1] = TRUE;
+            This->fixed_function_usage_map |= (1 << (i + 1));
         }
     }
 }
 
 static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
     int i, tex;
         }
     }
 }
 
 static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
     int i, tex;
+    WORD ffu_map;
 
     device_update_fixed_function_usage_map(This);
 
     device_update_fixed_function_usage_map(This);
+    ffu_map = This->fixed_function_usage_map;
 
     if (This->max_ffp_textures == This->max_ffp_texture_stages ||
 
     if (This->max_ffp_textures == This->max_ffp_texture_stages ||
-        This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures) {
-        for (i = 0; i < This->stateBlock->lowest_disabled_stage; ++i) {
-            if (!This->fixed_function_usage_map[i]) continue;
+            This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures) {
+        for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+        {
+            if (!(ffu_map & 1)) continue;
 
             if (This->texUnitMap[i] != i) {
                 device_map_stage(This, i, i);
 
             if (This->texUnitMap[i] != i) {
                 device_map_stage(This, i, i);
@@ -3796,8 +3831,9 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
 
     /* Now work out the mapping */
     tex = 0;
 
     /* Now work out the mapping */
     tex = 0;
-    for (i = 0; i < This->stateBlock->lowest_disabled_stage; ++i) {
-        if (!This->fixed_function_usage_map[i]) continue;
+    for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+    {
+        if (!(ffu_map & 1)) continue;
 
         if (This->texUnitMap[i] != tex) {
             device_map_stage(This, i, tex);
 
         if (This->texUnitMap[i] != tex) {
             device_map_stage(This, i, tex);
@@ -3840,7 +3876,7 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshad
 
         if (!pshader_sampler_tokens) {
             /* No pixel shader, check fixed function */
 
         if (!pshader_sampler_tokens) {
             /* No pixel shader, check fixed function */
-            return current_mapping >= MAX_TEXTURES || !This->fixed_function_usage_map[current_mapping];
+            return current_mapping >= MAX_TEXTURES || !(This->fixed_function_usage_map & (1 << current_mapping));
         }
 
         /* Pixel shader, check the shader's sampler map */
         }
 
         /* Pixel shader, check the shader's sampler map */
@@ -3861,8 +3897,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
     if (ps) {
         IWineD3DPixelShaderImpl *pshader = (IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader;
 
     if (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_UpdateSamplers((IWineD3DPixelShader *)pshader);
+        /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
+         * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
         pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
     }
 
         pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
     }
 
@@ -3890,8 +3926,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
 }
 
 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
 }
 
 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
-    BOOL vs = use_vs(This);
-    BOOL ps = use_ps(This);
+    BOOL vs = use_vs(This->stateBlock);
+    BOOL ps = use_ps(This->stateBlock);
     /*
      * Rules are:
      * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
     /*
      * Rules are:
      * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
@@ -3981,7 +4017,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(
         This->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
     }
 
         This->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
     }
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+    if (!This->isRecordingState) IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -4029,7 +4065,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(
         This->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
     }
 
         This->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
     }
 
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+    if (!This->isRecordingState) IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -4076,54 +4112,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(
                 srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
     }
 
                 srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
     }
 
-    for (i = start; i < count + start; ++i) {
-        if (!This->updateStateBlock->changed.pixelShaderConstantsF[i]) {
-            constants_entry *ptr = LIST_ENTRY(list_head(&This->updateStateBlock->set_pconstantsF), constants_entry, entry);
-            if (!ptr || ptr->count >= sizeof(ptr->idx) / sizeof(*ptr->idx)) {
-                ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(constants_entry));
-                list_add_head(&This->updateStateBlock->set_pconstantsF, &ptr->entry);
-            }
-            ptr->idx[ptr->count++] = i;
-            This->updateStateBlock->changed.pixelShaderConstantsF[i] = TRUE;
-        }
-    }
-
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
-
-    return WINED3D_OK;
-}
-
-static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF_DirtyConst(
-    IWineD3DDevice *iface,
-    UINT start,
-    CONST float *srcData,
-    UINT count) {
-
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    UINT i;
-
-    TRACE("(iface %p, srcData %p, start %d, count %d)\n",
-            iface, srcData, start, count);
-
-    /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
-    if (srcData == NULL || start + count > GL_LIMITS(pshader_constantsF) || start > GL_LIMITS(pshader_constantsF))
-        return WINED3DERR_INVALIDCALL;
-
-    memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, count * sizeof(float) * 4);
-    if(TRACE_ON(d3d)) {
-        for (i = 0; i < count; i++)
-            TRACE("Set FLOAT constant %u to { %f, %f, %f, %f }\n", start + i,
-                    srcData[i*4], srcData[i*4+1], srcData[i*4+2], srcData[i*4+3]);
+    if (!This->isRecordingState)
+    {
+        This->shader_backend->shader_update_float_pixel_constants(iface, start, count);
+        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
     }
 
     }
 
-    /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
-     * context. On a context switch the old context will be fully dirtified
-     */
-    memset(This->activeContext->pshader_const_dirty + start, 1,
-           sizeof(*This->activeContext->pshader_const_dirty) * count);
-    This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start+count+1);
-
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADERCONSTANT);
+    memset(This->updateStateBlock->changed.pixelShaderConstantsF + start, 1,
+            sizeof(*This->updateStateBlock->changed.pixelShaderConstantsF) * count);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -4584,7 +4580,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if
         return WINED3D_OK;
     }
 
         return WINED3D_OK;
     }
 
-    This->updateStateBlock->changed.textureState[Stage][Type] = TRUE;
+    This->updateStateBlock->changed.textureState[Stage] |= 1 << Type;
     This->updateStateBlock->textureState[Stage][Type]         = Value;
 
     if (This->isRecordingState) {
     This->updateStateBlock->textureState[Stage][Type]         = Value;
 
     if (This->isRecordingState) {
@@ -4673,20 +4669,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
 
     oldTexture = This->updateStateBlock->textures[Stage];
 
 
     oldTexture = This->updateStateBlock->textures[Stage];
 
-    if(pTexture != NULL) {
-        /* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH; 
-         */
-        if(((IWineD3DTextureImpl*)pTexture)->resource.pool == WINED3DPOOL_SCRATCH) {
-            WARN("(%p) Attempt to set scratch texture rejected\n", pTexture);
-            return WINED3DERR_INVALIDCALL;
-        }
-        This->stateBlock->textureDimensions[Stage] = IWineD3DBaseTexture_GetTextureDimensions(pTexture);
+    /* SetTexture isn't allowed on textures in WINED3DPOOL_SCRATCH */
+    if (pTexture && ((IWineD3DTextureImpl*)pTexture)->resource.pool == WINED3DPOOL_SCRATCH)
+    {
+        WARN("(%p) Attempt to set scratch texture rejected\n", pTexture);
+        return WINED3DERR_INVALIDCALL;
     }
 
     TRACE("GL_LIMITS %d\n",GL_LIMITS(sampler_stages));
     TRACE("(%p) : oldtexture(%p)\n", This,oldTexture);
 
     }
 
     TRACE("GL_LIMITS %d\n",GL_LIMITS(sampler_stages));
     TRACE("(%p) : oldtexture(%p)\n", This,oldTexture);
 
-    This->updateStateBlock->changed.textures[Stage] = TRUE;
+    This->updateStateBlock->changed.textures |= 1 << Stage;
     TRACE("(%p) : setting new texture to %p\n", This, pTexture);
     This->updateStateBlock->textures[Stage]         = pTexture;
 
     TRACE("(%p) : setting new texture to %p\n", This, pTexture);
     This->updateStateBlock->textures[Stage]         = pTexture;
 
@@ -4708,8 +4701,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
     if (NULL != This->updateStateBlock->textures[Stage]) {
         IWineD3DBaseTextureImpl *new = (IWineD3DBaseTextureImpl *) This->updateStateBlock->textures[Stage];
         ULONG bindCount = InterlockedIncrement(&new->baseTexture.bindCount);
     if (NULL != This->updateStateBlock->textures[Stage]) {
         IWineD3DBaseTextureImpl *new = (IWineD3DBaseTextureImpl *) This->updateStateBlock->textures[Stage];
         ULONG bindCount = InterlockedIncrement(&new->baseTexture.bindCount);
+        UINT dimensions = IWineD3DBaseTexture_GetTextureDimensions(pTexture);
 
         IWineD3DBaseTexture_AddRef(This->updateStateBlock->textures[Stage]);
 
         IWineD3DBaseTexture_AddRef(This->updateStateBlock->textures[Stage]);
+
+        if (!oldTexture || dimensions != IWineD3DBaseTexture_GetTextureDimensions(oldTexture))
+        {
+            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADER);
+        }
+
         if(oldTexture == NULL && Stage < MAX_TEXTURES) {
             /* The source arguments for color and alpha ops have different meanings when a NULL texture is bound,
              * so the COLOROP and ALPHAOP have to be dirtified.
         if(oldTexture == NULL && Stage < MAX_TEXTURES) {
             /* The source arguments for color and alpha ops have different meanings when a NULL texture is bound,
              * so the COLOROP and ALPHAOP have to be dirtified.
@@ -4841,42 +4841,22 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetDisplayMode(IWineD3DDevice *iface, U
 
 static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DStateBlockImpl *object;
-    HRESULT temp_result;
-    int i;
+    IWineD3DStateBlock *stateblock;
+    HRESULT hr;
 
     TRACE("(%p)\n", This);
 
     TRACE("(%p)\n", This);
-    
-    if (This->isRecordingState) {
-        return WINED3DERR_INVALIDCALL;
-    }
-    
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DStateBlockImpl));
-    if (NULL == object ) {
-        FIXME("(%p)Error allocating memory for stateblock\n", This);
-        return E_OUTOFMEMORY;
-    }
-    TRACE("(%p) created object %p\n", This, object);
-    object->wineD3DDevice= This;
-    /** FIXME: object->parent       = parent; **/
-    object->parent       = NULL;
-    object->blockType    = WINED3DSBT_RECORDED;
-    object->ref          = 1;
-    object->lpVtbl       = &IWineD3DStateBlock_Vtbl;
 
 
-    for(i = 0; i < LIGHTMAP_SIZE; i++) {
-        list_init(&object->lightMap[i]);
-    }
+    if (This->isRecordingState) return WINED3DERR_INVALIDCALL;
 
 
-    temp_result = allocate_shader_constants(object);
-    if (WINED3D_OK != temp_result)
-        return temp_result;
+    hr = IWineD3DDeviceImpl_CreateStateBlock(iface, WINED3DSBT_RECORDED, &stateblock, NULL);
+    if (FAILED(hr)) return hr;
 
     IWineD3DStateBlock_Release((IWineD3DStateBlock*)This->updateStateBlock);
 
     IWineD3DStateBlock_Release((IWineD3DStateBlock*)This->updateStateBlock);
-    This->updateStateBlock = object;
+    This->updateStateBlock = (IWineD3DStateBlockImpl *)stateblock;
     This->isRecordingState = TRUE;
 
     This->isRecordingState = TRUE;
 
-    TRACE("(%p) recording stateblock %p\n",This , object);
+    TRACE("(%p) recording stateblock %p\n", This, stateblock);
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -4886,21 +4866,30 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW
     IWineD3DStateBlockImpl *object = This->updateStateBlock;
 
     if (!This->isRecordingState) {
     IWineD3DStateBlockImpl *object = This->updateStateBlock;
 
     if (!This->isRecordingState) {
-        FIXME("(%p) not recording! returning error\n", This);
+        WARN("(%p) not recording! returning error\n", This);
         *ppStateBlock = NULL;
         return WINED3DERR_INVALIDCALL;
     }
 
         *ppStateBlock = NULL;
         return WINED3DERR_INVALIDCALL;
     }
 
-    for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
-        if(object->changed.renderState[i]) {
-            object->contained_render_states[object->num_contained_render_states] = i;
-            object->num_contained_render_states++;
+    for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
+    {
+        DWORD map = object->changed.renderState[i];
+        for (j = 0; map; map >>= 1, ++j)
+        {
+            if (!(map & 1)) continue;
+
+            object->contained_render_states[object->num_contained_render_states++] = (i << 5) | j;
         }
     }
         }
     }
-    for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
-        if(object->changed.transform[i]) {
-            object->contained_transform_states[object->num_contained_transform_states] = i;
-            object->num_contained_transform_states++;
+
+    for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i)
+    {
+        DWORD map = object->changed.transform[i];
+        for (j = 0; map; map >>= 1, ++j)
+        {
+            if (!(map & 1)) continue;
+
+            object->contained_transform_states[object->num_contained_transform_states++] = (i << 5) | j;
         }
     }
     for(i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
         }
     }
     for(i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
@@ -4923,6 +4912,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW
             object->num_contained_vs_consts_b++;
         }
     }
             object->num_contained_vs_consts_b++;
         }
     }
+    for (i = 0; i < GL_LIMITS(pshader_constantsF); ++i)
+    {
+        if (object->changed.pixelShaderConstantsF[i])
+        {
+            object->contained_ps_consts_f[object->num_contained_ps_consts_f] = i;
+            ++object->num_contained_ps_consts_f;
+        }
+    }
     for(i = 0; i < MAX_CONST_I; i++) {
         if (object->changed.pixelShaderConstantsI & (1 << i))
         {
     for(i = 0; i < MAX_CONST_I; i++) {
         if (object->changed.pixelShaderConstantsI & (1 << i))
         {
@@ -4938,21 +4935,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW
         }
     }
     for(i = 0; i < MAX_TEXTURES; i++) {
         }
     }
     for(i = 0; i < MAX_TEXTURES; i++) {
-        for(j = 1; j <= WINED3D_HIGHEST_TEXTURE_STATE; j++) {
-            if(object->changed.textureState[i][j]) {
-                object->contained_tss_states[object->num_contained_tss_states].stage = i;
-                object->contained_tss_states[object->num_contained_tss_states].state = j;
-                object->num_contained_tss_states++;
-            }
+        DWORD map = object->changed.textureState[i];
+
+        for(j = 0; map; map >>= 1, ++j)
+        {
+            if (!(map & 1)) continue;
+
+            object->contained_tss_states[object->num_contained_tss_states].stage = i;
+            object->contained_tss_states[object->num_contained_tss_states].state = j;
+            ++object->num_contained_tss_states;
         }
     }
     for(i = 0; i < MAX_COMBINED_SAMPLERS; i++){
         }
     }
     for(i = 0; i < MAX_COMBINED_SAMPLERS; i++){
-        for (j = 1; j < WINED3D_HIGHEST_SAMPLER_STATE; j++) {
-            if(object->changed.samplerState[i][j]) {
-                object->contained_sampler_states[object->num_contained_sampler_states].stage = i;
-                object->contained_sampler_states[object->num_contained_sampler_states].state = j;
-                object->num_contained_sampler_states++;
-            }
+        DWORD map = object->changed.samplerState[i];
+
+        for (j = 0; map; map >>= 1, ++j)
+        {
+            if (!(map & 1)) continue;
+
+            object->contained_sampler_states[object->num_contained_sampler_states].stage = i;
+            object->contained_sampler_states[object->num_contained_sampler_states].state = j;
+            ++object->num_contained_sampler_states;
         }
     }
 
         }
     }
 
@@ -5255,7 +5258,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitive(IWineD3DDevice *iface, WI
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
     }
     /* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
     }
     /* Account for the loading offset due to index buffers. Instead of reloading all sources correct it with the startvertex parameter */
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, 0/* NumVertices */, -1 /* indxStart */,
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0/* NumVertices */, StartVertex /* start_idx */,
                   0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */);
     return WINED3D_OK;
 }
                   0 /* indxSize */, NULL /* indxData */, 0 /* minIndex */);
     return WINED3D_OK;
 }
@@ -5277,7 +5280,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *
          * without an index buffer set. (The first time at least...)
          * D3D8 simply dies, but I doubt it can do much harm to return
          * D3DERR_INVALIDCALL there as well. */
          * without an index buffer set. (The first time at least...)
          * D3D8 simply dies, but I doubt it can do much harm to return
          * D3DERR_INVALIDCALL there as well. */
-        ERR("(%p) : Called without a valid index buffer set, returning WINED3DERR_INVALIDCALL\n", This);
+        WARN("(%p) : Called without a valid index buffer set, returning WINED3DERR_INVALIDCALL\n", This);
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -5308,7 +5311,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
     }
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
     }
 
-    drawPrimitive(iface, PrimitiveType, primCount, 0, NumVertices, startIndex,
+    drawPrimitive(iface, PrimitiveType, primCount, NumVertices, startIndex,
                    idxStride, vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex);
 
     return WINED3D_OK;
                    idxStride, vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex);
 
     return WINED3D_OK;
@@ -5341,8 +5344,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveUP(IWineD3DDevice *iface,
     /* TODO: Only mark dirty if drawing from a different UP address */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
 
     /* TODO: Only mark dirty if drawing from a different UP address */
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
 
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* start vertex */, 0  /* NumVertices */,
-                  0 /* indxStart*/, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */);
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* NumVertices */,
+                  0 /* start_idx */, 0 /* indxSize*/, NULL /* indxData */, 0 /* indxMin */);
 
     /* MSDN specifies stream zero settings must be set to NULL */
     This->stateBlock->streamStride[0] = 0;
 
     /* MSDN specifies stream zero settings must be set to NULL */
     This->stateBlock->streamStride[0] = 0;
@@ -5395,7 +5398,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
 
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* vertexStart */, NumVertices, 0 /* indxStart */, idxStride, pIndexData, MinVertexIndex);
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, NumVertices, 0 /* start_idx */, idxStride, pIndexData, MinVertexIndex);
 
     /* MSDN specifies stream zero settings and index buffer must be set to NULL */
     This->stateBlock->streamSource[0] = NULL;
 
     /* MSDN specifies stream zero settings and index buffer must be set to NULL */
     This->stateBlock->streamSource[0] = NULL;
@@ -5426,7 +5429,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided(IWineD3DDevice *if
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
     This->stateBlock->baseVertexIndex = 0;
     This->up_strided = DrawPrimStrideData;
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
     This->stateBlock->baseVertexIndex = 0;
     This->up_strided = DrawPrimStrideData;
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, 0, NULL, 0);
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0);
     This->up_strided = NULL;
     return WINED3D_OK;
 }
     This->up_strided = NULL;
     return WINED3D_OK;
 }
@@ -5448,7 +5451,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDev
     This->stateBlock->streamIsUP = TRUE;
     This->stateBlock->baseVertexIndex = 0;
     This->up_strided = DrawPrimStrideData;
     This->stateBlock->streamIsUP = TRUE;
     This->stateBlock->baseVertexIndex = 0;
     This->up_strided = DrawPrimStrideData;
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* startvertexidx */, 0 /* numindices */, 0 /* startidx */, idxSize, pIndexData, 0 /* minindex */);
+    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* numindices */, 0 /* start_idx */, idxSize, pIndexData, 0 /* minindex */);
     This->up_strided = NULL;
     return WINED3D_OK;
 }
     This->up_strided = NULL;
     return WINED3D_OK;
 }
@@ -5912,12 +5915,10 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
 
     ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
 
 
     ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
 
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        ENTER_GL();
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
-        checkGLcall("glActiveTextureARB");
-        LEAVE_GL();
-    }
+    ENTER_GL();
+    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
+    checkGLcall("glActiveTextureARB");
+    LEAVE_GL();
 
     /* Make sure the surface is loaded and up to date */
     IWineD3DSurface_PreLoad(pDestinationSurface);
 
     /* Make sure the surface is loaded and up to date */
     IWineD3DSurface_PreLoad(pDestinationSurface);
@@ -6787,10 +6788,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
                 }
 
                 /* Make sure that a proper texture unit is selected */
                 }
 
                 /* Make sure that a proper texture unit is selected */
-                if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-                    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
-                    checkGLcall("glActiveTextureARB");
-                }
+                GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
+                checkGLcall("glActiveTextureARB");
                 sampler = This->rev_tex_unit_map[0];
                 if (sampler != -1) {
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
                 sampler = This->rev_tex_unit_map[0];
                 if (sampler != -1) {
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
@@ -7214,16 +7213,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
        (pPresentationParameters->BackBufferWidth != swapchain->presentParms.BackBufferWidth ||
         pPresentationParameters->BackBufferHeight != swapchain->presentParms.BackBufferHeight))
     {
        (pPresentationParameters->BackBufferWidth != swapchain->presentParms.BackBufferWidth ||
         pPresentationParameters->BackBufferHeight != swapchain->presentParms.BackBufferHeight))
     {
-        WINED3DVIEWPORT vp;
         UINT i;
 
         UINT i;
 
-        vp.X = 0;
-        vp.Y = 0;
-        vp.Width = pPresentationParameters->BackBufferWidth;
-        vp.Height = pPresentationParameters->BackBufferHeight;
-        vp.MinZ = 0;
-        vp.MaxZ = 1;
-
         if(!pPresentationParameters->Windowed) {
             DisplayModeChanged = TRUE;
         }
         if(!pPresentationParameters->Windowed) {
             DisplayModeChanged = TRUE;
         }
@@ -7237,10 +7228,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         if(This->auto_depth_stencil_buffer) {
             updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters);
         }
         if(This->auto_depth_stencil_buffer) {
             updateSurfaceDesc((IWineD3DSurfaceImpl *)This->auto_depth_stencil_buffer, pPresentationParameters);
         }
-
-
-        /* Now set the new viewport */
-        IWineD3DDevice_SetViewport(iface, &vp);
     }
 
     if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) ||
     }
 
     if((pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) ||
@@ -7281,6 +7268,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         This->exStyle = exStyle;
     }
 
         This->exStyle = exStyle;
     }
 
+    TRACE("Resetting stateblock\n");
+    IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock);
+    IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
+
+    /* Note: No parent needed for initial internal stateblock */
+    hr = IWineD3DDevice_CreateStateBlock(iface, WINED3DSBT_INIT, (IWineD3DStateBlock **)&This->stateBlock, NULL);
+    if (FAILED(hr)) ERR("Resetting the stateblock failed with error 0x%08x\n", hr);
+    else TRACE("Created stateblock %p\n", This->stateBlock);
+    This->updateStateBlock = This->stateBlock;
+    IWineD3DStateBlock_AddRef((IWineD3DStateBlock *)This->updateStateBlock);
+
     hr = IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *) This->stateBlock);
     if(FAILED(hr)) {
         ERR("Resetting the stateblock failed with error 0x%08x\n", hr);
     hr = IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *) This->stateBlock);
     if(FAILED(hr)) {
         ERR("Resetting the stateblock failed with error 0x%08x\n", hr);
@@ -7441,7 +7439,6 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
         /* TODO: nothing really? */
         break;
         case WINED3DRTYPE_VERTEXBUFFER:
         /* TODO: nothing really? */
         break;
         case WINED3DRTYPE_VERTEXBUFFER:
-        /* MSDN: When an application no longer holds a references to this interface, the interface will automatically be freed. */
         {
             int streamNumber;
             TRACE("Cleaning up stream pointers\n");
         {
             int streamNumber;
             TRACE("Cleaning up stream pointers\n");
@@ -7467,7 +7464,6 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
         }
         break;
         case WINED3DRTYPE_INDEXBUFFER:
         }
         break;
         case WINED3DRTYPE_INDEXBUFFER:
-        /* MSDN: When an application no longer holds a references to this interface, the interface will automatically be freed.*/
         if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */
             if (This->updateStateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) {
                 This->updateStateBlock->pIndexData =  NULL;
         if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */
             if (This->updateStateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) {
                 This->updateStateBlock->pIndexData =  NULL;
@@ -7571,8 +7567,6 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_GetCurrentTexturePalette,
     IWineD3DDeviceImpl_SetDepthStencilSurface,
     IWineD3DDeviceImpl_GetDepthStencilSurface,
     IWineD3DDeviceImpl_GetCurrentTexturePalette,
     IWineD3DDeviceImpl_SetDepthStencilSurface,
     IWineD3DDeviceImpl_GetDepthStencilSurface,
-    IWineD3DDeviceImpl_SetFVF,
-    IWineD3DDeviceImpl_GetFVF,
     IWineD3DDeviceImpl_SetGammaRamp,
     IWineD3DDeviceImpl_GetGammaRamp,
     IWineD3DDeviceImpl_SetIndices,
     IWineD3DDeviceImpl_SetGammaRamp,
     IWineD3DDeviceImpl_GetGammaRamp,
     IWineD3DDeviceImpl_SetIndices,
@@ -7660,151 +7654,6 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_EnumResources
 };
 
     IWineD3DDeviceImpl_EnumResources
 };
 
-const IWineD3DDeviceVtbl IWineD3DDevice_DirtyConst_Vtbl =
-{
-    /*** IUnknown methods ***/
-    IWineD3DDeviceImpl_QueryInterface,
-    IWineD3DDeviceImpl_AddRef,
-    IWineD3DDeviceImpl_Release,
-    /*** IWineD3DDevice methods ***/
-    IWineD3DDeviceImpl_GetParent,
-    /*** Creation methods**/
-    IWineD3DDeviceImpl_CreateVertexBuffer,
-    IWineD3DDeviceImpl_CreateIndexBuffer,
-    IWineD3DDeviceImpl_CreateStateBlock,
-    IWineD3DDeviceImpl_CreateSurface,
-    IWineD3DDeviceImpl_CreateTexture,
-    IWineD3DDeviceImpl_CreateVolumeTexture,
-    IWineD3DDeviceImpl_CreateVolume,
-    IWineD3DDeviceImpl_CreateCubeTexture,
-    IWineD3DDeviceImpl_CreateQuery,
-    IWineD3DDeviceImpl_CreateSwapChain,
-    IWineD3DDeviceImpl_CreateVertexDeclaration,
-    IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF,
-    IWineD3DDeviceImpl_CreateVertexShader,
-    IWineD3DDeviceImpl_CreatePixelShader,
-    IWineD3DDeviceImpl_CreatePalette,
-    /*** Odd functions **/
-    IWineD3DDeviceImpl_Init3D,
-    IWineD3DDeviceImpl_InitGDI,
-    IWineD3DDeviceImpl_Uninit3D,
-    IWineD3DDeviceImpl_UninitGDI,
-    IWineD3DDeviceImpl_SetMultithreaded,
-    IWineD3DDeviceImpl_EvictManagedResources,
-    IWineD3DDeviceImpl_GetAvailableTextureMem,
-    IWineD3DDeviceImpl_GetBackBuffer,
-    IWineD3DDeviceImpl_GetCreationParameters,
-    IWineD3DDeviceImpl_GetDeviceCaps,
-    IWineD3DDeviceImpl_GetDirect3D,
-    IWineD3DDeviceImpl_GetDisplayMode,
-    IWineD3DDeviceImpl_SetDisplayMode,
-    IWineD3DDeviceImpl_GetNumberOfSwapChains,
-    IWineD3DDeviceImpl_GetRasterStatus,
-    IWineD3DDeviceImpl_GetSwapChain,
-    IWineD3DDeviceImpl_Reset,
-    IWineD3DDeviceImpl_SetDialogBoxMode,
-    IWineD3DDeviceImpl_SetCursorProperties,
-    IWineD3DDeviceImpl_SetCursorPosition,
-    IWineD3DDeviceImpl_ShowCursor,
-    IWineD3DDeviceImpl_TestCooperativeLevel,
-    /*** Getters and setters **/
-    IWineD3DDeviceImpl_SetClipPlane,
-    IWineD3DDeviceImpl_GetClipPlane,
-    IWineD3DDeviceImpl_SetClipStatus,
-    IWineD3DDeviceImpl_GetClipStatus,
-    IWineD3DDeviceImpl_SetCurrentTexturePalette,
-    IWineD3DDeviceImpl_GetCurrentTexturePalette,
-    IWineD3DDeviceImpl_SetDepthStencilSurface,
-    IWineD3DDeviceImpl_GetDepthStencilSurface,
-    IWineD3DDeviceImpl_SetFVF,
-    IWineD3DDeviceImpl_GetFVF,
-    IWineD3DDeviceImpl_SetGammaRamp,
-    IWineD3DDeviceImpl_GetGammaRamp,
-    IWineD3DDeviceImpl_SetIndices,
-    IWineD3DDeviceImpl_GetIndices,
-    IWineD3DDeviceImpl_SetBaseVertexIndex,
-    IWineD3DDeviceImpl_GetBaseVertexIndex,
-    IWineD3DDeviceImpl_SetLight,
-    IWineD3DDeviceImpl_GetLight,
-    IWineD3DDeviceImpl_SetLightEnable,
-    IWineD3DDeviceImpl_GetLightEnable,
-    IWineD3DDeviceImpl_SetMaterial,
-    IWineD3DDeviceImpl_GetMaterial,
-    IWineD3DDeviceImpl_SetNPatchMode,
-    IWineD3DDeviceImpl_GetNPatchMode,
-    IWineD3DDeviceImpl_SetPaletteEntries,
-    IWineD3DDeviceImpl_GetPaletteEntries,
-    IWineD3DDeviceImpl_SetPixelShader,
-    IWineD3DDeviceImpl_GetPixelShader,
-    IWineD3DDeviceImpl_SetPixelShaderConstantB,
-    IWineD3DDeviceImpl_GetPixelShaderConstantB,
-    IWineD3DDeviceImpl_SetPixelShaderConstantI,
-    IWineD3DDeviceImpl_GetPixelShaderConstantI,
-    IWineD3DDeviceImpl_SetPixelShaderConstantF_DirtyConst,
-    IWineD3DDeviceImpl_GetPixelShaderConstantF,
-    IWineD3DDeviceImpl_SetRenderState,
-    IWineD3DDeviceImpl_GetRenderState,
-    IWineD3DDeviceImpl_SetRenderTarget,
-    IWineD3DDeviceImpl_GetRenderTarget,
-    IWineD3DDeviceImpl_SetFrontBackBuffers,
-    IWineD3DDeviceImpl_SetSamplerState,
-    IWineD3DDeviceImpl_GetSamplerState,
-    IWineD3DDeviceImpl_SetScissorRect,
-    IWineD3DDeviceImpl_GetScissorRect,
-    IWineD3DDeviceImpl_SetSoftwareVertexProcessing,
-    IWineD3DDeviceImpl_GetSoftwareVertexProcessing,
-    IWineD3DDeviceImpl_SetStreamSource,
-    IWineD3DDeviceImpl_GetStreamSource,
-    IWineD3DDeviceImpl_SetStreamSourceFreq,
-    IWineD3DDeviceImpl_GetStreamSourceFreq,
-    IWineD3DDeviceImpl_SetTexture,
-    IWineD3DDeviceImpl_GetTexture,
-    IWineD3DDeviceImpl_SetTextureStageState,
-    IWineD3DDeviceImpl_GetTextureStageState,
-    IWineD3DDeviceImpl_SetTransform,
-    IWineD3DDeviceImpl_GetTransform,
-    IWineD3DDeviceImpl_SetVertexDeclaration,
-    IWineD3DDeviceImpl_GetVertexDeclaration,
-    IWineD3DDeviceImpl_SetVertexShader,
-    IWineD3DDeviceImpl_GetVertexShader,
-    IWineD3DDeviceImpl_SetVertexShaderConstantB,
-    IWineD3DDeviceImpl_GetVertexShaderConstantB,
-    IWineD3DDeviceImpl_SetVertexShaderConstantI,
-    IWineD3DDeviceImpl_GetVertexShaderConstantI,
-    IWineD3DDeviceImpl_SetVertexShaderConstantF_DirtyConst,
-    IWineD3DDeviceImpl_GetVertexShaderConstantF,
-    IWineD3DDeviceImpl_SetViewport,
-    IWineD3DDeviceImpl_GetViewport,
-    IWineD3DDeviceImpl_MultiplyTransform,
-    IWineD3DDeviceImpl_ValidateDevice,
-    IWineD3DDeviceImpl_ProcessVertices,
-    /*** State block ***/
-    IWineD3DDeviceImpl_BeginStateBlock,
-    IWineD3DDeviceImpl_EndStateBlock,
-    /*** Scene management ***/
-    IWineD3DDeviceImpl_BeginScene,
-    IWineD3DDeviceImpl_EndScene,
-    IWineD3DDeviceImpl_Present,
-    IWineD3DDeviceImpl_Clear,
-    /*** Drawing ***/
-    IWineD3DDeviceImpl_DrawPrimitive,
-    IWineD3DDeviceImpl_DrawIndexedPrimitive,
-    IWineD3DDeviceImpl_DrawPrimitiveUP,
-    IWineD3DDeviceImpl_DrawIndexedPrimitiveUP,
-    IWineD3DDeviceImpl_DrawPrimitiveStrided,
-    IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided,
-    IWineD3DDeviceImpl_DrawRectPatch,
-    IWineD3DDeviceImpl_DrawTriPatch,
-    IWineD3DDeviceImpl_DeletePatch,
-    IWineD3DDeviceImpl_ColorFill,
-    IWineD3DDeviceImpl_UpdateTexture,
-    IWineD3DDeviceImpl_UpdateSurface,
-    IWineD3DDeviceImpl_GetFrontBufferData,
-    /*** object tracking ***/
-    IWineD3DDeviceImpl_ResourceReleased,
-    IWineD3DDeviceImpl_EnumResources
-};
-
 const DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
     WINED3DRS_ALPHABLENDENABLE   ,
     WINED3DRS_ALPHAFUNC          ,
 const DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
     WINED3DRS_ALPHABLENDENABLE   ,
     WINED3DRS_ALPHAFUNC          ,
@@ -7844,7 +7693,6 @@ const DWORD SavedPixelStates_R[NUM_SAVEDPIXELSTATES_R] = {
 };
 
 const DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
 };
 
 const DWORD SavedPixelStates_T[NUM_SAVEDPIXELSTATES_T] = {
-    WINED3DTSS_ADDRESSW              ,
     WINED3DTSS_ALPHAARG0             ,
     WINED3DTSS_ALPHAARG1             ,
     WINED3DTSS_ALPHAARG2             ,
     WINED3DTSS_ALPHAARG0             ,
     WINED3DTSS_ALPHAARG1             ,
     WINED3DTSS_ALPHAARG2             ,
index 253860f..a78f4e5 100644 (file)
@@ -82,6 +82,7 @@ static const struct {
     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   MAKEDWORD_VERSION(2, 0)     },
     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   MAKEDWORD_VERSION(2, 0)     },
     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
+    {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG,                 0                           },
     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
@@ -109,9 +110,11 @@ static const struct {
     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
+    {"GL_EXT_texture_swizzle",              EXT_TEXTURE_SWIZZLE,            0                           },
     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
     {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD,                0                           },
     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
     {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD,                0                           },
     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
+    {"GL_EXT_vertex_array_bgra",            EXT_VERTEX_ARRAY_BGRA,          0                           },
     {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER,              0                           },
     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS,     0                           },
 
     {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER,              0                           },
     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS,     0                           },
 
@@ -187,7 +190,6 @@ glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
 glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
 glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
 glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
 glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
 glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
 glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
-glAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED];
 
 /**
  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
 
 /**
  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
@@ -519,8 +521,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     ENTER_GL();
 
     gl_string = (const char *) glGetString(GL_RENDERER);
     ENTER_GL();
 
     gl_string = (const char *) glGetString(GL_RENDERER);
-    if (NULL == gl_string)
-       gl_string = "None";
+    if (!gl_string) gl_string = "None";
     strcpy(gl_info->gl_renderer, gl_string);
 
     gl_string = (const char *) glGetString(GL_VENDOR);
     strcpy(gl_info->gl_renderer, gl_string);
 
     gl_string = (const char *) glGetString(GL_VENDOR);
@@ -715,7 +716,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     gl_info->max_texture_stages = 1;
     gl_info->max_fragment_samplers = 1;
     gl_info->max_vertex_samplers = 0;
     gl_info->max_texture_stages = 1;
     gl_info->max_fragment_samplers = 1;
     gl_info->max_vertex_samplers = 0;
-    gl_info->max_combined_samplers = 0;
+    gl_info->max_combined_samplers = gl_info->max_fragment_samplers + gl_info->max_vertex_samplers;
     gl_info->max_sampler_stages = 1;
     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
     gl_info->ps_arb_max_temps = 0;
     gl_info->max_sampler_stages = 1;
     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
     gl_info->ps_arb_max_temps = 0;
@@ -743,7 +744,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     gl_info->max_texture_size = gl_max;
     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
 
     gl_info->max_texture_size = gl_max;
     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
 
-    glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
+    glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
     gl_info->max_pointsizemin = gl_floatv[0];
     gl_info->max_pointsize = gl_floatv[1];
     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
     gl_info->max_pointsizemin = gl_floatv[0];
     gl_info->max_pointsize = gl_floatv[1];
     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
@@ -1303,7 +1304,8 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
             }
             break;
         case VENDOR_INTEL:
             }
             break;
         case VENDOR_INTEL:
-            if (strstr(gl_info->gl_renderer, "GMA 950")) {
+            if (strstr(gl_info->gl_renderer, "GMA 950") ||
+                strstr(gl_info->gl_renderer, "945GM")) {
                 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
                 gl_info->gl_card = CARD_INTEL_I945GM;
                 vidmem = 64;
                 /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
                 gl_info->gl_card = CARD_INTEL_I945GM;
                 vidmem = 64;
@@ -2361,6 +2363,10 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE
 
         case WINED3DFMT_G16R16F:
         case WINED3DFMT_G32R32F:
 
         case WINED3DFMT_G16R16F:
         case WINED3DFMT_G32R32F:
+            if(GL_SUPPORT(ARB_TEXTURE_RG)) {
+                TRACE_(d3d_caps)("[OK]\n");
+                return TRUE;
+            }
             TRACE_(d3d_caps)("[FAILED]\n");
             return FALSE;
 
             TRACE_(d3d_caps)("[FAILED]\n");
             return FALSE;
 
@@ -3146,11 +3152,11 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
     }
                         /* FIXME Add:
         pCaps->RasterCaps         |= WINED3DPRASTERCAPS_FOGRANGE;
     }
                         /* FIXME Add:
-                          WINED3DPRASTERCAPS_COLORPERSPECTIVE
-                          WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
-                          WINED3DPRASTERCAPS_ANTIALIASEDGES
-                          WINED3DPRASTERCAPS_ZBUFFERLESSHSR
-                          WINED3DPRASTERCAPS_WBUFFER */
+                           WINED3DPRASTERCAPS_COLORPERSPECTIVE
+                           WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
+                           WINED3DPRASTERCAPS_ANTIALIASEDGES
+                           WINED3DPRASTERCAPS_ZBUFFERLESSHSR
+                           WINED3DPRASTERCAPS_WBUFFER */
 
     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
                       WINED3DPCMPCAPS_EQUAL        |
 
     pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS       |
                       WINED3DPCMPCAPS_EQUAL        |
@@ -3616,16 +3622,17 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
 
 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
    and fields being inserted in the middle, a new structure is used in place    */
 
 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
    and fields being inserted in the middle, a new structure is used in place    */
-static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
-                                           DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
-                                           IUnknown *parent) {
-
+static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
+        WINED3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviourFlags, IUnknown *parent,
+        IWineD3DDeviceParent *device_parent, IWineD3DDevice **ppReturnedDeviceInterface)
+{
     IWineD3DDeviceImpl *object  = NULL;
     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
     WINED3DDISPLAYMODE  mode;
     const struct fragment_pipeline *frag_pipeline = NULL;
     int i;
     struct fragment_caps ffp_caps;
     IWineD3DDeviceImpl *object  = NULL;
     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
     WINED3DDISPLAYMODE  mode;
     const struct fragment_pipeline *frag_pipeline = NULL;
     int i;
     struct fragment_caps ffp_caps;
+    HRESULT hr;
 
     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
      * number and create a device without a 3D adapter for 2D only operation.
 
     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
      * number and create a device without a 3D adapter for 2D only operation.
@@ -3649,6 +3656,7 @@ static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
     IWineD3D_AddRef(object->wineD3D);
     object->parent  = parent;
     object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
     IWineD3D_AddRef(object->wineD3D);
     object->parent  = parent;
+    object->device_parent = device_parent;
     list_init(&object->resources);
     list_init(&object->shaders);
 
     list_init(&object->resources);
     list_init(&object->shaders);
 
@@ -3684,19 +3692,18 @@ static HRESULT  WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
     object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
     object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
     frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
     object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
     object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
-    compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
+    hr = compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
                         ffp_vertexstate_template, frag_pipeline, misc_state_template);
 
                         ffp_vertexstate_template, frag_pipeline, misc_state_template);
 
-    object->blitter = select_blit_implementation(Adapter, DeviceType);
+    if (FAILED(hr)) {
+        IWineD3D_Release(object->wineD3D);
+        HeapFree(GetProcessHeap(), 0, object);
 
 
-    /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
-     * model can deal with that. It is essentially the same, just with adjusted
-     * Set*ShaderConstantF implementations
-     */
-    if(object->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) object)) {
-        object->lpVtbl  = &IWineD3DDevice_DirtyConst_Vtbl;
+        return hr;
     }
 
     }
 
+    object->blitter = select_blit_implementation(Adapter, DeviceType);
+
     /* set the state of the device to valid */
     object->state = WINED3D_OK;
 
     /* set the state of the device to valid */
     object->state = WINED3D_OK;
 
@@ -4155,35 +4162,11 @@ static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = invalid_texcoord_func;
         multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = 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]      = (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]   = (glAttribFunc)GL_EXTCALL(glTexCoord2hvNV);
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = (glAttribFunc)GL_EXTCALL(glTexCoord4hvNV);
-    } else {
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2]   = invalid_func;
-        texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4]   = invalid_func;
-    }
 }
 
 #define PUSH1(att)        attribs[nAttribs++] = (att);
 BOOL InitAdapters(void) {
 }
 
 #define PUSH1(att)        attribs[nAttribs++] = (att);
 BOOL InitAdapters(void) {
-    static HMODULE mod_gl, mod_win32gl;
+    static HMODULE mod_gl;
     BOOL ret;
     int ps_selected_mode, vs_selected_mode;
 
     BOOL ret;
     int ps_selected_mode, vs_selected_mode;
 
@@ -4202,16 +4185,10 @@ BOOL InitAdapters(void) {
             ERR("Can't load opengl32.dll!\n");
             goto nogl_adapter;
         }
             ERR("Can't load opengl32.dll!\n");
             goto nogl_adapter;
         }
-        mod_win32gl = mod_gl;
 #else
 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
         mod_gl = GetModuleHandleA("gdi32.dll");
 #else
 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
         mod_gl = GetModuleHandleA("gdi32.dll");
-        mod_win32gl = LoadLibraryA("opengl32.dll");
-        if(!mod_win32gl) {
-            ERR("Can't load opengl32.dll!\n");
-            goto nogl_adapter;
-        }
 #endif
     }
 
 #endif
     }
 
@@ -4232,8 +4209,16 @@ BOOL InitAdapters(void) {
     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
      * otherwise because we have to use winex11.drv's override
      */
     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
      * otherwise because we have to use winex11.drv's override
      */
-    glFinish = (void*)GetProcAddress(mod_win32gl, "glFinish");
-    glFlush = (void*)GetProcAddress(mod_win32gl, "glFlush");
+#ifdef USE_WIN32_OPENGL
+    glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
+    glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
+#else
+    glFinish = (void*)pwglGetProcAddress("wglFinish");
+    glFlush = (void*)pwglGetProcAddress("wglFlush");
+#endif
+
+    glEnableWINE = glEnable;
+    glDisableWINE = glDisable;
 
     /* For now only one default adapter */
     {
 
     /* For now only one default adapter */
     {
@@ -4376,6 +4361,7 @@ BOOL InitAdapters(void) {
         }
 
         fixup_extensions(&Adapters[0].gl_info);
         }
 
         fixup_extensions(&Adapters[0].gl_info);
+        add_gl_compat_wrappers(&Adapters[0].gl_info);
 
         WineD3D_ReleaseFakeGLContext();
 
 
         WineD3D_ReleaseFakeGLContext();
 
index 7603103..b78078f 100644 (file)
@@ -152,12 +152,13 @@ void primitiveDeclarationConvertToStridedData(
     const DWORD *streams = vertexDeclaration->streams;
 
     /* Check for transformed vertices, disable vertex shader if present */
     const DWORD *streams = vertexDeclaration->streams;
 
     /* Check for transformed vertices, disable vertex shader if present */
-    strided->u.s.position_transformed = vertexDeclaration->position_transformed;
+    strided->position_transformed = vertexDeclaration->position_transformed;
     if(vertexDeclaration->position_transformed) {
         useVertexShaderFunction = FALSE;
     }
 
     /* Translate the declaration into strided data */
     if(vertexDeclaration->position_transformed) {
         useVertexShaderFunction = FALSE;
     }
 
     /* Translate the declaration into strided data */
+    strided->swizzle_map = 0;
     for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
         GLint streamVBO = 0;
         BOOL stride_used;
     for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
         GLint streamVBO = 0;
         BOOL stride_used;
@@ -201,8 +202,8 @@ void primitiveDeclarationConvertToStridedData(
                         element->Usage == WINED3DDECLUSAGE_POSITIONT)) {
                     static BOOL warned = FALSE;
                     if(!warned) {
                         element->Usage == WINED3DDECLUSAGE_POSITIONT)) {
                     static BOOL warned = FALSE;
                     if(!warned) {
-                       /* This may be bad with the fixed function pipeline */
-                       FIXME("Missing vbo streams with unfixed colors or transformed position, expect problems\n");
+                        /* This may be bad with the fixed function pipeline */
+                        FIXME("Missing vbo streams with unfixed colors or transformed position, expect problems\n");
                         warned = TRUE;
                     }
                 }
                         warned = TRUE;
                     }
                 }
@@ -234,6 +235,11 @@ void primitiveDeclarationConvertToStridedData(
                 strided->u.input[idx].dwStride = stride;
                 strided->u.input[idx].VBO = streamVBO;
                 strided->u.input[idx].streamNo = element->Stream;
                 strided->u.input[idx].dwStride = stride;
                 strided->u.input[idx].VBO = streamVBO;
                 strided->u.input[idx].streamNo = element->Stream;
+                if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->Type == WINED3DDECLTYPE_D3DCOLOR)
+                {
+                    strided->swizzle_map |= 1 << idx;
+                }
+                strided->use_map |= 1 << idx;
             }
         }
     }
             }
         }
     }
@@ -253,32 +259,35 @@ void primitiveDeclarationConvertToStridedData(
     }
 }
 
     }
 }
 
-static void drawStridedFast(IWineD3DDevice *iface,UINT numberOfVertices, GLenum glPrimitiveType,
-                     const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex) {
+static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
+        UINT min_vertex_idx, UINT max_vertex_idx, UINT count, short idx_size,
+        const void *idx_data, UINT start_idx)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
-    if (idxSize != 0 /* This crashes sometimes!*/) {
-        TRACE("(%p) : glElements(%x, %d, %d, ...)\n", This, glPrimitiveType, numberOfVertices, minIndex);
-        idxData = idxData == (void *)-1 ? NULL : idxData;
+    if (idx_size)
+    {
+        TRACE("(%p) : glElements(%x, %d, %d, ...)\n", This, primitive_type, count, min_vertex_idx);
+
 #if 1
 #if 1
-        glDrawElements(glPrimitiveType, numberOfVertices, idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
-                     (const char *)idxData+(idxSize * startIdx));
+        glDrawElements(primitive_type, count,
+                idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
+                (const char *)idx_data + (idx_size * start_idx));
         checkGLcall("glDrawElements");
         checkGLcall("glDrawElements");
-#else /* using drawRangeElements may be faster */
-
-        glDrawRangeElements(glPrimitiveType, minIndex, minIndex + numberOfVertices - 1, numberOfVertices,
-                      idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
-                      (const char *)idxData+(idxSize * startIdx));
+#else
+        glDrawRangeElements(primitive_type, min_vertex_idx, max_vertex_idx, count,
+                idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
+                (const char *)idx_data + (idx_size * start_idx));
         checkGLcall("glDrawRangeElements");
 #endif
         checkGLcall("glDrawRangeElements");
 #endif
+    }
+    else
+    {
+        TRACE("(%p) : glDrawArrays(%#x, %d, %d)\n", This, primitive_type, start_idx, count);
 
 
-    } else {
-        TRACE("(%p) : glDrawArrays(%#x, %d, %d)\n", This, glPrimitiveType, startVertex, numberOfVertices);
-        glDrawArrays(glPrimitiveType, startVertex, numberOfVertices);
+        glDrawArrays(primitive_type, start_idx, count);
         checkGLcall("glDrawArrays");
     }
         checkGLcall("glDrawArrays");
     }
-
-    return;
 }
 
 /*
 }
 
 /*
@@ -287,7 +296,7 @@ static void drawStridedFast(IWineD3DDevice *iface,UINT numberOfVertices, GLenum
  */
 
 static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT NumVertexes,
  */
 
 static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT NumVertexes,
-        GLenum glPrimType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex)
+        GLenum glPrimType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx)
 {
     unsigned int               textureNo    = 0;
     const WORD                *pIdxBufS     = NULL;
 {
     unsigned int               textureNo    = 0;
     const WORD                *pIdxBufS     = NULL;
@@ -295,8 +304,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
     ULONG                      vx_index;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const UINT *streamOffset = This->stateBlock->streamOffset;
     ULONG                      vx_index;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const UINT *streamOffset = This->stateBlock->streamOffset;
-    long                      SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
-    BOOL                      pixelShader = use_ps(This);
+    long                      SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
+    BOOL                      pixelShader = use_ps(This->stateBlock);
     BOOL specular_fog = FALSE;
     UINT texture_stages = GL_LIMITS(texture_stages);
     const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
     BOOL specular_fog = FALSE;
     UINT texture_stages = GL_LIMITS(texture_stages);
     const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
@@ -440,21 +449,15 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
         {
             int coord_idx;
             const void *ptr;
         {
             int coord_idx;
             const void *ptr;
+            int texture_idx;
 
             if (!(tmp_tex_mask & 1)) continue;
 
             coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX];
             ptr = texCoords[coord_idx] + (SkipnStrides * sd->u.s.texCoords[coord_idx].dwStride);
 
 
             if (!(tmp_tex_mask & 1)) continue;
 
             coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX];
             ptr = texCoords[coord_idx] + (SkipnStrides * sd->u.s.texCoords[coord_idx].dwStride);
 
-            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);
-            }
-            else
-            {
-                texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](ptr);
-            }
+            texture_idx = This->texUnitMap[texture];
+            multi_texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](GL_TEXTURE0_ARB + texture_idx, ptr);
         }
 
         /* Diffuse -------------------------------- */
         }
 
         /* Diffuse -------------------------------- */
@@ -603,10 +606,10 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
 }
 
 static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT numberOfVertices,
 }
 
 static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT numberOfVertices,
-        GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx, ULONG startVertex)
+        GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    long                      SkipnStrides = startVertex + This->stateBlock->loadBaseVertexIndex;
+    long                      SkipnStrides = startIdx + This->stateBlock->loadBaseVertexIndex;
     const WORD                *pIdxBufS     = NULL;
     const DWORD               *pIdxBufL     = NULL;
     ULONG                      vx_index;
     const WORD                *pIdxBufS     = NULL;
     const DWORD               *pIdxBufL     = NULL;
     ULONG                      vx_index;
@@ -664,7 +667,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr
 
 static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd,
         UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex,
 
 static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd,
         UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, short idxSize, ULONG minIndex,
-        ULONG startIdx, ULONG startVertex)
+        ULONG startIdx)
 {
     UINT numInstances = 0, i;
     int numInstancedAttribs = 0, j;
 {
     UINT numInstances = 0, i;
     int numInstancedAttribs = 0, j;
@@ -684,7 +687,6 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3
     }
 
     TRACE("(%p) : glElements(%x, %d, %d, ...)\n", This, glPrimitiveType, numberOfVertices, minIndex);
     }
 
     TRACE("(%p) : glElements(%x, %d, %d, ...)\n", This, glPrimitiveType, numberOfVertices, minIndex);
-    idxData = idxData == (void *)-1 ? NULL : idxData;
 
     /* First, figure out how many instances we have to draw */
     for(i = 0; i < MAX_STREAMS; i++) {
 
     /* First, figure out how many instances we have to draw */
     for(i = 0; i < MAX_STREAMS; i++) {
@@ -817,16 +819,9 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStrid
 }
 
 /* Routine common to the draw primitive and draw indexed primitive routines */
 }
 
 /* Routine common to the draw primitive and draw indexed primitive routines */
-void drawPrimitive(IWineD3DDevice *iface,
-                   int PrimitiveType,
-                   long NumPrimitives,
-                   /* for Indexed: */
-                   long  StartVertexIndex,
-                   UINT  numberOfVertices,
-                   long  StartIdx,
-                   short idxSize,
-                   const void *idxData,
-                   int   minIndex) {
+void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives,
+        UINT numberOfVertices, long StartIdx, short idxSize, const void *idxData, int minIndex)
+{
 
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl          *target;
 
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl          *target;
@@ -869,9 +864,11 @@ void drawPrimitive(IWineD3DDevice *iface,
         if (numberOfVertices == 0 )
             numberOfVertices = calculatedNumberOfindices;
 
         if (numberOfVertices == 0 )
             numberOfVertices = calculatedNumberOfindices;
 
-        if(!use_vs(This)) {
-            if(!This->strided_streams.u.s.position_transformed && This->activeContext->num_untracked_materials &&
-                This->stateBlock->renderState[WINED3DRS_LIGHTING]) {
+        if (!use_vs(This->stateBlock))
+        {
+            if (!This->strided_streams.position_transformed && This->activeContext->num_untracked_materials
+                    && This->stateBlock->renderState[WINED3DRS_LIGHTING])
+            {
                 static BOOL warned;
                 if (!warned) {
                     FIXME("Using software emulation because not all material properties could be tracked\n");
                 static BOOL warned;
                 if (!warned) {
                     FIXME("Using software emulation because not all material properties could be tracked\n");
@@ -904,7 +901,8 @@ void drawPrimitive(IWineD3DDevice *iface,
 
         if (This->useDrawStridedSlow || emulation) {
             /* Immediate mode drawing */
 
         if (This->useDrawStridedSlow || emulation) {
             /* Immediate mode drawing */
-            if(use_vs(This)) {
+            if (use_vs(This->stateBlock))
+            {
                 static BOOL warned;
                 if (!warned) {
                     FIXME("Using immediate mode with vertex shaders for half float emulation\n");
                 static BOOL warned;
                 if (!warned) {
                     FIXME("Using immediate mode with vertex shaders for half float emulation\n");
@@ -912,19 +910,19 @@ void drawPrimitive(IWineD3DDevice *iface,
                 } else {
                     TRACE("Using immediate mode with vertex shaders for half float emulation\n");
                 }
                 } else {
                     TRACE("Using immediate mode with vertex shaders for half float emulation\n");
                 }
-                drawStridedSlowVs(iface, strided, calculatedNumberOfindices, glPrimType,
-                                  idxData, idxSize, minIndex, StartIdx, StartVertexIndex);
+                drawStridedSlowVs(iface, strided, calculatedNumberOfindices,
+                        glPrimType, idxData, idxSize, minIndex, StartIdx);
             } else {
                 drawStridedSlow(iface, strided, calculatedNumberOfindices,
             } else {
                 drawStridedSlow(iface, strided, calculatedNumberOfindices,
-                                glPrimType, idxData, idxSize, minIndex, StartIdx, StartVertexIndex);
+                        glPrimType, idxData, idxSize, minIndex, StartIdx);
             }
         } else if(This->instancedDraw) {
             /* Instancing emulation with mixing immediate mode and arrays */
             drawStridedInstanced(iface, &This->strided_streams, calculatedNumberOfindices, glPrimType,
             }
         } else if(This->instancedDraw) {
             /* Instancing emulation with mixing immediate mode and arrays */
             drawStridedInstanced(iface, &This->strided_streams, calculatedNumberOfindices, glPrimType,
-                            idxData, idxSize, minIndex, StartIdx, StartVertexIndex);
+                            idxData, idxSize, minIndex, StartIdx);
         } else {
         } else {
-            drawStridedFast(iface, calculatedNumberOfindices, glPrimType,
-                            idxData, idxSize, minIndex, StartIdx, StartVertexIndex);
+            drawStridedFast(iface, glPrimType, minIndex, minIndex + numberOfVertices - 1,
+                    calculatedNumberOfindices, idxSize, idxData, StartIdx);
         }
     }
 
         }
     }
 
@@ -1035,9 +1033,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
            vtxStride * info->StartVertexOffsetWidth;
 
     /* Not entirely sure about what happens with transformed vertices */
            vtxStride * info->StartVertexOffsetWidth;
 
     /* Not entirely sure about what happens with transformed vertices */
-    if(strided.u.s.position_transformed) {
-        FIXME("Transformed position in rectpatch generation\n");
-    }
+    if (strided.position_transformed) FIXME("Transformed position in rectpatch generation\n");
+
     if(vtxStride % sizeof(GLfloat)) {
         /* glMap2f reads vertex sizes in GLfloats, the d3d stride is in bytes.
          * I don't see how the stride could not be a multiple of 4, but make sure
     if(vtxStride % sizeof(GLfloat)) {
         /* glMap2f reads vertex sizes in GLfloats, the d3d stride is in bytes.
          * I don't see how the stride could not be a multiple of 4, but make sure
@@ -1092,11 +1089,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) {
     checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FILLMODE));
     if(patch->has_normals) {
-        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};
+        static const GLfloat black[] = {0, 0, 0, 0};
+        static const GLfloat red[]   = {1, 0, 0, 0};
+        static const GLfloat green[] = {0, 1, 0, 0};
+        static const GLfloat blue[]  = {0, 0, 1, 0};
+        static const GLfloat white[] = {1, 1, 1, 1};
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
@@ -1263,9 +1260,9 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
 
     if(patch->has_normals) {
         /* Now do the same with reverse light directions */
 
     if(patch->has_normals) {
         /* Now do the same with reverse light directions */
-        const GLfloat x[4] = {-1,  0,  0, 0};
-        const GLfloat y[4] = { 0, -1,  0, 0};
-        const GLfloat z[4] = { 0,  0, -1, 0};
+        static const GLfloat x[] = {-1,  0,  0, 0};
+        static const GLfloat y[] = { 0, -1,  0, 0};
+        static const GLfloat z[] = { 0,  0, -1, 0};
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
diff --git a/reactos/dll/directx/wine/wined3d/gl_compat.c b/reactos/dll/directx/wine/wined3d/gl_compat.c
new file mode 100644 (file)
index 0000000..1fc48cc
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * Compatibility functions for older GL implementations
+ *
+ * Copyright 2008 Stefan Dösinger for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gl_compat);
+
+/* Start GL_ARB_multitexture emulation */
+static void WINE_GLAPI wine_glMultiTexCoord1fARB(GLenum target, GLfloat s) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord1f(s);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord1fvARB(GLenum target, const GLfloat *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord1fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord2f(s, t);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2fvARB(GLenum target, const GLfloat *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord2fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord3f(s, t, r);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord3fvARB(GLenum target, const GLfloat *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord3fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord4f(s, t, r, q);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4fvARB(GLenum target, const GLfloat *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord4fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2svARB(GLenum target, const GLshort *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord2sv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *v) {
+    if(target != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+    glTexCoord4sv(v);
+}
+
+static void WINE_GLAPI wine_glActiveTextureARB(GLenum texture) {
+    if(texture != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+}
+
+static void WINE_GLAPI wine_glClientActiveTextureARB(GLenum texture) {
+    if(texture != GL_TEXTURE0) {
+        ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+        return;
+    }
+}
+
+static void (WINE_GLAPI *old_multitex_glGetIntegerv) (GLenum pname, GLint* params) = NULL;
+static void WINE_GLAPI wine_glGetIntegerv(GLenum pname, GLint* params) {
+    switch(pname) {
+        case GL_ACTIVE_TEXTURE:         *params = 0;    break;
+        case GL_MAX_TEXTURE_UNITS_ARB:  *params = 1;    break;
+        default: old_multitex_glGetIntegerv(pname, params);
+    }
+}
+
+static void (WINE_GLAPI *old_multitex_glGetFloatv) (GLenum pname, GLfloat* params) = NULL;
+static void WINE_GLAPI wine_glGetFloatv(GLenum pname, GLfloat* params) {
+    if(pname == GL_ACTIVE_TEXTURE) *params = 0.0;
+    else old_multitex_glGetFloatv(pname, params);
+}
+
+static void (WINE_GLAPI *old_multitex_glGetDoublev) (GLenum pname, GLdouble* params) = NULL;
+static void WINE_GLAPI wine_glGetDoublev(GLenum pname, GLdouble* params) {
+    if(pname == GL_ACTIVE_TEXTURE) *params = 0.0;
+    else old_multitex_glGetDoublev(pname, params);
+}
+
+/* Start GL_EXT_fogcoord emulation */
+static void (WINE_GLAPI *old_fogcoord_glEnable) (GLenum cap) = NULL;
+static void WINE_GLAPI wine_glEnable(GLenum cap) {
+    if(cap == GL_FOG) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->fog_enabled = 1;
+        if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
+    }
+    old_fogcoord_glEnable(cap);
+}
+
+static void (WINE_GLAPI *old_fogcoord_glDisable) (GLenum cap) = NULL;
+static void WINE_GLAPI wine_glDisable(GLenum cap) {
+    if(cap == GL_FOG) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->fog_enabled = 0;
+        if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
+    }
+    old_fogcoord_glDisable(cap);
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogi) (GLenum pname, GLint param) = NULL;
+static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
+    if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->gl_fog_source = param;
+        if(param == GL_FRAGMENT_DEPTH_EXT) {
+            if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+        } else {
+            WARN("Fog coords activated, but not supported. Using slow emulation\n");
+            old_fogcoord_glDisable(GL_FOG);
+        }
+    } else {
+        if(pname == GL_FOG_START) {
+            getActiveContext()->fogstart = param;
+        } else if(pname == GL_FOG_END) {
+            getActiveContext()->fogend = param;
+        }
+        old_fogcoord_glFogi(pname, param);
+    }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogiv) (GLenum pname, const GLint *param) = NULL;
+static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
+    if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->gl_fog_source = *param;
+        if(*param == GL_FRAGMENT_DEPTH_EXT) {
+            if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+        } else {
+            WARN("Fog coords activated, but not supported. Using slow emulation\n");
+            old_fogcoord_glDisable(GL_FOG);
+        }
+    } else {
+        if(pname == GL_FOG_START) {
+            getActiveContext()->fogstart = *param;
+        } else if(pname == GL_FOG_END) {
+            getActiveContext()->fogend = *param;
+        }
+        old_fogcoord_glFogiv(pname, param);
+    }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogf) (GLenum pname, GLfloat param) = NULL;
+static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
+    if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->gl_fog_source = (GLint) param;
+        if(param == GL_FRAGMENT_DEPTH_EXT) {
+            if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+        } else {
+            WARN("Fog coords activated, but not supported. Using slow emulation\n");
+            old_fogcoord_glDisable(GL_FOG);
+        }
+    } else {
+        if(pname == GL_FOG_START) {
+            getActiveContext()->fogstart = param;
+        } else if(pname == GL_FOG_END) {
+            getActiveContext()->fogend = param;
+        }
+        old_fogcoord_glFogf(pname, param);
+    }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogfv) (GLenum pname, const GLfloat *param) = NULL;
+static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) {
+    if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+        WineD3DContext *ctx = getActiveContext();
+        ctx->gl_fog_source = (GLint) *param;
+        if(*param == GL_FRAGMENT_DEPTH_EXT) {
+            if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+        } else {
+            WARN("Fog coords activated, but not supported. Using slow emulation\n");
+            old_fogcoord_glDisable(GL_FOG);
+        }
+    } else {
+        if(pname == GL_FOG_COLOR) {
+            WineD3DContext *ctx = getActiveContext();
+            ctx->fogcolor[0] = param[0];
+            ctx->fogcolor[1] = param[1];
+            ctx->fogcolor[2] = param[2];
+            ctx->fogcolor[3] = param[3];
+        } else if(pname == GL_FOG_START) {
+            getActiveContext()->fogstart = *param;
+        } else if(pname == GL_FOG_END) {
+            getActiveContext()->fogend = *param;
+        }
+        old_fogcoord_glFogfv(pname, param);
+    }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glVertex4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex4fv) (const GLfloat *pos) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex3f) (GLfloat x, GLfloat y, GLfloat z) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex3fv) (const GLfloat *pos) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4f) (GLfloat r, GLfloat g, GLfloat b, GLfloat a) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4fv) (const GLfloat *color) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor3f) (GLfloat r, GLfloat g, GLfloat b) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor3fv) (const GLfloat *color) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4ub) (GLubyte r, GLubyte g, GLubyte b, GLubyte a) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoordfEXT) (GLfloat f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoorddEXT) (GLdouble f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoordfvEXT) (const GLfloat *f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoorddvEXT) (const GLdouble *f) = NULL;
+
+static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+    WineD3DContext *ctx = getActiveContext();
+    if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
+        GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
+        GLfloat i;
+
+        i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart);
+        c[0] = i * c[0] + (1.0 - i) * ctx->fogcolor[0];
+        c[1] = i * c[1] + (1.0 - i) * ctx->fogcolor[1];
+        c[2] = i * c[2] + (1.0 - i) * ctx->fogcolor[2];
+
+        old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]);
+        old_fogcoord_glVertex4f(x, y, z, w);
+    } else {
+        old_fogcoord_glVertex4f(x, y, z, w);
+    }
+}
+
+static void WINE_GLAPI wine_glVertex4fv(const GLfloat *pos) {
+    wine_glVertex4f(pos[0], pos[1], pos[2], pos[3]);
+}
+
+static void WINE_GLAPI wine_glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
+    wine_glVertex4f(x, y, z, 1.0);
+}
+
+static void WINE_GLAPI wine_glVertex3fv(const GLfloat *pos) {
+    wine_glVertex4f(pos[0], pos[1], pos[2], 1.0);
+}
+
+static void wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+    WineD3DContext *ctx = getActiveContext();
+    ctx->color[0] = r;
+    ctx->color[1] = g;
+    ctx->color[2] = b;
+    ctx->color[3] = a;
+    old_fogcoord_glColor4f(r, g, b, a);
+}
+
+static void wine_glColor4fv(const GLfloat *c) {
+    wine_glColor4f(c[0], c[1], c[2], c[3]);
+}
+
+static void wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
+    wine_glColor4f(r, g, b, 1.0);
+}
+
+static void wine_glColor3fv(const GLfloat *c) {
+    wine_glColor4f(c[0], c[1], c[2], 1.0);
+}
+
+static void wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
+    wine_glColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+}
+
+/* In D3D the fog coord is a UBYTE, so there's no problem with using the single
+ * precision function
+ */
+static void wine_glFogCoordfEXT(GLfloat f) {
+    WineD3DContext *ctx = getActiveContext();
+    ctx->fog_coord_value = f;
+}
+static void wine_glFogCoorddEXT(GLdouble f) {
+    wine_glFogCoordfEXT(f);
+}
+static void wine_glFogCoordfvEXT(const GLfloat *f) {
+    wine_glFogCoordfEXT(*f);
+}
+static void wine_glFogCoorddvEXT(const GLdouble *f) {
+    wine_glFogCoordfEXT(*f);
+}
+
+/* End GL_EXT_fog_coord emulation */
+
+#define GLINFO_LOCATION (*gl_info)
+void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info) {
+    if(!GL_SUPPORT(ARB_MULTITEXTURE)) {
+        TRACE("Applying GL_ARB_multitexture emulation hooks\n");
+        gl_info->glActiveTextureARB         = wine_glActiveTextureARB;
+        gl_info->glClientActiveTextureARB   = wine_glClientActiveTextureARB;
+        gl_info->glMultiTexCoord1fARB       = wine_glMultiTexCoord1fARB;
+        gl_info->glMultiTexCoord1fvARB      = wine_glMultiTexCoord1fvARB;
+        gl_info->glMultiTexCoord2fARB       = wine_glMultiTexCoord2fARB;
+        gl_info->glMultiTexCoord2fvARB      = wine_glMultiTexCoord2fvARB;
+        gl_info->glMultiTexCoord3fARB       = wine_glMultiTexCoord3fARB;
+        gl_info->glMultiTexCoord3fvARB      = wine_glMultiTexCoord3fvARB;
+        gl_info->glMultiTexCoord4fARB       = wine_glMultiTexCoord4fARB;
+        gl_info->glMultiTexCoord4fvARB      = wine_glMultiTexCoord4fvARB;
+        gl_info->glMultiTexCoord2svARB      = wine_glMultiTexCoord2svARB;
+        gl_info->glMultiTexCoord4svARB      = wine_glMultiTexCoord4svARB;
+        if(old_multitex_glGetIntegerv) {
+            FIXME("GL_ARB_multitexture glGetIntegerv hook already applied\n");
+        } else {
+            old_multitex_glGetIntegerv = glGetIntegerv;
+            glGetIntegerv = wine_glGetIntegerv;
+        }
+        if(old_multitex_glGetFloatv) {
+            FIXME("GL_ARB_multitexture glGetGloatv hook already applied\n");
+        } else {
+            old_multitex_glGetFloatv = glGetFloatv;
+            glGetFloatv = wine_glGetFloatv;
+        }
+        if(old_multitex_glGetDoublev) {
+            FIXME("GL_ARB_multitexture glGetDoublev hook already applied\n");
+        } else {
+            old_multitex_glGetDoublev = glGetDoublev;
+            glGetDoublev = wine_glGetDoublev;
+        }
+        gl_info->supported[ARB_MULTITEXTURE] = TRUE;
+    }
+
+    if(!GL_SUPPORT(EXT_FOG_COORD)) {
+        /* This emulation isn't perfect. There are a number of potential problems, but they should
+         * not matter in practise:
+         *
+         * Fog vs fragment shader: If we are using GL_ARB_fragment_program with the fog option, the
+         * glDisable(GL_FOG) here won't matter. However, if we have GL_ARB_fragment_program, it is pretty
+         * unlikely that we don't have GL_EXT_fog_coord. Besides, we probably have GL_ARB_vertex_program
+         * too, which would allow fog coord emulation in a fixed function vertex pipeline replacement.
+         *
+         * Fog vs texture: We apply the fog in the vertex color. An app could set up texturing settings which
+         * ignore the vertex color, thus effectively disabing our fog. However, in D3D this type of fog is
+         * a per-vertex fog too, so the apps shouldn't do that.
+         *
+         * Fog vs lighting: The app could in theory use D3DFOG_NONE table and D3DFOG_NONE vertex fog with
+         * untransformed vertices. That enables lighting and fog coords at the same time, and the lighting
+         * calculations could affect the already blended in fog color. There's nothing we can do against that,
+         * but most apps using fog color do their own lighting too and often even use RHW vertices. So live
+         * with it.
+         */
+        TRACE("Applying GL_ARB_fog_coord emulation hooks\n");
+
+        /* This probably means that the implementation doesn't advertise the extension, but implicitly supports
+         * it via the GL core version, or someone messed around in the extension table in directx.c. Add version-
+         * dependent loading for this extension if we ever hit this situation
+         */
+        if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
+            FIXME("GL implementation supports GL_ARB_fragment_program but not GL_EXT_fog_coord\n");
+            FIXME("The fog coord emulation will most likely fail\n");
+        } else if(GL_SUPPORT(ARB_FRAGMENT_SHADER)) {
+            FIXME("GL implementation supports GL_ARB_fragment_shader but not GL_EXT_fog_coord\n");
+            FIXME("The fog coord emulation will most likely fail\n");
+        }
+
+        if(old_fogcoord_glFogi) {
+            FIXME("GL_EXT_fogcoord glFogi hook already applied\n");
+        } else {
+            old_fogcoord_glFogi = glFogi;
+            glFogi = wine_glFogi;
+        }
+        if(old_fogcoord_glFogiv) {
+            FIXME("GL_EXT_fogcoord glFogiv hook already applied\n");
+        } else {
+            old_fogcoord_glFogiv = glFogiv;
+            glFogiv = wine_glFogiv;
+        }
+        if(old_fogcoord_glFogf) {
+            FIXME("GL_EXT_fogcoord glFogf hook already applied\n");
+        } else {
+            old_fogcoord_glFogf = glFogf;
+            glFogf = wine_glFogf;
+        }
+        if(old_fogcoord_glFogfv) {
+            FIXME("GL_EXT_fogcoord glFogfv hook already applied\n");
+        } else {
+            old_fogcoord_glFogfv = glFogfv;
+            glFogfv = wine_glFogfv;
+        }
+        if(old_fogcoord_glEnable) {
+            FIXME("GL_EXT_fogcoord glEnable hook already applied\n");
+        } else {
+            old_fogcoord_glEnable = glEnableWINE;
+            glEnableWINE = wine_glEnable;
+        }
+        if(old_fogcoord_glDisable) {
+            FIXME("GL_EXT_fogcoord glDisable hook already applied\n");
+        } else {
+            old_fogcoord_glDisable = glDisableWINE;
+            glDisableWINE = wine_glDisable;
+        }
+
+        if(old_fogcoord_glVertex4f) {
+            FIXME("GL_EXT_fogcoord glVertex4f hook already applied\n");
+        } else {
+            old_fogcoord_glVertex4f = glVertex4f;
+            glVertex4f = wine_glVertex4f;
+        }
+        if(old_fogcoord_glVertex4fv) {
+            FIXME("GL_EXT_fogcoord glVertex4fv hook already applied\n");
+        } else {
+            old_fogcoord_glVertex4fv = glVertex4fv;
+            glVertex4fv = wine_glVertex4fv;
+        }
+        if(old_fogcoord_glVertex3f) {
+            FIXME("GL_EXT_fogcoord glVertex3f hook already applied\n");
+        } else {
+            old_fogcoord_glVertex3f = glVertex3f;
+            glVertex3f = wine_glVertex3f;
+        }
+        if(old_fogcoord_glVertex3fv) {
+            FIXME("GL_EXT_fogcoord glVertex3fv hook already applied\n");
+        } else {
+            old_fogcoord_glVertex3fv = glVertex3fv;
+            glVertex3fv = wine_glVertex3fv;
+        }
+
+        if(old_fogcoord_glColor4f) {
+            FIXME("GL_EXT_fogcoord glColor4f hook already applied\n");
+        } else {
+            old_fogcoord_glColor4f = glColor4f;
+            glColor4f = wine_glColor4f;
+        }
+        if(old_fogcoord_glColor4fv) {
+            FIXME("GL_EXT_fogcoord glColor4fv hook already applied\n");
+        } else {
+            old_fogcoord_glColor4fv = glColor4fv;
+            glColor4fv = wine_glColor4fv;
+        }
+        if(old_fogcoord_glColor3f) {
+            FIXME("GL_EXT_fogcoord glColor3f hook already applied\n");
+        } else {
+            old_fogcoord_glColor3f = glColor3f;
+            glColor3f = wine_glColor3f;
+        }
+        if(old_fogcoord_glColor3fv) {
+            FIXME("GL_EXT_fogcoord glColor3fv hook already applied\n");
+        } else {
+            old_fogcoord_glColor3fv = glColor3fv;
+            glColor3fv = wine_glColor3fv;
+        }
+        if(old_fogcoord_glColor4ub) {
+            FIXME("GL_EXT_fogcoord glColor4ub hook already applied\n");
+        } else {
+            old_fogcoord_glColor4ub = glColor4ub;
+            glColor4ub = wine_glColor4ub;
+        }
+
+        if(old_fogcoord_glFogCoordfEXT) {
+            FIXME("GL_EXT_fogcoord glFogCoordfEXT hook already applied\n");
+        } else {
+            old_fogcoord_glFogCoordfEXT = gl_info->glFogCoordfEXT;
+            gl_info->glFogCoordfEXT = wine_glFogCoordfEXT;
+        }
+        if(old_fogcoord_glFogCoordfvEXT) {
+            FIXME("GL_EXT_fogcoord glFogCoordfvEXT hook already applied\n");
+        } else {
+            old_fogcoord_glFogCoordfvEXT = gl_info->glFogCoordfvEXT;
+            gl_info->glFogCoordfvEXT = wine_glFogCoordfvEXT;
+        }
+        if(old_fogcoord_glFogCoorddEXT) {
+            FIXME("GL_EXT_fogcoord glFogCoorddEXT hook already applied\n");
+        } else {
+            old_fogcoord_glFogCoorddEXT = gl_info->glFogCoorddEXT;
+            gl_info->glFogCoorddEXT = wine_glFogCoorddEXT;
+        }
+        if(old_fogcoord_glFogCoorddvEXT) {
+            FIXME("GL_EXT_fogcoord glFogCoorddvEXT hook already applied\n");
+        } else {
+            old_fogcoord_glFogCoorddvEXT = gl_info->glFogCoorddvEXT;
+            gl_info->glFogCoorddvEXT = wine_glFogCoorddvEXT;
+        }
+        gl_info->supported[EXT_FOG_COORD] = TRUE;
+    }
+}
+#undef GLINFO_LOCATION
index 4c1d223..8dfb416 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "config.h"
  */
 
 #include "config.h"
+#include <limits.h>
 #include <stdio.h>
 #include "wined3d_private.h"
 
 #include <stdio.h>
 #include "wined3d_private.h"
 
@@ -54,11 +55,35 @@ typedef struct {
     DWORD coord_mask;
 } glsl_sample_function_t;
 
     DWORD coord_mask;
 } glsl_sample_function_t;
 
+enum heap_node_op
+{
+    HEAP_NODE_TRAVERSE_LEFT,
+    HEAP_NODE_TRAVERSE_RIGHT,
+    HEAP_NODE_POP,
+};
+
+struct constant_entry
+{
+    unsigned int idx;
+    unsigned int version;
+};
+
+struct constant_heap
+{
+    struct constant_entry *entries;
+    unsigned int *positions;
+    unsigned int size;
+};
+
 /* GLSL shader private data */
 struct shader_glsl_priv {
     struct hash_table_t *glsl_program_lookup;
 /* GLSL shader private data */
 struct shader_glsl_priv {
     struct hash_table_t *glsl_program_lookup;
-    const struct glsl_shader_prog_link *glsl_program;
+    struct glsl_shader_prog_link *glsl_program;
+    struct constant_heap vconst_heap;
+    struct constant_heap pconst_heap;
+    unsigned char *stack;
     GLhandleARB depth_blt_program[tex_type_count];
     GLhandleARB depth_blt_program[tex_type_count];
+    UINT next_constant_version;
 };
 
 /* Struct to maintain data about a linked GLSL program */
 };
 
 /* Struct to maintain data about a linked GLSL program */
@@ -79,6 +104,7 @@ struct glsl_shader_prog_link {
     GLhandleARB                 vshader;
     IWineD3DPixelShader         *pshader;
     struct ps_compile_args      ps_args;
     GLhandleARB                 vshader;
     IWineD3DPixelShader         *pshader;
     struct ps_compile_args      ps_args;
+    UINT                        constant_version;
 };
 
 typedef struct {
 };
 
 typedef struct {
@@ -96,19 +122,23 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
     unsigned int i;
     BOOL is_spam;
 
     unsigned int i;
     BOOL is_spam;
 
-    const char *spam[] = {
+    static const char * const spam[] =
+    {
         "Vertex shader was successfully compiled to run on hardware.\n",    /* fglrx          */
         "Fragment shader was successfully compiled to run on hardware.\n",  /* fglrx          */
         "Fragment shader(s) linked, vertex shader(s) linked. \n ",          /* fglrx, with \n */
         "Fragment shader(s) linked, vertex shader(s) linked.",              /* fglrx, no \n   */
         "Vertex shader(s) linked, no fragment shader(s) defined. \n ",      /* fglrx, with \n */
         "Vertex shader(s) linked, no fragment shader(s) defined.",          /* fglrx, no \n   */
         "Vertex shader was successfully compiled to run on hardware.\n",    /* fglrx          */
         "Fragment shader was successfully compiled to run on hardware.\n",  /* fglrx          */
         "Fragment shader(s) linked, vertex shader(s) linked. \n ",          /* fglrx, with \n */
         "Fragment shader(s) linked, vertex shader(s) linked.",              /* fglrx, no \n   */
         "Vertex shader(s) linked, no fragment shader(s) defined. \n ",      /* fglrx, with \n */
         "Vertex shader(s) linked, no fragment shader(s) defined.",          /* fglrx, no \n   */
-        "Fragment shader was successfully compiled to run on hardware.\nWARNING: 0:1: extension 'GL_ARB_draw_buffers' is not supported",
+        "Fragment shader was successfully compiled to run on hardware.\n"
+        "WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported",
         "Fragment shader(s) linked, no vertex shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader(s) linked, no vertex shader(s) defined. \n ",      /* fglrx, with \n */
         "WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported\n"  /* MacOS ati      */
     };
 
         "Fragment shader(s) linked, no vertex shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader(s) linked, no vertex shader(s) defined. \n ",      /* fglrx, with \n */
         "WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported\n"  /* MacOS ati      */
     };
 
+    if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
+
     GL_EXTCALL(glGetObjectParameterivARB(obj,
                GL_OBJECT_INFO_LOG_LENGTH_ARB,
                &infologLength));
     GL_EXTCALL(glGetObjectParameterivARB(obj,
                GL_OBJECT_INFO_LOG_LENGTH_ARB,
                &infologLength));
@@ -188,106 +218,166 @@ static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, IWineD3DS
     }
 }
 
     }
 }
 
-/** 
- * 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, const WineD3D_GL_Info *gl_info,
-        unsigned int max_constants, const float *constants, const GLhandleARB *constant_locations,
-        const struct list *constant_list)
+static inline void walk_constant_heap(const WineD3D_GL_Info *gl_info, const float *constants,
+        const GLhandleARB *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
 {
 {
-    const constants_entry *constant;
-    const local_constant *lconst;
-    GLhandleARB tmp_loc;
-    DWORD i, j, k;
-    const DWORD *idx;
-
-    if (TRACE_ON(d3d_shader)) {
-        LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) {
-            idx = constant->idx;
-            j = constant->count;
-            while (j--) {
-                i = *idx++;
-                tmp_loc = constant_locations[i];
-                if (tmp_loc != -1) {
-                    TRACE_(d3d_constants)("Loading constants %i: %f, %f, %f, %f\n", i,
-                            constants[i * 4 + 0], constants[i * 4 + 1],
-                            constants[i * 4 + 2], constants[i * 4 + 3]);
+    int stack_idx = 0;
+    unsigned int heap_idx = 1;
+    unsigned int idx;
+
+    if (heap->entries[heap_idx].version <= version) return;
+
+    idx = heap->entries[heap_idx].idx;
+    if (constant_locations[idx] != -1) GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+
+    while (stack_idx >= 0)
+    {
+        /* Note that we fall through to the next case statement. */
+        switch(stack[stack_idx])
+        {
+            case HEAP_NODE_TRAVERSE_LEFT:
+            {
+                unsigned int left_idx = heap_idx << 1;
+                if (left_idx < heap->size && heap->entries[left_idx].version > version)
+                {
+                    heap_idx = left_idx;
+                    idx = heap->entries[heap_idx].idx;
+                    if (constant_locations[idx] != -1)
+                        GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+
+                    stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
+                    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+                    break;
                 }
             }
                 }
             }
+
+            case HEAP_NODE_TRAVERSE_RIGHT:
+            {
+                unsigned int right_idx = (heap_idx << 1) + 1;
+                if (right_idx < heap->size && heap->entries[right_idx].version > version)
+                {
+                    heap_idx = right_idx;
+                    idx = heap->entries[heap_idx].idx;
+                    if (constant_locations[idx] != -1)
+                        GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+
+                    stack[stack_idx++] = HEAP_NODE_POP;
+                    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+                    break;
+                }
+            }
+
+            case HEAP_NODE_POP:
+            {
+                heap_idx >>= 1;
+                --stack_idx;
+                break;
+            }
         }
     }
         }
     }
+    checkGLcall("walk_constant_heap()");
+}
 
 
-    /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
-    if(WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1 &&
-       shader_is_pshader_version(This->baseShader.hex_version)) {
-        float lcl_const[4];
-
-        LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) {
-            idx = constant->idx;
-            j = constant->count;
-            while (j--) {
-                i = *idx++;
-                tmp_loc = constant_locations[i];
-                if (tmp_loc != -1) {
-                    /* We found this uniform name in the program - go ahead and send the data */
-                    k = i * 4;
-                    if(constants[k + 0] < -1.0) lcl_const[0] = -1.0;
-                    else if(constants[k + 0] > 1.0) lcl_const[0] = 1.0;
-                    else lcl_const[0] = constants[k + 0];
-                    if(constants[k + 1] < -1.0) lcl_const[1] = -1.0;
-                    else if(constants[k + 1] > 1.0) lcl_const[1] = 1.0;
-                    else lcl_const[1] = constants[k + 1];
-                    if(constants[k + 2] < -1.0) lcl_const[2] = -1.0;
-                    else if(constants[k + 2] > 1.0) lcl_const[2] = 1.0;
-                    else lcl_const[2] = constants[k + 2];
-                    if(constants[k + 3] < -1.0) lcl_const[3] = -1.0;
-                    else if(constants[k + 3] > 1.0) lcl_const[3] = 1.0;
-                    else lcl_const[3] = constants[k + 3];
-
-                    GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, lcl_const));
+static inline void apply_clamped_constant(const WineD3D_GL_Info *gl_info, GLint location, const GLfloat *data)
+{
+    GLfloat clamped_constant[4];
+
+    if (location == -1) return;
+
+    clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0 ? 1.0 : data[0];
+    clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0 ? 1.0 : data[1];
+    clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0 ? 1.0 : data[2];
+    clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0 ? 1.0 : data[3];
+
+    GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
+}
+
+static inline void walk_constant_heap_clamped(const WineD3D_GL_Info *gl_info, const float *constants,
+        const GLhandleARB *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
+{
+    int stack_idx = 0;
+    unsigned int heap_idx = 1;
+    unsigned int idx;
+
+    if (heap->entries[heap_idx].version <= version) return;
+
+    idx = heap->entries[heap_idx].idx;
+    apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+
+    while (stack_idx >= 0)
+    {
+        /* Note that we fall through to the next case statement. */
+        switch(stack[stack_idx])
+        {
+            case HEAP_NODE_TRAVERSE_LEFT:
+            {
+                unsigned int left_idx = heap_idx << 1;
+                if (left_idx < heap->size && heap->entries[left_idx].version > version)
+                {
+                    heap_idx = left_idx;
+                    idx = heap->entries[heap_idx].idx;
+                    apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+
+                    stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
+                    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+                    break;
                 }
             }
                 }
             }
-        }
-    } else {
-        LIST_FOR_EACH_ENTRY(constant, constant_list, constants_entry, entry) {
-            idx = constant->idx;
-            j = constant->count;
-            while (j--) {
-                i = *idx++;
-                tmp_loc = constant_locations[i];
-                if (tmp_loc != -1) {
-                    /* We found this uniform name in the program - go ahead and send the data */
-                    GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, constants + (i * 4)));
+
+            case HEAP_NODE_TRAVERSE_RIGHT:
+            {
+                unsigned int right_idx = (heap_idx << 1) + 1;
+                if (right_idx < heap->size && heap->entries[right_idx].version > version)
+                {
+                    heap_idx = right_idx;
+                    idx = heap->entries[heap_idx].idx;
+                    apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+
+                    stack[stack_idx++] = HEAP_NODE_POP;
+                    stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+                    break;
                 }
             }
                 }
             }
+
+            case HEAP_NODE_POP:
+            {
+                heap_idx >>= 1;
+                --stack_idx;
+                break;
+            }
         }
     }
         }
     }
-    checkGLcall("glUniform4fvARB()");
+    checkGLcall("walk_constant_heap_clamped()");
+}
 
 
-    if(!This->baseShader.load_local_constsF) {
+/* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
+static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+        const float *constants, const GLhandleARB *constant_locations, const struct constant_heap *heap,
+        unsigned char *stack, UINT version)
+{
+    const local_constant *lconst;
+
+    /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
+    if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.reg_maps.shader_version) == 1
+            && shader_is_pshader_version(This->baseShader.reg_maps.shader_version))
+        walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
+    else
+        walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
+
+    if (!This->baseShader.load_local_constsF)
+    {
         TRACE("No need to load local float constants for this shader\n");
         return;
     }
 
         TRACE("No need to load local float constants for this shader\n");
         return;
     }
 
-    /* Load immediate constants */
-    if (TRACE_ON(d3d_shader)) {
-        LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-            tmp_loc = constant_locations[lconst->idx];
-            if (tmp_loc != -1) {
-                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]);
-            }
-        }
-    }
     /* Immediate constants are clamped to [-1;1] at shader creation time if needed */
     /* Immediate constants are clamped to [-1;1] at shader creation time if needed */
-    LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-        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, (const GLfloat *)lconst->value));
-        }
+    LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry)
+    {
+        GLhandleARB location = constant_locations[lconst->idx];
+        /* We found this uniform name in the program - go ahead and send the data */
+        if (location != -1) GL_EXTCALL(glUniform4fvARB(location, 1, (const GLfloat *)lconst->value));
     }
     checkGLcall("glUniform4fvARB()");
 }
     }
     checkGLcall("glUniform4fvARB()");
 }
@@ -335,7 +425,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine
     GLhandleARB tmp_loc;
     unsigned int i;
     char tmp_name[8];
     GLhandleARB tmp_loc;
     unsigned int i;
     char tmp_name[8];
-    char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
+    char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
     const char* prefix = is_pshader? "PB":"VB";
     struct list* ptr;
 
     const char* prefix = is_pshader? "PB":"VB";
     struct list* ptr;
 
@@ -379,7 +469,11 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine
     }
 }
 
     }
 }
 
-
+static void reset_program_constant_version(void *value, void *context)
+{
+    struct glsl_shader_prog_link *entry = (struct glsl_shader_prog_link *)value;
+    entry->constant_version = 0;
+}
 
 /**
  * Loads the app-supplied constants into the currently set GLSL program.
 
 /**
  * Loads the app-supplied constants into the currently set GLSL program.
@@ -390,14 +484,13 @@ static void shader_glsl_load_constants(
     char useVertexShader) {
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
     char useVertexShader) {
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
-    const struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv;
+    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv;
     IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
     const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
 
     IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
     const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
 
-    const GLhandleARB *constant_locations;
-    const struct list *constant_list;
     GLhandleARB programId;
     GLhandleARB programId;
-    const struct glsl_shader_prog_link *prog = priv->glsl_program;
+    struct glsl_shader_prog_link *prog = priv->glsl_program;
+    UINT constant_version;
     int i;
 
     if (!prog) {
     int i;
 
     if (!prog) {
@@ -405,24 +498,26 @@ static void shader_glsl_load_constants(
         return;
     }
     programId = prog->programId;
         return;
     }
     programId = prog->programId;
+    constant_version = prog->constant_version;
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
 
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
 
-        constant_locations = prog->vuniformF_locations;
-        constant_list = &stateBlock->set_vconstantsF;
-
         /* Load DirectX 9 float constants/uniforms for vertex shader */
         /* Load DirectX 9 float constants/uniforms for vertex shader */
-        shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
-                stateBlock->vertexShaderConstantF, constant_locations, constant_list);
+        shader_glsl_load_constantsF(vshader, gl_info, stateBlock->vertexShaderConstantF,
+                prog->vuniformF_locations, &priv->vconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
-        shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations,
-                stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI);
+        if(vshader->baseShader.uses_int_consts) {
+            shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations,
+                    stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI);
+        }
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
-        shader_glsl_load_constantsB(vshader, gl_info, programId,
-                stateBlock->vertexShaderConstantB, stateBlock->changed.vertexShaderConstantsB);
+        if(vshader->baseShader.uses_bool_consts) {
+            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]));
 
         /* Upload the position fixup params */
         GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
@@ -433,20 +528,21 @@ static void shader_glsl_load_constants(
 
         IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
 
 
         IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
 
-        constant_locations = prog->puniformF_locations;
-        constant_list = &stateBlock->set_pconstantsF;
-
         /* Load DirectX 9 float constants/uniforms for pixel shader */
         /* Load DirectX 9 float constants/uniforms for pixel shader */
-        shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF),
-                stateBlock->pixelShaderConstantF, constant_locations, constant_list);
+        shader_glsl_load_constantsF(pshader, gl_info, stateBlock->pixelShaderConstantF,
+                prog->puniformF_locations, &priv->pconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
-        shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations,
-                stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI);
+        if(pshader->baseShader.uses_int_consts) {
+            shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations,
+                    stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI);
+        }
 
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
 
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
-        shader_glsl_load_constantsB(pshader, gl_info, programId,
-                stateBlock->pixelShaderConstantB, stateBlock->changed.pixelShaderConstantsB);
+        if(pshader->baseShader.uses_bool_consts) {
+            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.
 
         /* 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.
@@ -486,19 +582,87 @@ static void shader_glsl_load_constants(
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
     }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
     }
+
+    if (priv->next_constant_version == UINT_MAX)
+    {
+        TRACE("Max constant version reached, resetting to 0.\n");
+        hash_table_for_each_entry(priv->glsl_program_lookup, reset_program_constant_version, NULL);
+        priv->next_constant_version = 1;
+    }
+    else
+    {
+        prog->constant_version = priv->next_constant_version++;
+    }
+}
+
+static inline void update_heap_entry(struct constant_heap *heap, unsigned int idx,
+        unsigned int heap_idx, DWORD new_version)
+{
+    struct constant_entry *entries = heap->entries;
+    unsigned int *positions = heap->positions;
+    unsigned int parent_idx;
+
+    while (heap_idx > 1)
+    {
+        parent_idx = heap_idx >> 1;
+
+        if (new_version <= entries[parent_idx].version) break;
+
+        entries[heap_idx] = entries[parent_idx];
+        positions[entries[parent_idx].idx] = heap_idx;
+        heap_idx = parent_idx;
+    }
+
+    entries[heap_idx].version = new_version;
+    entries[heap_idx].idx = idx;
+    positions[idx] = heap_idx;
+}
+
+static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
+    struct constant_heap *heap = &priv->vconst_heap;
+    UINT i;
+
+    for (i = start; i < count + start; ++i)
+    {
+        if (!This->stateBlock->changed.vertexShaderConstantsF[i])
+            update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
+        else
+            update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+    }
+}
+
+static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
+    struct constant_heap *heap = &priv->pconst_heap;
+    UINT i;
+
+    for (i = start; i < count + start; ++i)
+    {
+        if (!This->stateBlock->changed.pixelShaderConstantsF[i])
+            update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
+        else
+            update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+    }
 }
 
 /** Generate the variable & register declarations for the GLSL output target */
 static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
 }
 
 /** Generate the variable & register declarations for the GLSL output target */
 static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
-        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
+        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info,
+        const struct ps_compile_args *ps_args)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+    DWORD shader_version = reg_maps->shader_version;
     unsigned int i, extra_constants_needed = 0;
     const local_constant *lconst;
 
     /* There are some minor differences between pixel and vertex shaders */
     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);
+    char pshader = shader_is_pshader_version(shader_version);
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
@@ -532,7 +696,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
          * out. The nvidia driver only does that if the parameter is inout instead of out, hence the
          * inout.
          */
          * out. The nvidia driver only does that if the parameter is inout instead of out, hence the
          * inout.
          */
-        if(This->baseShader.hex_version >= WINED3DVS_VERSION(3, 0)) {
+        if (shader_version >= WINED3DVS_VERSION(3, 0))
+        {
             shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
         } else {
             shader_addline(buffer, "void order_ps_input();\n");
             shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
         } else {
             shader_addline(buffer, "void order_ps_input();\n");
@@ -562,7 +727,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
             ps_impl->numbumpenvmatconsts++;
         }
 
             ps_impl->numbumpenvmatconsts++;
         }
 
-        if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
+        if(ps_args->srgb_correction) {
             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",
             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",
@@ -633,8 +798,10 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
      * helper function shader that is linked in at link time
      */
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
      * helper function shader that is linked in at link time
      */
-    if(pshader && This->baseShader.hex_version >= WINED3DPS_VERSION(3, 0)) {
-        if(use_vs(device)) {
+    if (pshader && shader_version >= WINED3DPS_VERSION(3, 0))
+    {
+        if (use_vs(device->stateBlock))
+        {
             shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
         } else {
             /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed.
             shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
         } else {
             /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed.
@@ -803,8 +970,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
-
-    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+    DWORD shader_version = This->baseShader.reg_maps.shader_version;
+    char pshader = shader_is_pshader_version(shader_version);
     char tmpStr[150];
 
     *is_color = FALSE;   
     char tmpStr[150];
 
     *is_color = FALSE;   
@@ -816,7 +983,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
     case WINED3DSPR_INPUT:
         if (pshader) {
             /* Pixel shaders >= 3.0 */
     case WINED3DSPR_INPUT:
         if (pshader) {
             /* Pixel shaders >= 3.0 */
-            if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) {
+            if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3)
+            {
                 DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
                 if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
                 DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
                 if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
@@ -862,8 +1030,7 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
                     strcpy(tmpStr, "gl_SecondaryColor");
             }
         } else {
                     strcpy(tmpStr, "gl_SecondaryColor");
             }
         } else {
-            if (vshader_input_is_color((IWineD3DVertexShader*) This, reg))
-               *is_color = TRUE;
+            if (((IWineD3DVertexShaderImpl *)This)->swizzle_map & (1 << reg)) *is_color = TRUE;
             sprintf(tmpStr, "attrib%u", reg);
         } 
         break;
             sprintf(tmpStr, "attrib%u", reg);
         } 
         break;
@@ -876,7 +1043,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
 
            /* Relative addressing on shaders 2.0+ have a relative address token, 
             * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
 
            /* Relative addressing on shaders 2.0+ have a relative address token, 
             * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
-           if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2)  {
+           if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
+           {
                glsl_src_param_t rel_param;
                shader_glsl_add_src_param(arg, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
                if(reg) {
                glsl_src_param_t rel_param;
                shader_glsl_add_src_param(arg, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
                if(reg) {
@@ -955,10 +1123,8 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
     break;
     case WINED3DSPR_TEXCRDOUT:
         /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
     break;
     case WINED3DSPR_TEXCRDOUT:
         /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
-        if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3)
-            sprintf(tmpStr, "OUT[%u]", reg);
-        else
-            sprintf(tmpStr, "gl_TexCoord[%u]", reg);
+        if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(tmpStr, "OUT[%u]", reg);
+        else sprintf(tmpStr, "gl_TexCoord[%u]", reg);
     break;
     case WINED3DSPR_MISCTYPE:
         if (reg == 0) {
     break;
     case WINED3DSPR_MISCTYPE:
         if (reg == 0) {
@@ -1307,7 +1473,6 @@ static void shader_glsl_arith(const SHADER_OPCODE_ARG *arg)
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg)
 {
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 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;
     DWORD write_mask;
     SHADER_BUFFER* buffer = arg->buffer;
     glsl_src_param_t src0_param;
     DWORD write_mask;
@@ -1317,9 +1482,10 @@ static void shader_glsl_mov(const SHADER_OPCODE_ARG *arg)
 
     /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
      * shader versions WINED3DSIO_MOVA is used for this. */
 
     /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
      * shader versions WINED3DSIO_MOVA is used for this. */
-    if ((WINED3DSHADER_VERSION_MAJOR(shader->baseShader.hex_version) == 1 &&
-            !shader_is_pshader_version(shader->baseShader.hex_version) &&
-            shader_get_regtype(arg->dst) == WINED3DSPR_ADDR)) {
+    if ((WINED3DSHADER_VERSION_MAJOR(arg->reg_maps->shader_version) == 1
+            && !shader_is_pshader_version(arg->reg_maps->shader_version)
+            && shader_get_regtype(arg->dst) == WINED3DSPR_ADDR))
+    {
         /* This is a simple floor() */
         unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
         if (mask_size > 1) {
         /* This is a simple floor() */
         unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
         if (mask_size > 1) {
@@ -1487,12 +1653,12 @@ static void shader_glsl_map2gl(const SHADER_OPCODE_ARG *arg)
  */
 static void shader_glsl_expp(const 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;
 
     shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
 
     glsl_src_param_t src_param;
 
     shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
 
-    if (shader->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
+    if (arg->reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+    {
         char dst_mask[6];
 
         shader_addline(arg->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
         char dst_mask[6];
 
         shader_addline(arg->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
@@ -1683,14 +1849,14 @@ static void shader_glsl_cmp(const SHADER_OPCODE_ARG *arg)
  * the compare is done per component of src0. */
 static void shader_glsl_cnd(const SHADER_OPCODE_ARG *arg)
 {
  * the compare is done per component of src0. */
 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;
     glsl_src_param_t src2_param;
     DWORD write_mask, cmp_channel = 0;
     unsigned int i, j;
 
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
     DWORD write_mask, cmp_channel = 0;
     unsigned int i, j;
 
-    if (shader->baseShader.hex_version < WINED3DPS_VERSION(1, 4)) {
+    if (arg->reg_maps->shader_version < WINED3DPS_VERSION(1, 4))
+    {
         write_mask = shader_glsl_append_dst(arg->buffer, arg);
         shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
         shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param);
         write_mask = shader_glsl_append_dst(arg->buffer, arg);
         shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
         shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], write_mask, &src1_param);
@@ -1749,7 +1915,7 @@ static void shader_glsl_mnxn(const SHADER_OPCODE_ARG *arg)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
     const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)arg->shader;
     const SHADER_OPCODE *opcode_table = shader->baseShader.shader_ins;
-    DWORD shader_version = shader->baseShader.hex_version;
+    DWORD shader_version = arg->reg_maps->shader_version;
     int i;
     int nComponents = 0;
     SHADER_OPCODE_ARG tmpArg;
     int i;
     int nComponents = 0;
     SHADER_OPCODE_ARG tmpArg;
@@ -2085,7 +2251,7 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
 {
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 {
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-    DWORD hex_version = This->baseShader.hex_version;
+    DWORD shader_version = arg->reg_maps->shader_version;
     char dst_swizzle[6];
     glsl_sample_function_t sample_function;
     DWORD sampler_type;
     char dst_swizzle[6];
     glsl_sample_function_t sample_function;
     DWORD sampler_type;
@@ -2098,14 +2264,12 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
-    if (hex_version < WINED3DPS_VERSION(2,0)) {
-        sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
-    } else {
-        sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
-    }
+    if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK;
+    else sampler_idx = arg->src[1] & WINED3DSP_REGNUM_MASK;
     sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
 
     sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
 
-    if (hex_version < WINED3DPS_VERSION(1,4)) {
+    if (shader_version < WINED3DPS_VERSION(1,4))
+    {
         DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
         /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
         DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
         /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
@@ -2121,7 +2285,9 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
         } else {
             projected = FALSE;
         }
         } else {
             projected = FALSE;
         }
-    } else if (hex_version < WINED3DPS_VERSION(2,0)) {
+    }
+    else if (shader_version < WINED3DPS_VERSION(2,0))
+    {
         DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
 
         if (src_mod == WINED3DSPSM_DZ) {
         DWORD src_mod = arg->src[0] & WINED3DSP_SRCMOD_MASK;
 
         if (src_mod == WINED3DSPSM_DZ) {
@@ -2151,15 +2317,13 @@ static void pshader_glsl_tex(const SHADER_OPCODE_ARG *arg)
     shader_glsl_get_sample_function(sampler_type, projected, texrect, &sample_function);
     mask |= sample_function.coord_mask;
 
     shader_glsl_get_sample_function(sampler_type, projected, texrect, &sample_function);
     mask |= sample_function.coord_mask;
 
-    if (hex_version < WINED3DPS_VERSION(2,0)) {
-        shader_glsl_get_write_mask(arg->dst, dst_swizzle);
-    } else {
-        shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle);
-    }
+    if (shader_version < WINED3DPS_VERSION(2,0)) shader_glsl_get_write_mask(arg->dst, dst_swizzle);
+    else shader_glsl_get_swizzle(arg->src[1], FALSE, arg->dst, dst_swizzle);
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
-    if (hex_version < WINED3DPS_VERSION(1,4)) {
+    if (shader_version < WINED3DPS_VERSION(1,4))
+    {
         char coord_mask[6];
         shader_glsl_get_write_mask(mask, coord_mask);
         shader_addline(arg->buffer, "%s(Psampler%u, T%u%s)%s);\n",
         char coord_mask[6];
         shader_glsl_get_write_mask(mask, coord_mask);
         shader_addline(arg->buffer, "%s(Psampler%u, T%u%s)%s);\n",
@@ -2205,7 +2369,8 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
 
     shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
 
     shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
-    if (shader_is_pshader_version(This->baseShader.hex_version)) {
+    if (shader_is_pshader_version(arg->reg_maps->shader_version))
+    {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
         WARN("Using %sLod in fragment shader.\n", sample_function.name);
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
         WARN("Using %sLod in fragment shader.\n", sample_function.name);
@@ -2220,17 +2385,15 @@ static void shader_glsl_texldl(const SHADER_OPCODE_ARG *arg)
 static void pshader_glsl_texcoord(const SHADER_OPCODE_ARG *arg)
 {
     /* FIXME: Make this work for more than just 2D textures */
 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;
     SHADER_BUFFER* buffer = arg->buffer;
     SHADER_BUFFER* buffer = arg->buffer;
-    DWORD hex_version = This->baseShader.hex_version;
     DWORD write_mask;
     char dst_mask[6];
 
     write_mask = shader_glsl_append_dst(arg->buffer, arg);
     shader_glsl_get_write_mask(write_mask, dst_mask);
 
     DWORD write_mask;
     char dst_mask[6];
 
     write_mask = shader_glsl_append_dst(arg->buffer, arg);
     shader_glsl_get_write_mask(write_mask, dst_mask);
 
-    if (hex_version != WINED3DPS_VERSION(1,4)) {
+    if (arg->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+    {
         DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
         shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask);
     } else {
         DWORD reg = arg->dst & WINED3DSP_REGNUM_MASK;
         shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask);
     } else {
@@ -2654,13 +2817,12 @@ static void pshader_glsl_texreg2rgb(const SHADER_OPCODE_ARG *arg)
  * If any of the first 3 components are < 0, discard this pixel */
 static void pshader_glsl_texkill(const SHADER_OPCODE_ARG *arg)
 {
  * If any of the first 3 components are < 0, discard this pixel */
 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;
 
     /* The argument is a destination parameter, and no writemasks are allowed */
     shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
     glsl_dst_param_t dst_param;
 
     /* The argument is a destination parameter, and no writemasks are allowed */
     shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
-    if((hex_version >= WINED3DPS_VERSION(2,0))) {
+    if ((arg->reg_maps->shader_version >= WINED3DPS_VERSION(2,0)))
+    {
         /* 2.0 shaders compare all 4 components in texkill */
         shader_addline(arg->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
     } else {
         /* 2.0 shaders compare all 4 components in texkill */
         shader_addline(arg->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
     } else {
@@ -2948,8 +3110,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
     IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
     IWineD3DDeviceImpl *device;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
     IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
     IWineD3DDeviceImpl *device;
-    DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.hex_version);
-    DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.hex_version) : 0;
+    DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.reg_maps.shader_version);
+    DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0;
     unsigned int i;
     SHADER_BUFFER buffer;
     DWORD usage_token;
     unsigned int i;
     SHADER_BUFFER buffer;
     DWORD usage_token;
@@ -2958,10 +3120,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     char reg_mask[6];
     const struct semantic *semantics_out, *semantics_in;
 
     char reg_mask[6];
     const struct semantic *semantics_out, *semantics_in;
 
-    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
-    buffer.bsize = 0;
-    buffer.lineNo = 0;
-    buffer.newline = TRUE;
+    shader_buffer_init(&buffer);
 
     shader_addline(&buffer, "#version 120\n");
 
 
     shader_addline(&buffer, "#version 120\n");
 
@@ -3093,7 +3252,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     GL_EXTCALL(glCompileShaderARB(ret));
     checkGLcall("glCompileShaderARB(ret)");
 
     GL_EXTCALL(glCompileShaderARB(ret));
     checkGLcall("glCompileShaderARB(ret)");
 
-    HeapFree(GetProcessHeap(), 0, buffer.buffer);
+    shader_buffer_free(&buffer);
     return ret;
 }
 
     return ret;
 }
 
@@ -3164,6 +3323,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     entry->vshader = vshader_id;
     entry->pshader = pshader;
     entry->ps_args = compile_args;
     entry->vshader = vshader_id;
     entry->pshader = pshader;
     entry->ps_args = compile_args;
+    entry->constant_version = 0;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
 
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
 
@@ -3264,8 +3424,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
     checkGLcall("Find glsl program uniform locations");
 
     entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
     checkGLcall("Find glsl program uniform locations");
 
-    if (pshader && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.hex_version) >= 3
-            && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4) {
+    if (pshader
+            && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version) >= 3
+            && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
+    {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
     } else {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
     } else {
@@ -3309,7 +3471,8 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
-    const char *blt_vshader[] = {
+    static const char *blt_vshader[] =
+    {
         "#version 120\n"
         "void main(void)\n"
         "{\n"
         "#version 120\n"
         "void main(void)\n"
         "{\n"
@@ -3319,7 +3482,8 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t
         "}\n"
     };
 
         "}\n"
     };
 
-    const char *blt_pshaders[tex_type_count] = {
+    static const char *blt_pshaders[tex_type_count] =
+    {
         /* tex_1d */
         NULL,
         /* tex_2d */
         /* tex_1d */
         NULL,
         /* tex_2d */
@@ -3436,12 +3600,6 @@ static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     checkGLcall("glUseProgramObjectARB");
 }
 
     checkGLcall("glUseProgramObjectARB");
 }
 
-static void shader_glsl_cleanup(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-    GL_EXTCALL(glUseProgramObjectARB(0));
-}
-
 static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     const struct list *linked_programs;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
 static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     const struct list *linked_programs;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
@@ -3454,7 +3612,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     /* Note: Do not use QueryInterface here to find out which shader type this is because this code
      * can be called from IWineD3DBaseShader::Release
      */
     /* 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);
+    char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
 
     if(pshader) {
         ps = (IWineD3DPixelShaderImpl *) This;
 
     if(pshader) {
         ps = (IWineD3DPixelShaderImpl *) This;
@@ -3529,10 +3687,64 @@ static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
            (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0);
 }
 
            (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0);
 }
 
+static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
+{
+    SIZE_T size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
+    void *mem = HeapAlloc(GetProcessHeap(), 0, size);
+
+    if (!mem)
+    {
+        ERR("Failed to allocate memory\n");
+        return FALSE;
+    }
+
+    heap->entries = mem;
+    heap->entries[1].version = 0;
+    heap->positions = (unsigned int *)(heap->entries + constant_count + 1);
+    heap->size = 1;
+
+    return TRUE;
+}
+
+static void constant_heap_free(struct constant_heap *heap)
+{
+    HeapFree(GetProcessHeap(), 0, heap->entries);
+}
+
 static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
+    SIZE_T stack_size = wined3d_log2i(max(GL_LIMITS(vshader_constantsF), GL_LIMITS(pshader_constantsF))) + 1;
+
+    priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack));
+    if (!priv->stack)
+    {
+        ERR("Failed to allocate memory.\n");
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
+    }
+
+    if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
+    {
+        ERR("Failed to initialize vertex shader constant heap\n");
+        HeapFree(GetProcessHeap(), 0, priv->stack);
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
+    }
+
+    if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
+    {
+        ERR("Failed to initialize pixel shader constant heap\n");
+        constant_heap_free(&priv->vconst_heap);
+        HeapFree(GetProcessHeap(), 0, priv->stack);
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
+    }
+
     priv->glsl_program_lookup = hash_table_create(glsl_program_key_hash, glsl_program_key_compare);
     priv->glsl_program_lookup = hash_table_create(glsl_program_key_hash, glsl_program_key_compare);
+    priv->next_constant_version = 1;
+
     This->shader_priv = priv;
     return WINED3D_OK;
 }
     This->shader_priv = priv;
     return WINED3D_OK;
 }
@@ -3552,6 +3764,8 @@ static void shader_glsl_free(IWineD3DDevice *iface) {
     }
 
     hash_table_destroy(priv->glsl_program_lookup, NULL, NULL);
     }
 
     hash_table_destroy(priv->glsl_program_lookup, NULL, NULL);
+    constant_heap_free(&priv->pconst_heap);
+    constant_heap_free(&priv->vconst_heap);
 
     HeapFree(GetProcessHeap(), 0, This->shader_priv);
     This->shader_priv = NULL;
 
     HeapFree(GetProcessHeap(), 0, This->shader_priv);
     This->shader_priv = NULL;
@@ -3562,7 +3776,7 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
     return FALSE;
 }
 
     return FALSE;
 }
 
-static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
@@ -3585,23 +3799,19 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     }
 
     /* Base Declarations */
     }
 
     /* Base Declarations */
-    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
 
     /* Pack 3.0 inputs */
 
     /* Pack 3.0 inputs */
-    if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
-
-        if(((IWineD3DDeviceImpl *) This->baseShader.device)->strided_streams.u.s.position_transformed) {
-            pshader_glsl_input_pack(buffer, This->semantics_in, iface, pretransformed);
-        } else if(!use_vs((IWineD3DDeviceImpl *) This->baseShader.device)) {
-            pshader_glsl_input_pack(buffer, This->semantics_in, iface, fixedfunction);
-        }
+    if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0) && args->vp_mode != vertexshader) {
+        pshader_glsl_input_pack(buffer, This->semantics_in, iface, args->vp_mode);
     }
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
     }
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
-    if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
+    if (reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+    {
         /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
         if(GL_SUPPORT(ARB_DRAW_BUFFERS))
             shader_addline(buffer, "gl_FragData[0] = R0;\n");
         /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
         if(GL_SUPPORT(ARB_DRAW_BUFFERS))
             shader_addline(buffer, "gl_FragData[0] = R0;\n");
@@ -3614,7 +3824,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     } else {
         fragcolor = "gl_FragColor";
     }
     } else {
         fragcolor = "gl_FragColor";
     }
-    if(((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
+    if(args->srgb_correction) {
         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);
         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);
@@ -3630,9 +3840,22 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
      * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
      * -1/(e-s) and e/(e-s) respectively.
      */
      * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
      * -1/(e-s) and e/(e-s) respectively.
      */
-    if(This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
-        shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");
-        shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
+    if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {
+        switch(args->fog) {
+            case FOG_OFF: break;
+            case FOG_LINEAR:
+                shader_addline(buffer, "float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);\n");
+                shader_addline(buffer, "float fogend = gl_Fog.end * -fogstart;\n");
+                shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);\n");
+                shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
+                break;
+            case FOG_EXP:
+                FIXME("Implement EXP fog in glsl\n");
+                break;
+            case FOG_EXP2:
+                FIXME("Implement EXP2 fog in glsl\n");
+                break;
+        }
     }
 
     shader_addline(buffer, "}\n");
     }
 
     shader_addline(buffer, "}\n");
@@ -3658,17 +3881,14 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
     shader_addline(buffer, "#version 120\n");
 
     /* Base Declarations */
     shader_addline(buffer, "#version 120\n");
 
     /* Base Declarations */
-    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Unpack 3.0 outputs */
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Unpack 3.0 outputs */
-    if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0)) {
-        shader_addline(buffer, "order_ps_input(OUT);\n");
-    } else {
-        shader_addline(buffer, "order_ps_input();\n");
-    }
+    if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");
+    else shader_addline(buffer, "order_ps_input();\n");
 
     /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
     if (!reg_maps->fog)
 
     /* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
     if (!reg_maps->fog)
@@ -3863,8 +4083,9 @@ const shader_backend_t glsl_shader_backend = {
     shader_glsl_select,
     shader_glsl_select_depth_blt,
     shader_glsl_deselect_depth_blt,
     shader_glsl_select,
     shader_glsl_select_depth_blt,
     shader_glsl_deselect_depth_blt,
+    shader_glsl_update_float_vertex_constants,
+    shader_glsl_update_float_pixel_constants,
     shader_glsl_load_constants,
     shader_glsl_load_constants,
-    shader_glsl_cleanup,
     shader_glsl_color_correction,
     shader_glsl_destroy,
     shader_glsl_alloc,
     shader_glsl_color_correction,
     shader_glsl_destroy,
     shader_glsl_alloc,
index 0737892..2325f70 100644 (file)
@@ -108,7 +108,7 @@ static DWORD WINAPI IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *ifa
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface) {
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface) {
-    FIXME("iface %p stub!\n", iface);
+    TRACE("iface %p.\n", iface);
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface) {
 }
 
 static void WINAPI IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface) {
index 77f5365..fc727d6 100644 (file)
@@ -41,7 +41,7 @@ static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateb
     }
 
     if(stateblock->textures[stage]) {
     }
 
     if(stateblock->textures[stage]) {
-        switch(stateblock->textureDimensions[stage]) {
+        switch(IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
             case GL_TEXTURE_2D:
                 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
                 checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
             case GL_TEXTURE_2D:
                 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
                 checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
@@ -451,32 +451,24 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
 
 
 static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 
 
 static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
-    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
+    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
 
     TRACE("Setting color op for stage %d\n", stage);
 
 
     TRACE("Setting color op for stage %d\n", stage);
 
-    if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
-        ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
-        /* Using a pixel shader? Don't care for anything here, the shader applying does it */
-        return;
-    }
+    /* Using a pixel shader? Don't care for anything here, the shader applying does it */
+    if (use_ps(stateblock)) return;
 
     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
 
     if (mapped_stage != -1) {
 
     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
 
     if (mapped_stage != -1) {
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
-                FIXME("Attempt to enable unsupported stage!\n");
-                return;
-            }
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-            checkGLcall("glActiveTextureARB");
-        } else if (stage > 0) {
-            WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+        if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
+            FIXME("Attempt to enable unsupported stage!\n");
             return;
         }
             return;
         }
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+        checkGLcall("glActiveTextureARB");
     }
 
     if(stateblock->lowest_disabled_stage > 0) {
     }
 
     if(stateblock->lowest_disabled_stage > 0) {
@@ -564,7 +556,7 @@ static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
 }
 
 static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
     float mat[2][2];
 
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
     float mat[2][2];
 
@@ -800,6 +792,13 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              nvrc_texfactor      }, 0                               },
     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              nvrc_texfactor      }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
index 8f6e37a..338e66e 100644 (file)
@@ -1,4 +1,4 @@
-/*             DirectDraw - IDirectPalette base interface
+/*              DirectDraw - IDirectPalette base interface
  *
  * Copyright 1997-2000 Marcus Meissner
  * Copyright 2000-2001 TransGaming Technologies Inc.
  *
  * Copyright 1997-2000 Marcus Meissner
  * Copyright 2000-2001 TransGaming Technologies Inc.
index 0557d86..9f96c59 100644 (file)
@@ -37,15 +37,46 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 #define GLNAME_REQUIRE_GLSL  ((const char *)1)
 
 static HRESULT  WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) {
 #define GLNAME_REQUIRE_GLSL  ((const char *)1)
 
 static HRESULT  WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) {
-    return IWineD3DBaseShaderImpl_QueryInterface((IWineD3DBaseShader *) iface, riid, ppobj);
+    TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), ppobj);
+
+    if (IsEqualGUID(riid, &IID_IWineD3DPixelShader)
+            || IsEqualGUID(riid, &IID_IWineD3DBaseShader)
+            || IsEqualGUID(riid, &IID_IWineD3DBase)
+            || IsEqualGUID(riid, &IID_IUnknown))
+    {
+        IUnknown_AddRef(iface);
+        *ppobj = iface;
+        return S_OK;
+    }
+
+    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
+
+    *ppobj = NULL;
+    return E_NOINTERFACE;
 }
 
 static ULONG  WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface) {
 }
 
 static ULONG  WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface) {
-    return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface);
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
+    ULONG refcount = InterlockedIncrement(&This->baseShader.ref);
+
+    TRACE("%p increasing refcount to %u\n", This, refcount);
+
+    return refcount;
 }
 
 static ULONG  WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) {
 }
 
 static ULONG  WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) {
-    return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
+    ULONG refcount = InterlockedDecrement(&This->baseShader.ref);
+
+    TRACE("%p decreasing refcount to %u\n", This, refcount);
+
+    if (!refcount)
+    {
+        shader_cleanup((IWineD3DBaseShader *)iface);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return refcount;
 }
 
 /* *******************************************
 }
 
 /* *******************************************
@@ -84,111 +115,105 @@ static HRESULT  WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader*
      * return D3DERR_MOREDATA. That's not actually true. */
     return WINED3DERR_INVALIDCALL;
   }
      * return D3DERR_MOREDATA. That's not actually true. */
     return WINED3DERR_INVALIDCALL;
   }
-  if (NULL == This->baseShader.function) { /* no function defined */
-    TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
-    (*(DWORD **) pData) = NULL;
-  } else {
-    if (This->baseShader.functionLength == 0) {
 
 
-    }
-    TRACE("(%p) : GetFunction copying to %p\n", This, pData);
-    memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
-  }
+  TRACE("(%p) : GetFunction copying to %p\n", This, pData);
+  memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
+
   return WINED3D_OK;
 }
 
 CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
     /* Arithmetic */
   return WINED3D_OK;
 }
 
 CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
     /* Arithmetic */
-    {WINED3DSIO_NOP,          "nop",          "NOP",               0, 0, WINED3DSIH_NOP,          0,                      0                     },
-    {WINED3DSIO_MOV,          "mov",          "MOV",               1, 2, WINED3DSIH_MOV,          0,                      0                     },
-    {WINED3DSIO_ADD,          "add",          "ADD",               1, 3, WINED3DSIH_ADD,          0,                      0                     },
-    {WINED3DSIO_SUB,          "sub",          "SUB",               1, 3, WINED3DSIH_SUB,          0,                      0                     },
-    {WINED3DSIO_MAD,          "mad",          "MAD",               1, 4, WINED3DSIH_MAD,          0,                      0                     },
-    {WINED3DSIO_MUL,          "mul",          "MUL",               1, 3, WINED3DSIH_MUL,          0,                      0                     },
-    {WINED3DSIO_RCP,          "rcp",          "RCP",               1, 2, WINED3DSIH_RCP,          0,                      0                     },
-    {WINED3DSIO_RSQ,          "rsq",          "RSQ",               1, 2, WINED3DSIH_RSQ,          0,                      0                     },
-    {WINED3DSIO_DP3,          "dp3",          "DP3",               1, 3, WINED3DSIH_DP3,          0,                      0                     },
-    {WINED3DSIO_DP4,          "dp4",          "DP4",               1, 3, WINED3DSIH_DP4,          0,                      0                     },
-    {WINED3DSIO_MIN,          "min",          "MIN",               1, 3, WINED3DSIH_MIN,          0,                      0                     },
-    {WINED3DSIO_MAX,          "max",          "MAX",               1, 3, WINED3DSIH_MAX,          0,                      0                     },
-    {WINED3DSIO_SLT,          "slt",          "SLT",               1, 3, WINED3DSIH_SLT,          0,                      0                     },
-    {WINED3DSIO_SGE,          "sge",          "SGE",               1, 3, WINED3DSIH_SGE,          0,                      0                     },
-    {WINED3DSIO_ABS,          "abs",          "ABS",               1, 2, WINED3DSIH_ABS,          0,                      0                     },
-    {WINED3DSIO_EXP,          "exp",          "EX2",               1, 2, WINED3DSIH_EXP,          0,                      0                     },
-    {WINED3DSIO_LOG,          "log",          "LG2",               1, 2, WINED3DSIH_LOG,          0,                      0                     },
-    {WINED3DSIO_EXPP,         "expp",         "EXP",               1, 2, WINED3DSIH_EXPP,         0,                      0                     },
-    {WINED3DSIO_LOGP,         "logp",         "LOG",               1, 2, WINED3DSIH_LOGP,         0,                      0                     },
-    {WINED3DSIO_DST,          "dst",          "DST",               1, 3, WINED3DSIH_DST,          0,                      0                     },
-    {WINED3DSIO_LRP,          "lrp",          "LRP",               1, 4, WINED3DSIH_LRP,          0,                      0                     },
-    {WINED3DSIO_FRC,          "frc",          "FRC",               1, 2, WINED3DSIH_FRC,          0,                      0                     },
-    {WINED3DSIO_CND,          "cnd",          NULL,                1, 4, WINED3DSIH_CND,          WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_CMP,          "cmp",          NULL,                1, 4, WINED3DSIH_CMP,          WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
-    {WINED3DSIO_POW,          "pow",          "POW",               1, 3, WINED3DSIH_POW,          0,                      0                     },
-    {WINED3DSIO_CRS,          "crs",          "XPD",               1, 3, WINED3DSIH_CRS,          0,                      0                     },
-    {WINED3DSIO_NRM,          "nrm",          NULL,                1, 2, WINED3DSIH_NRM,          0,                      0                     },
-    {WINED3DSIO_SINCOS,       "sincos",       NULL,                1, 4, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
-    {WINED3DSIO_SINCOS,       "sincos",       "SCS",               1, 2, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_DP2ADD,       "dp2add",       NULL,                1, 4, WINED3DSIH_DP2ADD,       WINED3DPS_VERSION(2,0), -1                    },
+    {WINED3DSIO_NOP,          "nop",          0, 0, WINED3DSIH_NOP,          0,                      0                     },
+    {WINED3DSIO_MOV,          "mov",          1, 2, WINED3DSIH_MOV,          0,                      0                     },
+    {WINED3DSIO_ADD,          "add",          1, 3, WINED3DSIH_ADD,          0,                      0                     },
+    {WINED3DSIO_SUB,          "sub",          1, 3, WINED3DSIH_SUB,          0,                      0                     },
+    {WINED3DSIO_MAD,          "mad",          1, 4, WINED3DSIH_MAD,          0,                      0                     },
+    {WINED3DSIO_MUL,          "mul",          1, 3, WINED3DSIH_MUL,          0,                      0                     },
+    {WINED3DSIO_RCP,          "rcp",          1, 2, WINED3DSIH_RCP,          0,                      0                     },
+    {WINED3DSIO_RSQ,          "rsq",          1, 2, WINED3DSIH_RSQ,          0,                      0                     },
+    {WINED3DSIO_DP3,          "dp3",          1, 3, WINED3DSIH_DP3,          0,                      0                     },
+    {WINED3DSIO_DP4,          "dp4",          1, 3, WINED3DSIH_DP4,          0,                      0                     },
+    {WINED3DSIO_MIN,          "min",          1, 3, WINED3DSIH_MIN,          0,                      0                     },
+    {WINED3DSIO_MAX,          "max",          1, 3, WINED3DSIH_MAX,          0,                      0                     },
+    {WINED3DSIO_SLT,          "slt",          1, 3, WINED3DSIH_SLT,          0,                      0                     },
+    {WINED3DSIO_SGE,          "sge",          1, 3, WINED3DSIH_SGE,          0,                      0                     },
+    {WINED3DSIO_ABS,          "abs",          1, 2, WINED3DSIH_ABS,          0,                      0                     },
+    {WINED3DSIO_EXP,          "exp",          1, 2, WINED3DSIH_EXP,          0,                      0                     },
+    {WINED3DSIO_LOG,          "log",          1, 2, WINED3DSIH_LOG,          0,                      0                     },
+    {WINED3DSIO_EXPP,         "expp",         1, 2, WINED3DSIH_EXPP,         0,                      0                     },
+    {WINED3DSIO_LOGP,         "logp",         1, 2, WINED3DSIH_LOGP,         0,                      0                     },
+    {WINED3DSIO_DST,          "dst",          1, 3, WINED3DSIH_DST,          0,                      0                     },
+    {WINED3DSIO_LRP,          "lrp",          1, 4, WINED3DSIH_LRP,          0,                      0                     },
+    {WINED3DSIO_FRC,          "frc",          1, 2, WINED3DSIH_FRC,          0,                      0                     },
+    {WINED3DSIO_CND,          "cnd",          1, 4, WINED3DSIH_CND,          WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
+    {WINED3DSIO_CMP,          "cmp",          1, 4, WINED3DSIH_CMP,          WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
+    {WINED3DSIO_POW,          "pow",          1, 3, WINED3DSIH_POW,          0,                      0                     },
+    {WINED3DSIO_CRS,          "crs",          1, 3, WINED3DSIH_CRS,          0,                      0                     },
+    {WINED3DSIO_NRM,          "nrm",          1, 2, WINED3DSIH_NRM,          0,                      0                     },
+    {WINED3DSIO_SINCOS,       "sincos",       1, 4, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
+    {WINED3DSIO_SINCOS,       "sincos",       1, 2, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(3,0), -1                    },
+    {WINED3DSIO_DP2ADD,       "dp2add",       1, 4, WINED3DSIH_DP2ADD,       WINED3DPS_VERSION(2,0), -1                    },
     /* Matrix */
     /* Matrix */
-    {WINED3DSIO_M4x4,         "m4x4",         "undefined",         1, 3, WINED3DSIH_M4x4,         0,                      0                     },
-    {WINED3DSIO_M4x3,         "m4x3",         "undefined",         1, 3, WINED3DSIH_M4x3,         0,                      0                     },
-    {WINED3DSIO_M3x4,         "m3x4",         "undefined",         1, 3, WINED3DSIH_M3x4,         0,                      0                     },
-    {WINED3DSIO_M3x3,         "m3x3",         "undefined",         1, 3, WINED3DSIH_M3x3,         0,                      0                     },
-    {WINED3DSIO_M3x2,         "m3x2",         "undefined",         1, 3, WINED3DSIH_M3x2,         0,                      0                     },
+    {WINED3DSIO_M4x4,         "m4x4",         1, 3, WINED3DSIH_M4x4,         0,                      0                     },
+    {WINED3DSIO_M4x3,         "m4x3",         1, 3, WINED3DSIH_M4x3,         0,                      0                     },
+    {WINED3DSIO_M3x4,         "m3x4",         1, 3, WINED3DSIH_M3x4,         0,                      0                     },
+    {WINED3DSIO_M3x3,         "m3x3",         1, 3, WINED3DSIH_M3x3,         0,                      0                     },
+    {WINED3DSIO_M3x2,         "m3x2",         1, 3, WINED3DSIH_M3x2,         0,                      0                     },
     /* Register declarations */
     /* Register declarations */
-    {WINED3DSIO_DCL,          "dcl",          NULL,                0, 2, WINED3DSIH_DCL,          0,                      0                     },
+    {WINED3DSIO_DCL,          "dcl",          0, 2, WINED3DSIH_DCL,          0,                      0                     },
     /* Flow control - requires GLSL or software shaders */
     /* Flow control - requires GLSL or software shaders */
-    {WINED3DSIO_REP ,         "rep",          NULL,                0, 1, WINED3DSIH_REP,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDREP,       "endrep",       NULL,                0, 0, WINED3DSIH_ENDREP,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_IF,           "if",           NULL,                0, 1, WINED3DSIH_IF,           WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_IFC,          "ifc",          NULL,                0, 2, WINED3DSIH_IFC,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ELSE,         "else",         NULL,                0, 0, WINED3DSIH_ELSE,         WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDIF,        "endif",        NULL,                0, 0, WINED3DSIH_ENDIF,        WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAK,        "break",        NULL,                0, 0, WINED3DSIH_BREAK,        WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKC,       "breakc",       NULL,                0, 2, WINED3DSIH_BREAKC,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKP,       "breakp",       GLNAME_REQUIRE_GLSL, 0, 1, WINED3DSIH_BREAKP,       0,                      0                     },
-    {WINED3DSIO_CALL,         "call",         NULL,                0, 1, WINED3DSIH_CALL,         WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_CALLNZ,       "callnz",       NULL,                0, 2, WINED3DSIH_CALLNZ,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_LOOP,         "loop",         NULL,                0, 2, WINED3DSIH_LOOP,         WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_RET,          "ret",          NULL,                0, 0, WINED3DSIH_RET,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDLOOP,      "endloop",      NULL,                0, 0, WINED3DSIH_ENDLOOP,      WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_LABEL,        "label",        NULL,                0, 1, WINED3DSIH_LABEL,        WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_REP ,         "rep",          0, 1, WINED3DSIH_REP,          WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_ENDREP,       "endrep",       0, 0, WINED3DSIH_ENDREP,       WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_IF,           "if",           0, 1, WINED3DSIH_IF,           WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_IFC,          "ifc",          0, 2, WINED3DSIH_IFC,          WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_ELSE,         "else",         0, 0, WINED3DSIH_ELSE,         WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_ENDIF,        "endif",        0, 0, WINED3DSIH_ENDIF,        WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_BREAK,        "break",        0, 0, WINED3DSIH_BREAK,        WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_BREAKC,       "breakc",       0, 2, WINED3DSIH_BREAKC,       WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_BREAKP,       "breakp",       0, 1, WINED3DSIH_BREAKP,       0,                      0                     },
+    {WINED3DSIO_CALL,         "call",         0, 1, WINED3DSIH_CALL,         WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_CALLNZ,       "callnz",       0, 2, WINED3DSIH_CALLNZ,       WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_LOOP,         "loop",         0, 2, WINED3DSIH_LOOP,         WINED3DPS_VERSION(3,0), -1                    },
+    {WINED3DSIO_RET,          "ret",          0, 0, WINED3DSIH_RET,          WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_ENDLOOP,      "endloop",      0, 0, WINED3DSIH_ENDLOOP,      WINED3DPS_VERSION(3,0), -1                    },
+    {WINED3DSIO_LABEL,        "label",        0, 1, WINED3DSIH_LABEL,        WINED3DPS_VERSION(2,1), -1                    },
     /* Constant definitions */
     /* Constant definitions */
-    {WINED3DSIO_DEF,          "def",          "undefined",         1, 5, WINED3DSIH_DEF,          0,                      0                     },
-    {WINED3DSIO_DEFB,         "defb",         GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_DEFB,         0,                      0                     },
-    {WINED3DSIO_DEFI,         "defi",         GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_DEFI,         0,                      0                     },
+    {WINED3DSIO_DEF,          "def",          1, 5, WINED3DSIH_DEF,          0,                      0                     },
+    {WINED3DSIO_DEFB,         "defb",         1, 2, WINED3DSIH_DEFB,         0,                      0                     },
+    {WINED3DSIO_DEFI,         "defi",         1, 5, WINED3DSIH_DEFI,         0,                      0                     },
     /* Texture */
     /* Texture */
-    {WINED3DSIO_TEXCOORD,     "texcoord",     "undefined",         1, 1, WINED3DSIH_TEXCOORD,     0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXCOORD,     "texcrd",       "undefined",         1, 2, WINED3DSIH_TEXCOORD,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_TEXKILL,      "texkill",      "KIL",               1, 1, WINED3DSIH_TEXKILL,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
-    {WINED3DSIO_TEX,          "tex",          "undefined",         1, 1, WINED3DSIH_TEX,          0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEX,          "texld",        "undefined",         1, 2, WINED3DSIH_TEX,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_TEX,          "texld",        "undefined",         1, 3, WINED3DSIH_TEX,          WINED3DPS_VERSION(2,0), -1                    },
-    {WINED3DSIO_TEXBEM,       "texbem",       "undefined",         1, 2, WINED3DSIH_TEXBEM,       0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXBEML,      "texbeml",      GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXBEML,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2AR,    "texreg2ar",    "undefined",         1, 2, WINED3DSIH_TEXREG2AR,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2GB,    "texreg2gb",    "undefined",         1, 2, WINED3DSIH_TEXREG2GB,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2RGB,   "texreg2rgb",   "undefined",         1, 2, WINED3DSIH_TEXREG2RGB,   WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2PAD,   "texm3x2pad",   "undefined",         1, 2, WINED3DSIH_TEXM3x2PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2TEX,   "texm3x2tex",   "undefined",         1, 2, WINED3DSIH_TEXM3x2TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3PAD,   "texm3x3pad",   "undefined",         1, 2, WINED3DSIH_TEXM3x3PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3DIFF,  "texm3x3diff",  GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXM3x3DIFF,  WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)},
-    {WINED3DSIO_TEXM3x3SPEC,  "texm3x3spec",  "undefined",         1, 3, WINED3DSIH_TEXM3x3SPEC,  WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined",         1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3TEX,   "texm3x3tex",   "undefined",         1, 2, WINED3DSIH_TEXM3x3TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDP3TEX,    "texdp3tex",    NULL,                1, 2, WINED3DSIH_TEXDP3TEX,    WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDP3,       "texdp3",       NULL,                1, 2, WINED3DSIH_TEXDP3,       WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3,      "texm3x3",      NULL,                1, 2, WINED3DSIH_TEXM3x3,      WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDEPTH,     "texdepth",     NULL,                1, 1, WINED3DSIH_TEXDEPTH,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_BEM,          "bem",          "undefined",         1, 3, WINED3DSIH_BEM,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_DSX,          "dsx",          NULL,                1, 2, WINED3DSIH_DSX,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_DSY,          "dsy",          NULL,                1, 2, WINED3DSIH_DSY,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_TEXLDD,       "texldd",       GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_TEXLDD,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_SETP,         "setp",         GLNAME_REQUIRE_GLSL, 1, 3, WINED3DSIH_SETP,         0,                      0                     },
-    {WINED3DSIO_TEXLDL,       "texldl",       NULL,                1, 3, WINED3DSIH_TEXLDL,       WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_PHASE,        "phase",        GLNAME_REQUIRE_GLSL, 0, 0, WINED3DSIH_PHASE,        0,                      0                     },
-    {0,                       NULL,           NULL,                0, 0, 0,                       0,                      0                     }
+    {WINED3DSIO_TEXCOORD,     "texcoord",     1, 1, WINED3DSIH_TEXCOORD,     0,                      WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXCOORD,     "texcrd",       1, 2, WINED3DSIH_TEXCOORD,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
+    {WINED3DSIO_TEXKILL,      "texkill",      1, 1, WINED3DSIH_TEXKILL,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
+    {WINED3DSIO_TEX,          "tex",          1, 1, WINED3DSIH_TEX,          0,                      WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEX,          "texld",        1, 2, WINED3DSIH_TEX,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
+    {WINED3DSIO_TEX,          "texld",        1, 3, WINED3DSIH_TEX,          WINED3DPS_VERSION(2,0), -1                    },
+    {WINED3DSIO_TEXBEM,       "texbem",       1, 2, WINED3DSIH_TEXBEM,       0,                      WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXBEML,      "texbeml",      1, 2, WINED3DSIH_TEXBEML,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2AR,    "texreg2ar",    1, 2, WINED3DSIH_TEXREG2AR,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2GB,    "texreg2gb",    1, 2, WINED3DSIH_TEXREG2GB,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2RGB,   "texreg2rgb",   1, 2, WINED3DSIH_TEXREG2RGB,   WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2PAD,   "texm3x2pad",   1, 2, WINED3DSIH_TEXM3x2PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2TEX,   "texm3x2tex",   1, 2, WINED3DSIH_TEXM3x2TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3PAD,   "texm3x3pad",   1, 2, WINED3DSIH_TEXM3x3PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3DIFF,  "texm3x3diff",  1, 2, WINED3DSIH_TEXM3x3DIFF,  WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)},
+    {WINED3DSIO_TEXM3x3SPEC,  "texm3x3spec",  1, 3, WINED3DSIH_TEXM3x3SPEC,  WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3TEX,   "texm3x3tex",   1, 2, WINED3DSIH_TEXM3x3TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXDP3TEX,    "texdp3tex",    1, 2, WINED3DSIH_TEXDP3TEX,    WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXDP3,       "texdp3",       1, 2, WINED3DSIH_TEXDP3,       WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3,      "texm3x3",      1, 2, WINED3DSIH_TEXM3x3,      WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
+    {WINED3DSIO_TEXDEPTH,     "texdepth",     1, 1, WINED3DSIH_TEXDEPTH,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
+    {WINED3DSIO_BEM,          "bem",          1, 3, WINED3DSIH_BEM,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
+    {WINED3DSIO_DSX,          "dsx",          1, 2, WINED3DSIH_DSX,          WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_DSY,          "dsy",          1, 2, WINED3DSIH_DSY,          WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_TEXLDD,       "texldd",       1, 5, WINED3DSIH_TEXLDD,       WINED3DPS_VERSION(2,1), -1                    },
+    {WINED3DSIO_SETP,         "setp",         1, 3, WINED3DSIH_SETP,         0,                      0                     },
+    {WINED3DSIO_TEXLDL,       "texldl",       1, 3, WINED3DSIH_TEXLDL,       WINED3DPS_VERSION(3,0), -1                    },
+    {WINED3DSIO_PHASE,        "phase",        0, 0, WINED3DSIH_PHASE,        0,                      0                     },
+    {0,                       NULL,           0, 0, 0,                       0,                      0                     }
 };
 
 static void pshader_set_limits(
 };
 
 static void pshader_set_limits(
@@ -198,7 +223,8 @@ static void pshader_set_limits(
       This->baseShader.limits.address = 0;
       This->baseShader.limits.packed_output = 0;
 
       This->baseShader.limits.address = 0;
       This->baseShader.limits.packed_output = 0;
 
-      switch (This->baseShader.hex_version) {
+      switch (This->baseShader.reg_maps.shader_version)
+      {
           case WINED3DPS_VERSION(1,0):
           case WINED3DPS_VERSION(1,1):
           case WINED3DPS_VERSION(1,2):
           case WINED3DPS_VERSION(1,0):
           case WINED3DPS_VERSION(1,1):
           case WINED3DPS_VERSION(1,2):
@@ -265,154 +291,159 @@ static void pshader_set_limits(
                    This->baseShader.limits.sampler = 16;
                    This->baseShader.limits.packed_input = 0;
                    This->baseShader.limits.label = 0;
                    This->baseShader.limits.sampler = 16;
                    This->baseShader.limits.packed_input = 0;
                    This->baseShader.limits.label = 0;
-                   FIXME("Unrecognized pixel shader version %#x\n", 
-                       This->baseShader.hex_version);
+                   FIXME("Unrecognized pixel shader version %#x\n",
+                           This->baseShader.reg_maps.shader_version);
       }
 }
 
       }
 }
 
-/** Generate a pixel shader string using either GL_FRAGMENT_PROGRAM_ARB
-    or GLSL and send it to the card */
-static inline GLuint IWineD3DPixelShaderImpl_GenerateShader(
-    IWineD3DPixelShaderImpl *This) {
-    SHADER_BUFFER buffer;
-
-    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
-    buffer.bsize = 0;
-    buffer.lineNo = 0;
-    buffer.newline = TRUE;
-
-    return ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_generate_pshader((IWineD3DPixelShader *) This, &buffer);
-}
-
 static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
 static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
+    unsigned int i, highest_reg_used = 0, num_regs_used = 0;
+    shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    HRESULT hr;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     /* First pass: trace shader */
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     /* First pass: trace shader */
-    shader_trace_init((IWineD3DBaseShader*) This, pFunction);
-    pshader_set_limits(This);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
     list_init(&This->baseShader.constantsB);
     list_init(&This->baseShader.constantsI);
 
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
     list_init(&This->baseShader.constantsB);
     list_init(&This->baseShader.constantsI);
 
-    if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) {
-        shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
-        HRESULT hr;
-        unsigned int i, j, highest_reg_used = 0, num_regs_used = 0;
-
-        /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-        memset(reg_maps, 0, sizeof(shader_reg_maps));
-        hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-            This->semantics_in, NULL, pFunction, NULL);
-        if (FAILED(hr)) return hr;
-        /* FIXME: validate reg_maps against OpenGL */
-
-        for(i = 0; i < MAX_REG_INPUT; i++) {
-            if(This->input_reg_used[i]) {
-                num_regs_used++;
-                highest_reg_used = i;
-            }
+    /* Second pass: figure out which registers are used, what the semantics are, etc.. */
+    memset(reg_maps, 0, sizeof(shader_reg_maps));
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction);
+    if (FAILED(hr)) return hr;
+
+    pshader_set_limits(This);
+
+    for (i = 0; i < MAX_REG_INPUT; ++i)
+    {
+        if (This->input_reg_used[i])
+        {
+            ++num_regs_used;
+            highest_reg_used = i;
         }
         }
+    }
 
 
-        /* Don't do any register mapping magic if it is not needed, or if we can't
-         * achieve anything anyway
-         */
-        if(highest_reg_used < (GL_LIMITS(glsl_varyings) / 4) ||
-           num_regs_used > (GL_LIMITS(glsl_varyings) / 4) ) {
-            if(num_regs_used > (GL_LIMITS(glsl_varyings) / 4)) {
-                /* This happens with relative addressing. The input mapper function
-                 * warns about this if the higher registers are declared too, so
-                 * don't write a FIXME here
-                 */
-                WARN("More varying registers used than supported\n");
-            }
+    /* Don't do any register mapping magic if it is not needed, or if we can't
+     * achieve anything anyway */
+    if (highest_reg_used < (GL_LIMITS(glsl_varyings) / 4)
+            || num_regs_used > (GL_LIMITS(glsl_varyings) / 4))
+    {
+        if (num_regs_used > (GL_LIMITS(glsl_varyings) / 4))
+        {
+            /* This happens with relative addressing. The input mapper function
+             * warns about this if the higher registers are declared too, so
+             * don't write a FIXME here */
+            WARN("More varying registers used than supported\n");
+        }
 
 
-            for(i = 0; i < MAX_REG_INPUT; i++) {
-                This->input_reg_map[i] = i;
-            }
-            This->declared_in_count = highest_reg_used + 1;
-        } else {
-            j = 0;
-            for(i = 0; i < MAX_REG_INPUT; i++) {
-                if(This->input_reg_used[i]) {
-                    This->input_reg_map[i] = j;
-                    j++;
-                } else {
-                    This->input_reg_map[i] = -1;
-                }
-            }
-            This->declared_in_count = j;
+        for (i = 0; i < MAX_REG_INPUT; ++i)
+        {
+            This->input_reg_map[i] = i;
+        }
+
+        This->declared_in_count = highest_reg_used + 1;
+    }
+    else
+    {
+        This->declared_in_count = 0;
+        for (i = 0; i < MAX_REG_INPUT; ++i)
+        {
+            if (This->input_reg_used[i]) This->input_reg_map[i] = This->declared_in_count++;
+            else This->input_reg_map[i] = -1;
         }
     }
         }
     }
+
     This->baseShader.load_local_constsF = FALSE;
 
     This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
 
     TRACE("(%p) : Copying the function\n", This);
     This->baseShader.load_local_constsF = FALSE;
 
     This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
 
     TRACE("(%p) : Copying the function\n", This);
-    if (NULL != pFunction) {
-        void *function;
 
 
-        function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
-        if (!function) return E_OUTOFMEMORY;
-        memcpy(function, pFunction, This->baseShader.functionLength);
-        This->baseShader.function = function;
-    } else {
-        This->baseShader.function = NULL;
-    }
+    This->baseShader.function = HeapAlloc(GetProcessHeap(), 0, This->baseShader.functionLength);
+    if (!This->baseShader.function) return E_OUTOFMEMORY;
+    memcpy(This->baseShader.function, pFunction, This->baseShader.functionLength);
 
     return WINED3D_OK;
 }
 
 
     return WINED3D_OK;
 }
 
+static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
+{
+    DWORD shader_version = reg_maps->shader_version;
+    DWORD *samplers = reg_maps->samplers;
+    unsigned int i;
+
+    if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return;
+
+    for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
+    {
+        /* We don't sample from this sampler */
+        if (!samplers[i]) continue;
+
+        if (!textures[i])
+        {
+            ERR("No texture bound to sampler %u, using 2D\n", i);
+            samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+            continue;
+        }
+
+        switch (IWineD3DBaseTexture_GetTextureDimensions(textures[i]))
+        {
+            case GL_TEXTURE_RECTANGLE_ARB:
+            case GL_TEXTURE_2D:
+                /* We have to select between texture rectangles and 2D textures later because 2.0 and
+                 * 3.0 shaders only have WINED3DSTT_2D as well */
+                samplers[i] = (1 << 31) | WINED3DSTT_2D;
+                break;
+
+            case GL_TEXTURE_3D:
+                samplers[i] = (1 << 31) | WINED3DSTT_VOLUME;
+                break;
+
+            case GL_TEXTURE_CUBE_MAP_ARB:
+                samplers[i] = (1 << 31) | WINED3DSTT_CUBE;
+                break;
+
+            default:
+                FIXME("Unrecognized texture type %#x, using 2D\n",
+                        IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
+                samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+        }
+    }
+}
+
 static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
 {
     CONST DWORD *function = This->baseShader.function;
 static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
 {
     CONST DWORD *function = This->baseShader.function;
-    HRESULT hr;
     GLuint retval;
     GLuint retval;
+    SHADER_BUFFER buffer;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 
     TRACE("(%p) : function %p\n", This, function);
 
 
     TRACE("(%p) : function %p\n", This, function);
 
-    hr = IWineD3DPixelShader_UpdateSamplers((IWineD3DPixelShader *) This);
-    if(FAILED(hr)) {
-        ERR("Failed to update sampler information\n");
-        return 0;
-    }
+    pixelshader_update_samplers(&This->baseShader.reg_maps,
+            ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
 
     /* Reset fields tracking stateblock values being hardcoded in the shader */
     This->baseShader.num_sampled_samplers = 0;
 
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
 
     /* Reset fields tracking stateblock values being hardcoded in the shader */
     This->baseShader.num_sampled_samplers = 0;
 
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
-    retval = IWineD3DPixelShaderImpl_GenerateShader(This);
+    shader_buffer_init(&buffer);
+    retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
+    shader_buffer_free(&buffer);
 
     This->baseShader.is_compiled = TRUE;
 
     return retval;
 }
 
 
     This->baseShader.is_compiled = TRUE;
 
     return retval;
 }
 
-static HRESULT WINAPI IWineD3DPixelShaderImpl_UpdateSamplers(IWineD3DPixelShader *iface) {
-    IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
-
-    if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) {
-        IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-        shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
-        HRESULT hr;
-
-        /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-        memset(reg_maps, 0, sizeof(shader_reg_maps));
-        hr = shader_get_registers_used((IWineD3DBaseShader*)This, reg_maps,
-                                        This->semantics_in, NULL, This->baseShader.function, deviceImpl->stateBlock);
-        return hr;
-        /* FIXME: validate reg_maps against OpenGL */
-    } else {
-        return WINED3D_OK;
-    }
-}
-
 const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
 {
     /*** IUnknown methods ***/
 const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
 {
     /*** IUnknown methods ***/
@@ -424,7 +455,6 @@ const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
     /*** IWineD3DBaseShader methods ***/
     IWineD3DPixelShaderImpl_SetFunction,
     /*** IWineD3DPixelShader methods ***/
     /*** IWineD3DBaseShader methods ***/
     IWineD3DPixelShaderImpl_SetFunction,
     /*** IWineD3DPixelShader methods ***/
-    IWineD3DPixelShaderImpl_UpdateSamplers,
     IWineD3DPixelShaderImpl_GetDevice,
     IWineD3DPixelShaderImpl_GetFunction
 };
     IWineD3DPixelShaderImpl_GetDevice,
     IWineD3DPixelShaderImpl_GetFunction
 };
@@ -433,9 +463,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
     UINT i, sampler;
     IWineD3DBaseTextureImpl *tex;
 
     UINT i, sampler;
     IWineD3DBaseTextureImpl *tex;
 
+    memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set */
     args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
 
     args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
 
-    memset(args->color_fixup, 0, sizeof(args->color_fixup));
     for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
         sampler = shader->baseShader.sampled_samplers[i];
         tex = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
     for(i = 0; i < shader->baseShader.num_sampled_samplers; i++) {
         sampler = shader->baseShader.sampled_samplers[i];
         tex = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
@@ -445,16 +475,45 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
         }
         args->color_fixup[sampler] = tex->baseTexture.shader_color_fixup;
     }
         }
         args->color_fixup[sampler] = tex->baseTexture.shader_color_fixup;
     }
-    if(shader->baseShader.hex_version >= WINED3DPS_VERSION(3,0)) {
-        if(((IWineD3DDeviceImpl *) shader->baseShader.device)->strided_streams.u.s.position_transformed) {
+    if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0))
+    {
+        if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.position_transformed)
+        {
             args->vp_mode = pretransformed;
             args->vp_mode = pretransformed;
-        } else if(use_vs((IWineD3DDeviceImpl *) shader->baseShader.device)) {
+        }
+        else if (use_vs(stateblock))
+        {
             args->vp_mode = vertexshader;
         } else {
             args->vp_mode = fixedfunction;
         }
             args->vp_mode = vertexshader;
         } else {
             args->vp_mode = fixedfunction;
         }
+        args->fog = FOG_OFF;
     } else {
         args->vp_mode = vertexshader;
     } else {
         args->vp_mode = vertexshader;
+        if(stateblock->renderState[WINED3DRS_FOGENABLE]) {
+            switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
+                case WINED3DFOG_NONE:
+                    if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.position_transformed
+                            || use_vs(stateblock))
+                    {
+                        args->fog = FOG_LINEAR;
+                        break;
+                    }
+                    switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
+                        case WINED3DFOG_NONE: /* Drop through */
+                        case WINED3DFOG_LINEAR: args->fog = FOG_LINEAR; break;
+                        case WINED3DFOG_EXP:    args->fog = FOG_EXP;    break;
+                        case WINED3DFOG_EXP2:   args->fog = FOG_EXP2;   break;
+                    }
+                    break;
+
+                case WINED3DFOG_LINEAR: args->fog = FOG_LINEAR; break;
+                case WINED3DFOG_EXP:    args->fog = FOG_EXP;    break;
+                case WINED3DFOG_EXP2:   args->fog = FOG_EXP2;   break;
+            }
+        } else {
+            args->fog = FOG_OFF;
+        }
     }
 }
 
     }
 }
 
index 7826325..05e114c 100644 (file)
@@ -63,8 +63,18 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
         ENTER_GL();
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
         ENTER_GL();
+        /* Queries are specific to the GL context that created them. Not
+         * deleting the query will obviously leak it, but that's still better
+         * than potentially deleting a different query with the same id in this
+         * context, and (still) leaking the actual query. */
         if(This->type == WINED3DQUERYTYPE_EVENT) {
         if(This->type == WINED3DQUERYTYPE_EVENT) {
-            if(GL_SUPPORT(APPLE_FENCE)) {
+            if (((WineQueryEventData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
+                    || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
+            {
+                FIXME("Query was created in a different context, skipping deletion\n");
+            }
+            else if(GL_SUPPORT(APPLE_FENCE))
+            {
                 GL_EXTCALL(glDeleteFencesAPPLE(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
                 checkGLcall("glDeleteFencesAPPLE");
             } else if(GL_SUPPORT(NV_FENCE)) {
                 GL_EXTCALL(glDeleteFencesAPPLE(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
                 checkGLcall("glDeleteFencesAPPLE");
             } else if(GL_SUPPORT(NV_FENCE)) {
@@ -72,8 +82,16 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
                 checkGLcall("glDeleteFencesNV");
             }
         } else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
                 checkGLcall("glDeleteFencesNV");
             }
         } else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
-            GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
-            checkGLcall("glDeleteQueriesARB");
+            if (((WineQueryOcclusionData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
+                    || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
+            {
+                FIXME("Query was created in a different context, skipping deletion\n");
+            }
+            else
+            {
+                GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
+                checkGLcall("glDeleteQueriesARB");
+            }
         }
         LEAVE_GL();
 
         }
         LEAVE_GL();
 
@@ -268,48 +286,68 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
 
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
 
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
+    GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
     DWORD* data = pData;
     DWORD* data = pData;
+    GLuint available;
+    GLuint samples;
     HRESULT res;
     HRESULT res;
+
     TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
     TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
-    if(This->state == QUERY_CREATED) {
+    if (This->state == QUERY_CREATED)
+    {
         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
         TRACE("Query wasn't yet started, returning S_OK\n");
         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
         TRACE("Query wasn't yet started, returning S_OK\n");
-        res = S_OK;
         if(data) *data = 0;
         if(data) *data = 0;
-    } else if(This->state == QUERY_BUILDING) {
+        return S_OK;
+    }
+
+    if (This->state == QUERY_BUILDING)
+    {
         /* Msdn says this returns an error, but our tests show that S_FALSE is returned */
         TRACE("Query is building, returning S_FALSE\n");
         /* Msdn says this returns an error, but our tests show that S_FALSE is returned */
         TRACE("Query is building, returning S_FALSE\n");
-        res = S_FALSE;
-    } else if (GL_SUPPORT(ARB_OCCLUSION_QUERY) &&
-        ((WineQueryOcclusionData *)This->extendedData)->ctx == This->wineD3DDevice->activeContext &&
-                This->wineD3DDevice->activeContext->tid == GetCurrentThreadId()) {
-        GLuint available;
-        GLuint samples;
-        GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
+        return S_FALSE;
+    }
 
 
-        ENTER_GL();
-        GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
-        checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
-        TRACE("(%p) : available %d.\n", This, available);
-
-        if (available) {
-            if(data) {
-                GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
-                checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
-                TRACE("(%p) : Returning %d samples.\n", This, samples);
-                *data = samples;
-            }
-            res = S_OK;
-        } else {
-            res = S_FALSE;
-        }
-        LEAVE_GL();
-    } else {
-        WARN("(%p) : Occlusion queries not supported, or wrong context. Returning 1.\n", This);
+    if (!GL_SUPPORT(ARB_OCCLUSION_QUERY))
+    {
+        WARN("(%p) : Occlusion queries not supported. Returning 1.\n", This);
         *data = 1;
         *data = 1;
+        return S_OK;
+    }
+
+    if (((WineQueryOcclusionData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
+            || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
+    {
+        FIXME("%p Wrong context, returning 1.\n", This);
+        *data = 1;
+        return S_OK;
+    }
+
+    ENTER_GL();
+
+    GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
+    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
+    TRACE("(%p) : available %d.\n", This, available);
+
+    if (available)
+    {
+        if (data)
+        {
+            GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
+            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
+            TRACE("(%p) : Returning %d samples.\n", This, samples);
+            *data = samples;
+        }
         res = S_OK;
     }
         res = S_OK;
     }
+    else
+    {
+        res = S_FALSE;
+    }
+
+    LEAVE_GL();
+
     return res;
 }
 
     return res;
 }
 
@@ -324,7 +362,7 @@ static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
         return S_OK;
     } if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
         return S_OK;
     } if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
-        WARN("Query context not active, reporting GPU idle\n");
+        FIXME("Query context not active, reporting GPU idle\n");
         *data = TRUE;
     } else if(GL_SUPPORT(APPLE_FENCE)) {
         ENTER_GL();
         *data = TRUE;
     } else if(GL_SUPPORT(APPLE_FENCE)) {
         ENTER_GL();
@@ -460,7 +498,7 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface,  D
         WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
 
         if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
         WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
 
         if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
-            WARN("Not the owning context, can't start query\n");
+            FIXME("Not the owning context, can't start query\n");
         } else {
             ENTER_GL();
             /* This is allowed according to msdn and our tests. Reset the query and restart */
         } else {
             ENTER_GL();
             /* This is allowed according to msdn and our tests. Reset the query and restart */
index efcac7b..1231b34 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
 
+HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
+        IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
+{
+    resource->wineD3DDevice = device;
+    resource->parent = parent;
+    resource->resourceType = resource_type;
+    resource->ref = 1;
+    resource->pool = pool;
+    resource->format = format;
+    resource->usage = usage;
+    resource->size = size;
+    resource->priority = 0;
+    list_init(&resource->privateData);
+
+    if (size)
+    {
+        resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
+        if (!resource->heapMemory)
+        {
+            ERR("Out of memory!\n");
+            return WINED3DERR_OUTOFVIDEOMEMORY;
+        }
+    }
+    else
+    {
+        resource->heapMemory = NULL;
+    }
+    resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+
+    /* Check that we have enough video ram left */
+    if (pool == WINED3DPOOL_DEFAULT)
+    {
+        if (size > IWineD3DDevice_GetAvailableTextureMem((IWineD3DDevice *)device))
+        {
+            ERR("Out of adapter memory\n");
+            HeapFree(GetProcessHeap(), 0, resource->heapMemory);
+            return WINED3DERR_OUTOFVIDEOMEMORY;
+        }
+        WineD3DAdapterChangeGLRam(device, size);
+    }
+
+    return WINED3D_OK;
+}
+
 void resource_cleanup(IWineD3DResource *iface)
 {
     IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
 void resource_cleanup(IWineD3DResource *iface)
 {
     IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
index 0da9842..67fc1c7 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Direct3D state management
  *
 /*
  * Direct3D state management
  *
@@ -96,7 +95,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
 
     transformed = ((stateblock->wineD3DDevice->strided_streams.u.s.position.lpData != NULL ||
                     stateblock->wineD3DDevice->strided_streams.u.s.position.VBO != 0) &&
 
     transformed = ((stateblock->wineD3DDevice->strided_streams.u.s.position.lpData != NULL ||
                     stateblock->wineD3DDevice->strided_streams.u.s.position.VBO != 0) &&
-                    stateblock->wineD3DDevice->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
+                    stateblock->wineD3DDevice->strided_streams.position_transformed) ? TRUE : FALSE;
 
     if (stateblock->renderState[WINED3DRS_LIGHTING] && !transformed) {
         glEnable(GL_LIGHTING);
 
     if (stateblock->renderState[WINED3DRS_LIGHTING] && !transformed) {
         glEnable(GL_LIGHTING);
@@ -470,27 +469,29 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     float ref;
     BOOL enable_ckey = FALSE;
 
     float ref;
     BOOL enable_ckey = FALSE;
 
-    IWineD3DSurfaceImpl *surf;
-
     /* Find out if the texture on the first stage has a ckey set
      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
      * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
      * in case it finds some texture+colorkeyenable combination which needs extra care.
      */
     /* Find out if the texture on the first stage has a ckey set
      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
      * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
      * in case it finds some texture+colorkeyenable combination which needs extra care.
      */
-    if(stateblock->textures[0] && (
-       stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
-       stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
-        surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
-
-        if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) {
-            const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL);
-            /* The surface conversion does not do color keying conversion for surfaces that have an alpha
-             * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
-             * surface has alpha bits
-             */
-            if(fmt->alphaMask == 0x00000000) {
-                enable_ckey = TRUE;
+    if (stateblock->textures[0])
+    {
+        UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
+
+        if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+        {
+            IWineD3DSurfaceImpl *surf;
+
+            surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
+
+            if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
+            {
+                const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL);
+                /* The surface conversion does not do color keying conversion for surfaces that have an alpha
+                 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
+                 * surface has alpha bits */
+                if (fmt->alphaMask == 0x00000000) enable_ckey = TRUE;
             }
         }
     }
             }
         }
     }
@@ -531,7 +532,8 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
-    if (use_vs(stateblock->wineD3DDevice)) {
+    if (use_vs(stateblock))
+    {
         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
          * conditions I got sick of tracking down. The shader state handler disables all clip planes because
         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
          * conditions I got sick of tracking down. The shader state handler disables all clip planes because
@@ -702,7 +704,7 @@ state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
             checkGLcall("glFinalCombinerInputNV()");
         }
     } else {
             checkGLcall("glFinalCombinerInputNV()");
         }
     } else {
-        const GLfloat black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+        static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
 
         /* for the case of enabled lighting: */
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
 
         /* for the case of enabled lighting: */
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
@@ -751,14 +753,10 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     /* And now the default texture color as well */
     for (i = 0; i < GL_LIMITS(texture_stages); i++) {
         /* Note the WINED3DRS value applies to all textures, but GL has one
     /* And now the default texture color as well */
     for (i = 0; i < GL_LIMITS(texture_stages); i++) {
         /* Note the WINED3DRS value applies to all textures, but GL has one
-            * per texture, so apply it now ready to be used!
-            */
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
-            checkGLcall("glActiveTextureARB");
-        } else if (i>0) {
-            FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-        }
+         * per texture, so apply it now ready to be used!
+         */
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+        checkGLcall("glActiveTextureARB");
 
         glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
         checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
 
         glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
         checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
@@ -898,40 +896,98 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glStencilMask");
 }
 
     checkGLcall("glStencilMask");
 }
 
-static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
-    BOOL is_ps3 = use_ps(stateblock->wineD3DDevice)
-                  && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0);
-    float fogstart, fogend;
+static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    if (!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
 
 
+    /* Table fog on: Never use fog coords, and use per-fragment fog */
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE) {
+        glHint(GL_FOG_HINT, GL_NICEST);
+        if(context->fog_coord) {
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
+            context->fog_coord = FALSE;
+        }
+        return;
+    }
+
+    /* Otherwise use per-vertex fog in any case */
+    glHint(GL_FOG_HINT, GL_FASTEST);
+
+    if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
+        /* No fog at all, or transformed vertices: Use fog coord */
+        if(!context->fog_coord) {
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
+            context->fog_coord = TRUE;
+        }
+    } else {
+        /* Otherwise, use the fragment depth */
+        if(context->fog_coord) {
+            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
+            context->fog_coord = FALSE;
+        }
+    }
+}
+
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    float fogstart, fogend;
     union {
         DWORD d;
         float f;
     } tmpvalue;
 
     union {
         DWORD d;
         float f;
     } tmpvalue;
 
-    if (!fogenable) {
+    switch(context->fog_source) {
+        case FOGSOURCE_VS:
+            fogstart = 1.0;
+            fogend = 0.0;
+            break;
+
+        case FOGSOURCE_COORD:
+            fogstart = 255.0;
+            fogend = 0.0;
+            break;
+
+        case FOGSOURCE_FFP:
+            tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
+            fogstart = tmpvalue.f;
+            tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
+            fogend = tmpvalue.f;
+            /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
+            if(fogstart == fogend) {
+                fogstart = -1.0 / 0.0;
+                fogend = 0.0;
+            }
+            break;
+
+        default:
+            /* This should not happen.context->fog_source is set in wined3d, not the app.
+             * Still this is needed to make the compiler happy
+             */
+            ERR("Unexpected fog coordinate source\n");
+            fogstart = 0.0;
+            fogend = 0.0;
+    }
+
+    glFogf(GL_FOG_START, fogstart);
+    checkGLcall("glFogf(GL_FOG_START, fogstart)");
+    TRACE("Fog Start == %f\n", fogstart);
+
+    glFogf(GL_FOG_END, fogend);
+    checkGLcall("glFogf(GL_FOG_END, fogend)");
+    TRACE("Fog End == %f\n", fogend);
+}
+
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    enum fogsource new_source;
+
+    if (!stateblock->renderState[WINED3DRS_FOGENABLE]) {
         /* No fog? Disable it, and we're done :-) */
         /* No fog? Disable it, and we're done :-) */
-        glDisable(GL_FOG);
+        glDisableWINE(GL_FOG);
         checkGLcall("glDisable GL_FOG");
         checkGLcall("glDisable GL_FOG");
-        if( use_ps(stateblock->wineD3DDevice)
-                && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) {
-            /* disable fog in the pixel shader
-             * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
-             * -1/(e-s) and e/(e-s) respectively.
-             */
-            glFogf(GL_FOG_START, 0.0f);
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");
-            glFogf(GL_FOG_END, 1.0f);
-            checkGLcall("glFogf(GL_FOG_END, fogend)");
-        }
         return;
     }
 
         return;
     }
 
-    tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
-    fogstart = tmpvalue.f;
-    tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
-    fogend = tmpvalue.f;
-
     /* Fog Rules:
      *
      * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
     /* Fog Rules:
      *
      * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
@@ -968,177 +1024,86 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
      * without shaders).
      */
 
      * without shaders).
      */
 
-    if( is_ps3 ) {
-        if( !use_vs(stateblock->wineD3DDevice)
-                && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ) {
-            FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n");
-        }
-    }
-
-    if (use_vs(stateblock->wineD3DDevice)
-            && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
+    if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
         if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
         if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
-            if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n");
-            /* Disable fog */
-            fogenable = FALSE;
+            FIXME("vertex shader with table fog used\n");
         } else {
             /* Set fog computation in the rasterizer to pass through the value (just blend it) */
             glFogi(GL_FOG_MODE, GL_LINEAR);
             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
         } else {
             /* Set fog computation in the rasterizer to pass through the value (just blend it) */
             glFogi(GL_FOG_MODE, GL_LINEAR);
             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-            fogstart = 1.0;
-            fogend = 0.0;
-        }
-
-        if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-            context->fog_coord = FALSE;
         }
         context->last_was_foggy_shader = TRUE;
         }
         context->last_was_foggy_shader = TRUE;
-    }
-    else if( use_ps(stateblock->wineD3DDevice) ) {
-        /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
-         * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader.
-         */
-        WINED3DFOGMODE mode;
-        context->last_was_foggy_shader = FALSE;
-
-        /* If both fogmodes are set use the table fog mode */
-        if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
-            mode = stateblock->renderState[WINED3DRS_FOGVERTEXMODE];
-        else
-            mode = stateblock->renderState[WINED3DRS_FOGTABLEMODE];
-
-        switch (mode) {
-            case WINED3DFOG_EXP:
-            case WINED3DFOG_EXP2:
-                if(!is_ps3) FIXME("Implement non linear fog for pixel shader < 3.0\n");
-                /* Disable fog */
-                fogenable = FALSE;
-                break;
-
-            case WINED3DFOG_LINEAR:
-                fogstart = -1.0f/(fogend-fogstart);
-                fogend *= -fogstart;
-                break;
-
-            case WINED3DFOG_NONE:
-                if(!is_ps3) FIXME("Implement software vertex fog for pixel shader < 3.0\n");
-                /* Disable fog */
-                fogenable = FALSE;
-                break;
-            default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
-        }
-
-        if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-            glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-            checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-            context->fog_coord = FALSE;
-        }
+        new_source = FOGSOURCE_VS;
     }
     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
      * the system will apply only pixel(=table) fog effects."
      */
     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
     }
     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
      * the system will apply only pixel(=table) fog effects."
      */
     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
-        glHint(GL_FOG_HINT, GL_FASTEST);
-        checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
         context->last_was_foggy_shader = FALSE;
 
         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
             /* If processed vertices are used, fall through to the NONE case */
         context->last_was_foggy_shader = FALSE;
 
         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
             /* If processed vertices are used, fall through to the NONE case */
-            case WINED3DFOG_EXP:  {
+            case WINED3DFOG_EXP:
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_EXP);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_EXP);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
-                    if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                        checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                        context->fog_coord = FALSE;
-                    }
+                    new_source = FOGSOURCE_FFP;
                     break;
                 }
                     break;
                 }
-            }
-            case WINED3DFOG_EXP2: {
+                /* drop through */
+
+            case WINED3DFOG_EXP2:
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_EXP2);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_EXP2);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
-                    if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                        checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                        context->fog_coord = FALSE;
-                    }
+                    new_source = FOGSOURCE_FFP;
                     break;
                 }
                     break;
                 }
-            }
-            case WINED3DFOG_LINEAR: {
+                /* drop through */
+
+            case WINED3DFOG_LINEAR:
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_LINEAR);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
                 if(!context->last_was_rhw) {
                     glFogi(GL_FOG_MODE, GL_LINEAR);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-                    if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                        checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                        context->fog_coord = FALSE;
-                    }
+                    new_source = FOGSOURCE_FFP;
                     break;
                 }
                     break;
                 }
-            }
-            case WINED3DFOG_NONE: {
+                /* drop through */
+
+            case WINED3DFOG_NONE:
                 /* Both are none? According to msdn the alpha channel of the specular
                  * color contains a fog factor. Set it in drawStridedSlow.
                  * Same happens with Vertexfog on transformed vertices
                  */
                 /* Both are none? According to msdn the alpha channel of the specular
                  * color contains a fog factor. Set it in drawStridedSlow.
                  * Same happens with Vertexfog on transformed vertices
                  */
-                if(GL_SUPPORT(EXT_FOG_COORD)) {
-                    if(context->fog_coord == FALSE) {
-                        glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
-                        checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
-                        context->fog_coord = TRUE;
-                    }
-                    glFogi(GL_FOG_MODE, GL_LINEAR);
-                    checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-                    fogstart = 0xff;
-                    fogend = 0x0;
-                } else {
-                    /* Disable GL fog, handle this in software in drawStridedSlow */
-                    fogenable = FALSE;
-                }
+                new_source = FOGSOURCE_COORD;
+                glFogi(GL_FOG_MODE, GL_LINEAR);
+                checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
                 break;
                 break;
-            }
-            default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
+
+            default:
+                FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
+                new_source = FOGSOURCE_FFP; /* Make the compiler happy */
         }
     } else {
         glHint(GL_FOG_HINT, GL_NICEST);
         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
         context->last_was_foggy_shader = FALSE;
         }
     } else {
         glHint(GL_FOG_HINT, GL_NICEST);
         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
         context->last_was_foggy_shader = FALSE;
+        new_source = FOGSOURCE_FFP;
 
         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
             case WINED3DFOG_EXP:
                 glFogi(GL_FOG_MODE, GL_EXP);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
 
         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
             case WINED3DFOG_EXP:
                 glFogi(GL_FOG_MODE, GL_EXP);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
-                if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                    context->fog_coord = FALSE;
-                }
                 break;
 
             case WINED3DFOG_EXP2:
                 glFogi(GL_FOG_MODE, GL_EXP2);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
                 break;
 
             case WINED3DFOG_EXP2:
                 glFogi(GL_FOG_MODE, GL_EXP2);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
-                if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                    context->fog_coord = FALSE;
-                }
                 break;
 
             case WINED3DFOG_LINEAR:
                 glFogi(GL_FOG_MODE, GL_LINEAR);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
                 break;
 
             case WINED3DFOG_LINEAR:
                 glFogi(GL_FOG_MODE, GL_LINEAR);
                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-                if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
-                    glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
-                    checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
-                    context->fog_coord = FALSE;
-                }
                 break;
 
             case WINED3DFOG_NONE:   /* Won't happen */
                 break;
 
             case WINED3DFOG_NONE:   /* Won't happen */
@@ -1147,43 +1112,11 @@ static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
         }
     }
 
         }
     }
 
-    if(fogenable) {
-        glEnable(GL_FOG);
-        checkGLcall("glEnable GL_FOG");
-
-        if(fogstart != fogend)
-        {
-            glFogfv(GL_FOG_START, &fogstart);
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");
-            TRACE("Fog Start == %f\n", fogstart);
-
-            glFogfv(GL_FOG_END, &fogend);
-            checkGLcall("glFogf(GL_FOG_END, fogend)");
-            TRACE("Fog End == %f\n", fogend);
-        }
-        else
-        {
-            glFogf(GL_FOG_START, -1.0 / 0.0);
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");
-            TRACE("Fog Start == %f\n", fogstart);
-
-            glFogf(GL_FOG_END, 0.0);
-            checkGLcall("glFogf(GL_FOG_END, fogend)");
-            TRACE("Fog End == %f\n", fogend);
-        }
-    } else {
-        glDisable(GL_FOG);
-        checkGLcall("glDisable GL_FOG");
-        if( use_ps(stateblock->wineD3DDevice) ) {
-            /* disable fog in the pixel shader
-             * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
-             * -1/(e-s) and e/(e-s) respectively.
-             */
-            glFogf(GL_FOG_START, 0.0f);
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");
-            glFogf(GL_FOG_END, 1.0f);
-            checkGLcall("glFogf(GL_FOG_END, fogend)");
-        }
+    glEnableWINE(GL_FOG);
+    checkGLcall("glEnable GL_FOG");
+    if(new_source != context->fog_source) {
+        context->fog_source = new_source;
+        state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
     }
 }
 
     }
 }
 
@@ -1203,14 +1136,14 @@ static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
-static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1323,7 +1256,7 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
                 checkGLcall("glMaterialfv");
             } else {
                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
                 checkGLcall("glMaterialfv");
             } else {
-                const GLfloat black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+                static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
                 checkGLcall("glMaterialfv");
             }
                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
                 checkGLcall("glMaterialfv");
             }
@@ -1934,10 +1867,6 @@ static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTE
         op = WINED3DTOP_SELECTARG1;
     }
 
         op = WINED3DTOP_SELECTARG1;
     }
 
-        /* From MSDN (WINED3DTSS_ALPHAARG1) :
-    The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
-    then the default argument is WINED3DTA_DIFFUSE.
-    FIXME? If texture added/removed, may need to reset back as well?    */
     if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
         get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
     } else {
     if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
         get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
     } else {
@@ -2908,32 +2837,24 @@ static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTE
 
 
 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 
 
 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
-    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
+    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
 
     TRACE("Setting color op for stage %d\n", stage);
 
 
     TRACE("Setting color op for stage %d\n", stage);
 
-    if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
-        ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
-        /* Using a pixel shader? Don't care for anything here, the shader applying does it */
-        return;
-    }
+    /* Using a pixel shader? Don't care for anything here, the shader applying does it */
+    if (use_ps(stateblock)) return;
 
     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
 
     if (mapped_stage != -1) {
 
     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
 
     if (mapped_stage != -1) {
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
-                FIXME("Attempt to enable unsupported stage!\n");
-                return;
-            }
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-            checkGLcall("glActiveTextureARB");
-        } else if (stage > 0) {
-            WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+        if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
+            FIXME("Attempt to enable unsupported stage!\n");
             return;
         }
             return;
         }
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+        checkGLcall("glActiveTextureARB");
     }
 
     if(stage >= stateblock->lowest_disabled_stage) {
     }
 
     if(stage >= stateblock->lowest_disabled_stage) {
@@ -2972,26 +2893,20 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
 }
 
 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
-    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
+    BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
     DWORD op, arg1, arg2, arg0;
 
     TRACE("Setting alpha op for stage %d\n", stage);
     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
     if (mapped_stage != -1) {
     DWORD op, arg1, arg2, arg0;
 
     TRACE("Setting alpha op for stage %d\n", stage);
     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
     if (mapped_stage != -1) {
-        if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-            if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
-                FIXME("Attempt to enable unsupported stage!\n");
-                return;
-            }
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-            checkGLcall("glActiveTextureARB");
-        } else if (stage > 0) {
-            /* We can't do anything here */
-            WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+        if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
+            FIXME("Attempt to enable unsupported stage!\n");
             return;
         }
             return;
         }
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+        checkGLcall("glActiveTextureARB");
     }
 
     op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
     }
 
     op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
@@ -2999,50 +2914,64 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext
     arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
     arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
 
     arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
     arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
 
-    if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
-       stateblock->textures[0] &&
-       (stateblock->textureDimensions[0] == GL_TEXTURE_2D || stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
-        IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
+    if (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && stateblock->textures[0])
+    {
+        UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
 
 
-        if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
-           getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
+        if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+        {
+            IWineD3DSurfaceImpl *surf;
 
 
-            /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
-             * On the other hand applications can still use texture combiners apparently. This code takes care that apps
-             * cannot remove the texture's alpha channel entirely.
-             *
-             * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
-             * on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures and alpha component of diffuse color to
-             * draw things like translucent text and perform other blending effects.
-             *
-             * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To provide the
-             * behavior expected by the game, while emulating the colorkey, diffuse alpha must be modulated with texture alpha.
-             * OTOH, Moto racer 2 at some points sets alphaop/alphaarg to SELECTARG/CURRENT, yet puts garbage in diffuse alpha
-             * (zeroes). This works on native, because the game disables alpha test and alpha blending. Alpha test is overwritten by
-             * wine's for purposes of color-keying though, so this will lead to missing geometry if texture alpha is modulated
-             * (pixels fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha blending,
-             * it can be expected to provide meaningful values in diffuse alpha, so it should be modulated with texture alpha;
-             * otherwise, selecting diffuse alpha is ignored in favour of texture alpha.
-
-             * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
-             */
-            if(op == WINED3DTOP_DISABLE) {
-                arg1 = WINED3DTA_TEXTURE;
-                op = WINED3DTOP_SELECTARG1;
-            }
-            else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) {
-                if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
-                    arg2 = WINED3DTA_TEXTURE;
-                    op = WINED3DTOP_MODULATE;
-                }
-                else arg1 = WINED3DTA_TEXTURE;
-            }
-            else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) {
-                if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
+            surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
+
+            if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
+                    && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
+            {
+                /* Color keying needs to pass alpha values from the texture through to have the alpha test work
+                 * properly. On the other hand applications can still use texture combiners apparently. This code
+                 * takes care that apps cannot remove the texture's alpha channel entirely.
+                 *
+                 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
+                 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
+                 * and alpha component of diffuse color to draw things like translucent text and perform other
+                 * blending effects.
+                 *
+                 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
+                 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
+                 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
+                 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
+                 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
+                 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
+                 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
+                 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
+                 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
+                 * alpha.
+                 *
+                 * What to do with multitexturing? So far no app has been found that uses color keying with
+                 * multitexturing */
+                if (op == WINED3DTOP_DISABLE)
+                {
                     arg1 = WINED3DTA_TEXTURE;
                     arg1 = WINED3DTA_TEXTURE;
-                    op = WINED3DTOP_MODULATE;
+                    op = WINED3DTOP_SELECTARG1;
+                }
+                else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE)
+                {
+                    if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
+                    {
+                        arg2 = WINED3DTA_TEXTURE;
+                        op = WINED3DTOP_MODULATE;
+                    }
+                    else arg1 = WINED3DTA_TEXTURE;
+                }
+                else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE)
+                {
+                    if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
+                    {
+                        arg1 = WINED3DTA_TEXTURE;
+                        op = WINED3DTOP_MODULATE;
+                    }
+                    else arg2 = WINED3DTA_TEXTURE;
                 }
                 }
-                else arg2 = WINED3DTA_TEXTURE;
             }
         }
     }
             }
         }
     }
@@ -3063,31 +2992,25 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext
 }
 
 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
     BOOL generated;
     int coordIdx;
 
     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
     BOOL generated;
     int coordIdx;
 
     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
-    if(use_vs(stateblock->wineD3DDevice) ||
-       isStateDirty(context, STATE_VDECL)) {
+    if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL))
+    {
         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
         return;
     }
 
     if (mapped_stage == -1) return;
 
         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
         return;
     }
 
     if (mapped_stage == -1) return;
 
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        if(mapped_stage >= GL_LIMITS(textures)) {
-            return;
-        }
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-        checkGLcall("glActiveTextureARB");
-    } else if (mapped_stage > 0) {
-        /* We can't do anything here */
-        WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+    if(mapped_stage >= GL_LIMITS(textures)) {
         return;
     }
         return;
     }
+    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+    checkGLcall("glActiveTextureARB");
     generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
     coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1);
 
     generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
     coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1);
 
@@ -3101,7 +3024,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
                         stateblock->wineD3DDevice->frag_pipe->ffp_proj_control);
 
     /* The sampler applying function calls us if this changes */
                         stateblock->wineD3DDevice->frag_pipe->ffp_proj_control);
 
     /* The sampler applying function calls us if this changes */
-    if(context->lastWasPow2Texture[texUnit] && stateblock->textures[texUnit]) {
+    if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit])
+    {
         if(generated) {
             FIXME("Non-power2 texture being used with generated texture coords\n");
         }
         if(generated) {
             FIXME("Non-power2 texture being used with generated texture coords\n");
         }
@@ -3125,13 +3049,6 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D
     unsigned int mapped_stage = 0;
     unsigned int textureNo = 0;
 
     unsigned int mapped_stage = 0;
     unsigned int textureNo = 0;
 
-    /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
-    /* Abort if we don't support the extension. */
-    if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
-        return;
-    }
-
     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
 
     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
 
@@ -3153,7 +3070,7 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D
 
             /* The coords to supply depend completely on the fvf / vertex shader */
             glTexCoordPointer(
 
             /* The coords to supply depend completely on the fvf / vertex shader */
             glTexCoordPointer(
-                    WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
+                    WINED3D_ATR_FORMAT(sd->u.s.texCoords[coordIdx].dwType),
                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
                     sd->u.s.texCoords[coordIdx].dwStride,
                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
                     sd->u.s.texCoords[coordIdx].dwStride,
                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
@@ -3173,35 +3090,27 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D
 }
 
 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
-    const GLfloat s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
-    const GLfloat t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
-    const GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
-    const GLfloat q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
+    static const GLfloat s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
+    static const GLfloat t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
+    static const GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
+    static const GLfloat q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
 
     if (mapped_stage == -1) {
         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
         return;
     }
 
 
     if (mapped_stage == -1) {
         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
         return;
     }
 
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
-            return;
-        }
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-        checkGLcall("glActiveTextureARB");
-    } else if (stage > 0) {
-        /* We can't do anything here */
-        WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+    if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
         return;
     }
         return;
     }
+    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+    checkGLcall("glActiveTextureARB");
 
     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
      *
 
     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
      *
-     * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
-     * one flag, you can still specify an index value, which the system uses to
-     * determine the texture wrapping mode.
+     * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
      * means use the vertex position (camera-space) as the input texture coordinates
      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
      * means use the vertex position (camera-space) as the input texture coordinates
      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
@@ -3356,11 +3265,11 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
        return;
     }
 
        return;
     }
 
-    device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
+    device->shader_backend->shader_load_constants((IWineD3DDevice *)device, use_ps(stateblock), use_vs(stateblock));
 }
 
 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
 
     if(stateblock->pixelShader && stage != 0 &&
        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
 
     if(stateblock->pixelShader && stage != 0 &&
        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
@@ -3388,20 +3297,26 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, W
      * misc pipeline
      */
     if(sampler < MAX_TEXTURES) {
      * misc pipeline
      */
     if(sampler < MAX_TEXTURES) {
-        if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D ||
-           stateblock->textureDimensions[sampler] == GL_TEXTURE_RECTANGLE_ARB) {
+        UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(texture);
+
+        if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+        {
             if(((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0 ||
                ((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[5] != 1.0 ) {
                 texIsPow2 = TRUE;
             }
             if(((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0 ||
                ((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[5] != 1.0 ) {
                 texIsPow2 = TRUE;
             }
-        } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
+        }
+        else if (texture_dimensions == GL_TEXTURE_CUBE_MAP_ARB)
+        {
             if(((IWineD3DCubeTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0) {
                 texIsPow2 = TRUE;
             }
         }
 
             if(((IWineD3DCubeTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0) {
                 texIsPow2 = TRUE;
             }
         }
 
-        if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
-            context->lastWasPow2Texture[sampler] = texIsPow2;
+        if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
+        {
+            if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler;
+            else context->lastWasPow2Texture &= ~(1 << sampler);
             transform_texture(STATE_TEXTURESTAGE(stateblock->wineD3DDevice->texUnitMap[sampler], WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
         }
     }
             transform_texture(STATE_TEXTURESTAGE(stateblock->wineD3DDevice->texUnitMap[sampler], WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
         }
     }
@@ -3425,17 +3340,11 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
         return;
     }
 
         return;
     }
 
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        if (mapped_stage >= GL_LIMITS(combined_samplers)) {
-            return;
-        }
-        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
-        checkGLcall("glActiveTextureARB");
-    } else if (sampler > 0) {
-        /* We can't do anything here */
-        WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+    if (mapped_stage >= GL_LIMITS(combined_samplers)) {
         return;
     }
         return;
     }
+    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+    checkGLcall("glActiveTextureARB");
 
     if(stateblock->textures[sampler]) {
         IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
 
     if(stateblock->textures[sampler]) {
         IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
@@ -3450,7 +3359,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
             checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
         }
 
             checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
         }
 
-        if(!use_ps(stateblock->wineD3DDevice) && sampler < stateblock->lowest_disabled_stage) {
+        if (!use_ps(stateblock) && sampler < stateblock->lowest_disabled_stage)
+        {
             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
                 /* If color keying is enabled update the alpha test, it depends on the existence
                  * of a color key in stage 0
             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
                 /* If color keying is enabled update the alpha test, it depends on the existence
                  * of a color key in stage 0
@@ -3473,26 +3383,10 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
     }
 }
 
     }
 }
 
-static void apply_pshader_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
-
-    if (use_ps(device)) {
-        if(!context->last_was_pshader) {
-            state_fog(state, stateblock, context);
-        }
-        context->last_was_pshader = TRUE;
-    } else {
-        if(context->last_was_pshader) {
-            state_fog(state, stateblock, context);
-        }
-        context->last_was_pshader = FALSE;
-    }
-}
-
 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
-    BOOL use_pshader = use_ps(device);
-    BOOL use_vshader = use_vs(device);
+    BOOL use_pshader = use_ps(stateblock);
+    BOOL use_vshader = use_vs(stateblock);
     int i;
 
     if (use_pshader) {
     int i;
 
     if (use_pshader) {
@@ -3533,7 +3427,7 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
 }
 
 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
+    DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     if(stateblock->pixelShader && stage != 0 &&
        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
     if(stateblock->pixelShader && stage != 0 &&
        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
@@ -3945,7 +3839,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     for (i = 0; i < MAX_ATTRIBS; i++) {
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     for (i = 0; i < MAX_ATTRIBS; i++) {
-        if (!strided->u.input[i].VBO && !strided->u.input[i].lpData)
+        if (!(strided->use_map & (1 << i)))
         {
             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
             continue;
         {
             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
             continue;
@@ -3979,7 +3873,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
                 shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]);
                 shift_index = shift_index % strided->u.input[i].dwStride;
                 GL_EXTCALL(glVertexAttribPointerARB(i,
                 shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]);
                 shift_index = shift_index % strided->u.input[i].dwStride;
                 GL_EXTCALL(glVertexAttribPointerARB(i,
-                                WINED3D_ATR_SIZE(strided->u.input[i].dwType),
+                                WINED3D_ATR_FORMAT(strided->u.input[i].dwType),
                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
                                 vb->conv_stride,
                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
                                 vb->conv_stride,
@@ -3990,7 +3884,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
 
             } else {
                 GL_EXTCALL(glVertexAttribPointerARB(i,
 
             } else {
                 GL_EXTCALL(glVertexAttribPointerARB(i,
-                                WINED3D_ATR_SIZE(strided->u.input[i].dwType),
+                                WINED3D_ATR_FORMAT(strided->u.input[i].dwType),
                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
                                 strided->u.input[i].dwStride,
                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
                                 strided->u.input[i].dwStride,
@@ -4111,16 +4005,16 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
 
         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
 
         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
-            TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
+            TRACE("Blend %d %p %d\n", WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType),
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
 
             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
 
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
 
             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
 
-            GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1));
+            GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) + 1));
 
             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
 
             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
-                WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
+                WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) ,
                 sd->u.s.blendWeights.dwStride,
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
 
                 sd->u.s.blendWeights.dwStride,
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
 
@@ -4131,7 +4025,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
             }
 
             GL_EXTCALL(glWeightPointerARB)(
             }
 
             GL_EXTCALL(glWeightPointerARB)(
-                WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
+                WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType),
                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
                 sd->u.s.blendWeights.dwStride,
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
                 sd->u.s.blendWeights.dwStride,
                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
@@ -4183,7 +4077,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
             curVBO = sd->u.s.position.VBO;
         }
 
             curVBO = sd->u.s.position.VBO;
         }
 
-        /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
+        /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
            handling for rhw mode should not impact screen position whereas in GL it does.
            This may result in very slightly distorted textures in rhw mode.
            There's always the other option of fixing the view matrix to
            handling for rhw mode should not impact screen position whereas in GL it does.
            This may result in very slightly distorted textures in rhw mode.
            There's always the other option of fixing the view matrix to
@@ -4192,12 +4086,12 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
            This only applies to user pointer sources, in VBOs the vertices are fixed up
          */
         if(sd->u.s.position.VBO == 0) {
            This only applies to user pointer sources, in VBOs the vertices are fixed up
          */
         if(sd->u.s.position.VBO == 0) {
-            glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
+            glVertexPointer(3 /* min(WINED3D_ATR_FORMAT(sd->u.s.position.dwType),3) */,
                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
         } else {
             glVertexPointer(
                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
         } else {
             glVertexPointer(
-                WINED3D_ATR_SIZE(sd->u.s.position.dwType),
+                WINED3D_ATR_FORMAT(sd->u.s.position.dwType),
                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
         }
                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
         }
@@ -4251,7 +4145,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
             curVBO = sd->u.s.diffuse.VBO;
         }
 
             curVBO = sd->u.s.diffuse.VBO;
         }
 
-        glColorPointer(WINED3D_ATR_SIZE(sd->u.s.diffuse.dwType),
+        glColorPointer(WINED3D_ATR_FORMAT(sd->u.s.diffuse.dwType),
                        WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType),
                        sd->u.s.diffuse.dwStride,
                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
                        WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType),
                        sd->u.s.diffuse.dwStride,
                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
@@ -4277,7 +4171,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3
                 checkGLcall("glBindBufferARB");
                 curVBO = sd->u.s.specular.VBO;
             }
                 checkGLcall("glBindBufferARB");
                 curVBO = sd->u.s.specular.VBO;
             }
-            GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_SIZE(sd->u.s.specular.dwType),
+            GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_FORMAT(sd->u.s.specular.dwType),
                                                    WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType),
                                                    sd->u.s.specular.dwStride,
                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
                                                    WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType),
                                                    sd->u.s.specular.dwStride,
                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
@@ -4344,13 +4238,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     BOOL load_numbered = FALSE;
     BOOL load_named = FALSE;
 
     BOOL load_numbered = FALSE;
     BOOL load_named = FALSE;
 
-    if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
-        ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
-        useVertexShaderFunction = TRUE;
-    } else {
-        useVertexShaderFunction = FALSE;
-    }
-
+    useVertexShaderFunction = (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader) ? TRUE : FALSE;
 
     if(device->up_strided) {
         /* Note: this is a ddraw fixed-function code path */
 
     if(device->up_strided) {
         /* Note: this is a ddraw fixed-function code path */
@@ -4372,9 +4260,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
                 useVertexShaderFunction, dataLocations, &fixup);
     }
 
                 useVertexShaderFunction, dataLocations, &fixup);
     }
 
-    if (dataLocations->u.s.position_transformed) {
-        useVertexShaderFunction = FALSE;
-    }
+    if (dataLocations->position_transformed) useVertexShaderFunction = FALSE;
 
     if(useVertexShaderFunction) {
         if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
 
     if(useVertexShaderFunction) {
         if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
@@ -4384,7 +4270,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
             load_numbered = TRUE;
             device->useDrawStridedSlow = FALSE;
         }
             load_numbered = TRUE;
             device->useDrawStridedSlow = FALSE;
         }
-    } else if (fixup ||
+    } else if (fixup || GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) ||
                (dataLocations->u.s.pSize.lpData == NULL &&
                 dataLocations->u.s.diffuse.lpData == NULL &&
                 dataLocations->u.s.specular.lpData == NULL)) {
                (dataLocations->u.s.pSize.lpData == NULL &&
                 dataLocations->u.s.diffuse.lpData == NULL &&
                 dataLocations->u.s.specular.lpData == NULL)) {
@@ -4437,20 +4323,16 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
 }
 
 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
-    BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
-            && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
+    BOOL updateFog = FALSE;
+    BOOL useVertexShaderFunction = use_vs(stateblock);
+    BOOL usePixelShaderFunction = use_ps(stateblock);
     BOOL transformed;
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
 
     BOOL transformed;
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
 
-    /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
-     * here simply check whether a shader was set, or the user disabled shaders
-     */
-    if (use_vs(device)) {
-        useVertexShaderFunction = TRUE;
-
+    if (useVertexShaderFunction)
+    {
         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
             updateFog = TRUE;
         }
         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
             updateFog = TRUE;
         }
@@ -4458,9 +4340,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
         updateFog = TRUE;
     }
 
         updateFog = TRUE;
     }
 
-    transformed = device->strided_streams.u.s.position_transformed;
-    if (transformed) useVertexShaderFunction = FALSE;
-
+    transformed = device->strided_streams.position_transformed;
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
         updateFog = TRUE;
     }
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
         updateFog = TRUE;
     }
@@ -4577,7 +4457,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     context->last_was_vshader = useVertexShaderFunction;
 
     if(updateFog) {
     context->last_was_vshader = useVertexShaderFunction;
 
     if(updateFog) {
-        state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
+        device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
     }
     if(!useVertexShaderFunction) {
         int i;
     }
     if(!useVertexShaderFunction) {
         int i;
@@ -5293,13 +5173,9 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = {
     { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
       /* Fog */
     { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
       /* Fog */
-    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    }, 0                               },
     { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    }, 0                               },
     { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
@@ -5328,8 +5204,6 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = {
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
-    /* pixel shaders need a different fog input */
-    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pshader_fog   }, 0                               },
     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
@@ -5446,6 +5320,13 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }, 0                               },
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }, 0                               },
     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
     { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }, 0                               },
     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
@@ -5547,7 +5428,7 @@ static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock,
     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
 }
 
     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
 }
 
-void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
@@ -5579,6 +5460,7 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
         memset(set, 0, sizeof(set));
 
         for(i = 0; cur[i].state; i++) {
         memset(set, 0, sizeof(set));
 
         for(i = 0; cur[i].state; i++) {
+            APPLYSTATEFUNC *funcs_array;
 
             /* Only use the first matching state with the available extension from one template.
              * e.g.
 
             /* Only use the first matching state with the available extension from one template.
              * e.g.
@@ -5611,17 +5493,24 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
                                                                    0,
                                                                    sizeof(**dev_multistate_funcs) * 2);
                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
                                                                    0,
                                                                    sizeof(**dev_multistate_funcs) * 2);
+                    if (!dev_multistate_funcs[cur[i].state]) {
+                        goto out_of_mem;
+                    }
+
                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
                     break;
                 case 2:
                     StateTable[cur[i].state].apply = multistate_apply_3;
                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
                     break;
                 case 2:
                     StateTable[cur[i].state].apply = multistate_apply_3;
-                    HeapFree(GetProcessHeap(), 0, multistate_funcs[cur[i].state]);
-                    dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
-                                                                   0,
-                                                                   sizeof(**dev_multistate_funcs) * 3);
-                    dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
-                    dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
+                    funcs_array = HeapReAlloc(GetProcessHeap(),
+                                              0,
+                                              dev_multistate_funcs[cur[i].state],
+                                              sizeof(**dev_multistate_funcs) * 3);
+                    if (!funcs_array) {
+                        goto out_of_mem;
+                    }
+
+                    dev_multistate_funcs[cur[i].state] = funcs_array;
                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
                     break;
                 default:
                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
                     break;
                 default:
@@ -5637,5 +5526,16 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
             StateTable[cur[i].state].representative = cur[i].content.representative;
         }
     }
             StateTable[cur[i].state].representative = cur[i].content.representative;
         }
     }
+
+    return WINED3D_OK;
+
+out_of_mem:
+    for (i = 0; i <= STATE_HIGHEST; ++i) {
+        HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
+    }
+
+    memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
+
+    return E_OUTOFMEMORY;
 }
 #undef GLINFO_LOCATION
 }
 #undef GLINFO_LOCATION
index 3faa5a0..e1f1dd8 100644 (file)
@@ -38,28 +38,36 @@ HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) {
     
     IWineD3DStateBlockImpl *This = object;
 
     
     IWineD3DStateBlockImpl *This = object;
 
-#define WINED3D_MEMCHECK(_object) if (NULL == _object) { FIXME("Out of memory!\n"); return E_OUTOFMEMORY; }
-
     /* Allocate space for floating point constants */
     object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
     /* Allocate space for floating point constants */
     object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
-    WINED3D_MEMCHECK(object->pixelShaderConstantF);
+    if (!object->pixelShaderConstantF) goto fail;
+
     object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF));
     object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF));
-    WINED3D_MEMCHECK(object->changed.pixelShaderConstantsF);
+    if (!object->changed.pixelShaderConstantsF) goto fail;
+
     object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
     object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
-    WINED3D_MEMCHECK(object->vertexShaderConstantF);
+    if (!object->vertexShaderConstantF) goto fail;
+
     object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
     object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
-    WINED3D_MEMCHECK(object->changed.vertexShaderConstantsF);
-    object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(vshader_constantsF));
-    WINED3D_MEMCHECK(object->contained_vs_consts_f);
-    object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(pshader_constantsF));
-    WINED3D_MEMCHECK(object->contained_ps_consts_f);
+    if (!object->changed.vertexShaderConstantsF) goto fail;
 
 
-    list_init(&object->set_vconstantsF);
-    list_init(&object->set_pconstantsF);
+    object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(vshader_constantsF));
+    if (!object->contained_vs_consts_f) goto fail;
 
 
-#undef WINED3D_MEMCHECK
+    object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(pshader_constantsF));
+    if (!object->contained_ps_consts_f) goto fail;
 
     return WINED3D_OK;
 
     return WINED3D_OK;
+
+fail:
+    ERR("Failed to allocate memory\n");
+    HeapFree(GetProcessHeap(), 0, object->pixelShaderConstantF);
+    HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
+    HeapFree(GetProcessHeap(), 0, object->vertexShaderConstantF);
+    HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
+    HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
+    HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
+    return E_OUTOFMEMORY;
 }
 
 /** Copy all members of one stateblock to another */
 }
 
 /** Copy all members of one stateblock to another */
@@ -71,7 +79,6 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES *
     /* Single values */
     dest->indices = source->indices;
     dest->material = source->material;
     /* Single values */
     dest->indices = source->indices;
     dest->material = source->material;
-    dest->fvf = source->fvf;
     dest->viewport = source->viewport;
     dest->vertexDecl = source->vertexDecl;
     dest->pixelShader = source->pixelShader;
     dest->viewport = source->viewport;
     dest->vertexDecl = source->vertexDecl;
     dest->pixelShader = source->pixelShader;
@@ -79,14 +86,14 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES *
     dest->scissorRect = dest->scissorRect;
 
     /* Fixed size arrays */
     dest->scissorRect = dest->scissorRect;
 
     /* Fixed size arrays */
-    memcpy(dest->streamSource, source->streamSource, bsize * MAX_STREAMS);
-    memcpy(dest->streamFreq, source->streamFreq, bsize * MAX_STREAMS);
-    memcpy(dest->textures, source->textures, bsize * MAX_COMBINED_SAMPLERS);
-    memcpy(dest->transform, source->transform, bsize * (HIGHEST_TRANSFORMSTATE + 1));
-    memcpy(dest->renderState, source->renderState, bsize * (WINEHIGHEST_RENDER_STATE + 1));
-    memcpy(dest->textureState, source->textureState, bsize * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1));
-    memcpy(dest->samplerState, source->samplerState, bsize * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
-    memcpy(dest->clipplane, source->clipplane, bsize * MAX_CLIPPLANES);
+    dest->streamSource = source->streamSource;
+    dest->streamFreq = source->streamFreq;
+    dest->textures = source->textures;
+    memcpy(dest->transform, source->transform, sizeof(source->transform));
+    memcpy(dest->renderState, source->renderState, sizeof(source->renderState));
+    memcpy(dest->textureState, source->textureState, sizeof(source->textureState));
+    memcpy(dest->samplerState, source->samplerState, sizeof(source->samplerState));
+    dest->clipplane = source->clipplane;
     dest->pixelShaderConstantsB = source->pixelShaderConstantsB;
     dest->pixelShaderConstantsI = source->pixelShaderConstantsI;
     dest->vertexShaderConstantsB = source->vertexShaderConstantsB;
     dest->pixelShaderConstantsB = source->pixelShaderConstantsB;
     dest->pixelShaderConstantsI = source->pixelShaderConstantsI;
     dest->vertexShaderConstantsB = source->vertexShaderConstantsB;
@@ -97,6 +104,13 @@ static void stateblock_savedstates_copy(IWineD3DStateBlock* iface, SAVEDSTATES *
     memcpy(dest->vertexShaderConstantsF, source->vertexShaderConstantsF, bsize * GL_LIMITS(vshader_constantsF));
 }
 
     memcpy(dest->vertexShaderConstantsF, source->vertexShaderConstantsF, bsize * GL_LIMITS(vshader_constantsF));
 }
 
+static inline void stateblock_set_bits(DWORD *map, UINT map_size)
+{
+    DWORD mask = (1 << (map_size & 0x1f)) - 1;
+    memset(map, 0xff, (map_size >> 5) * sizeof(*map));
+    if (mask) map[map_size >> 5] = mask;
+}
+
 /** Set all members of a stateblock savedstate to the given value */
 void stateblock_savedstates_set(
     IWineD3DStateBlock* iface,
 /** Set all members of a stateblock savedstate to the given value */
 void stateblock_savedstates_set(
     IWineD3DStateBlock* iface,
@@ -109,7 +123,6 @@ void stateblock_savedstates_set(
     /* Single values */
     states->indices = value;
     states->material = value;
     /* Single values */
     states->indices = value;
     states->material = value;
-    states->fvf = value;
     states->viewport = value;
     states->vertexDecl = value;
     states->pixelShader = value;
     states->viewport = value;
     states->vertexDecl = value;
     states->pixelShader = value;
@@ -117,18 +130,37 @@ void stateblock_savedstates_set(
     states->scissorRect = value;
 
     /* Fixed size arrays */
     states->scissorRect = value;
 
     /* Fixed size arrays */
-    memset(states->streamSource, value, bsize * MAX_STREAMS);
-    memset(states->streamFreq, value, bsize * MAX_STREAMS);
-    memset(states->textures, value, bsize * MAX_COMBINED_SAMPLERS);
-    memset(states->transform, value, bsize * (HIGHEST_TRANSFORMSTATE + 1));
-    memset(states->renderState, value, bsize * (WINEHIGHEST_RENDER_STATE + 1));
-    memset(states->textureState, value, bsize * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1));
-    memset(states->samplerState, value, bsize * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
-    memset(states->clipplane, value, bsize * MAX_CLIPPLANES);
-    states->pixelShaderConstantsB = value ? 0xffff : 0;
-    states->pixelShaderConstantsI = value ? 0xffff : 0;
-    states->vertexShaderConstantsB = value ? 0xffff : 0;
-    states->vertexShaderConstantsI = value ? 0xffff : 0;
+    if (value)
+    {
+        int i;
+        states->streamSource = 0xffff;
+        states->streamFreq = 0xffff;
+        states->textures = 0xfffff;
+        stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
+        stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
+        for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
+        for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3fff;
+        states->clipplane = 0xffffffff;
+        states->pixelShaderConstantsB = 0xffff;
+        states->pixelShaderConstantsI = 0xffff;
+        states->vertexShaderConstantsB = 0xffff;
+        states->vertexShaderConstantsI = 0xffff;
+    }
+    else
+    {
+        states->streamSource = 0;
+        states->streamFreq = 0;
+        states->textures = 0;
+        memset(states->transform, 0, sizeof(states->transform));
+        memset(states->renderState, 0, sizeof(states->renderState));
+        memset(states->textureState, 0, sizeof(states->textureState));
+        memset(states->samplerState, 0, sizeof(states->samplerState));
+        states->clipplane = 0;
+        states->pixelShaderConstantsB = 0;
+        states->pixelShaderConstantsI = 0;
+        states->vertexShaderConstantsB = 0;
+        states->vertexShaderConstantsI = 0;
+    }
 
     /* Dynamically sized arrays */
     memset(states->pixelShaderConstantsF, value, bsize * GL_LIMITS(pshader_constantsF));
 
     /* Dynamically sized arrays */
     memset(states->pixelShaderConstantsF, value, bsize * GL_LIMITS(pshader_constantsF));
@@ -156,7 +188,6 @@ void stateblock_copy(
     stateblock_savedstates_copy(source, &Dest->changed, &This->changed);
 
     /* Single items */
     stateblock_savedstates_copy(source, &Dest->changed, &This->changed);
 
     /* Single items */
-    Dest->fvf = This->fvf;
     Dest->vertexDecl = This->vertexDecl;
     Dest->vertexShader = This->vertexShader;
     Dest->streamIsUP = This->streamIsUP;
     Dest->vertexDecl = This->vertexDecl;
     Dest->vertexShader = This->vertexShader;
     Dest->streamIsUP = This->streamIsUP;
@@ -203,7 +234,6 @@ void stateblock_copy(
     memcpy(Dest->clipplane,    This->clipplane,    sizeof(double) * MAX_CLIPPLANES * 4);
     memcpy(Dest->renderState,  This->renderState,  sizeof(DWORD) * (WINEHIGHEST_RENDER_STATE + 1));
     memcpy(Dest->textures,     This->textures,     sizeof(IWineD3DBaseTexture*) * MAX_COMBINED_SAMPLERS);
     memcpy(Dest->clipplane,    This->clipplane,    sizeof(double) * MAX_CLIPPLANES * 4);
     memcpy(Dest->renderState,  This->renderState,  sizeof(DWORD) * (WINEHIGHEST_RENDER_STATE + 1));
     memcpy(Dest->textures,     This->textures,     sizeof(IWineD3DBaseTexture*) * MAX_COMBINED_SAMPLERS);
-    memcpy(Dest->textureDimensions, This->textureDimensions, sizeof(int) * MAX_COMBINED_SAMPLERS);
     memcpy(Dest->textureState, This->textureState, sizeof(DWORD) * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1));
     memcpy(Dest->samplerState, This->samplerState, sizeof(DWORD) * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
 
     memcpy(Dest->textureState, This->textureState, sizeof(DWORD) * MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1));
     memcpy(Dest->samplerState, This->samplerState, sizeof(DWORD) * MAX_COMBINED_SAMPLERS * (WINED3D_HIGHEST_SAMPLER_STATE + 1));
 
@@ -245,7 +275,6 @@ static ULONG  WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
 
     if (!refCount) {
     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
 
     if (!refCount) {
-        constants_entry *constant, *constant2;
         int counter;
 
         /* type 0 represents the primary stateblock, so free all the resources */
         int counter;
 
         /* type 0 represents the primary stateblock, so free all the resources */
@@ -287,15 +316,6 @@ static ULONG  WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
         HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
         HeapFree(GetProcessHeap(), 0, This->contained_vs_consts_f);
         HeapFree(GetProcessHeap(), 0, This->contained_ps_consts_f);
         HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
         HeapFree(GetProcessHeap(), 0, This->contained_vs_consts_f);
         HeapFree(GetProcessHeap(), 0, This->contained_ps_consts_f);
-
-        LIST_FOR_EACH_ENTRY_SAFE(constant, constant2, &This->set_vconstantsF, constants_entry, entry) {
-            HeapFree(GetProcessHeap(), 0, constant);
-        }
-
-        LIST_FOR_EACH_ENTRY_SAFE(constant, constant2, &This->set_pconstantsF, constants_entry, entry) {
-            HeapFree(GetProcessHeap(), 0, constant);
-        }
-
         HeapFree(GetProcessHeap(), 0, This);
     }
     return refCount;
         HeapFree(GetProcessHeap(), 0, This);
     }
     return refCount;
@@ -378,6 +398,7 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
     IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
     IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
     unsigned int i, j;
     IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
     IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
     unsigned int i, j;
+    DWORD map;
 
     TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This);
 
 
     TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This);
 
@@ -396,11 +417,11 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Vertex Shader Float Constants */
         for (j = 0; j < This->num_contained_vs_consts_f; ++j) {
             i = This->contained_vs_consts_f[j];
         /* Vertex Shader Float Constants */
         for (j = 0; j < This->num_contained_vs_consts_f; ++j) {
             i = This->contained_vs_consts_f[j];
-            TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i,
-                targetStateBlock->vertexShaderConstantF[i * 4],
-                targetStateBlock->vertexShaderConstantF[i * 4 + 1],
-                targetStateBlock->vertexShaderConstantF[i * 4 + 2],
-                targetStateBlock->vertexShaderConstantF[i * 4 + 3]);
+            TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
+                    targetStateBlock->vertexShaderConstantF[i * 4],
+                    targetStateBlock->vertexShaderConstantF[i * 4 + 1],
+                    targetStateBlock->vertexShaderConstantF[i * 4 + 2],
+                    targetStateBlock->vertexShaderConstantF[i * 4 + 3]);
 
             This->vertexShaderConstantF[i * 4]      = targetStateBlock->vertexShaderConstantF[i * 4];
             This->vertexShaderConstantF[i * 4 + 1]  = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
 
             This->vertexShaderConstantF[i * 4]      = targetStateBlock->vertexShaderConstantF[i * 4];
             This->vertexShaderConstantF[i * 4 + 1]  = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
@@ -411,11 +432,11 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Vertex Shader Integer Constants */
         for (j = 0; j < This->num_contained_vs_consts_i; ++j) {
             i = This->contained_vs_consts_i[j];
         /* Vertex Shader Integer Constants */
         for (j = 0; j < This->num_contained_vs_consts_i; ++j) {
             i = This->contained_vs_consts_i[j];
-            TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i,
-                targetStateBlock->vertexShaderConstantI[i * 4],
-                targetStateBlock->vertexShaderConstantI[i * 4 + 1],
-                targetStateBlock->vertexShaderConstantI[i * 4 + 2],
-                targetStateBlock->vertexShaderConstantI[i * 4 + 3]);
+            TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
+                    targetStateBlock->vertexShaderConstantI[i * 4],
+                    targetStateBlock->vertexShaderConstantI[i * 4 + 1],
+                    targetStateBlock->vertexShaderConstantI[i * 4 + 2],
+                    targetStateBlock->vertexShaderConstantI[i * 4 + 3]);
 
             This->vertexShaderConstantI[i * 4]      = targetStateBlock->vertexShaderConstantI[i * 4];
             This->vertexShaderConstantI[i * 4 + 1]  = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
 
             This->vertexShaderConstantI[i * 4]      = targetStateBlock->vertexShaderConstantI[i * 4];
             This->vertexShaderConstantI[i * 4 + 1]  = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
@@ -426,8 +447,8 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Vertex Shader Boolean Constants */
         for (j = 0; j < This->num_contained_vs_consts_b; ++j) {
             i = This->contained_vs_consts_b[j];
         /* Vertex Shader Boolean Constants */
         for (j = 0; j < This->num_contained_vs_consts_b; ++j) {
             i = This->contained_vs_consts_b[j];
-            TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i,
-                targetStateBlock->vertexShaderConstantB[i]? "TRUE":"FALSE");
+            TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
+                    targetStateBlock->vertexShaderConstantB[i] ? "TRUE" : "FALSE");
 
             This->vertexShaderConstantB[i] =  targetStateBlock->vertexShaderConstantB[i];
         }
 
             This->vertexShaderConstantB[i] =  targetStateBlock->vertexShaderConstantB[i];
         }
@@ -435,11 +456,11 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Pixel Shader Float Constants */
         for (j = 0; j < This->num_contained_ps_consts_f; ++j) {
             i = This->contained_ps_consts_f[j];
         /* Pixel Shader Float Constants */
         for (j = 0; j < This->num_contained_ps_consts_f; ++j) {
             i = This->contained_ps_consts_f[j];
-            TRACE("Setting %p from %p %d to { %f, %f, %f, %f }\n", This, targetStateBlock, i,
-                targetStateBlock->pixelShaderConstantF[i * 4],
-                targetStateBlock->pixelShaderConstantF[i * 4 + 1],
-                targetStateBlock->pixelShaderConstantF[i * 4 + 2],
-                targetStateBlock->pixelShaderConstantF[i * 4 + 3]);
+            TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
+                    targetStateBlock->pixelShaderConstantF[i * 4],
+                    targetStateBlock->pixelShaderConstantF[i * 4 + 1],
+                    targetStateBlock->pixelShaderConstantF[i * 4 + 2],
+                    targetStateBlock->pixelShaderConstantF[i * 4 + 3]);
 
             This->pixelShaderConstantF[i * 4]      = targetStateBlock->pixelShaderConstantF[i * 4];
             This->pixelShaderConstantF[i * 4 + 1]  = targetStateBlock->pixelShaderConstantF[i * 4 + 1];
 
             This->pixelShaderConstantF[i * 4]      = targetStateBlock->pixelShaderConstantF[i * 4];
             This->pixelShaderConstantF[i * 4 + 1]  = targetStateBlock->pixelShaderConstantF[i * 4 + 1];
@@ -450,11 +471,11 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Pixel Shader Integer Constants */
         for (j = 0; j < This->num_contained_ps_consts_i; ++j) {
             i = This->contained_ps_consts_i[j];
         /* Pixel Shader Integer Constants */
         for (j = 0; j < This->num_contained_ps_consts_i; ++j) {
             i = This->contained_ps_consts_i[j];
-            TRACE("Setting %p from %p %d to { %d, %d, %d, %d }\n", This, targetStateBlock, i,
-                targetStateBlock->pixelShaderConstantI[i * 4],
-                targetStateBlock->pixelShaderConstantI[i * 4 + 1],
-                targetStateBlock->pixelShaderConstantI[i * 4 + 2],
-                targetStateBlock->pixelShaderConstantI[i * 4 + 3]);
+            TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
+                    targetStateBlock->pixelShaderConstantI[i * 4],
+                    targetStateBlock->pixelShaderConstantI[i * 4 + 1],
+                    targetStateBlock->pixelShaderConstantI[i * 4 + 2],
+                    targetStateBlock->pixelShaderConstantI[i * 4 + 3]);
 
             This->pixelShaderConstantI[i * 4]      = targetStateBlock->pixelShaderConstantI[i * 4];
             This->pixelShaderConstantI[i * 4 + 1]  = targetStateBlock->pixelShaderConstantI[i * 4 + 1];
 
             This->pixelShaderConstantI[i * 4]      = targetStateBlock->pixelShaderConstantI[i * 4];
             This->pixelShaderConstantI[i * 4 + 1]  = targetStateBlock->pixelShaderConstantI[i * 4 + 1];
@@ -465,23 +486,23 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         /* Pixel Shader Boolean Constants */
         for (j = 0; j < This->num_contained_ps_consts_b; ++j) {
             i = This->contained_ps_consts_b[j];
         /* Pixel Shader Boolean Constants */
         for (j = 0; j < This->num_contained_ps_consts_b; ++j) {
             i = This->contained_ps_consts_b[j];
-            TRACE("Setting %p from %p %d to %s\n", This, targetStateBlock, i,
-                targetStateBlock->pixelShaderConstantB[i]? "TRUE":"FALSE");
+            TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
+                    targetStateBlock->pixelShaderConstantB[i] ? "TRUE" : "FALSE");
 
             This->pixelShaderConstantB[i] =  targetStateBlock->pixelShaderConstantB[i];
         }
 
         /* Others + Render & Texture */
         for (i = 0; i < This->num_contained_transform_states; i++) {
 
             This->pixelShaderConstantB[i] =  targetStateBlock->pixelShaderConstantB[i];
         }
 
         /* Others + Render & Texture */
         for (i = 0; i < This->num_contained_transform_states; i++) {
-            TRACE("Updating transform %d\n", i);
+            TRACE("Updating transform %u\n", i);
             This->transforms[This->contained_transform_states[i]] =
                 targetStateBlock->transforms[This->contained_transform_states[i]];
         }
 
         if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
                         || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
             This->transforms[This->contained_transform_states[i]] =
                 targetStateBlock->transforms[This->contained_transform_states[i]];
         }
 
         if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
                         || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
-            TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
-                  targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
+            TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n",
+                    targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
             if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
             if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
             This->pIndexData = targetStateBlock->pIndexData;
             if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
             if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
             This->pIndexData = targetStateBlock->pIndexData;
@@ -494,10 +515,6 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
             This->vertexDecl = targetStateBlock->vertexDecl;
         }
 
             This->vertexDecl = targetStateBlock->vertexDecl;
         }
 
-        if(This->changed.fvf && This->fvf != targetStateBlock->fvf){
-            This->fvf = targetStateBlock->fvf;
-        }
-
         if (This->changed.material && memcmp(&targetStateBlock->material,
                                                     &This->material,
                                                     sizeof(WINED3DMATERIAL)) != 0) {
         if (This->changed.material && memcmp(&targetStateBlock->material,
                                                     &This->material,
                                                     sizeof(WINED3DMATERIAL)) != 0) {
@@ -520,43 +537,54 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
             targetStateBlock->scissorRect = This->scissorRect;
         }
 
             targetStateBlock->scissorRect = This->scissorRect;
         }
 
-        for (i = 0; i < MAX_STREAMS; i++) {
-            if (This->changed.streamSource[i] &&
-                            ((This->streamStride[i] != targetStateBlock->streamStride[i]) ||
-                            (This->streamSource[i] != targetStateBlock->streamSource[i]))) {
-                TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i],
-                                                                            targetStateBlock->streamStride[i]);
+        map = This->changed.streamSource;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
+
+            if (This->streamStride[i] != targetStateBlock->streamStride[i]
+                    || This->streamSource[i] != targetStateBlock->streamSource[i])
+            {
+                TRACE("Updating stream source %u to %p, stride to %u\n",
+                        i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]);
                 This->streamStride[i] = targetStateBlock->streamStride[i];
                 if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
                 if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
                 This->streamSource[i] = targetStateBlock->streamSource[i];
             }
                 This->streamStride[i] = targetStateBlock->streamStride[i];
                 if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
                 if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
                 This->streamSource[i] = targetStateBlock->streamSource[i];
             }
+        }
 
 
-            if (This->changed.streamFreq[i] &&
-            (This->streamFreq[i] != targetStateBlock->streamFreq[i]
-            || This->streamFlags[i] != targetStateBlock->streamFlags[i])){
-                    TRACE("Updating stream frequency %d to %d flags to %d\n", i ,  targetStateBlock->streamFreq[i] ,
-                                                                                   targetStateBlock->streamFlags[i]);
-                    This->streamFreq[i]  =  targetStateBlock->streamFreq[i];
-                    This->streamFlags[i] =  targetStateBlock->streamFlags[i];
+        map = This->changed.streamFreq;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
+
+            if (This->streamFreq[i] != targetStateBlock->streamFreq[i]
+                    || This->streamFlags[i] != targetStateBlock->streamFlags[i])
+            {
+                TRACE("Updating stream frequency %u to %u flags to %#x\n",
+                        i, targetStateBlock->streamFreq[i], targetStateBlock->streamFlags[i]);
+                This->streamFreq[i] = targetStateBlock->streamFreq[i];
+                This->streamFlags[i] = targetStateBlock->streamFlags[i];
             }
         }
 
             }
         }
 
-        for (i = 0; i < GL_LIMITS(clipplanes); i++) {
-            if (This->changed.clipplane[i] && memcmp(&targetStateBlock->clipplane[i],
-                                                        &This->clipplane[i],
-                                                        sizeof(This->clipplane)) != 0) {
+        map = This->changed.clipplane;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
 
 
-                TRACE("Updating clipplane %d\n", i);
-                memcpy(&This->clipplane[i], &targetStateBlock->clipplane[i],
-                                        sizeof(This->clipplane));
+            if (memcmp(targetStateBlock->clipplane[i], This->clipplane[i], sizeof(*This->clipplane)))
+            {
+                TRACE("Updating clipplane %u\n", i);
+                memcpy(This->clipplane[i], targetStateBlock->clipplane[i], sizeof(*This->clipplane));
             }
         }
 
         /* Render */
         for (i = 0; i < This->num_contained_render_states; i++) {
             }
         }
 
         /* Render */
         for (i = 0; i < This->num_contained_render_states; i++) {
-            TRACE("Updating renderState %d to %d\n",
-                  This->contained_render_states[i], targetStateBlock->renderState[This->contained_render_states[i]]);
+            TRACE("Updating renderState %u to %u\n", This->contained_render_states[i],
+                    targetStateBlock->renderState[This->contained_render_states[i]]);
             This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]];
         }
 
             This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]];
         }
 
@@ -565,26 +593,27 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
             DWORD stage = This->contained_tss_states[j].stage;
             DWORD state = This->contained_tss_states[j].state;
 
             DWORD stage = This->contained_tss_states[j].stage;
             DWORD state = This->contained_tss_states[j].state;
 
-            TRACE("Updating texturestagestate %d,%d to %d (was %d)\n", stage,state,
-                  targetStateBlock->textureState[stage][state], This->textureState[stage][state]);
-                    This->textureState[stage][state] =  targetStateBlock->textureState[stage][state];
+            TRACE("Updating texturestage state %u, %u to %u (was %u)\n", stage, state,
+                    targetStateBlock->textureState[stage][state], This->textureState[stage][state]);
+            This->textureState[stage][state] = targetStateBlock->textureState[stage][state];
         }
 
         /* Samplers */
         /* TODO: move over to using memcpy */
         }
 
         /* Samplers */
         /* TODO: move over to using memcpy */
-        for (j = 0; j < MAX_COMBINED_SAMPLERS; j++) {
-            if (This->changed.textures[j]) {
-                TRACE("Updating texture %d to %p (was %p)\n", j, targetStateBlock->textures[j],  This->textures[j]);
-                This->textures[j] = targetStateBlock->textures[j];
-            }
+        map = This->changed.textures;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
+
+            TRACE("Updating texture %u to %p (was %p)\n", i, targetStateBlock->textures[i], This->textures[i]);
+            This->textures[i] = targetStateBlock->textures[i];
         }
 
         for (j = 0; j < This->num_contained_sampler_states; j++) {
             DWORD stage = This->contained_sampler_states[j].stage;
             DWORD state = This->contained_sampler_states[j].state;
         }
 
         for (j = 0; j < This->num_contained_sampler_states; j++) {
             DWORD stage = This->contained_sampler_states[j].stage;
             DWORD state = This->contained_sampler_states[j].state;
-            TRACE("Updating sampler state %d,%d to %d (was %d)\n",
-                stage, state, targetStateBlock->samplerState[stage][state],
-                This->samplerState[stage][state]);
+            TRACE("Updating sampler state %u, %u to %u (was %u)\n", stage, state,
+                    targetStateBlock->samplerState[stage][state], This->samplerState[stage][state]);
             This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state];
         }
         if(This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) {
             This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state];
         }
         if(This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) {
@@ -615,7 +644,6 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
         memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState));
         memcpy(This->textures, targetStateBlock->textures, sizeof(This->textures));
         memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
         memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState));
         memcpy(This->textures, targetStateBlock->textures, sizeof(This->textures));
-        memcpy(This->textureDimensions, targetStateBlock->textureDimensions, sizeof(This->textureDimensions));
         memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
         memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
         This->scissorRect = targetStateBlock->scissorRect;
         memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
         memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
         This->scissorRect = targetStateBlock->scissorRect;
@@ -728,6 +756,7 @@ should really perform a delta so that only the changes get updated*/
 
     UINT i;
     UINT j;
 
     UINT i;
     UINT j;
+    DWORD map;
 
     TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
 
 
     TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
 
@@ -780,7 +809,7 @@ should really perform a delta so that only the changes get updated*/
             DWORD stage = This->contained_tss_states[i].stage;
             DWORD state = This->contained_tss_states[i].state;
             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state]         = This->textureState[stage][state];
             DWORD stage = This->contained_tss_states[i].stage;
             DWORD state = This->contained_tss_states[i].state;
             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state]         = This->textureState[stage][state];
-            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage][state] = TRUE;
+            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage] |= 1 << state;
             /* TODO: Record a display list to apply all gl states. For now apply by brute force */
             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
         }
             /* TODO: Record a display list to apply all gl states. For now apply by brute force */
             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
         }
@@ -789,7 +818,7 @@ should really perform a delta so that only the changes get updated*/
             DWORD stage = This->contained_sampler_states[i].stage;
             DWORD state = This->contained_sampler_states[i].state;
             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state]         = This->samplerState[stage][state];
             DWORD stage = This->contained_sampler_states[i].stage;
             DWORD state = This->contained_sampler_states[i].state;
             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state]         = This->samplerState[stage][state];
-            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage][state] = TRUE;
+            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage] |= 1 << state;
             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
         }
 
             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
         }
 
@@ -803,10 +832,6 @@ should really perform a delta so that only the changes get updated*/
             IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
         }
 
             IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
         }
 
-        if (This->changed.fvf) {
-            IWineD3DDevice_SetFVF(pDevice, This->fvf);
-        }
-
         if (This->changed.vertexDecl) {
             IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
         }
         if (This->changed.vertexDecl) {
             IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
         }
@@ -824,35 +849,41 @@ should really perform a delta so that only the changes get updated*/
         }
 
         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
         }
 
         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
-        for (i=0; i<MAX_STREAMS; i++) {
-            if (This->changed.streamSource[i])
-                IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
-
-            if (This->changed.streamFreq[i])
-                IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
+        map = This->changed.streamSource;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
         }
         }
-        for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
-            if (This->changed.textures[j]) {
-                if (j < MAX_FRAGMENT_SAMPLERS) {
-                    IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
-                } else {
-                    IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS, This->textures[j]);
-                }
-            }
+
+        map = This->changed.streamFreq;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
         }
 
         }
 
-        for (i = 0; i < GL_LIMITS(clipplanes); i++) {
-            if (This->changed.clipplane[i]) {
-                float clip[4];
-
-                clip[0] = This->clipplane[i][0];
-                clip[1] = This->clipplane[i][1];
-                clip[2] = This->clipplane[i][2];
-                clip[3] = This->clipplane[i][3];
-                IWineD3DDevice_SetClipPlane(pDevice, i, clip);
-            }
+        map = This->changed.textures;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
+
+            if (i < MAX_FRAGMENT_SAMPLERS) IWineD3DDevice_SetTexture(pDevice, i, This->textures[i]);
+            else IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS,
+                    This->textures[i]);
         }
 
         }
 
+        map = This->changed.clipplane;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            float clip[4];
+
+            if (!(map & 1)) continue;
+
+            clip[0] = This->clipplane[i][0];
+            clip[1] = This->clipplane[i][1];
+            clip[2] = This->clipplane[i][2];
+            clip[3] = This->clipplane[i][3];
+            IWineD3DDevice_SetClipPlane(pDevice, i, clip);
+        }
     } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
         IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
         for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
     } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
         IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
         for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
@@ -968,7 +999,8 @@ should really perform a delta so that only the changes get updated*/
             IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
         }
         for(j = 0; j < MAX_TEXTURES; j++) {
             IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
         }
         for(j = 0; j < MAX_TEXTURES; j++) {
-            for(i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE; i++) {
+            for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
+            {
                 IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
             }
         }
                 IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
             }
         }
@@ -979,7 +1011,6 @@ should really perform a delta so that only the changes get updated*/
         }
         IWineD3DDevice_SetIndices(pDevice, This->pIndexData);
         IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
         }
         IWineD3DDevice_SetIndices(pDevice, This->pIndexData);
         IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
-        IWineD3DDevice_SetFVF(pDevice, This->fvf);
         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
         IWineD3DDevice_SetMaterial(pDevice, &This->material);
         IWineD3DDevice_SetViewport(pDevice, &This->viewport);
         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
         IWineD3DDevice_SetMaterial(pDevice, &This->material);
         IWineD3DDevice_SetViewport(pDevice, &This->viewport);
@@ -994,7 +1025,8 @@ should really perform a delta so that only the changes get updated*/
             UINT sampler = j < MAX_FRAGMENT_SAMPLERS ? j : WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS;
 
             IWineD3DDevice_SetTexture(pDevice, sampler, This->textures[j]);
             UINT sampler = j < MAX_FRAGMENT_SAMPLERS ? j : WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS;
 
             IWineD3DDevice_SetTexture(pDevice, sampler, This->textures[j]);
-            for(i = 1; i < WINED3D_HIGHEST_SAMPLER_STATE; i++) {
+            for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; ++i)
+            {
                 IWineD3DDevice_SetSamplerState(pDevice, sampler, i, This->samplerState[j][i]);
             }
         }
                 IWineD3DDevice_SetSamplerState(pDevice, sampler, i, This->samplerState[j][i]);
             }
         }
@@ -1125,7 +1157,7 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
     IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
     tmpfloat.f = 1.0f;
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
     tmpfloat.f = 1.0f;
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
-    tmpfloat.f = 1.0f;
+    tmpfloat.f = ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion < 9 ? 0.0f : 1.0f;
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
@@ -1141,7 +1173,7 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
     tmpfloat.f = 1.0f;
     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        0xbaadcafe);
     tmpfloat.f = 1.0f;
     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        0xbaadcafe);
-    tmpfloat.f = 64.0f;
+    tmpfloat.f = GL_LIMITS(pointsize);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
@@ -1211,7 +1243,6 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
         This->textureState[i][WINED3DTSS_BUMPENVLSCALE         ] = 0;
         This->textureState[i][WINED3DTSS_BUMPENVLOFFSET        ] = 0;
         This->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS ] = WINED3DTTFF_DISABLE;
         This->textureState[i][WINED3DTSS_BUMPENVLSCALE         ] = 0;
         This->textureState[i][WINED3DTSS_BUMPENVLOFFSET        ] = 0;
         This->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS ] = WINED3DTTFF_DISABLE;
-        This->textureState[i][WINED3DTSS_ADDRESSW              ] = WINED3DTADDRESS_WRAP;
         This->textureState[i][WINED3DTSS_COLORARG0             ] = WINED3DTA_CURRENT;
         This->textureState[i][WINED3DTSS_ALPHAARG0             ] = WINED3DTA_CURRENT;
         This->textureState[i][WINED3DTSS_RESULTARG             ] = WINED3DTA_CURRENT;
         This->textureState[i][WINED3DTSS_COLORARG0             ] = WINED3DTA_CURRENT;
         This->textureState[i][WINED3DTSS_ALPHAARG0             ] = WINED3DTA_CURRENT;
         This->textureState[i][WINED3DTSS_RESULTARG             ] = WINED3DTA_CURRENT;
@@ -1238,7 +1269,7 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
 
     for(i = 0; i < GL_LIMITS(textures); i++) {
         /* Note: This avoids calling SetTexture, so pretend it has been called */
 
     for(i = 0; i < GL_LIMITS(textures); i++) {
         /* Note: This avoids calling SetTexture, so pretend it has been called */
-        This->changed.textures[i] = TRUE;
+        This->changed.textures |= 1 << i;
         This->textures[i]         = NULL;
     }
 
         This->textures[i]         = NULL;
     }
 
@@ -1249,6 +1280,8 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
     hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
     if( hr == WINED3D_OK && swapchain != NULL) {
     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
     hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
     if( hr == WINED3D_OK && swapchain != NULL) {
+        WINED3DVIEWPORT vp;
+
         hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
         if( hr == WINED3D_OK && backbuffer != NULL) {
             IWineD3DSurface_GetDesc(backbuffer, &desc);
         hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
         if( hr == WINED3D_OK && backbuffer != NULL) {
             IWineD3DSurface_GetDesc(backbuffer, &desc);
@@ -1263,6 +1296,16 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
                 ERR("This should never happen, expect rendering issues!\n");
             }
         }
                 ERR("This should never happen, expect rendering issues!\n");
             }
         }
+
+        /* Set the default viewport */
+        vp.X      = 0;
+        vp.Y      = 0;
+        vp.Width  = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferWidth;
+        vp.Height = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferHeight;
+        vp.MinZ   = 0.0f;
+        vp.MaxZ   = 1.0f;
+        IWineD3DDevice_SetViewport(device, &vp);
+
         IWineD3DSwapChain_Release(swapchain);
     }
 
         IWineD3DSwapChain_Release(swapchain);
     }
 
index 0191403..03d483a 100644 (file)
@@ -99,15 +99,11 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This) {
      *
      * TODO: Track the current active texture per GL context instead of using glGet
      */
      *
      * TODO: Track the current active texture per GL context instead of using glGet
      */
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-        GLint active_texture;
-        ENTER_GL();
-        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
-        LEAVE_GL();
-        active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
-    } else {
-        active_sampler = 0;
-    }
+    GLint active_texture;
+    ENTER_GL();
+    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+    LEAVE_GL();
+    active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
 
     if (active_sampler != -1) {
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
 
     if (active_sampler != -1) {
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
@@ -480,6 +476,43 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchai
     return GL_BACK;
 }
 
     return GL_BACK;
 }
 
+/* Slightly inefficient way to handle multiple dirty rects but it works :) */
+void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect)
+{
+    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+    IWineD3DBaseTexture *baseTexture = NULL;
+
+    if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE))
+        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);
+
+    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
+    if (dirty_rect)
+    {
+        This->dirtyRect.left = min(This->dirtyRect.left, dirty_rect->left);
+        This->dirtyRect.top = min(This->dirtyRect.top, dirty_rect->top);
+        This->dirtyRect.right = max(This->dirtyRect.right, dirty_rect->right);
+        This->dirtyRect.bottom = max(This->dirtyRect.bottom, dirty_rect->bottom);
+    }
+    else
+    {
+        This->dirtyRect.left = 0;
+        This->dirtyRect.top = 0;
+        This->dirtyRect.right = This->currentDesc.Width;
+        This->dirtyRect.bottom = This->currentDesc.Height;
+    }
+
+    TRACE("(%p) : Dirty: yes, Rect:(%d, %d, %d, %d)\n", This, This->dirtyRect.left,
+            This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
+
+    /* if the container is a basetexture then mark it dirty. */
+    if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
+    {
+        TRACE("Passing to container\n");
+        IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
+        IWineD3DBaseTexture_Release(baseTexture);
+    }
+}
+
 static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
@@ -695,6 +728,9 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
     BOOL bpp;
     RECT local_rect;
     BOOL srcIsUpsideDown;
     BOOL bpp;
     RECT local_rect;
     BOOL srcIsUpsideDown;
+    GLint rowLen = 0;
+    GLint skipPix = 0;
+    GLint skipRow = 0;
 
     if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) {
         static BOOL warned = FALSE;
 
     if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) {
         static BOOL warned = FALSE;
@@ -790,14 +826,42 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
     if(This->Flags & SFLAG_PBO) {
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
         checkGLcall("glBindBufferARB");
     if(This->Flags & SFLAG_PBO) {
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
         checkGLcall("glBindBufferARB");
+        if(mem != NULL) {
+            ERR("mem not null for pbo -- unexpected\n");
+            mem = NULL;
+        }
     }
 
     }
 
-    glReadPixels(local_rect.left, local_rect.top,
+    /* Save old pixel store pack state */
+    glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
+    checkGLcall("glIntegerv");
+    glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
+    checkGLcall("glIntegerv");
+    glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
+    checkGLcall("glIntegerv");
+
+    /* Setup pixel store pack state -- to glReadPixels into the correct place */
+    glPixelStorei(GL_PACK_ROW_LENGTH, This->currentDesc.Width);
+    checkGLcall("glPixelStorei");
+    glPixelStorei(GL_PACK_SKIP_PIXELS, local_rect.left);
+    checkGLcall("glPixelStorei");
+    glPixelStorei(GL_PACK_SKIP_ROWS, local_rect.top);
+    checkGLcall("glPixelStorei");
+
+    glReadPixels(local_rect.left, (!srcIsUpsideDown) ? (This->currentDesc.Height - local_rect.bottom) : local_rect.top ,
                  local_rect.right - local_rect.left,
                  local_rect.bottom - local_rect.top,
                  fmt, type, mem);
     checkGLcall("glReadPixels");
 
                  local_rect.right - local_rect.left,
                  local_rect.bottom - local_rect.top,
                  fmt, type, mem);
     checkGLcall("glReadPixels");
 
+    /* Reset previous pixel store pack state */
+    glPixelStorei(GL_PACK_ROW_LENGTH, rowLen);
+    checkGLcall("glPixelStorei");
+    glPixelStorei(GL_PACK_SKIP_PIXELS, skipPix);
+    checkGLcall("glPixelStorei");
+    glPixelStorei(GL_PACK_SKIP_ROWS, skipRow);
+    checkGLcall("glPixelStorei");
+
     if(This->Flags & SFLAG_PBO) {
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
         checkGLcall("glBindBufferARB");
     if(This->Flags & SFLAG_PBO) {
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
         checkGLcall("glBindBufferARB");
@@ -832,7 +896,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
         }
 
         top = mem + pitch * local_rect.top;
         }
 
         top = mem + pitch * local_rect.top;
-        bottom = mem + pitch * ( local_rect.bottom - local_rect.top - 1);
+        bottom = mem + pitch * (local_rect.bottom - 1);
         for(i = 0; i < (local_rect.bottom - local_rect.top) / 2; i++) {
             memcpy(row, top + off, len);
             memcpy(top + off, bottom + off, len);
         for(i = 0; i < (local_rect.bottom - local_rect.top) / 2; i++) {
             memcpy(row, top + off, len);
             memcpy(top + off, bottom + off, len);
@@ -936,6 +1000,7 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
         TRACE("Locking offscreen render target\n");
         ENTER_GL();
         glReadBuffer(device->offscreenBuffer);
         TRACE("Locking offscreen render target\n");
         ENTER_GL();
         glReadBuffer(device->offscreenBuffer);
+        checkGLcall("glReadBuffer");
         LEAVE_GL();
     }
 
         LEAVE_GL();
     }
 
@@ -1165,7 +1230,7 @@ lock_end:
          * Dirtify on lock
          * as seen in msdn docs
          */
          * Dirtify on lock
          * as seen in msdn docs
          */
-        IWineD3DSurface_AddDirtyRect(iface, pRect);
+        surface_add_dirty_rect(iface, pRect);
 
         /** Dirtify Container if needed */
         if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) {
 
         /** Dirtify Container if needed */
         if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture))) {
@@ -1293,7 +1358,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
 
     if (!(This->Flags & SFLAG_LOCKED)) {
         WARN("trying to Unlock an unlocked surf@%p\n", This);
 
     if (!(This->Flags & SFLAG_LOCKED)) {
         WARN("trying to Unlock an unlocked surf@%p\n", This);
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NOTLOCKED;
     }
 
     if (This->Flags & SFLAG_PBO) {
     }
 
     if (This->Flags & SFLAG_PBO) {
@@ -1500,11 +1565,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC
     TRACE("(%p)->(%p)\n",This,hDC);
 
     if (!(This->Flags & SFLAG_DCINUSE))
     TRACE("(%p)->(%p)\n",This,hDC);
 
     if (!(This->Flags & SFLAG_DCINUSE))
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NODC;
 
     if (This->hDC !=hDC) {
         WARN("Application tries to release an invalid DC(%p), surface dc is %p\n", hDC, This->hDC);
 
     if (This->hDC !=hDC) {
         WARN("Application tries to release an invalid DC(%p), surface dc is %p\n", hDC, This->hDC);
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NODC;
     }
 
     if((This->Flags & SFLAG_PBO) && This->resource.allocatedMemory) {
     }
 
     if((This->Flags & SFLAG_PBO) && This->resource.allocatedMemory) {
@@ -1700,6 +1765,14 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             *target_bpp = 2;
             break;
 
             *target_bpp = 2;
             break;
 
+        case WINED3DFMT_G16R16:
+            *convert = CONVERT_G16R16;
+            *format = GL_RGB;
+            *internal = GL_RGB16_EXT;
+            *type = GL_UNSIGNED_SHORT;
+            *target_bpp = 6;
+            break;
+
         default:
             break;
     }
         default:
             break;
     }
@@ -1795,7 +1868,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
                 Dest = (WORD *) (dst + y * outpitch);
                 for (x = 0; x < width; x++ ) {
                     WORD color = *Source++;
                 Dest = (WORD *) (dst + y * outpitch);
                 for (x = 0; x < width; x++ ) {
                     WORD color = *Source++;
-                   *Dest = color;
+                    *Dest = color;
                     if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                         (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                         *Dest |= (1 << 15);
                     if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                         (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                         *Dest |= (1 << 15);
@@ -2027,6 +2100,27 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
             break;
         }
 
             break;
         }
 
+        case CONVERT_G16R16:
+        {
+            unsigned int x, y;
+            const WORD *Source;
+            WORD *Dest;
+
+            for(y = 0; y < height; y++) {
+                Source = (const WORD *)(src + y * pitch);
+                Dest = (WORD *) (dst + y * outpitch);
+                for (x = 0; x < width; x++ ) {
+                    WORD green = (*Source++);
+                    WORD red = (*Source++);
+                    Dest[0] = green;
+                    Dest[1] = red;
+                    Dest[2] = 0xffff;
+                    Dest += 3;
+                }
+            }
+            break;
+        }
+
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
@@ -2446,40 +2540,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-/**
- *   Slightly inefficient way to handle multiple dirty rects but it works :)
- */
-static HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect)
-{
-    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    IWineD3DBaseTexture *baseTexture = NULL;
-
-    if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE))
-        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);
-
-    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
-    if (NULL != pDirtyRect) {
-        This->dirtyRect.left   = min(This->dirtyRect.left,   pDirtyRect->left);
-        This->dirtyRect.top    = min(This->dirtyRect.top,    pDirtyRect->top);
-        This->dirtyRect.right  = max(This->dirtyRect.right,  pDirtyRect->right);
-        This->dirtyRect.bottom = max(This->dirtyRect.bottom, pDirtyRect->bottom);
-    } else {
-        This->dirtyRect.left   = 0;
-        This->dirtyRect.top    = 0;
-        This->dirtyRect.right  = This->currentDesc.Width;
-        This->dirtyRect.bottom = This->currentDesc.Height;
-    }
-    TRACE("(%p) : Dirty: yes, Rect:(%d,%d,%d,%d)\n", This, This->dirtyRect.left,
-          This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
-    /* if the container is a basetexture then mark it dirty. */
-    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
-        TRACE("Passing to container\n");
-        IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
-        IWineD3DBaseTexture_Release(baseTexture);
-    }
-    return WINED3D_OK;
-}
-
 static HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     HRESULT hr;
 static HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     HRESULT hr;
@@ -3809,7 +3869,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
         3:    WARN and return WINED3DERR_NOTAVAILABLE;
         4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
         */
         3:    WARN and return WINED3DERR_NOTAVAILABLE;
         4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
         */
-        WARN("(%p) Creating an oversized surface\n", This);
+        WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n",
+             This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height);
         This->Flags |= SFLAG_OVERSIZE;
 
         /* This will be initialized on the first blt */
         This->Flags |= SFLAG_OVERSIZE;
 
         /* This will be initialized on the first blt */
@@ -4678,7 +4739,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
     IWineD3DBaseSurfaceImpl_SetClipper,
     IWineD3DBaseSurfaceImpl_GetClipper,
     /* Internal use: */
     IWineD3DBaseSurfaceImpl_SetClipper,
     IWineD3DBaseSurfaceImpl_GetClipper,
     /* Internal use: */
-    IWineD3DSurfaceImpl_AddDirtyRect,
     IWineD3DSurfaceImpl_LoadTexture,
     IWineD3DSurfaceImpl_BindTexture,
     IWineD3DSurfaceImpl_SaveSnapshot,
     IWineD3DSurfaceImpl_LoadTexture,
     IWineD3DSurfaceImpl_BindTexture,
     IWineD3DSurfaceImpl_SaveSnapshot,
index 2710a8f..f023c2e 100644 (file)
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "wine/port.h"
 #include "wined3d_private.h"
 #include "config.h"
 #include "wine/port.h"
 #include "wined3d_private.h"
+#include "float.h"
 
 #include <assert.h>
 
 
 #include <assert.h>
 
@@ -45,7 +46,7 @@ static inline unsigned short float_32_to_16(const float *in)
     /* Deal with special numbers */
     if(*in == 0.0) return 0x0000;
     if(isnan(*in)) return 0x7C01;
     /* Deal with special numbers */
     if(*in == 0.0) return 0x0000;
     if(isnan(*in)) return 0x7C01;
-    if(!finite(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);
+    if(!_finite(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);
 
     if(tmp < pow(2, 10)) {
         do
 
     if(tmp < pow(2, 10)) {
         do
@@ -166,11 +167,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFI
         ERR("Called without a valid ppContainer.\n");
     }
 
         ERR("Called without a valid ppContainer.\n");
     }
 
-    /** From MSDN:
-     * If the surface is created using CreateImageSurface/CreateOffscreenPlainSurface, CreateRenderTarget,
-     * or CreateDepthStencilSurface, the surface is considered stand alone. In this case,
-     * GetContainer will return the Direct3D device used to create the surface.
-     */
+    /* Standalone surfaces return the device as container. */
     if (This->container) {
         container = This->container;
     } else {
     if (This->container) {
         container = This->container;
     } else {
@@ -702,6 +699,46 @@ static void convert_r32f_r16f(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD
     }
 }
 
     }
 }
 
+static void convert_r5g6b5_x8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    static const unsigned char convert_5to8[] =
+    {
+        0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
+        0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
+        0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
+        0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
+    };
+    static const unsigned char convert_6to8[] =
+    {
+        0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
+        0x20, 0x24, 0x28, 0x2d, 0x31, 0x35, 0x39, 0x3d,
+        0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d,
+        0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d,
+        0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
+        0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
+        0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd7, 0xdb, 0xdf,
+        0xe3, 0xe7, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xff,
+    };
+    unsigned int x, y;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        const WORD *src_line = (const WORD *)(src + y * pitch_in);
+        DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+        for (x = 0; x < w; ++x)
+        {
+            WORD pixel = src_line[x];
+            dst_line[x] = 0xff000000
+                    | convert_5to8[(pixel & 0xf800) >> 11] << 16
+                    | convert_6to8[(pixel & 0x07e0) >> 5] << 8
+                    | convert_5to8[(pixel & 0x001f)];
+        }
+    }
+}
+
 struct d3dfmt_convertor_desc {
     WINED3DFORMAT from, to;
     void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
 struct d3dfmt_convertor_desc {
     WINED3DFORMAT from, to;
     void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
@@ -710,6 +747,7 @@ struct d3dfmt_convertor_desc {
 static const struct d3dfmt_convertor_desc convertors[] =
 {
     {WINED3DFMT_R32F,       WINED3DFMT_R16F,        convert_r32f_r16f},
 static const struct d3dfmt_convertor_desc convertors[] =
 {
     {WINED3DFMT_R32F,       WINED3DFMT_R16F,        convert_r32f_r16f},
+    {WINED3DFMT_R5G6B5,     WINED3DFMT_X8R8G8B8,    convert_r5g6b5_x8r8g8b8},
 };
 
 static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
 };
 
 static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
index d062458..eab5dde 100644 (file)
@@ -168,7 +168,7 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
     if (!(This->Flags & SFLAG_LOCKED))
     {
         WARN("trying to Unlock an unlocked surf@%p\n", This);
     if (!(This->Flags & SFLAG_LOCKED))
     {
         WARN("trying to Unlock an unlocked surf@%p\n", This);
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NOTLOCKED;
     }
 
     /* Can be useful for debugging */
     }
 
     /* Can be useful for debugging */
@@ -341,7 +341,7 @@ const char* filename)
 
         for (y = 0; y < This->pow2Height; y++) {
             const unsigned char *src = This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface));
 
         for (y = 0; y < This->pow2Height; y++) {
             const unsigned char *src = This->resource.allocatedMemory + (y * 1 * IWineD3DSurface_GetPitch(iface));
-            for (x = 0; x < This->pow2Width; x++) {        
+            for (x = 0; x < This->pow2Width; x++) {
                 unsigned int color;
                 unsigned int comp;
                 int i;
                 unsigned int color;
                 unsigned int comp;
                 int i;
@@ -442,11 +442,11 @@ static HRESULT WINAPI IWineGDISurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC
     TRACE("(%p)->(%p)\n",This,hDC);
 
     if (!(This->Flags & SFLAG_DCINUSE))
     TRACE("(%p)->(%p)\n",This,hDC);
 
     if (!(This->Flags & SFLAG_DCINUSE))
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NODC;
 
     if (This->hDC !=hDC) {
         WARN("Application tries to release an invalid DC(%p), surface dc is %p\n", hDC, This->hDC);
 
     if (This->hDC !=hDC) {
         WARN("Application tries to release an invalid DC(%p), surface dc is %p\n", hDC, This->hDC);
-        return WINED3DERR_INVALIDCALL;
+        return WINEDDERR_NODC;
     }
 
     /* we locked first, so unlock now */
     }
 
     /* we locked first, so unlock now */
@@ -540,14 +540,6 @@ static void WINAPI IWineGDISurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescr
     *glDescription = NULL;
 }
 
     *glDescription = NULL;
 }
 
-static HRESULT WINAPI IWineGDISurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect) {
-    /* GDI surface data can only be in one location, the system memory dib section. So they are
-     * always clean by definition.
-     */
-    TRACE("No dirtification in GDI surfaces\n");
-    return WINED3D_OK;
-}
-
 static HRESULT WINAPI IWineGDISurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 
 static HRESULT WINAPI IWineGDISurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 
@@ -673,7 +665,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
     IWineD3DBaseSurfaceImpl_SetClipper,
     IWineD3DBaseSurfaceImpl_GetClipper,
     /* Internal use: */
     IWineD3DBaseSurfaceImpl_SetClipper,
     IWineD3DBaseSurfaceImpl_GetClipper,
     /* Internal use: */
-    IWineGDISurfaceImpl_AddDirtyRect,
     IWineGDISurfaceImpl_LoadTexture,
     IWineD3DBaseSurfaceImpl_BindTexture,
     IWineGDISurfaceImpl_SaveSnapshot,
     IWineGDISurfaceImpl_LoadTexture,
     IWineD3DBaseSurfaceImpl_BindTexture,
     IWineGDISurfaceImpl_SaveSnapshot,
index 71fb455..e83d869 100644 (file)
@@ -137,7 +137,7 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
             FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
 
         for (i = 0; i < This->baseTexture.levels; i++) {
             FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
 
         for (i = 0; i < This->baseTexture.levels; i++) {
-            IWineD3DSurface_AddDirtyRect(This->surfaces[i], NULL);
+            surface_add_dirty_rect(This->surfaces[i], NULL);
             surface_force_reload(This->surfaces[i]);
             IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
         }
             surface_force_reload(This->surfaces[i]);
             IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
         }
@@ -303,7 +303,7 @@ static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, U
         TRACE("(%p) Level (%d)\n", This, Level);
         return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc);
     }
         TRACE("(%p) Level (%d)\n", This, Level);
         return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc);
     }
-    FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
+    WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
     return WINED3DERR_INVALIDCALL;
 }
 
     return WINED3DERR_INVALIDCALL;
 }
 
@@ -360,7 +360,9 @@ static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, C
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
-    return IWineD3DSurface_AddDirtyRect(This->surfaces[0], pDirtyRect);
+    surface_add_dirty_rect(This->surfaces[0], pDirtyRect);
+
+    return WINED3D_OK;
 }
 
 const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
 }
 
 const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
index fd4f4ee..cc09584 100644 (file)
@@ -167,7 +167,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
     /* IEEE formats */
     {WINED3DFMT_R32F           ,GL_RGB32F_ARB                    ,GL_RGB32F_ARB                          , 0,           GL_RED                    ,GL_FLOAT
         ,WINED3DFMT_FLAG_RENDERTARGET },
     /* IEEE formats */
     {WINED3DFMT_R32F           ,GL_RGB32F_ARB                    ,GL_RGB32F_ARB                          , 0,           GL_RED                    ,GL_FLOAT
         ,WINED3DFMT_FLAG_RENDERTARGET },
-    {WINED3DFMT_G32R32F        ,0                                ,0                                      , 0,           0                         ,0
+    {WINED3DFMT_G32R32F        ,GL_RG32F                         ,GL_RG32F                               , 0,           GL_RG                     ,GL_FLOAT
         ,WINED3DFMT_FLAG_RENDERTARGET },
     {WINED3DFMT_A32B32G32R32F  ,GL_RGBA32F_ARB                   ,GL_RGBA32F_ARB                         , 0,           GL_RGBA                   ,GL_FLOAT
         ,WINED3DFMT_FLAG_RENDERTARGET },
         ,WINED3DFMT_FLAG_RENDERTARGET },
     {WINED3DFMT_A32B32G32R32F  ,GL_RGBA32F_ARB                   ,GL_RGBA32F_ARB                         , 0,           GL_RGBA                   ,GL_FLOAT
         ,WINED3DFMT_FLAG_RENDERTARGET },
@@ -177,7 +177,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
     /* Float */
     {WINED3DFMT_R16F           ,GL_RGB16F_ARB                    ,GL_RGB16F_ARB                          , 0,           GL_RED                    ,GL_HALF_FLOAT_ARB
         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
     /* Float */
     {WINED3DFMT_R16F           ,GL_RGB16F_ARB                    ,GL_RGB16F_ARB                          , 0,           GL_RED                    ,GL_HALF_FLOAT_ARB
         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
-    {WINED3DFMT_G16R16F        ,0                                ,0                                      , 0,           0                         ,0
+    {WINED3DFMT_G16R16F        ,GL_RG16F                         ,GL_RG16F                               , 0,           GL_RG                     ,GL_HALF_FLOAT_ARB
         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
     {WINED3DFMT_A16B16G16R16F  ,GL_RGBA16F_ARB                   ,GL_RGBA16F_ARB                         , 0,           GL_RGBA                   ,GL_HALF_FLOAT_ARB
         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
         ,WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
     {WINED3DFMT_A16B16G16R16F  ,GL_RGBA16F_ARB                   ,GL_RGBA16F_ARB                         , 0,           GL_RGBA                   ,GL_HALF_FLOAT_ARB
         ,WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET },
@@ -366,10 +366,22 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
     dst = getFmtIdx(WINED3DFMT_R16F);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
     dst = getFmtIdx(WINED3DFMT_R16F);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+    /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
+    if(GL_SUPPORT(ARB_TEXTURE_RG))
+    {
+        gl_info->gl_formats[dst].glInternal = GL_R16F;
+        gl_info->gl_formats[dst].glGammaInternal = GL_R16F;
+    }
 
     dst = getFmtIdx(WINED3DFMT_R32F);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
 
     dst = getFmtIdx(WINED3DFMT_R32F);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+    /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
+    if(GL_SUPPORT(ARB_TEXTURE_RG))
+    {
+        gl_info->gl_formats[dst].glInternal = GL_R32F;
+        gl_info->gl_formats[dst].glGammaInternal = GL_R32F;
+    }
 
     dst = getFmtIdx(WINED3DFMT_G16R16);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
 
     dst = getFmtIdx(WINED3DFMT_G16R16);
     gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
@@ -470,33 +482,42 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
 }
 
 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
 }
 
 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
-static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] = {
-                                  {WINED3DDECLTYPE_FLOAT1,    1, GL_FLOAT           , GL_FALSE ,sizeof(float)},
-                                  {WINED3DDECLTYPE_FLOAT2,    2, GL_FLOAT           , GL_FALSE ,sizeof(float)},
-                                  {WINED3DDECLTYPE_FLOAT3,    3, GL_FLOAT           , GL_FALSE ,sizeof(float)},
-                                  {WINED3DDECLTYPE_FLOAT4,    4, GL_FLOAT           , GL_FALSE ,sizeof(float)},
-                                  {WINED3DDECLTYPE_D3DCOLOR,  4, GL_UNSIGNED_BYTE   , GL_TRUE  ,sizeof(BYTE)},
-                                  {WINED3DDECLTYPE_UBYTE4,    4, GL_UNSIGNED_BYTE   , GL_FALSE ,sizeof(BYTE)},
-                                  {WINED3DDECLTYPE_SHORT2,    2, GL_SHORT           , GL_FALSE ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_SHORT4,    4, GL_SHORT           , GL_FALSE ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_UBYTE4N,   4, GL_UNSIGNED_BYTE   , GL_TRUE  ,sizeof(BYTE)},
-                                  {WINED3DDECLTYPE_SHORT2N,   2, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_SHORT4N,   4, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_USHORT2N,  2, GL_UNSIGNED_SHORT  , GL_TRUE  ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_USHORT4N,  4, GL_UNSIGNED_SHORT  , GL_TRUE  ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_UDEC3,     3, GL_UNSIGNED_SHORT  , GL_FALSE ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_DEC3N,     3, GL_SHORT           , GL_TRUE  ,sizeof(short int)},
-                                  {WINED3DDECLTYPE_FLOAT16_2, 2, GL_HALF_FLOAT_NV   , GL_FALSE ,sizeof(GLhalfNV)},
-                                  {WINED3DDECLTYPE_FLOAT16_4, 4, GL_HALF_FLOAT_NV   , GL_FALSE ,sizeof(GLhalfNV)}};
+static WINED3DGLTYPE const glTypeLookupTemplate[WINED3DDECLTYPE_UNUSED] =
+{
+    {WINED3DDECLTYPE_FLOAT1,    1, GL_FLOAT,          1, GL_FALSE, sizeof(float)},
+    {WINED3DDECLTYPE_FLOAT2,    2, GL_FLOAT,          2, GL_FALSE, sizeof(float)},
+    {WINED3DDECLTYPE_FLOAT3,    3, GL_FLOAT,          3, GL_FALSE, sizeof(float)},
+    {WINED3DDECLTYPE_FLOAT4,    4, GL_FLOAT,          4, GL_FALSE, sizeof(float)},
+    {WINED3DDECLTYPE_D3DCOLOR,  4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
+    {WINED3DDECLTYPE_UBYTE4,    4, GL_UNSIGNED_BYTE,  4, GL_FALSE, sizeof(BYTE)},
+    {WINED3DDECLTYPE_SHORT2,    2, GL_SHORT,          2, GL_FALSE, sizeof(short int)},
+    {WINED3DDECLTYPE_SHORT4,    4, GL_SHORT,          4, GL_FALSE, sizeof(short int)},
+    {WINED3DDECLTYPE_UBYTE4N,   4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
+    {WINED3DDECLTYPE_SHORT2N,   2, GL_SHORT,          2, GL_TRUE,  sizeof(short int)},
+    {WINED3DDECLTYPE_SHORT4N,   4, GL_SHORT,          4, GL_TRUE,  sizeof(short int)},
+    {WINED3DDECLTYPE_USHORT2N,  2, GL_UNSIGNED_SHORT, 2, GL_TRUE,  sizeof(short int)},
+    {WINED3DDECLTYPE_USHORT4N,  4, GL_UNSIGNED_SHORT, 4, GL_TRUE,  sizeof(short int)},
+    {WINED3DDECLTYPE_UDEC3,     3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
+    {WINED3DDECLTYPE_DEC3N,     3, GL_SHORT,          3, GL_TRUE,  sizeof(short int)},
+    {WINED3DDECLTYPE_FLOAT16_2, 2, GL_FLOAT,          2, GL_FALSE, sizeof(GLhalfNV)},
+    {WINED3DDECLTYPE_FLOAT16_4, 4, GL_FLOAT,          4, GL_FALSE, sizeof(GLhalfNV)}
+};
 
 void init_type_lookup(WineD3D_GL_Info *gl_info) {
     memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
 
 void init_type_lookup(WineD3D_GL_Info *gl_info) {
     memcpy(gl_info->glTypeLookup, glTypeLookupTemplate, sizeof(glTypeLookupTemplate));
-    if(!GL_SUPPORT(NV_HALF_FLOAT)) {
+
+    if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
+    {
+        gl_info->glTypeLookup[WINED3DDECLTYPE_D3DCOLOR].format = GL_BGRA;
+    }
+
+    if (GL_SUPPORT(NV_HALF_FLOAT))
+    {
         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
          * It is the job of the vertex buffer code to make sure that the vbos have the right format
          */
         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
          * It is the job of the vertex buffer code to make sure that the vbos have the right format
          */
-        gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_FLOAT;
-        gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_FLOAT;
+        gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_2].glType = GL_HALF_FLOAT_NV;
+        gl_info->glTypeLookup[WINED3DDECLTYPE_FLOAT16_4].glType = GL_HALF_FLOAT_NV;
     }
 }
 
     }
 }
 
@@ -742,7 +763,7 @@ const char* debug_d3ddeclusage(BYTE usage) {
 
 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
   switch (res) {
 
 const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
   switch (res) {
-#define RES_TO_STR(res) case res: return #res;
+#define RES_TO_STR(res) case res: return #res
     RES_TO_STR(WINED3DRTYPE_SURFACE);
     RES_TO_STR(WINED3DRTYPE_VOLUME);
     RES_TO_STR(WINED3DRTYPE_TEXTURE);
     RES_TO_STR(WINED3DRTYPE_SURFACE);
     RES_TO_STR(WINED3DRTYPE_VOLUME);
     RES_TO_STR(WINED3DRTYPE_TEXTURE);
@@ -759,7 +780,7 @@ const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
 
 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
   switch (PrimitiveType) {
 
 const char* debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) {
   switch (PrimitiveType) {
-#define PRIM_TO_STR(prim) case prim: return #prim;
+#define PRIM_TO_STR(prim) case prim: return #prim
     PRIM_TO_STR(WINED3DPT_POINTLIST);
     PRIM_TO_STR(WINED3DPT_LINELIST);
     PRIM_TO_STR(WINED3DPT_LINESTRIP);
     PRIM_TO_STR(WINED3DPT_POINTLIST);
     PRIM_TO_STR(WINED3DPT_LINELIST);
     PRIM_TO_STR(WINED3DPT_LINESTRIP);
@@ -1008,15 +1029,11 @@ const char* debug_d3dtexturestate(DWORD state) {
     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLSCALE         );
     D3DSTATE_TO_STR(WINED3DTSS_BUMPENVLOFFSET        );
     D3DSTATE_TO_STR(WINED3DTSS_TEXTURETRANSFORMFLAGS );
-    D3DSTATE_TO_STR(WINED3DTSS_ADDRESSW              );
     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
 #undef D3DSTATE_TO_STR
     D3DSTATE_TO_STR(WINED3DTSS_COLORARG0             );
     D3DSTATE_TO_STR(WINED3DTSS_ALPHAARG0             );
     D3DSTATE_TO_STR(WINED3DTSS_RESULTARG             );
     D3DSTATE_TO_STR(WINED3DTSS_CONSTANT              );
 #undef D3DSTATE_TO_STR
-  case 12:
-    /* Note WINED3DTSS are not consecutive, so skip these */
-    return "unused";
   default:
     FIXME("Unrecognized %u texture state!\n", state);
     return "unrecognized";
   default:
     FIXME("Unrecognized %u texture state!\n", state);
     return "unrecognized";
@@ -1086,7 +1103,7 @@ const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
 
 const char* debug_d3dpool(WINED3DPOOL Pool) {
   switch (Pool) {
 
 const char* debug_d3dpool(WINED3DPOOL Pool) {
   switch (Pool) {
-#define POOL_TO_STR(p) case p: return #p;
+#define POOL_TO_STR(p) case p: return #p
     POOL_TO_STR(WINED3DPOOL_DEFAULT);
     POOL_TO_STR(WINED3DPOOL_MANAGED);
     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
     POOL_TO_STR(WINED3DPOOL_DEFAULT);
     POOL_TO_STR(WINED3DPOOL_MANAGED);
     POOL_TO_STR(WINED3DPOOL_SYSTEMMEM);
@@ -1500,6 +1517,7 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
+        case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
         default: ERR("Unexpected position mask\n");
     }
     for (i = 0; i < numTextures; i++) {
         default: ERR("Unexpected position mask\n");
     }
     for (i = 0; i < numTextures; i++) {
@@ -1711,6 +1729,16 @@ void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *val
     HeapFree(GetProcessHeap(), 0, table);
 }
 
     HeapFree(GetProcessHeap(), 0, table);
 }
 
+void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
+{
+    unsigned int i = 0;
+
+    for (i = 0; i < table->entry_count; ++i)
+    {
+        callback(table->entries[i].value, context);
+    }
+}
+
 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
         unsigned int idx)
 {
 static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
         unsigned int idx)
 {
@@ -1917,7 +1945,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
             settings->op[i].aop = WINED3DTOP_DISABLE;
             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
             settings->op[i].aop = WINED3DTOP_DISABLE;
             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
-            settings->op[i].color_correction = COLOR_FIXUP_IDENTITY;
+            settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
             settings->op[i].dst = resultreg;
             settings->op[i].tex_type = tex_1d;
             settings->op[i].projected = proj_none;
             settings->op[i].dst = resultreg;
             settings->op[i].tex_type = tex_1d;
             settings->op[i].projected = proj_none;
@@ -1927,11 +1955,11 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
 
         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
         if(texture) {
 
         texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
         if(texture) {
-            settings->op[i].color_correction = texture->baseTexture.shader_color_fixup;
+            settings->op[i].color_fixup = texture->baseTexture.shader_color_fixup;
             if(ignore_textype) {
                 settings->op[i].tex_type = tex_1d;
             } else {
             if(ignore_textype) {
                 settings->op[i].tex_type = tex_1d;
             } else {
-                switch(stateblock->textureDimensions[i]) {
+                switch (IWineD3DBaseTexture_GetTextureDimensions((IWineD3DBaseTexture *)texture)) {
                     case GL_TEXTURE_1D:
                         settings->op[i].tex_type = tex_1d;
                         break;
                     case GL_TEXTURE_1D:
                         settings->op[i].tex_type = tex_1d;
                         break;
@@ -1950,21 +1978,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
                 }
             }
         } else {
                 }
             }
         } else {
-            settings->op[i].color_correction = COLOR_FIXUP_IDENTITY;
+            settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
             settings->op[i].tex_type = tex_1d;
         }
 
         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
 
             settings->op[i].tex_type = tex_1d;
         }
 
         cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
         aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
 
-        carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
-        carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
-        carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
+        carg1 = (args[cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : ARG_UNUSED;
+        carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
+        carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
 
         if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
                          carg1, carg2, carg0)) {
 
         if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
                          carg1, carg2, carg0)) {
-            carg0 = 0xffffffff;
-            carg2 = 0xffffffff;
+            carg0 = ARG_UNUSED;
+            carg2 = ARG_UNUSED;
             carg1 = WINED3DTA_CURRENT;
             cop = WINED3DTOP_SELECTARG1;
         }
             carg1 = WINED3DTA_CURRENT;
             cop = WINED3DTOP_SELECTARG1;
         }
@@ -1978,45 +2006,54 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
             aarg2 = carg2;
             aarg0 = carg0;
         } else {
             aarg2 = carg2;
             aarg0 = carg0;
         } else {
-            aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
-            aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
-            aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
+            aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : ARG_UNUSED;
+            aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : ARG_UNUSED;
+            aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : ARG_UNUSED;
         }
 
         }
 
-        if(i == 0 && stateblock->textures[0] &&
-                  stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&
-                 (stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
-                  stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
+        if (i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE])
+        {
+            UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
 
 
-            if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
-               getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
+            if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+            {
+                IWineD3DSurfaceImpl *surf;
+                surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
 
 
-                if(aop == WINED3DTOP_DISABLE) {
-                   aarg1 = WINED3DTA_TEXTURE;
-                   aop = WINED3DTOP_SELECTARG1;
-                }
-                else if(aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE) {
-                    if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
-                        aarg2 = WINED3DTA_TEXTURE;
-                        aop = WINED3DTOP_MODULATE;
+                if (surf->CKeyFlags & WINEDDSD_CKSRCBLT
+                        && getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000)
+                {
+                    if (aop == WINED3DTOP_DISABLE)
+                    {
+                       aarg1 = WINED3DTA_TEXTURE;
+                       aop = WINED3DTOP_SELECTARG1;
                     }
                     }
-                    else aarg1 = WINED3DTA_TEXTURE;
-                }
-                else if(aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE) {
-                    if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
-                        aarg1 = WINED3DTA_TEXTURE;
-                        aop = WINED3DTOP_MODULATE;
+                    else if (aop == WINED3DTOP_SELECTARG1 && aarg1 != WINED3DTA_TEXTURE)
+                    {
+                        if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
+                        {
+                            aarg2 = WINED3DTA_TEXTURE;
+                            aop = WINED3DTOP_MODULATE;
+                        }
+                        else aarg1 = WINED3DTA_TEXTURE;
+                    }
+                    else if (aop == WINED3DTOP_SELECTARG2 && aarg2 != WINED3DTA_TEXTURE)
+                    {
+                        if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
+                        {
+                            aarg1 = WINED3DTA_TEXTURE;
+                            aop = WINED3DTOP_MODULATE;
+                        }
+                        else aarg2 = WINED3DTA_TEXTURE;
                     }
                     }
-                    else aarg2 = WINED3DTA_TEXTURE;
                 }
             }
         }
 
         if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
            aarg1, aarg2, aarg0)) {
                 }
             }
         }
 
         if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
            aarg1, aarg2, aarg0)) {
-               aarg0 = 0xffffffff;
-               aarg2 = 0xffffffff;
+               aarg0 = ARG_UNUSED;
+               aarg2 = ARG_UNUSED;
                aarg1 = WINED3DTA_CURRENT;
                aop = WINED3DTOP_SELECTARG1;
         }
                aarg1 = WINED3DTA_CURRENT;
                aop = WINED3DTOP_SELECTARG1;
         }
@@ -2115,7 +2152,7 @@ void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *des
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     if(stateblock->textures[stage]) {
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     if(stateblock->textures[stage]) {
-        switch(stateblock->textureDimensions[stage]) {
+        switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
             case GL_TEXTURE_2D:
                 glDisable(GL_TEXTURE_3D);
                 checkGLcall("glDisable(GL_TEXTURE_3D)");
             case GL_TEXTURE_2D:
                 glDisable(GL_TEXTURE_3D);
                 checkGLcall("glDisable(GL_TEXTURE_3D)");
@@ -2236,3 +2273,29 @@ BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
 
     return memcmp(ka, kb, sizeof(*ka)) == 0;
 }
 
     return memcmp(ka, kb, sizeof(*ka)) == 0;
 }
+
+UINT wined3d_log2i(UINT32 x)
+{
+    static const BYTE l[] =
+    {
+        0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    };
+    UINT32 i;
+
+    return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
+}
index 5964033..0408819 100644 (file)
@@ -327,8 +327,9 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
      * done, or if the DIFFUSE is replaced with a D3DCOLOR BLENDWEIGHT we can happily dismiss the change. Some conversion types
      * depend on the semantic as well, for example a FLOAT4 texcoord needs no conversion while a FLOAT4 positiont needs one
      */
      * done, or if the DIFFUSE is replaced with a D3DCOLOR BLENDWEIGHT we can happily dismiss the change. Some conversion types
      * depend on the semantic as well, for example a FLOAT4 texcoord needs no conversion while a FLOAT4 positiont needs one
      */
-    if(use_vs(device)) {
-        TRACE("vhsader\n");
+    if (use_vs(device->stateBlock))
+    {
+        TRACE("vshader\n");
         /* If the current vertex declaration is marked for no half float conversion don't bother to
          * analyse the strided streams in depth, just set them up for no conversion. Return decl changed
          * if we used conversion before
         /* If the current vertex declaration is marked for no half float conversion don't bother to
          * analyse the strided streams in depth, just set them up for no conversion. Return decl changed
          * if we used conversion before
@@ -363,10 +364,11 @@ static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
          * FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all
          * the attributes that our current fixed function pipeline implementation cares for.
          */
          * FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all
          * the attributes that our current fixed function pipeline implementation cares for.
          */
+        BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA);
         ret = check_attribute(This, &device->strided_streams.u.s.position,     TRUE, TRUE,  FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.normal,       TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.position,     TRUE, TRUE,  FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.normal,       TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.diffuse,      TRUE, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.specular,     TRUE, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
+        ret = check_attribute(This, &device->strided_streams.u.s.diffuse,      !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
+        ret = check_attribute(This, &device->strided_streams.u.s.specular,     !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[0], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[1], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[2], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[0], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[1], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         ret = check_attribute(This, &device->strided_streams.u.s.texCoords[2], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
index 7fc711b..f63e2e7 100644 (file)
@@ -207,7 +207,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte
         const WINED3DVERTEXELEMENT *elements, UINT element_count) {
     IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
     HRESULT hr = WINED3D_OK;
         const WINED3DVERTEXELEMENT *elements, UINT element_count) {
     IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
     HRESULT hr = WINED3D_OK;
-    int i, j;
+    int i;
     char isPreLoaded[MAX_STREAMS];
 
     TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
     char isPreLoaded[MAX_STREAMS];
 
     TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
@@ -263,39 +263,13 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte
             isPreLoaded[This->pDeclarationWine[i].Stream] = 1;
         }
 
             isPreLoaded[This->pDeclarationWine[i].Stream] = 1;
         }
 
-        /* Create a sorted array containing the attribute declarations that are of type
-         * D3DCOLOR. D3DCOLOR requires swizzling of the r and b component, and if the
-         * declaration of one attribute changes the vertex shader needs recompilation.
-         * Having a sorted array of the attributes allows efficient comparison of the
-         * declaration against a shader
-         */
-        if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) {
-            for(j = 0; j < This->num_swizzled_attribs; j++) {
-                if(This->swizzled_attribs[j].usage >  This->pDeclarationWine[i].Usage ||
-                  (This->swizzled_attribs[j].usage == This->pDeclarationWine[i].Usage &&
-                   This->swizzled_attribs[j].idx   >   This->pDeclarationWine[i].UsageIndex)) {
-                    memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j],
-                             sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j + 1)));
-                    break;
-                }
-            }
-
-            This->swizzled_attribs[j].usage = This->pDeclarationWine[i].Usage;
-            This->swizzled_attribs[j].idx = This->pDeclarationWine[i].UsageIndex;
-            This->num_swizzled_attribs++;
-        } else if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_2 ||
-                  This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_4) {
-            if(!GL_SUPPORT(NV_HALF_FLOAT)) {
-                This->half_float_conv_needed = TRUE;
-            }
+        if (This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_2
+                || This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_4)
+        {
+            if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE;
         }
     }
 
         }
     }
 
-    TRACE("Swizzled attributes found:\n");
-    for(i = 0; i < This->num_swizzled_attribs; i++) {
-        TRACE("%u: %s%d\n", i,
-              debug_d3ddeclusage(This->swizzled_attribs[i].usage), This->swizzled_attribs[i].idx);
-    }
     TRACE("Returning\n");
     return hr;
 }
     TRACE("Returning\n");
     return hr;
 }
index 0f246f9..339d955 100644 (file)
@@ -43,71 +43,71 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
     /* This table is not order or position dependent. */
 
     /* Arithmetic */
     /* This table is not order or position dependent. */
 
     /* Arithmetic */
-    {WINED3DSIO_NOP,     "nop",     "NOP",               0, 0, WINED3DSIH_NOP,     0,                      0                     },
-    {WINED3DSIO_MOV,     "mov",     "MOV",               1, 2, WINED3DSIH_MOV,     0,                      0                     },
-    {WINED3DSIO_MOVA,    "mova",    NULL,                1, 2, WINED3DSIH_MOVA,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ADD,     "add",     "ADD",               1, 3, WINED3DSIH_ADD,     0,                      0                     },
-    {WINED3DSIO_SUB,     "sub",     "SUB",               1, 3, WINED3DSIH_SUB,     0,                      0                     },
-    {WINED3DSIO_MAD,     "mad",     "MAD",               1, 4, WINED3DSIH_MAD,     0,                      0                     },
-    {WINED3DSIO_MUL,     "mul",     "MUL",               1, 3, WINED3DSIH_MUL,     0,                      0                     },
-    {WINED3DSIO_RCP,     "rcp",     "RCP",               1, 2, WINED3DSIH_RCP,     0,                      0                     },
-    {WINED3DSIO_RSQ,     "rsq",     "RSQ",               1, 2, WINED3DSIH_RSQ,     0,                      0                     },
-    {WINED3DSIO_DP3,     "dp3",     "DP3",               1, 3, WINED3DSIH_DP3,     0,                      0                     },
-    {WINED3DSIO_DP4,     "dp4",     "DP4",               1, 3, WINED3DSIH_DP4,     0,                      0                     },
-    {WINED3DSIO_MIN,     "min",     "MIN",               1, 3, WINED3DSIH_MIN,     0,                      0                     },
-    {WINED3DSIO_MAX,     "max",     "MAX",               1, 3, WINED3DSIH_MAX,     0,                      0                     },
-    {WINED3DSIO_SLT,     "slt",     "SLT",               1, 3, WINED3DSIH_SLT,     0,                      0                     },
-    {WINED3DSIO_SGE,     "sge",     "SGE",               1, 3, WINED3DSIH_SGE,     0,                      0                     },
-    {WINED3DSIO_ABS,     "abs",     "ABS",               1, 2, WINED3DSIH_ABS,     0,                      0                     },
-    {WINED3DSIO_EXP,     "exp",     "EX2",               1, 2, WINED3DSIH_EXP,     0,                      0                     },
-    {WINED3DSIO_LOG,     "log",     "LG2",               1, 2, WINED3DSIH_LOG,     0,                      0                     },
-    {WINED3DSIO_EXPP,    "expp",    "EXP",               1, 2, WINED3DSIH_EXPP,    0,                      0                     },
-    {WINED3DSIO_LOGP,    "logp",    "LOG",               1, 2, WINED3DSIH_LOGP,    0,                      0                     },
-    {WINED3DSIO_LIT,     "lit",     "LIT",               1, 2, WINED3DSIH_LIT,     0,                      0                     },
-    {WINED3DSIO_DST,     "dst",     "DST",               1, 3, WINED3DSIH_DST,     0,                      0                     },
-    {WINED3DSIO_LRP,     "lrp",     "LRP",               1, 4, WINED3DSIH_LRP,     0,                      0                     },
-    {WINED3DSIO_FRC,     "frc",     "FRC",               1, 2, WINED3DSIH_FRC,     0,                      0                     },
-    {WINED3DSIO_POW,     "pow",     "POW",               1, 3, WINED3DSIH_POW,     0,                      0                     },
-    {WINED3DSIO_CRS,     "crs",     "XPD",               1, 3, WINED3DSIH_CRS,     0,                      0                     },
-    /* TODO: sng can possibly be performed a  s
+    {WINED3DSIO_NOP,     "nop",     0, 0, WINED3DSIH_NOP,     0,                      0                     },
+    {WINED3DSIO_MOV,     "mov",     1, 2, WINED3DSIH_MOV,     0,                      0                     },
+    {WINED3DSIO_MOVA,    "mova",    1, 2, WINED3DSIH_MOVA,    WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_ADD,     "add",     1, 3, WINED3DSIH_ADD,     0,                      0                     },
+    {WINED3DSIO_SUB,     "sub",     1, 3, WINED3DSIH_SUB,     0,                      0                     },
+    {WINED3DSIO_MAD,     "mad",     1, 4, WINED3DSIH_MAD,     0,                      0                     },
+    {WINED3DSIO_MUL,     "mul",     1, 3, WINED3DSIH_MUL,     0,                      0                     },
+    {WINED3DSIO_RCP,     "rcp",     1, 2, WINED3DSIH_RCP,     0,                      0                     },
+    {WINED3DSIO_RSQ,     "rsq",     1, 2, WINED3DSIH_RSQ,     0,                      0                     },
+    {WINED3DSIO_DP3,     "dp3",     1, 3, WINED3DSIH_DP3,     0,                      0                     },
+    {WINED3DSIO_DP4,     "dp4",     1, 3, WINED3DSIH_DP4,     0,                      0                     },
+    {WINED3DSIO_MIN,     "min",     1, 3, WINED3DSIH_MIN,     0,                      0                     },
+    {WINED3DSIO_MAX,     "max",     1, 3, WINED3DSIH_MAX,     0,                      0                     },
+    {WINED3DSIO_SLT,     "slt",     1, 3, WINED3DSIH_SLT,     0,                      0                     },
+    {WINED3DSIO_SGE,     "sge",     1, 3, WINED3DSIH_SGE,     0,                      0                     },
+    {WINED3DSIO_ABS,     "abs",     1, 2, WINED3DSIH_ABS,     0,                      0                     },
+    {WINED3DSIO_EXP,     "exp",     1, 2, WINED3DSIH_EXP,     0,                      0                     },
+    {WINED3DSIO_LOG,     "log",     1, 2, WINED3DSIH_LOG,     0,                      0                     },
+    {WINED3DSIO_EXPP,    "expp",    1, 2, WINED3DSIH_EXPP,    0,                      0                     },
+    {WINED3DSIO_LOGP,    "logp",    1, 2, WINED3DSIH_LOGP,    0,                      0                     },
+    {WINED3DSIO_LIT,     "lit",     1, 2, WINED3DSIH_LIT,     0,                      0                     },
+    {WINED3DSIO_DST,     "dst",     1, 3, WINED3DSIH_DST,     0,                      0                     },
+    {WINED3DSIO_LRP,     "lrp",     1, 4, WINED3DSIH_LRP,     0,                      0                     },
+    {WINED3DSIO_FRC,     "frc",     1, 2, WINED3DSIH_FRC,     0,                      0                     },
+    {WINED3DSIO_POW,     "pow",     1, 3, WINED3DSIH_POW,     0,                      0                     },
+    {WINED3DSIO_CRS,     "crs",     1, 3, WINED3DSIH_CRS,     0,                      0                     },
+    /* TODO: sng can possibly be performed as
         RCP tmp, vec
         MUL out, tmp, vec*/
         RCP tmp, vec
         MUL out, tmp, vec*/
-    {WINED3DSIO_SGN,     "sgn",     NULL,                1, 2, WINED3DSIH_SGN,     0,                      0                     },
-    {WINED3DSIO_NRM,     "nrm",     NULL,                1, 2, WINED3DSIH_NRM,     0,                      0                     },
-    {WINED3DSIO_SINCOS,  "sincos",  NULL,                1, 4, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
-    {WINED3DSIO_SINCOS,  "sincos",  "SCS",               1, 2, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(3,0), -1                    },
+    {WINED3DSIO_SGN,     "sgn",     1, 2, WINED3DSIH_SGN,     0,                      0                     },
+    {WINED3DSIO_NRM,     "nrm",     1, 2, WINED3DSIH_NRM,     0,                      0                     },
+    {WINED3DSIO_SINCOS,  "sincos",  1, 4, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
+    {WINED3DSIO_SINCOS,  "sincos",  1, 2, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(3,0), -1                    },
     /* Matrix */
     /* Matrix */
-    {WINED3DSIO_M4x4,    "m4x4",    "undefined",         1, 3, WINED3DSIH_M4x4,    0,                      0                     },
-    {WINED3DSIO_M4x3,    "m4x3",    "undefined",         1, 3, WINED3DSIH_M4x3,    0,                      0                     },
-    {WINED3DSIO_M3x4,    "m3x4",    "undefined",         1, 3, WINED3DSIH_M3x4,    0,                      0                     },
-    {WINED3DSIO_M3x3,    "m3x3",    "undefined",         1, 3, WINED3DSIH_M3x3,    0,                      0                     },
-    {WINED3DSIO_M3x2,    "m3x2",    "undefined",         1, 3, WINED3DSIH_M3x2,    0,                      0                     },
+    {WINED3DSIO_M4x4,    "m4x4",    1, 3, WINED3DSIH_M4x4,    0,                      0                     },
+    {WINED3DSIO_M4x3,    "m4x3",    1, 3, WINED3DSIH_M4x3,    0,                      0                     },
+    {WINED3DSIO_M3x4,    "m3x4",    1, 3, WINED3DSIH_M3x4,    0,                      0                     },
+    {WINED3DSIO_M3x3,    "m3x3",    1, 3, WINED3DSIH_M3x3,    0,                      0                     },
+    {WINED3DSIO_M3x2,    "m3x2",    1, 3, WINED3DSIH_M3x2,    0,                      0                     },
     /* Declare registers */
     /* Declare registers */
-    {WINED3DSIO_DCL,     "dcl",     NULL,                0, 2, WINED3DSIH_DCL,     0,                      0                     },
+    {WINED3DSIO_DCL,     "dcl",     0, 2, WINED3DSIH_DCL,     0,                      0                     },
     /* Constant definitions */
     /* Constant definitions */
-    {WINED3DSIO_DEF,     "def",     NULL,                1, 5, WINED3DSIH_DEF,     0,                      0                     },
-    {WINED3DSIO_DEFB,    "defb",    GLNAME_REQUIRE_GLSL, 1, 2, WINED3DSIH_DEFB,    0,                      0                     },
-    {WINED3DSIO_DEFI,    "defi",    GLNAME_REQUIRE_GLSL, 1, 5, WINED3DSIH_DEFI,    0,                      0                     },
+    {WINED3DSIO_DEF,     "def",     1, 5, WINED3DSIH_DEF,     0,                      0                     },
+    {WINED3DSIO_DEFB,    "defb",    1, 2, WINED3DSIH_DEFB,    0,                      0                     },
+    {WINED3DSIO_DEFI,    "defi",    1, 5, WINED3DSIH_DEFI,    0,                      0                     },
     /* Flow control - requires GLSL or software shaders */
     /* Flow control - requires GLSL or software shaders */
-    {WINED3DSIO_REP ,    "rep",     NULL,                0, 1, WINED3DSIH_REP,     WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDREP,  "endrep",  NULL,                0, 0, WINED3DSIH_ENDREP,  WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_IF,      "if",      NULL,                0, 1, WINED3DSIH_IF,      WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_IFC,     "ifc",     NULL,                0, 2, WINED3DSIH_IFC,     WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ELSE,    "else",    NULL,                0, 0, WINED3DSIH_ELSE,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDIF,   "endif",   NULL,                0, 0, WINED3DSIH_ENDIF,   WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_BREAK,   "break",   NULL,                0, 0, WINED3DSIH_BREAK,   WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKC,  "breakc",  NULL,                0, 2, WINED3DSIH_BREAKC,  WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKP,  "breakp",  GLNAME_REQUIRE_GLSL, 0, 1, WINED3DSIH_BREAKP,  0,                      0                     },
-    {WINED3DSIO_CALL,    "call",    NULL,                0, 1, WINED3DSIH_CALL,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_CALLNZ,  "callnz",  NULL,                0, 2, WINED3DSIH_CALLNZ,  WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_LOOP,    "loop",    NULL,                0, 2, WINED3DSIH_LOOP,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_RET,     "ret",     NULL,                0, 0, WINED3DSIH_RET,     WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDLOOP, "endloop", NULL,                0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_LABEL,   "label",   NULL,                0, 1, WINED3DSIH_LABEL,   WINED3DVS_VERSION(2,0), -1                    },
-
-    {WINED3DSIO_SETP,    "setp",    GLNAME_REQUIRE_GLSL, 1, 3, WINED3DSIH_SETP,    0,                      0                     },
-    {WINED3DSIO_TEXLDL,  "texldl",  NULL,                1, 3, WINED3DSIH_TEXLDL,  WINED3DVS_VERSION(3,0), -1                    },
-    {0,                  NULL,      NULL,                0, 0, 0,                  0,                      0                     }
+    {WINED3DSIO_REP ,    "rep",     0, 1, WINED3DSIH_REP,     WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_ENDREP,  "endrep",  0, 0, WINED3DSIH_ENDREP,  WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_IF,      "if",      0, 1, WINED3DSIH_IF,      WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_IFC,     "ifc",     0, 2, WINED3DSIH_IFC,     WINED3DVS_VERSION(2,1), -1                    },
+    {WINED3DSIO_ELSE,    "else",    0, 0, WINED3DSIH_ELSE,    WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_ENDIF,   "endif",   0, 0, WINED3DSIH_ENDIF,   WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_BREAK,   "break",   0, 0, WINED3DSIH_BREAK,   WINED3DVS_VERSION(2,1), -1                    },
+    {WINED3DSIO_BREAKC,  "breakc",  0, 2, WINED3DSIH_BREAKC,  WINED3DVS_VERSION(2,1), -1                    },
+    {WINED3DSIO_BREAKP,  "breakp",  0, 1, WINED3DSIH_BREAKP,  0,                      0                     },
+    {WINED3DSIO_CALL,    "call",    0, 1, WINED3DSIH_CALL,    WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_CALLNZ,  "callnz",  0, 2, WINED3DSIH_CALLNZ,  WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_LOOP,    "loop",    0, 2, WINED3DSIH_LOOP,    WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_RET,     "ret",     0, 0, WINED3DSIH_RET,     WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1                    },
+    {WINED3DSIO_LABEL,   "label",   0, 1, WINED3DSIH_LABEL,   WINED3DVS_VERSION(2,0), -1                    },
+
+    {WINED3DSIO_SETP,    "setp",    1, 3, WINED3DSIH_SETP,    0,                      0                     },
+    {WINED3DSIO_TEXLDL,  "texldl",  1, 3, WINED3DSIH_TEXLDL,  WINED3DVS_VERSION(3,0), -1                    },
+    {0,                  NULL,      0, 0, 0,                  0,                      0                     }
 };
 
 static void vshader_set_limits(
 };
 
 static void vshader_set_limits(
@@ -120,7 +120,8 @@ static void vshader_set_limits(
       /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
       This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
 
       /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
       This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
 
-      switch (This->baseShader.hex_version) {
+      switch (This->baseShader.reg_maps.shader_version)
+      {
           case WINED3DVS_VERSION(1,0):
           case WINED3DVS_VERSION(1,1):
                    This->baseShader.limits.temporary = 12;
           case WINED3DVS_VERSION(1,0):
           case WINED3DVS_VERSION(1,1):
                    This->baseShader.limits.temporary = 12;
@@ -161,7 +162,7 @@ static void vshader_set_limits(
                    This->baseShader.limits.sampler = 0;
                    This->baseShader.limits.label = 16;
                    FIXME("Unrecognized vertex shader version %#x\n",
                    This->baseShader.limits.sampler = 0;
                    This->baseShader.limits.label = 16;
                    FIXME("Unrecognized vertex shader version %#x\n",
-                       This->baseShader.hex_version);
+                           This->baseShader.reg_maps.shader_version);
       }
 }
 
       }
 }
 
@@ -217,150 +218,65 @@ BOOL vshader_get_input(
     return FALSE;
 }
 
     return FALSE;
 }
 
-BOOL vshader_input_is_color(
-    IWineD3DVertexShader* iface,
-    unsigned int regnum) {
-
-    IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
-
-    DWORD usage_token = This->semantics_in[regnum].usage;
-    DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-    DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-
-    int i;
-
-    for(i = 0; i < This->num_swizzled_attribs; i++) {
-        if(This->swizzled_attribs[i].usage == usage &&
-           This->swizzled_attribs[i].idx == usage_idx) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static inline void find_swizzled_attribs(IWineD3DVertexDeclaration *declaration, IWineD3DVertexShaderImpl *This) {
-    UINT num = 0, i, j;
-    UINT numoldswizzles = This->num_swizzled_attribs;
-    IWineD3DVertexDeclarationImpl *decl = (IWineD3DVertexDeclarationImpl *) declaration;
-
-    DWORD usage_token, usage, usage_idx;
-    BOOL found;
-
-    attrib_declaration oldswizzles[sizeof(This->swizzled_attribs) / sizeof(This->swizzled_attribs[0])];
-
-    /* Back up the old swizzles to keep attributes that are undefined in the current declaration */
-    memcpy(oldswizzles, This->swizzled_attribs, sizeof(oldswizzles));
-
-    memset(This->swizzled_attribs, 0, sizeof(This->swizzled_attribs[0]) * MAX_ATTRIBS);
-
-    for(i = 0; i < decl->num_swizzled_attribs; i++) {
-        for(j = 0; j < MAX_ATTRIBS; j++) {
-
-            if(!This->baseShader.reg_maps.attributes[j]) continue;
-
-            usage_token = This->semantics_in[j].usage;
-            usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-            usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-
-            if(decl->swizzled_attribs[i].usage == usage &&
-               decl->swizzled_attribs[i].idx == usage_idx) {
-                This->swizzled_attribs[num].usage = usage;
-                This->swizzled_attribs[num].idx = usage_idx;
-                num++;
-            }
-        }
-    }
-
-    /* Add previously converted attributes back in if they are not defined in the current declaration */
-    for(i = 0; i < numoldswizzles; i++) {
-
-        found = FALSE;
-        for(j = 0; j < decl->declarationWNumElements; j++) {
-            if(oldswizzles[i].usage == decl->pDeclarationWine[j].Usage &&
-               oldswizzles[i].idx == decl->pDeclarationWine[j].UsageIndex) {
-                found = TRUE;
-            }
-        }
-        if(found) {
-            /* This previously converted attribute is declared in the current declaration. Either it is
-             * already in the new array, or it should not be there. Skip it
-             */
-            continue;
-        }
-        /* We have a previously swizzled attribute that is not defined by the current vertex declaration.
-         * Insert it into the new conversion array to keep it in the old defined state. Otherwise we end up
-         * recompiling if the old decl is used again because undefined attributes are reset to no swizzling.
-         * In the reverse way(attribute was not swizzled and is not declared in new declaration) the attrib
-         * stays unswizzled as well because it isn't found in the oldswizzles array
-         */
-        for(j = 0; j < num; j++) {
-            if(oldswizzles[i].usage > This->swizzled_attribs[j].usage || (
-               oldswizzles[i].usage == This->swizzled_attribs[j].usage &&
-               oldswizzles[i].idx > This->swizzled_attribs[j].idx)) {
-                memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j],
-                         sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j + 1)));
-                break;
-            }
-        }
-        This->swizzled_attribs[j].usage = oldswizzles[i].usage;
-        This->swizzled_attribs[j].idx = oldswizzles[i].idx;
-        num++;
-    }
-
-    TRACE("New swizzled attributes array\n");
-    for(i = 0; i < num; i++) {
-        TRACE("%d: %s(%d), %d\n", i, debug_d3ddeclusage(This->swizzled_attribs[i].usage),
-              This->swizzled_attribs[i].usage, This->swizzled_attribs[i].idx);
-    }
-    This->num_swizzled_attribs = num;
-}
 /** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
     or GLSL and send it to the card */
 static void IWineD3DVertexShaderImpl_GenerateShader(IWineD3DVertexShader *iface,
         const struct shader_reg_maps* reg_maps, const DWORD *pFunction)
 {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
 /** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
     or GLSL and send it to the card */
 static void IWineD3DVertexShaderImpl_GenerateShader(IWineD3DVertexShader *iface,
         const struct shader_reg_maps* reg_maps, const DWORD *pFunction)
 {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    IWineD3DVertexDeclaration *decl = ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->vertexDecl;
     SHADER_BUFFER buffer;
 
     SHADER_BUFFER buffer;
 
-    find_swizzled_attribs(decl, This);
-
-#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
-        it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
-    if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
-        HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
-        This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
-        This->fixupVertexBufferSize = PGMSIZE;
-        This->fixupVertexBuffer[0] = 0;
-    }
-    buffer.buffer = This->device->fixupVertexBuffer;
-#else
-    buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE); 
-#endif
-    buffer.bsize = 0;
-    buffer.lineNo = 0;
-    buffer.newline = TRUE;
+    This->swizzle_map = ((IWineD3DDeviceImpl *)This->baseShader.device)->strided_streams.swizzle_map;
 
 
+    shader_buffer_init(&buffer);
     ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_generate_vshader(iface, &buffer);
     ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_generate_vshader(iface, &buffer);
-
-#if 1 /* if were using the data buffer of device then we don't need to free it */
-  HeapFree(GetProcessHeap(), 0, buffer.buffer);
-#endif
+    shader_buffer_free(&buffer);
 }
 
 /* *******************************************
    IWineD3DVertexShader IUnknown parts follow
    ******************************************* */
 static HRESULT  WINAPI IWineD3DVertexShaderImpl_QueryInterface(IWineD3DVertexShader *iface, REFIID riid, LPVOID *ppobj) {
 }
 
 /* *******************************************
    IWineD3DVertexShader IUnknown parts follow
    ******************************************* */
 static HRESULT  WINAPI IWineD3DVertexShaderImpl_QueryInterface(IWineD3DVertexShader *iface, REFIID riid, LPVOID *ppobj) {
-    return IWineD3DBaseShaderImpl_QueryInterface((IWineD3DBaseShader *) iface, riid, ppobj);
+    TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), ppobj);
+
+    if (IsEqualGUID(riid, &IID_IWineD3DVertexShader)
+            || IsEqualGUID(riid, &IID_IWineD3DBaseShader)
+            || IsEqualGUID(riid, &IID_IWineD3DBase)
+            || IsEqualGUID(riid, &IID_IUnknown))
+    {
+        IUnknown_AddRef(iface);
+        *ppobj = iface;
+        return S_OK;
+    }
+
+    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
+
+    *ppobj = NULL;
+    return E_NOINTERFACE;
 }
 
 static ULONG  WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface) {
 }
 
 static ULONG  WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface) {
-    return IWineD3DBaseShaderImpl_AddRef((IWineD3DBaseShader *) iface);
+    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
+    ULONG refcount = InterlockedIncrement(&This->baseShader.ref);
+
+    TRACE("%p increasing refcount to %u\n", This, refcount);
+
+    return refcount;
 }
 
 static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) {
 }
 
 static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) {
-    return IWineD3DBaseShaderImpl_Release((IWineD3DBaseShader *) iface);
+    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
+    ULONG refcount = InterlockedDecrement(&This->baseShader.ref);
+
+    TRACE("%p decreasing refcount to %u\n", This, refcount);
+
+    if (!refcount)
+    {
+        shader_cleanup((IWineD3DBaseShader *)iface);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return refcount;
 }
 
 /* *******************************************
 }
 
 /* *******************************************
@@ -398,16 +314,10 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
          * return D3DERR_MOREDATA. That's not actually true. */
         return WINED3DERR_INVALIDCALL;
     }
          * return D3DERR_MOREDATA. That's not actually true. */
         return WINED3DERR_INVALIDCALL;
     }
-    if (NULL == This->baseShader.function) { /* no function defined */
-        TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
-        (*(DWORD **) pData) = NULL;
-    } else {
-        if(This->baseShader.functionLength == 0){
 
 
-        }
-        TRACE("(%p) : GetFunction copying to %p\n", This, pData);
-        memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
-    }
+    TRACE("(%p) : GetFunction copying to %p\n", This, pData);
+    memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -425,8 +335,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     /* First pass: trace shader */
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     /* First pass: trace shader */
-    shader_trace_init((IWineD3DBaseShader*) This, pFunction);
-    vshader_set_limits(This);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
@@ -438,9 +347,11 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     This->max_rel_offset = 0;
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
     This->max_rel_offset = 0;
     memset(reg_maps, 0, sizeof(shader_reg_maps));
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-       This->semantics_in, This->semantics_out, pFunction, NULL);
+            This->semantics_in, This->semantics_out, pFunction);
     if (hr != WINED3D_OK) return hr;
 
     if (hr != WINED3D_OK) return hr;
 
+    vshader_set_limits(This);
+
     This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
 
     if(deviceImpl->vs_selected_mode == SHADER_ARB &&
     This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
 
     if(deviceImpl->vs_selected_mode == SHADER_ARB &&
@@ -462,16 +373,9 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     This->baseShader.load_local_constsF = This->baseShader.reg_maps.usesrelconstF && !list_empty(&This->baseShader.constantsF);
 
     /* copy the function ... because it will certainly be released by application */
     This->baseShader.load_local_constsF = This->baseShader.reg_maps.usesrelconstF && !list_empty(&This->baseShader.constantsF);
 
     /* copy the function ... because it will certainly be released by application */
-    if (NULL != pFunction) {
-        void *function;
-
-        function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
-        if (!function) return E_OUTOFMEMORY;
-        memcpy(function, pFunction, This->baseShader.functionLength);
-        This->baseShader.function = function;
-    } else {
-        This->baseShader.function = NULL;
-    }
+    This->baseShader.function = HeapAlloc(GetProcessHeap(), 0, This->baseShader.functionLength);
+    if (!This->baseShader.function) return E_OUTOFMEMORY;
+    memcpy(This->baseShader.function, pFunction, This->baseShader.functionLength);
 
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
@@ -514,56 +418,8 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static inline BOOL swizzled_attribs_differ(IWineD3DVertexShaderImpl *This, IWineD3DVertexDeclarationImpl *vdecl) {
-    UINT i, j, k;
-    BOOL found;
-
-    DWORD usage_token;
-    DWORD usage;
-    DWORD usage_idx;
-
-    for(i = 0; i < vdecl->declarationWNumElements; i++) {
-        /* Ignore tesselated streams and the termination entry(position0, stream 255, unused) */
-        if(vdecl->pDeclarationWine[i].Stream >= MAX_STREAMS ||
-           vdecl->pDeclarationWine[i].Type == WINED3DDECLTYPE_UNUSED) continue;
-
-        for(j = 0; j < MAX_ATTRIBS; j++) {
-            if(!This->baseShader.reg_maps.attributes[j]) continue;
-
-            usage_token = This->semantics_in[j].usage;
-            usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-            usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-
-            if(vdecl->pDeclarationWine[i].Usage != usage ||
-               vdecl->pDeclarationWine[i].UsageIndex != usage_idx) {
-                continue;
-            }
-
-            found = FALSE;
-            for(k = 0; k < This->num_swizzled_attribs; k++) {
-                if(This->swizzled_attribs[k].usage == usage &&
-                    This->swizzled_attribs[k].idx == usage_idx) {
-                    found = TRUE;
-                }
-            }
-            if(!found && vdecl->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) {
-                TRACE("Attribute %s%d is D3DCOLOR now but wasn't before\n",
-                      debug_d3ddeclusage(usage), usage_idx);
-                return TRUE;
-            }
-            if( found && vdecl->pDeclarationWine[i].Type != WINED3DDECLTYPE_D3DCOLOR) {
-                TRACE("Attribute %s%d was D3DCOLOR before but is not any more\n",
-                      debug_d3ddeclusage(usage), usage_idx);
-                return TRUE;
-            }
-        }
-    }
-    return FALSE;
-}
-
 HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
 HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    IWineD3DVertexDeclarationImpl *vdecl;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
 
     CONST DWORD *function = This->baseShader.function;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
 
@@ -571,20 +427,10 @@ HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
 
     /* We're already compiled. */
     if (This->baseShader.is_compiled) {
 
     /* We're already compiled. */
     if (This->baseShader.is_compiled) {
-        vdecl = (IWineD3DVertexDeclarationImpl *) deviceImpl->stateBlock->vertexDecl;
-
-        if(This->num_swizzled_attribs != vdecl->num_swizzled_attribs ||
-           memcmp(This->swizzled_attribs, vdecl->swizzled_attribs, sizeof(vdecl->swizzled_attribs[0]) * This->num_swizzled_attribs) != 0) {
-
-            /* The swizzled attributes differ between shader and declaration. This doesn't necessarily mean
-             * we have to recompile, but we have to take a deeper look at see if the attribs that differ
-             * are declared in the decl and used in the shader
-             */
-            if(swizzled_attribs_differ(This, vdecl)) {
-                WARN("Recompiling vertex shader %p due to D3DCOLOR input changes\n", This);
-                goto recompile;
-            }
-            WARN("Swizzled attribute validation required an expensive comparison\n");
+        if ((This->swizzle_map & deviceImpl->strided_streams.use_map) != deviceImpl->strided_streams.swizzle_map)
+        {
+            WARN("Recompiling vertex shader %p due to D3DCOLOR input changes\n", This);
+            goto recompile;
         }
 
         return WINED3D_OK;
         }
 
         return WINED3D_OK;
@@ -599,12 +445,6 @@ HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
         deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface);
     }
 
         deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface);
     }
 
-    /* We don't need to compile */
-    if (!function) {
-        This->baseShader.is_compiled = TRUE;
-        return WINED3D_OK;
-    }
-
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
     IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
     IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
index 6700bb4..ceffae7 100644 (file)
@@ -64,6 +64,31 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
     }
 }
 
     }
 }
 
+void volume_add_dirty_box(IWineD3DVolume *iface, const WINED3DBOX *dirty_box)
+{
+    IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
+
+    This->dirty = TRUE;
+    if (dirty_box)
+    {
+        This->lockedBox.Left = min(This->lockedBox.Left, dirty_box->Left);
+        This->lockedBox.Top = min(This->lockedBox.Top, dirty_box->Top);
+        This->lockedBox.Front = min(This->lockedBox.Front, dirty_box->Front);
+        This->lockedBox.Right = max(This->lockedBox.Right, dirty_box->Right);
+        This->lockedBox.Bottom = max(This->lockedBox.Bottom, dirty_box->Bottom);
+        This->lockedBox.Back = max(This->lockedBox.Back, dirty_box->Back);
+    }
+    else
+    {
+        This->lockedBox.Left = 0;
+        This->lockedBox.Top = 0;
+        This->lockedBox.Front = 0;
+        This->lockedBox.Right = This->currentDesc.Width;
+        This->lockedBox.Bottom = This->currentDesc.Height;
+        This->lockedBox.Back = This->currentDesc.Depth;
+    }
+}
+
 /* *******************************************
    IWineD3DVolume IUnknown parts follow
    ******************************************* */
 /* *******************************************
    IWineD3DVolume IUnknown parts follow
    ******************************************* */
@@ -225,7 +250,7 @@ static HRESULT WINAPI IWineD3DVolumeImpl_LockBox(IWineD3DVolume *iface, WINED3DL
        * Dirtify on lock
        * as seen in msdn docs
        */
        * Dirtify on lock
        * as seen in msdn docs
        */
-      IWineD3DVolume_AddDirtyBox(iface, &This->lockedBox);
+      volume_add_dirty_box(iface, &This->lockedBox);
 
       /**  Dirtify Container if needed */
       if (NULL != This->container) {
 
       /**  Dirtify Container if needed */
       if (NULL != This->container) {
@@ -261,39 +286,6 @@ static HRESULT WINAPI IWineD3DVolumeImpl_UnlockBox(IWineD3DVolume *iface) {
 
 /* Internal use functions follow : */
 
 
 /* Internal use functions follow : */
 
-static HRESULT WINAPI IWineD3DVolumeImpl_CleanDirtyBox(IWineD3DVolume *iface) {
-  IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
-  This->dirty = FALSE;
-  This->lockedBox.Left   = This->currentDesc.Width;
-  This->lockedBox.Top    = This->currentDesc.Height;
-  This->lockedBox.Front  = This->currentDesc.Depth;
-  This->lockedBox.Right  = 0;
-  This->lockedBox.Bottom = 0;
-  This->lockedBox.Back   = 0;
-  return WINED3D_OK;
-}
-
-static HRESULT WINAPI IWineD3DVolumeImpl_AddDirtyBox(IWineD3DVolume *iface, CONST WINED3DBOX* pDirtyBox) {
-  IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
-  This->dirty = TRUE;
-   if (NULL != pDirtyBox) {
-    This->lockedBox.Left   = min(This->lockedBox.Left,   pDirtyBox->Left);
-    This->lockedBox.Top    = min(This->lockedBox.Top,    pDirtyBox->Top);
-    This->lockedBox.Front  = min(This->lockedBox.Front,  pDirtyBox->Front);
-    This->lockedBox.Right  = max(This->lockedBox.Right,  pDirtyBox->Right);
-    This->lockedBox.Bottom = max(This->lockedBox.Bottom, pDirtyBox->Bottom);
-    This->lockedBox.Back   = max(This->lockedBox.Back,   pDirtyBox->Back);
-  } else {
-    This->lockedBox.Left   = 0;
-    This->lockedBox.Top    = 0;
-    This->lockedBox.Front  = 0;
-    This->lockedBox.Right  = This->currentDesc.Width;
-    This->lockedBox.Bottom = This->currentDesc.Height;
-    This->lockedBox.Back   = This->currentDesc.Depth;
-  }
-  return WINED3D_OK;
-}
-
 static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWineD3DBase* container) {
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
 
 static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWineD3DBase* container) {
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
 
@@ -374,8 +366,6 @@ const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl =
     IWineD3DVolumeImpl_LockBox,
     IWineD3DVolumeImpl_UnlockBox,
     /* Internal interface */
     IWineD3DVolumeImpl_LockBox,
     IWineD3DVolumeImpl_UnlockBox,
     /* Internal interface */
-    IWineD3DVolumeImpl_AddDirtyBox,
-    IWineD3DVolumeImpl_CleanDirtyBox,
     IWineD3DVolumeImpl_LoadTexture,
     IWineD3DVolumeImpl_SetContainer
 };
     IWineD3DVolumeImpl_LoadTexture,
     IWineD3DVolumeImpl_SetContainer
 };
index 9da4c95..ea8c073 100644 (file)
@@ -119,7 +119,7 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
             FIXME("Volumetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
 
         for (i = 0; i < This->baseTexture.levels; i++) {
             FIXME("Volumetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
 
         for (i = 0; i < This->baseTexture.levels; i++) {
-            IWineD3DVolume_AddDirtyBox(This->volumes[i], NULL);
+            volume_add_dirty_box(This->volumes[i], NULL);
             IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
         }
     } else {
             IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
         }
     } else {
@@ -244,7 +244,7 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTextu
         TRACE("(%p) Level (%d)\n", This, Level);
         return IWineD3DVolume_GetDesc(This->volumes[Level], pDesc);
     } else {
         TRACE("(%p) Level (%d)\n", This, Level);
         return IWineD3DVolume_GetDesc(This->volumes[Level], pDesc);
     } else {
-        FIXME("(%p) Level (%d)\n", This, Level);
+        WARN("(%p) Level (%d)\n", This, Level);
     }
     return WINED3D_OK;
 }
     }
     return WINED3D_OK;
 }
@@ -255,7 +255,7 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTex
       IWineD3DVolume_AddRef(*ppVolumeLevel);
       TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel);
     } else {
       IWineD3DVolume_AddRef(*ppVolumeLevel);
       TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel);
     } else {
-      FIXME("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
+      WARN("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
       return WINED3DERR_INVALIDCALL;
     }
     return WINED3D_OK;
       return WINED3DERR_INVALIDCALL;
     }
     return WINED3D_OK;
@@ -295,7 +295,9 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTextur
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of volume Level (0)\n", This);
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
     This->baseTexture.dirty = TRUE;
     TRACE("(%p) : dirtyfication of volume Level (0)\n", This);
-    return IWineD3DVolume_AddDirtyBox(This->volumes[0], pDirtyBox);
+    volume_add_dirty_box(This->volumes[0], pDirtyBox);
+
+    return WINED3D_OK;
 }
 
 const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
 }
 
 const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
index cf81629..32e089c 100644 (file)
@@ -26,6 +26,7 @@
        <file>device.c</file>
        <file>directx.c</file>
        <file>drawprim.c</file>
        <file>device.c</file>
        <file>directx.c</file>
        <file>drawprim.c</file>
+       <file>gl_compat.c</file>
        <file>glsl_shader.c</file>
        <file>indexbuffer.c</file>
        <file>nvidia_texture_shader.c</file>
        <file>glsl_shader.c</file>
        <file>indexbuffer.c</file>
        <file>nvidia_texture_shader.c</file>
@@ -52,4 +53,4 @@
        <file>version.rc</file>
 
        <dependency>wineheaders</dependency>
        <file>version.rc</file>
 
        <dependency>wineheaders</dependency>
-</module>
\ No newline at end of file
+</module>
index f92adc6..07ca0d5 100644 (file)
@@ -866,6 +866,7 @@ void (WINE_GLAPI *glDepthFunc) (GLenum func);
 void (WINE_GLAPI *glDepthMask) (GLboolean flag);
 void (WINE_GLAPI *glDepthRange) (GLclampd nearParam, GLclampd farParam);
 void (WINE_GLAPI *glDisable) (GLenum cap);
 void (WINE_GLAPI *glDepthMask) (GLboolean flag);
 void (WINE_GLAPI *glDepthRange) (GLclampd nearParam, GLclampd farParam);
 void (WINE_GLAPI *glDisable) (GLenum cap);
+void (WINE_GLAPI *glDisableWINE) (GLenum cap);
 void (WINE_GLAPI *glDisableClientState) (GLenum array);
 void (WINE_GLAPI *glDrawArrays) (GLenum mode, GLint first, GLsizei count);
 void (WINE_GLAPI *glDrawBuffer) (GLenum mode);
 void (WINE_GLAPI *glDisableClientState) (GLenum array);
 void (WINE_GLAPI *glDrawArrays) (GLenum mode, GLint first, GLsizei count);
 void (WINE_GLAPI *glDrawBuffer) (GLenum mode);
@@ -875,6 +876,7 @@ void (WINE_GLAPI *glEdgeFlag) (GLboolean flag);
 void (WINE_GLAPI *glEdgeFlagPointer) (GLsizei stride, const GLvoid* pointer);
 void (WINE_GLAPI *glEdgeFlagv) (const GLboolean* flag);
 void (WINE_GLAPI *glEnable) (GLenum cap);
 void (WINE_GLAPI *glEdgeFlagPointer) (GLsizei stride, const GLvoid* pointer);
 void (WINE_GLAPI *glEdgeFlagv) (const GLboolean* flag);
 void (WINE_GLAPI *glEnable) (GLenum cap);
+void (WINE_GLAPI *glEnableWINE) (GLenum cap);
 void (WINE_GLAPI *glEnableClientState) (GLenum array);
 void (WINE_GLAPI *glEnd) ();
 void (WINE_GLAPI *glEndList) ();
 void (WINE_GLAPI *glEnableClientState) (GLenum array);
 void (WINE_GLAPI *glEnd) ();
 void (WINE_GLAPI *glEndList) ();
@@ -2037,6 +2039,39 @@ typedef void (WINE_GLAPI * PGLFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint le
 #define GL_RGBA16F_ARB                    0x881A
 #define GL_RGB16F_ARB                     0x881B
 #endif
 #define GL_RGBA16F_ARB                    0x881A
 #define GL_RGB16F_ARB                     0x881B
 #endif
+/* GL_ARB_texture_rg */
+#ifndef GL_ARB_texture_rg
+#define GL_RG                             0x8227
+#define GL_RG_INTEGER                     0x8228
+#define GL_R8                             0x8229
+#define GL_R16                            0x822A
+#define GL_RG8                            0x822B
+#define GL_RG16                           0x822C
+#define GL_R16F                           0x822D
+#define GL_R32F                           0x822E
+#define GL_RG16F                          0x822F
+#define GL_RG32F                          0x8230
+#define GL_R8I                            0x8231
+#define GL_R8UI                           0x8232
+#define GL_R16I                           0x8233
+#define GL_R16UI                          0x8234
+#define GL_R32I                           0x8235
+#define GL_R32UI                          0x8236
+#define GL_RG8I                           0x8237
+#define GL_RG8UI                          0x8238
+#define GL_RG16I                          0x8239
+#define GL_RG16UI                         0x823A
+#define GL_RG32I                          0x823B
+#define GL_RG32UI                         0x823C
+#endif
+/* GL_EXT_texture_swizzle */
+#ifndef GL_EXT_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R_EXT          0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT          0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT          0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT          0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT       0x8E46
+#endif
 /* GL_ARB_half_float_pixel */
 #ifndef GL_ARB_half_float_pixel
 #define GL_ARB_half_float_pixel
 /* GL_ARB_half_float_pixel */
 #ifndef GL_ARB_half_float_pixel
 #define GL_ARB_half_float_pixel
@@ -2288,10 +2323,10 @@ typedef void (WINE_GLAPI * PGLFNBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, G
 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT     0x8456
 #define GL_FOG_COORDINATE_ARRAY_EXT             0x8457
 #endif /* GL_EXT_fog_coord */
 #define GL_FOG_COORDINATE_ARRAY_POINTER_EXT     0x8456
 #define GL_FOG_COORDINATE_ARRAY_EXT             0x8457
 #endif /* GL_EXT_fog_coord */
-typedef void (WINE_GLAPI * PGLFNGLFOGCOORDFEXTPROC) (GLfloat intesity);
-typedef void (WINE_GLAPI * PGLFNGLFOGCOORDFVEXTPROC) (GLfloat intesity);
-typedef void (WINE_GLAPI * PGLFNGLFOGCOORDDEXTPROC) (GLfloat intesity);
-typedef void (WINE_GLAPI * PGLFNGLFOGCOORDDVEXTPROC) (GLfloat intesity);
+typedef void (WINE_GLAPI * PGLFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (WINE_GLAPI * PGLFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (WINE_GLAPI * PGLFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (WINE_GLAPI * PGLFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
 typedef void (WINE_GLAPI * PGLFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, GLvoid *data);
 /* GL_ARB_shader_objects (GLSL) */
 #ifndef GL_ARB_shader_objects
 typedef void (WINE_GLAPI * PGLFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, GLvoid *data);
 /* GL_ARB_shader_objects (GLSL) */
 #ifndef GL_ARB_shader_objects
@@ -3317,6 +3352,7 @@ typedef enum _GL_SupportedExt {
   ARB_TEXTURE_MIRRORED_REPEAT,
   ARB_TEXTURE_NON_POWER_OF_TWO,
   ARB_TEXTURE_RECTANGLE,
   ARB_TEXTURE_MIRRORED_REPEAT,
   ARB_TEXTURE_NON_POWER_OF_TWO,
   ARB_TEXTURE_RECTANGLE,
+  ARB_TEXTURE_RG,
   ARB_VERTEX_PROGRAM,
   ARB_VERTEX_BLEND,
   ARB_VERTEX_BUFFER_OBJECT,
   ARB_VERTEX_PROGRAM,
   ARB_VERTEX_BLEND,
   ARB_VERTEX_BUFFER_OBJECT,
@@ -3347,7 +3383,9 @@ typedef enum _GL_SupportedExt {
   EXT_TEXTURE_ENV_COMBINE,
   EXT_TEXTURE_ENV_DOT3,
   EXT_TEXTURE_SRGB,
   EXT_TEXTURE_ENV_COMBINE,
   EXT_TEXTURE_ENV_DOT3,
   EXT_TEXTURE_SRGB,
+  EXT_TEXTURE_SWIZZLE,
   EXT_GPU_PROGRAM_PARAMETERS,
   EXT_GPU_PROGRAM_PARAMETERS,
+  EXT_VERTEX_ARRAY_BGRA,
   /* NVIDIA */
   NV_HALF_FLOAT,
   NV_FOG_DISTANCE,
   /* NVIDIA */
   NV_HALF_FLOAT,
   NV_FOG_DISTANCE,
@@ -3471,7 +3509,7 @@ typedef enum _GL_SupportedExt {
     USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC,                            glFogCoordfEXT,                             EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDFVEXTPROC,                           glFogCoordfvEXT,                            EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDDEXTPROC,                            glFogCoorddEXT,                             EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDFEXTPROC,                            glFogCoordfEXT,                             EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDFVEXTPROC,                           glFogCoordfvEXT,                            EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDDEXTPROC,                            glFogCoorddEXT,                             EXT_FOG_COORD,          NULL )\
-    USE_GL_FUNC(PGLFNGLFOGCOORDDVEXTPROC,                           glFogCoordvEXT,                             EXT_FOG_COORD,          NULL )\
+    USE_GL_FUNC(PGLFNGLFOGCOORDDVEXTPROC,                           glFogCoorddvEXT,                            EXT_FOG_COORD,          NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDPOINTEREXTPROC,                      glFogCoordPointerEXT,                       EXT_FOG_COORD,          NULL )\
     /* GL_EXT_framebuffer_object */ \
     USE_GL_FUNC(PGLFNGLISRENDERBUFFEREXTPROC,                       glIsRenderbufferEXT,                        EXT_FRAMEBUFFER_OBJECT, NULL )\
     USE_GL_FUNC(PGLFNGLFOGCOORDPOINTEREXTPROC,                      glFogCoordPointerEXT,                       EXT_FOG_COORD,          NULL )\
     /* GL_EXT_framebuffer_object */ \
     USE_GL_FUNC(PGLFNGLISRENDERBUFFEREXTPROC,                       glIsRenderbufferEXT,                        EXT_FRAMEBUFFER_OBJECT, NULL )\
@@ -3579,8 +3617,8 @@ typedef enum _GL_SupportedExt {
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX2FVARBPROC,               glUniformMatrix2fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX3FVARBPROC,               glUniformMatrix3fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX4FVARBPROC,               glUniformMatrix4fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX2FVARBPROC,               glUniformMatrix2fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX3FVARBPROC,               glUniformMatrix3fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUNIFORMMATRIX4FVARBPROC,               glUniformMatrix4fvARB,                      ARB_SHADER_OBJECTS,     NULL )\
-    USE_GL_FUNC(WINED3D_PFNGLGETUNIFORMFVARBPROC,                   glGetUniform4fvARB,                         ARB_SHADER_OBJECTS,     NULL )\
-    USE_GL_FUNC(WINED3D_PFNGLGETUNIFORMIVARBPROC,                   glGetUniform4ivARB,                         ARB_SHADER_OBJECTS,     NULL )\
+    USE_GL_FUNC(WINED3D_PFNGLGETUNIFORMFVARBPROC,                   glGetUniformfvARB,                          ARB_SHADER_OBJECTS,     NULL )\
+    USE_GL_FUNC(WINED3D_PFNGLGETUNIFORMIVARBPROC,                   glGetUniformivARB,                          ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLGETINFOLOGARBPROC,                     glGetInfoLogARB,                            ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUSEPROGRAMOBJECTARBPROC,               glUseProgramObjectARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLCREATESHADEROBJECTARBPROC,             glCreateShaderObjectARB,                    ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLGETINFOLOGARBPROC,                     glGetInfoLogARB,                            ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLUSEPROGRAMOBJECTARBPROC,               glUseProgramObjectARB,                      ARB_SHADER_OBJECTS,     NULL )\
     USE_GL_FUNC(WINED3D_PFNGLCREATESHADEROBJECTARBPROC,             glCreateShaderObjectARB,                    ARB_SHADER_OBJECTS,     NULL )\
@@ -3678,8 +3716,8 @@ typedef enum _GL_SupportedExt {
     USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC,                          glXGetVideoSyncSGI,                         SGI_VIDEO_SYNC,         NULL )\
     USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC,                         glXWaitVideoSyncSGI,                        SGI_VIDEO_SYNC,         NULL )\
     /* GL_APPLE_flush_render */ \
     USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC,                          glXGetVideoSyncSGI,                         SGI_VIDEO_SYNC,         NULL )\
     USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC,                         glXWaitVideoSyncSGI,                        SGI_VIDEO_SYNC,         NULL )\
     /* GL_APPLE_flush_render */ \
-    USE_GL_FUNC(PGLFNFLUSHRENDERAPPLEPROC,                          glFlushRenderApple,                         APPLE_FLUSH_RENDER,     NULL )\
-    USE_GL_FUNC(PGLFNFINISHRENDERAPPLEPROC,                         glFinishRenderApple,                        APPLE_FLUSH_RENDER,     NULL )\
+    USE_GL_FUNC(PGLFNFLUSHRENDERAPPLEPROC,                          glFlushRenderAPPLE,                         APPLE_FLUSH_RENDER,     NULL )\
+    USE_GL_FUNC(PGLFNFINISHRENDERAPPLEPROC,                         glFinishRenderAPPLE,                        APPLE_FLUSH_RENDER,     NULL )\
     /* GL_EXT_gpu_program_parameters */ \
     USE_GL_FUNC(PGLFNPROGRAMENVPARAMETERS4FVEXTPROC,                glProgramEnvParameters4fvEXT,            EXT_GPU_PROGRAM_PARAMETERS,NULL )\
     USE_GL_FUNC(PGLFNPROGRAMLOCALPARAMETERS4FVEXTPROC,              glProgramLocalParameters4fvEXT,          EXT_GPU_PROGRAM_PARAMETERS,NULL )\
     /* GL_EXT_gpu_program_parameters */ \
     USE_GL_FUNC(PGLFNPROGRAMENVPARAMETERS4FVEXTPROC,                glProgramEnvParameters4fvEXT,            EXT_GPU_PROGRAM_PARAMETERS,NULL )\
     USE_GL_FUNC(PGLFNPROGRAMLOCALPARAMETERS4FVEXTPROC,              glProgramLocalParameters4fvEXT,          EXT_GPU_PROGRAM_PARAMETERS,NULL )\
@@ -3817,6 +3855,7 @@ typedef struct _WINED3DGLTYPE {
     int         d3dType;
     GLint       size;
     GLenum      glType;
     int         d3dType;
     GLint       size;
     GLenum      glType;
+    GLint       format;
     GLboolean   normalized;
     int         typesize;
 } WINED3DGLTYPE;
     GLboolean   normalized;
     int         typesize;
 } WINED3DGLTYPE;
index ee8f07f..b401f94 100644 (file)
@@ -29,8 +29,8 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 int num_lock = 0;
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 int num_lock = 0;
-void (*wine_tsx11_lock_ptr)(void) = NULL;
-void (*wine_tsx11_unlock_ptr)(void) = NULL;
+void (*CDECL wine_tsx11_lock_ptr)(void) = NULL;
+void (*CDECL wine_tsx11_unlock_ptr)(void) = NULL;
 
 
 /* When updating default value here, make sure to update winecfg as well,
 
 
 /* When updating default value here, make sure to update winecfg as well,
@@ -88,7 +88,7 @@ static inline DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char* n
     return ERROR_FILE_NOT_FOUND;
 }
 
     return ERROR_FILE_NOT_FOUND;
 }
 
-static void wined3d_do_nothing(void)
+static void CDECL wined3d_do_nothing(void)
 {
 }
 
 {
 }
 
index 79617a5..0965a77 100644 (file)
@@ -155,6 +155,7 @@ struct hash_table_t {
 
 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function);
 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb);
 
 struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function);
 void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb);
+void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context);
 void *hash_table_get(const struct hash_table_t *table, const void *key);
 void hash_table_put(struct hash_table_t *table, void *key, void *value);
 void hash_table_remove(struct hash_table_t *table, void *key);
 void *hash_table_get(const struct hash_table_t *table, const void *key);
 void hash_table_put(struct hash_table_t *table, void *key, void *value);
 void hash_table_remove(struct hash_table_t *table, void *key);
@@ -214,6 +215,7 @@ void init_type_lookup(WineD3D_GL_Info *gl_info);
 #define WINED3D_ATR_TYPE(type)          GLINFO_LOCATION.glTypeLookup[type].d3dType
 #define WINED3D_ATR_SIZE(type)          GLINFO_LOCATION.glTypeLookup[type].size
 #define WINED3D_ATR_GLTYPE(type)        GLINFO_LOCATION.glTypeLookup[type].glType
 #define WINED3D_ATR_TYPE(type)          GLINFO_LOCATION.glTypeLookup[type].d3dType
 #define WINED3D_ATR_SIZE(type)          GLINFO_LOCATION.glTypeLookup[type].size
 #define WINED3D_ATR_GLTYPE(type)        GLINFO_LOCATION.glTypeLookup[type].glType
+#define WINED3D_ATR_FORMAT(type)        GLINFO_LOCATION.glTypeLookup[type].format
 #define WINED3D_ATR_NORMALIZED(type)    GLINFO_LOCATION.glTypeLookup[type].normalized
 #define WINED3D_ATR_TYPESIZE(type)      GLINFO_LOCATION.glTypeLookup[type].typesize
 
 #define WINED3D_ATR_NORMALIZED(type)    GLINFO_LOCATION.glTypeLookup[type].normalized
 #define WINED3D_ATR_TYPESIZE(type)      GLINFO_LOCATION.glTypeLookup[type].typesize
 
@@ -429,19 +431,50 @@ enum tex_types
     tex_type_count = 5,
 };
 
     tex_type_count = 5,
 };
 
+enum vertexprocessing_mode {
+    fixedfunction,
+    vertexshader,
+    pretransformed
+};
+
+struct stb_const_desc {
+    char                    texunit;
+    UINT                    const_num;
+};
+
+enum fogmode {
+    FOG_OFF,
+    FOG_LINEAR,
+    FOG_EXP,
+    FOG_EXP2
+};
+
+/* Stateblock dependent parameters which have to be hardcoded
+ * into the shader code
+ */
+struct ps_compile_args {
+    struct color_fixup_desc     color_fixup[MAX_FRAGMENT_SAMPLERS];
+    BOOL                        srgb_correction;
+    enum vertexprocessing_mode  vp_mode;
+    enum fogmode                fog;
+    /* Projected textures(ps 1.0-1.3) */
+    /* Texture types(2D, Cube, 3D) in ps 1.x */
+};
+
 typedef struct {
     const SHADER_HANDLER *shader_instruction_handler_table;
     void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
 typedef struct {
     const SHADER_HANDLER *shader_instruction_handler_table;
     void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
+    void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
+    void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
     void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
-    void (*shader_cleanup)(IWineD3DDevice *iface);
     void (*shader_color_correction)(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup);
     void (*shader_destroy)(IWineD3DBaseShader *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
     void (*shader_color_correction)(const struct SHADER_OPCODE_ARG *arg, struct color_fixup_desc fixup);
     void (*shader_destroy)(IWineD3DBaseShader *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
-    GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer);
+    GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
     void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer);
     void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
     void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer);
     void (*shader_get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *caps);
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
@@ -453,8 +486,8 @@ extern const shader_backend_t none_shader_backend;
 
 /* X11 locking */
 
 
 /* X11 locking */
 
-extern void (*wine_tsx11_lock_ptr)(void);
-extern void (*wine_tsx11_unlock_ptr)(void);
+extern void (* CDECL wine_tsx11_lock_ptr)(void);
+extern void (* CDECL wine_tsx11_unlock_ptr)(void);
 
 /* As GLX relies on X, this is needed */
 extern int num_lock;
 
 /* As GLX relies on X, this is needed */
 extern int num_lock;
@@ -501,9 +534,7 @@ extern int num_lock;
 
 #define MAX_STREAMS  16  /* Maximum possible streams - used for fixed size arrays
                             See MaxStreams in MSDN under GetDeviceCaps */
 
 #define MAX_STREAMS  16  /* Maximum possible streams - used for fixed size arrays
                             See MaxStreams in MSDN under GetDeviceCaps */
-                         /* Maximum number of constants provided to the shaders */
-#define HIGHEST_TRANSFORMSTATE 512 
-                         /* Highest value in WINED3DTRANSFORMSTATETYPE */
+#define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */
 
 /* Checking of API calls */
 /* --------------------- */
 
 /* Checking of API calls */
 /* --------------------- */
@@ -613,16 +644,8 @@ extern LONG primCounter;
  */
 
 /* Routine common to the draw primitive and draw indexed primitive routines */
  */
 
 /* Routine common to the draw primitive and draw indexed primitive routines */
-void drawPrimitive(IWineD3DDevice *iface,
-                    int PrimitiveType,
-                    long NumPrimitives,
-                    /* for Indexed: */
-                    long  StartVertexIndex,
-                    UINT  numberOfVertices,
-                    long  StartIdx,
-                    short idxBytes,
-                    const void *idxData,
-                    int   minIndex);
+void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives,
+        UINT numberOfVertices, long start_idx, short idxBytes, const void *idxData, int minIndex);
 
 void primitiveDeclarationConvertToStridedData(
      IWineD3DDevice *iface,
 
 void primitiveDeclarationConvertToStridedData(
      IWineD3DDevice *iface,
@@ -639,7 +662,6 @@ extern glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
 extern glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
 extern glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
 extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
 extern glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
 extern glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
 extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
-extern glAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED];
 
 #define eps 1e-8
 
 
 #define eps 1e-8
 
@@ -653,7 +675,7 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock,
 #define STATE_RENDER(a) (a)
 #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
 
 #define STATE_RENDER(a) (a)
 #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
 
-#define STATE_TEXTURESTAGE(stage, num) (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + (stage) * WINED3D_HIGHEST_TEXTURE_STATE + (num))
+#define STATE_TEXTURESTAGE(stage, num) (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + 1 + (stage) * (WINED3D_HIGHEST_TEXTURE_STATE + 1) + (num))
 #define STATE_IS_TEXTURESTAGE(a) ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE))
 
 /* + 1 because samplers start with 0 */
 #define STATE_IS_TEXTURESTAGE(a) ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE))
 
 /* + 1 because samplers start with 0 */
@@ -740,7 +762,7 @@ extern const struct fragment_pipeline nvts_fragment_pipeline;
 extern const struct fragment_pipeline nvrc_fragment_pipeline;
 
 /* "Base" state table */
 extern const struct fragment_pipeline nvrc_fragment_pipeline;
 
 /* "Base" state table */
-void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
 
         const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
 
@@ -756,6 +778,12 @@ struct blit_shader {
 extern const struct blit_shader ffp_blit;
 extern const struct blit_shader arbfp_blit;
 
 extern const struct blit_shader ffp_blit;
 extern const struct blit_shader arbfp_blit;
 
+enum fogsource {
+    FOGSOURCE_FFP,
+    FOGSOURCE_VS,
+    FOGSOURCE_COORD,
+};
+
 /* The new context manager that should deal with onscreen and offscreen rendering */
 struct WineD3DContext {
     /* State dirtification
 /* The new context manager that should deal with onscreen and offscreen rendering */
 struct WineD3DContext {
     /* State dirtification
@@ -772,21 +800,27 @@ struct WineD3DContext {
     DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some information about the context state for optimization */
     DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some information about the context state for optimization */
-    BOOL                    draw_buffer_dirty;
-    BOOL                    last_was_rhw;      /* true iff last draw_primitive was in xyzrhw mode */
-    BOOL                    last_was_pshader;
-    BOOL                    last_was_vshader;
-    BOOL                    last_was_foggy_shader;
-    BOOL                    namedArraysLoaded, numberedArraysLoaded;
+    WORD draw_buffer_dirty : 1;
+    WORD last_was_rhw : 1;              /* true iff last draw_primitive was in xyzrhw mode */
+    WORD last_was_pshader : 1;
+    WORD last_was_vshader : 1;
+    WORD last_was_foggy_shader : 1;
+    WORD namedArraysLoaded : 1;
+    WORD numberedArraysLoaded : 1;
+    WORD last_was_blit : 1;
+    WORD last_was_ckey : 1;
+    WORD fog_coord : 1;
+    WORD isPBuffer : 1;
+    WORD fog_enabled : 1;
+    WORD num_untracked_materials : 2;   /* Max value 2 */
+    WORD padding : 2;
+    BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
+    BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */
     DWORD                   numbered_array_mask;
     DWORD                   numbered_array_mask;
-    BOOL                    lastWasPow2Texture[MAX_TEXTURES];
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
-    unsigned char           num_untracked_materials;
     GLenum                  untracked_materials[2];
     GLenum                  untracked_materials[2];
-    BOOL                    last_was_blit, last_was_ckey;
     UINT                    blit_w, blit_h;
     UINT                    blit_w, blit_h;
-    char                    texShaderBumpMap;
-    BOOL                    fog_coord;
+    enum fogsource          fog_source;
 
     char                    *vshader_const_dirty, *pshader_const_dirty;
 
 
     char                    *vshader_const_dirty, *pshader_const_dirty;
 
@@ -795,7 +829,6 @@ struct WineD3DContext {
     HWND                    win_handle;
     HDC                     hdc;
     HPBUFFERARB             pbuffer;
     HWND                    win_handle;
     HDC                     hdc;
     HPBUFFERARB             pbuffer;
-    BOOL                    isPBuffer;
     GLint                   aux_buffers;
 
     /* FBOs */
     GLint                   aux_buffers;
 
     /* FBOs */
@@ -803,6 +836,11 @@ struct WineD3DContext {
     struct fbo_entry        *current_fbo;
     GLuint                  src_fbo;
     GLuint                  dst_fbo;
     struct fbo_entry        *current_fbo;
     GLuint                  src_fbo;
     GLuint                  dst_fbo;
+
+    /* Extension emulation */
+    GLint                   gl_fog_source;
+    GLfloat                 fog_coord_value;
+    GLfloat                 color[4], fogstart, fogend, fogcolor[4];
 };
 
 typedef enum ContextUsage {
 };
 
 typedef enum ContextUsage {
@@ -813,6 +851,7 @@ typedef enum ContextUsage {
 } ContextUsage;
 
 void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
 } ContextUsage;
 
 void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
+WineD3DContext *getActiveContext(void);
 WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
 void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
 WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
 void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
@@ -891,6 +930,7 @@ struct WineD3DAdapter
 extern BOOL InitAdapters(void);
 extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
 extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
 extern BOOL InitAdapters(void);
 extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
 extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
+extern void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info);
 
 /*****************************************************************************
  * High order patch management
 
 /*****************************************************************************
  * High order patch management
@@ -924,7 +964,7 @@ enum dst_arg
 /*****************************************************************************
  * Fixed function pipeline replacements
  */
 /*****************************************************************************
  * Fixed function pipeline replacements
  */
-#define ARG_UNUSED          0x3f
+#define ARG_UNUSED          0xff
 struct texture_stage_op
 {
     unsigned                cop : 8;
 struct texture_stage_op
 {
     unsigned                cop : 8;
@@ -937,7 +977,7 @@ struct texture_stage_op
     unsigned                aarg2 : 8;
     unsigned                aarg0 : 8;
 
     unsigned                aarg2 : 8;
     unsigned                aarg0 : 8;
 
-    struct color_fixup_desc color_correction;
+    struct color_fixup_desc color_fixup;
     unsigned                tex_type : 3;
     unsigned                dst : 1;
     unsigned                projected : 2;
     unsigned                tex_type : 3;
     unsigned                dst : 1;
     unsigned                projected : 2;
@@ -946,12 +986,7 @@ struct texture_stage_op
 
 struct ffp_frag_settings {
     struct texture_stage_op     op[MAX_TEXTURES];
 
 struct ffp_frag_settings {
     struct texture_stage_op     op[MAX_TEXTURES];
-    enum {
-        FOG_OFF,
-        FOG_LINEAR,
-        FOG_EXP,
-        FOG_EXP2
-    } fog;
+    enum fogmode fog;
     /* Use an int instead of a char to get dword alignment */
     unsigned int sRGB_write;
 };
     /* Use an int instead of a char to get dword alignment */
     unsigned int sRGB_write;
 };
@@ -1004,6 +1039,7 @@ struct IWineD3DDeviceImpl
 
     /* WineD3D Information  */
     IUnknown               *parent;
 
     /* WineD3D Information  */
     IUnknown               *parent;
+    IWineD3DDeviceParent   *device_parent;
     IWineD3D               *wineD3D;
     struct WineD3DAdapter  *adapter;
 
     IWineD3D               *wineD3D;
     struct WineD3DAdapter  *adapter;
 
@@ -1030,19 +1066,30 @@ struct IWineD3DDeviceImpl
 
     unsigned int max_ffp_textures, max_ffp_texture_stages;
 
 
     unsigned int max_ffp_textures, max_ffp_texture_stages;
 
-    /* To store */
-    BOOL                    view_ident;        /* true iff view matrix is identity                */
-    BOOL                    untransformed;
-    BOOL                    vertexBlendUsed;   /* To avoid needless setting of the blend matrices */
+    WORD view_ident : 1;                /* true iff view matrix is identity */
+    WORD untransformed : 1;
+    WORD vertexBlendUsed : 1;           /* To avoid needless setting of the blend matrices */
+    WORD isRecordingState : 1;
+    WORD isInDraw : 1;
+    WORD render_offscreen : 1;
+    WORD bCursorVisible : 1;
+    WORD haveHardwareCursor : 1;
+    WORD d3d_initialized : 1;
+    WORD inScene : 1;                   /* A flag to check for proper BeginScene / EndScene call pairs */
+    WORD softwareVertexProcessing : 1;  /* process vertex shaders using software or hardware */
+    WORD useDrawStridedSlow : 1;
+    WORD instancedDraw : 1;
+    WORD padding : 3;
+
+    BYTE fixed_function_usage_map;      /* MAX_TEXTURES, 8 */
+
 #define DDRAW_PITCH_ALIGNMENT 8
 #define D3D8_PITCH_ALIGNMENT 4
     unsigned char           surface_alignment; /* Line Alignment of surfaces                      */
 
     /* State block related */
 #define DDRAW_PITCH_ALIGNMENT 8
 #define D3D8_PITCH_ALIGNMENT 4
     unsigned char           surface_alignment; /* Line Alignment of surfaces                      */
 
     /* State block related */
-    BOOL                    isRecordingState;
     IWineD3DStateBlockImpl *stateBlock;
     IWineD3DStateBlockImpl *updateStateBlock;
     IWineD3DStateBlockImpl *stateBlock;
     IWineD3DStateBlockImpl *updateStateBlock;
-    BOOL                   isInDraw;
 
     /* Internal use fields  */
     WINED3DDEVICE_CREATION_PARAMETERS createParms;
 
     /* Internal use fields  */
     WINED3DDEVICE_CREATION_PARAMETERS createParms;
@@ -1072,7 +1119,6 @@ struct IWineD3DDeviceImpl
     UINT                    paletteConversionShader;
 
     /* For rendering to a texture using glCopyTexImage */
     UINT                    paletteConversionShader;
 
     /* For rendering to a texture using glCopyTexImage */
-    BOOL                    render_offscreen;
     GLenum                  *draw_buffers;
     GLuint                  depth_blt_texture;
     GLuint                  depth_blt_rb;
     GLenum                  *draw_buffers;
     GLuint                  depth_blt_texture;
     GLuint                  depth_blt_rb;
@@ -1080,14 +1126,12 @@ struct IWineD3DDeviceImpl
     UINT                    depth_blt_rb_h;
 
     /* Cursor management */
     UINT                    depth_blt_rb_h;
 
     /* Cursor management */
-    BOOL                    bCursorVisible;
     UINT                    xHotSpot;
     UINT                    yHotSpot;
     UINT                    xScreenSpace;
     UINT                    yScreenSpace;
     UINT                    cursorWidth, cursorHeight;
     GLuint                  cursorTexture;
     UINT                    xHotSpot;
     UINT                    yHotSpot;
     UINT                    xScreenSpace;
     UINT                    yScreenSpace;
     UINT                    cursorWidth, cursorHeight;
     GLuint                  cursorTexture;
-    BOOL                    haveHardwareCursor;
     HCURSOR                 hardwareCursor;
 
     /* The Wine logo surface */
     HCURSOR                 hardwareCursor;
 
     /* The Wine logo surface */
@@ -1096,18 +1140,8 @@ struct IWineD3DDeviceImpl
     /* Textures for when no other textures are mapped */
     UINT                          dummyTextureName[MAX_TEXTURES];
 
     /* Textures for when no other textures are mapped */
     UINT                          dummyTextureName[MAX_TEXTURES];
 
-    /* Debug stream management */
-    BOOL                     debug;
-
     /* Device state management */
     HRESULT                 state;
     /* Device state management */
     HRESULT                 state;
-    BOOL                    d3d_initialized;
-
-    /* A flag to check for proper BeginScene / EndScene call pairs */
-    BOOL inScene;
-
-    /* process vertex shaders using software or hardware */
-    BOOL softwareVertexProcessing;
 
     /* DirectDraw stuff */
     DWORD ddraw_width, ddraw_height;
 
     /* DirectDraw stuff */
     DWORD ddraw_width, ddraw_height;
@@ -1119,13 +1153,10 @@ struct IWineD3DDeviceImpl
     /* With register combiners we can skip junk texture stages */
     DWORD                     texUnitMap[MAX_COMBINED_SAMPLERS];
     DWORD                     rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
     /* With register combiners we can skip junk texture stages */
     DWORD                     texUnitMap[MAX_COMBINED_SAMPLERS];
     DWORD                     rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
-    BOOL                      fixed_function_usage_map[MAX_TEXTURES];
 
     /* Stream source management */
     WineDirect3DVertexStridedData strided_streams;
     const WineDirect3DVertexStridedData *up_strided;
 
     /* Stream source management */
     WineDirect3DVertexStridedData strided_streams;
     const WineDirect3DVertexStridedData *up_strided;
-    BOOL                      useDrawStridedSlow;
-    BOOL                      instancedDraw;
 
     /* Context management */
     WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
 
     /* Context management */
     WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
@@ -1142,7 +1173,7 @@ struct IWineD3DDeviceImpl
     struct WineD3DRectPatch *currentPatch;
 };
 
     struct WineD3DRectPatch *currentPatch;
 };
 
-extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl, IWineD3DDevice_DirtyConst_Vtbl;
+extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
 
 HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfaceImpl *target, DWORD Count,
                                         CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
 
 HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfaceImpl *target, DWORD Count,
                                         CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color,
@@ -1210,6 +1241,8 @@ HRESULT resource_get_parent(IWineD3DResource *iface, IUnknown **parent);
 DWORD resource_get_priority(IWineD3DResource *iface);
 HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid,
         void *data, DWORD *data_size);
 DWORD resource_get_priority(IWineD3DResource *iface);
 HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid,
         void *data, DWORD *data_size);
+HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
+        IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent);
 WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface);
 DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority);
 HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
 WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface);
 DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority);
 HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
@@ -1349,6 +1382,7 @@ WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture
 BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface);
 BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface);
+void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage);
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type);
 BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type);
 BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
@@ -1424,6 +1458,8 @@ typedef struct IWineD3DVolumeImpl
 
 extern const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl;
 
 
 extern const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl;
 
+void volume_add_dirty_box(IWineD3DVolume *iface, const WINED3DBOX *dirty_box);
+
 /*****************************************************************************
  * IWineD3DVolumeTexture implementation structure (extends IWineD3DBaseTextureImpl)
  */
 /*****************************************************************************
  * IWineD3DVolumeTexture implementation structure (extends IWineD3DBaseTextureImpl)
  */
@@ -1681,6 +1717,7 @@ typedef enum {
     CONVERT_Q8W8V8U8,
     CONVERT_V16U16,
     CONVERT_A4L4,
     CONVERT_Q8W8V8U8,
     CONVERT_V16U16,
     CONVERT_A4L4,
+    CONVERT_G16R16,
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
@@ -1690,11 +1727,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This);
 /*****************************************************************************
  * IWineD3DVertexDeclaration implementation structure
  */
 /*****************************************************************************
  * IWineD3DVertexDeclaration implementation structure
  */
-typedef struct attrib_declaration {
-    DWORD usage;
-    DWORD idx;
-} attrib_declaration;
-
 #define MAX_ATTRIBS 16
 
 typedef struct IWineD3DVertexDeclarationImpl {
 #define MAX_ATTRIBS 16
 
 typedef struct IWineD3DVertexDeclarationImpl {
@@ -1713,10 +1745,6 @@ typedef struct IWineD3DVertexDeclarationImpl {
     UINT                    num_streams;
     BOOL                    position_transformed;
     BOOL                    half_float_conv_needed;
     UINT                    num_streams;
     BOOL                    position_transformed;
     BOOL                    half_float_conv_needed;
-
-    /* Ordered array of declaration types that need swizzling in a vshader */
-    attrib_declaration      swizzled_attribs[MAX_ATTRIBS];
-    UINT                    num_swizzled_attribs;
 } IWineD3DVertexDeclarationImpl;
 
 extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;
 } IWineD3DVertexDeclarationImpl;
 
 extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;
@@ -1729,36 +1757,30 @@ extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;
 /*   Note: Very long winded but gl Lists are not flexible enough */
 /*   to resolve everything we need, so doing it manually for now */
 typedef struct SAVEDSTATES {
 /*   Note: Very long winded but gl Lists are not flexible enough */
 /*   to resolve everything we need, so doing it manually for now */
 typedef struct SAVEDSTATES {
-        BOOL                      indices;
-        BOOL                      material;
-        BOOL                      fvf;
-        BOOL                      streamSource[MAX_STREAMS];
-        BOOL                      streamFreq[MAX_STREAMS];
-        BOOL                      textures[MAX_COMBINED_SAMPLERS];
-        BOOL                      transform[HIGHEST_TRANSFORMSTATE + 1];
-        BOOL                      viewport;
-        BOOL                      renderState[WINEHIGHEST_RENDER_STATE + 1];
-        BOOL                      textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
-        BOOL                      samplerState[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
-        BOOL                      clipplane[MAX_CLIPPLANES];
-        BOOL                      vertexDecl;
-        BOOL                      pixelShader;
-        WORD                      pixelShaderConstantsB;
-        WORD                      pixelShaderConstantsI;
-        BOOL                     *pixelShaderConstantsF;
-        BOOL                      vertexShader;
-        WORD                      vertexShaderConstantsB;
-        WORD                      vertexShaderConstantsI;
-        BOOL                     *vertexShaderConstantsF;
-        BOOL                      scissorRect;
+    DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1];
+    WORD streamSource;                          /* MAX_STREAMS, 16 */
+    WORD streamFreq;                            /* MAX_STREAMS, 16 */
+    DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1];
+    DWORD textureState[MAX_TEXTURES];           /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */
+    WORD samplerState[MAX_COMBINED_SAMPLERS];   /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */
+    DWORD textures;                             /* MAX_COMBINED_SAMPLERS, 20 */
+    DWORD clipplane;                            /* WINED3DMAXUSERCLIPPLANES, 32 */
+    WORD pixelShaderConstantsB;                 /* MAX_CONST_B, 16 */
+    WORD pixelShaderConstantsI;                 /* MAX_CONST_I, 16 */
+    BOOL *pixelShaderConstantsF;
+    WORD vertexShaderConstantsB;                /* MAX_CONST_B, 16 */
+    WORD vertexShaderConstantsI;                /* MAX_CONST_I, 16 */
+    BOOL *vertexShaderConstantsF;
+    BYTE indices : 1;
+    BYTE material : 1;
+    BYTE viewport : 1;
+    BYTE vertexDecl : 1;
+    BYTE pixelShader : 1;
+    BYTE vertexShader : 1;
+    BYTE scissorRect : 1;
+    BYTE padding : 1;
 } SAVEDSTATES;
 
 } SAVEDSTATES;
 
-typedef struct {
-    struct  list entry;
-    DWORD   count;
-    DWORD   idx[13];
-} constants_entry;
-
 struct StageState {
     DWORD stage;
     DWORD state;
 struct StageState {
     DWORD stage;
     DWORD state;
@@ -1777,11 +1799,7 @@ struct IWineD3DStateBlockImpl
 
     /* Array indicating whether things have been set or changed */
     SAVEDSTATES               changed;
 
     /* Array indicating whether things have been set or changed */
     SAVEDSTATES               changed;
-    struct list               set_vconstantsF;
-    struct list               set_pconstantsF;
 
 
-    /* Drawing - Vertex Shader or FVF related */
-    DWORD                     fvf;
     /* Vertex Shader Declaration */
     IWineD3DVertexDeclaration *vertexDecl;
 
     /* Vertex Shader Declaration */
     IWineD3DVertexDeclaration *vertexDecl;
 
@@ -1837,7 +1855,6 @@ struct IWineD3DStateBlockImpl
 
     /* Texture */
     IWineD3DBaseTexture      *textures[MAX_COMBINED_SAMPLERS];
 
     /* Texture */
     IWineD3DBaseTexture      *textures[MAX_COMBINED_SAMPLERS];
-    int                       textureDimensions[MAX_COMBINED_SAMPLERS];
 
     /* Texture State Stage */
     DWORD                     textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
 
     /* Texture State Stage */
     DWORD                     textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
@@ -1865,7 +1882,7 @@ struct IWineD3DStateBlockImpl
     unsigned int              num_contained_ps_consts_b;
     DWORD                     *contained_ps_consts_f;
     unsigned int              num_contained_ps_consts_f;
     unsigned int              num_contained_ps_consts_b;
     DWORD                     *contained_ps_consts_f;
     unsigned int              num_contained_ps_consts_f;
-    struct StageState         contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE)];
+    struct StageState         contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)];
     unsigned int              num_contained_tss_states;
     struct StageState         contained_sampler_states[MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
     unsigned int              num_contained_sampler_states;
     unsigned int              num_contained_tss_states;
     struct StageState         contained_sampler_states[MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
     unsigned int              num_contained_sampler_states;
@@ -2019,7 +2036,12 @@ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock
 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 
 
+void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect);
 void surface_force_reload(IWineD3DSurface *iface);
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
 void surface_load_ds_location(IWineD3DSurface *iface, DWORD location);
 void surface_force_reload(IWineD3DSurface *iface);
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
 void surface_load_ds_location(IWineD3DSurface *iface, DWORD location);
@@ -2034,6 +2056,7 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize
 /* Math utils */
 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
 unsigned int count_bits(unsigned int mask);
 /* Math utils */
 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
 unsigned int count_bits(unsigned int mask);
+UINT wined3d_log2i(UINT32 x);
 
 /*****************************************************************************
  * To enable calling of inherited functions, requires prototypes 
 
 /*****************************************************************************
  * To enable calling of inherited functions, requires prototypes 
@@ -2069,7 +2092,7 @@ typedef struct local_constant {
 } local_constant;
 
 typedef struct shader_reg_maps {
 } local_constant;
 
 typedef struct shader_reg_maps {
-
+    DWORD shader_version;
     char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
     char temporary[MAX_REG_TEMP];           /* pixel, vertex */
     char address[MAX_REG_ADDR];             /* vertex */
     char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
     char temporary[MAX_REG_TEMP];           /* pixel, vertex */
     char address[MAX_REG_ADDR];             /* vertex */
@@ -2110,7 +2133,6 @@ typedef enum COMPARISON_TYPE {
 typedef struct SHADER_OPCODE {
     unsigned int  opcode;
     const char*   name;
 typedef struct SHADER_OPCODE {
     unsigned int  opcode;
     const char*   name;
-    const char*   glname;
     char          dst_token;
     CONST UINT    num_params;
     enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
     char          dst_token;
     CONST UINT    num_params;
     enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
@@ -2172,10 +2194,6 @@ extern BOOL vshader_get_input(
     BYTE usage_req, BYTE usage_idx_req,
     unsigned int* regnum);
 
     BYTE usage_req, BYTE usage_idx_req,
     unsigned int* regnum);
 
-extern BOOL vshader_input_is_color(
-    IWineD3DVertexShader* iface,
-    unsigned int regnum);
-
 extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
 
 /* GLSL helper functions */
 extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
 
 /* GLSL helper functions */
@@ -2187,7 +2205,6 @@ extern void shader_glsl_add_instruction_modifiers(const SHADER_OPCODE_ARG *arg);
 typedef struct IWineD3DBaseShaderClass
 {
     LONG                            ref;
 typedef struct IWineD3DBaseShaderClass
 {
     LONG                            ref;
-    DWORD                           hex_version;
     SHADER_LIMITS                   limits;
     SHADER_PARSE_STATE              parse_state;
     CONST SHADER_OPCODE             *shader_ins;
     SHADER_LIMITS                   limits;
     SHADER_PARSE_STATE              parse_state;
     CONST SHADER_OPCODE             *shader_ins;
@@ -2196,6 +2213,7 @@ typedef struct IWineD3DBaseShaderClass
     BOOL                            is_compiled;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
     BOOL                            is_compiled;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
+    BOOL                            uses_bool_consts, uses_int_consts;
 
     /* Type of shader backend */
     int shader_mode;
 
     /* Type of shader backend */
     int shader_mode;
@@ -2228,25 +2246,18 @@ typedef struct IWineD3DBaseShaderImpl {
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
-HRESULT  WINAPI IWineD3DBaseShaderImpl_QueryInterface(IWineD3DBaseShader *iface, REFIID riid, LPVOID *ppobj);
-ULONG  WINAPI IWineD3DBaseShaderImpl_AddRef(IWineD3DBaseShader *iface);
-ULONG  WINAPI IWineD3DBaseShaderImpl_Release(IWineD3DBaseShader *iface);
-
-extern HRESULT shader_get_registers_used(
-    IWineD3DBaseShader *iface,
-    shader_reg_maps* reg_maps,
-    semantic* semantics_in,
-    semantic* semantics_out,
-    CONST DWORD* pToken,
-    IWineD3DStateBlockImpl *stateBlock);
+void shader_buffer_init(struct SHADER_BUFFER *buffer);
+void shader_buffer_free(struct SHADER_BUFFER *buffer);
+void shader_cleanup(IWineD3DBaseShader *iface);
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
+        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code);
+void shader_init(struct IWineD3DBaseShaderClass *shader,
+        IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
+void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
 
 extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
 
 
 extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
 
-extern void shader_trace_init(
-    IWineD3DBaseShader *iface,
-    const DWORD* pFunction);
-
 static inline int shader_get_regtype(const DWORD param) {
     return (((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) |
             ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2));
 static inline int shader_get_regtype(const DWORD param) {
     return (((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) |
             ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2));
@@ -2336,9 +2347,7 @@ typedef struct IWineD3DVertexShaderImpl {
     semantic semantics_in [MAX_ATTRIBS];
     semantic semantics_out [MAX_REG_OUTPUT];
 
     semantic semantics_in [MAX_ATTRIBS];
     semantic semantics_out [MAX_REG_OUTPUT];
 
-    /* Ordered array of attributes that are swizzled */
-    attrib_declaration          swizzled_attribs [MAX_ATTRIBS];
-    UINT                        num_swizzled_attribs;
+    WORD swizzle_map;   /* MAX_ATTRIBS, 16 */
 
     UINT                       min_rel_offset, max_rel_offset;
     UINT                       rel_offset;
 
     UINT                       min_rel_offset, max_rel_offset;
     UINT                       rel_offset;
@@ -2352,29 +2361,6 @@ HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface);
 /*****************************************************************************
  * IDirect3DPixelShader implementation structure
  */
 /*****************************************************************************
  * IDirect3DPixelShader implementation structure
  */
-
-enum vertexprocessing_mode {
-    fixedfunction,
-    vertexshader,
-    pretransformed
-};
-
-struct stb_const_desc {
-    char                    texunit;
-    UINT                    const_num;
-};
-
-/* Stateblock dependent parameters which have to be hardcoded
- * into the shader code
- */
-struct ps_compile_args {
-    struct color_fixup_desc     color_fixup[MAX_FRAGMENT_SAMPLERS];
-    BOOL                        srgb_correction;
-    enum vertexprocessing_mode  vp_mode;
-    /* Projected textures(ps 1.0-1.3) */
-    /* Texture types(2D, Cube, 3D) in ps 1.x */
-};
-
 struct ps_compiled_shader {
     struct ps_compile_args      args;
     GLuint                      prgId;
 struct ps_compiled_shader {
     struct ps_compile_args      args;
     GLuint                      prgId;
@@ -2473,17 +2459,17 @@ typedef struct {
 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt,
         const WineD3D_GL_Info *gl_info, const struct GlPixelFormatDesc **glDesc);
 
 const StaticPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt,
         const WineD3D_GL_Info *gl_info, const struct GlPixelFormatDesc **glDesc);
 
-static inline BOOL use_vs(IWineD3DDeviceImpl *device) {
-    return (device->vs_selected_mode != SHADER_NONE
-            && device->stateBlock->vertexShader
-            && ((IWineD3DVertexShaderImpl *)device->stateBlock->vertexShader)->baseShader.function
-            && !device->strided_streams.u.s.position_transformed);
+static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock)
+{
+    return (stateblock->vertexShader
+            && !stateblock->wineD3DDevice->strided_streams.position_transformed
+            && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE);
 }
 
 }
 
-static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
-    return (device->ps_selected_mode != SHADER_NONE
-            && device->stateBlock->pixelShader
-            && ((IWineD3DPixelShaderImpl *)device->stateBlock->pixelShader)->baseShader.function);
+static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock)
+{
+    return (stateblock->pixelShader
+            && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE);
 }
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
 }
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
index abb0d3b..2307f5d 100644 (file)
@@ -74,6 +74,7 @@ cpp_quote("#define WINED3DERR_INVALIDCALL                      MAKE_WINED3DHRESU
 cpp_quote("#define WINED3DERR_DRIVERINVALIDCALL                MAKE_WINED3DHRESULT(2157)")
 cpp_quote("#define WINED3DERR_WASSTILLDRAWING                  MAKE_WINED3DHRESULT(540)")
 cpp_quote("#define WINEDDERR_NOTAOVERLAYSURFACE                MAKE_WINED3DHRESULT(580)")
 cpp_quote("#define WINED3DERR_DRIVERINVALIDCALL                MAKE_WINED3DHRESULT(2157)")
 cpp_quote("#define WINED3DERR_WASSTILLDRAWING                  MAKE_WINED3DHRESULT(540)")
 cpp_quote("#define WINEDDERR_NOTAOVERLAYSURFACE                MAKE_WINED3DHRESULT(580)")
+cpp_quote("#define WINEDDERR_NOTLOCKED                         MAKE_WINED3DHRESULT(584)")
 cpp_quote("#define WINEDDERR_NODC                              MAKE_WINED3DHRESULT(586)")
 cpp_quote("#define WINEDDERR_DCALREADYCREATED                  MAKE_WINED3DHRESULT(620)")
 cpp_quote("#define WINEDDERR_NOTFLIPPABLE                      MAKE_WINED3DHRESULT(582)")
 cpp_quote("#define WINEDDERR_NODC                              MAKE_WINED3DHRESULT(586)")
 cpp_quote("#define WINEDDERR_DCALREADYCREATED                  MAKE_WINED3DHRESULT(620)")
 cpp_quote("#define WINEDDERR_NOTFLIPPABLE                      MAKE_WINED3DHRESULT(582)")
@@ -554,35 +555,24 @@ typedef enum _WINED3DMULTISAMPLE_TYPE
 
 typedef enum _WINED3DTEXTURESTAGESTATETYPE
 {
 
 typedef enum _WINED3DTEXTURESTAGESTATETYPE
 {
-    WINED3DTSS_COLOROP                      = 1,
-    WINED3DTSS_COLORARG1                    = 2,
-    WINED3DTSS_COLORARG2                    = 3,
-    WINED3DTSS_ALPHAOP                      = 4,
-    WINED3DTSS_ALPHAARG1                    = 5,
-    WINED3DTSS_ALPHAARG2                    = 6,
-    WINED3DTSS_BUMPENVMAT00                 = 7,
-    WINED3DTSS_BUMPENVMAT01                 = 8,
-    WINED3DTSS_BUMPENVMAT10                 = 9,
-    WINED3DTSS_BUMPENVMAT11                 = 10,
-    WINED3DTSS_TEXCOORDINDEX                = 11,
-    WINED3DTSS_ADDRESS                      = 12,
-    WINED3DTSS_ADDRESSU                     = 13,
-    WINED3DTSS_ADDRESSV                     = 14,
-    WINED3DTSS_BORDERCOLOR                  = 15,
-    WINED3DTSS_MAGFILTER                    = 16,
-    WINED3DTSS_MINFILTER                    = 17,
-    WINED3DTSS_MIPFILTER                    = 18,
-    WINED3DTSS_MIPMAPLODBIAS                = 19,
-    WINED3DTSS_MAXMIPLEVEL                  = 20,
-    WINED3DTSS_MAXANISOTROPY                = 21,
-    WINED3DTSS_BUMPENVLSCALE                = 22,
-    WINED3DTSS_BUMPENVLOFFSET               = 23,
-    WINED3DTSS_TEXTURETRANSFORMFLAGS        = 24,
-    WINED3DTSS_ADDRESSW                     = 25,
-    WINED3DTSS_COLORARG0                    = 26,
-    WINED3DTSS_ALPHAARG0                    = 27,
-    WINED3DTSS_RESULTARG                    = 28,
-    WINED3DTSS_CONSTANT                     = 32,
+    WINED3DTSS_COLOROP                      = 0,
+    WINED3DTSS_COLORARG1                    = 1,
+    WINED3DTSS_COLORARG2                    = 2,
+    WINED3DTSS_ALPHAOP                      = 3,
+    WINED3DTSS_ALPHAARG1                    = 4,
+    WINED3DTSS_ALPHAARG2                    = 5,
+    WINED3DTSS_BUMPENVMAT00                 = 6,
+    WINED3DTSS_BUMPENVMAT01                 = 7,
+    WINED3DTSS_BUMPENVMAT10                 = 8,
+    WINED3DTSS_BUMPENVMAT11                 = 9,
+    WINED3DTSS_TEXCOORDINDEX                = 10,
+    WINED3DTSS_BUMPENVLSCALE                = 11,
+    WINED3DTSS_BUMPENVLOFFSET               = 12,
+    WINED3DTSS_TEXTURETRANSFORMFLAGS        = 13,
+    WINED3DTSS_COLORARG0                    = 14,
+    WINED3DTSS_ALPHAARG0                    = 15,
+    WINED3DTSS_RESULTARG                    = 16,
+    WINED3DTSS_CONSTANT                     = 17,
     WINED3DTSS_FORCE_DWORD                  = 0x7fffffff
 } WINED3DTEXTURESTAGESTATETYPE;
 const UINT WINED3D_HIGHEST_TEXTURE_STATE    = WINED3DTSS_CONSTANT;
     WINED3DTSS_FORCE_DWORD                  = 0x7fffffff
 } WINED3DTEXTURESTAGESTATETYPE;
 const UINT WINED3D_HIGHEST_TEXTURE_STATE    = WINED3DTSS_CONSTANT;
@@ -889,7 +879,7 @@ const UINT WINED3DCLIPPLANE5                                    = (1 << 5);
 
 /* FVF (Flexible Vertex Format) codes */
 const UINT WINED3DFVF_RESERVED0                                 = 0x0001;
 
 /* FVF (Flexible Vertex Format) codes */
 const UINT WINED3DFVF_RESERVED0                                 = 0x0001;
-const UINT WINED3DFVF_POSITION_MASK                             = 0x000e;
+const UINT WINED3DFVF_POSITION_MASK                             = 0x400e;
 const UINT WINED3DFVF_XYZ                                       = 0x0002;
 const UINT WINED3DFVF_XYZRHW                                    = 0x0004;
 const UINT WINED3DFVF_XYZB1                                     = 0x0006;
 const UINT WINED3DFVF_XYZ                                       = 0x0002;
 const UINT WINED3DFVF_XYZRHW                                    = 0x0004;
 const UINT WINED3DFVF_XYZB1                                     = 0x0006;
@@ -1890,10 +1880,13 @@ typedef struct WineDirect3DVertexStridedData
             WineDirect3DStridedData sample;
 
             /* Add fields here */
             WineDirect3DStridedData sample;
 
             /* Add fields here */
-            BOOL position_transformed;
         } s;
         WineDirect3DStridedData input[16];  /* Indexed by constants in D3DVSDE_REGISTER */
     } u;
         } s;
         WineDirect3DStridedData input[16];  /* Indexed by constants in D3DVSDE_REGISTER */
     } u;
+
+    BOOL position_transformed;
+    WORD swizzle_map;       /* MAX_ATTRIBS, 16 */
+    WORD use_map;           /* MAX_ATTRIBS, 16 */
 } WineDirect3DVertexStridedData;
 
 typedef struct _WINED3DVSHADERCAPS2_0
 } WineDirect3DVertexStridedData;
 
 typedef struct _WINED3DVSHADERCAPS2_0
@@ -2116,22 +2109,65 @@ interface IWineD3DVolume;
 interface IWineD3DSwapChain;
 interface IWineD3DDevice;
 
 interface IWineD3DSwapChain;
 interface IWineD3DDevice;
 
-typedef HRESULT (*D3DCB_CREATESURFACEFN)(IUnknown *pDevice, IUnknown *pSuperior, UINT Width,
-        UINT Height, WINED3DFORMAT Format, DWORD Usage, WINED3DPOOL Pool, UINT Level, WINED3DCUBEMAP_FACES Face,
-        IWineD3DSurface **ppSurface, HANDLE *pSharedHandle);
-typedef HRESULT (*D3DCB_CREATERENDERTARGETFN)(IUnknown *pDevice, IUnknown *pSuperior, UINT Width,
-        UINT Height, WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
-        BOOL Lockable, IWineD3DSurface **ppSurface, HANDLE *pSharedHandle);
-typedef HRESULT (*D3DCB_CREATEDEPTHSTENCILSURFACEFN)(IUnknown *pDevice, IUnknown *pSuperior, UINT Width,
-        UINT Height, WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
-        BOOL Discard, IWineD3DSurface **ppSurface, HANDLE *pSharedHandle);
+[
+    object,
+    local,
+    uuid(aeb62dfc-bdcb-4f02-9519-1eeea00c15cd)
+]
+interface IWineD3DDeviceParent : IUnknown
+{
+    HRESULT CreateSurface(
+        [in] IUnknown *superior,
+        [in] UINT width,
+        [in] UINT height,
+        [in] WINED3DFORMAT format,
+        [in] DWORD usage,
+        [in] WINED3DPOOL pool,
+        [in] UINT level,
+        [in] WINED3DCUBEMAP_FACES face,
+        [out] IWineD3DSurface **surface
+    );
+
+    HRESULT CreateRenderTarget(
+        [in] IUnknown *superior,
+        [in] UINT width,
+        [in] UINT height,
+        [in] WINED3DFORMAT format,
+        [in] WINED3DMULTISAMPLE_TYPE multisample_type,
+        [in] DWORD multisample_quality,
+        [in] BOOL lockable,
+        [out] IWineD3DSurface **surface
+    );
+
+    HRESULT CreateDepthStencilSurface(
+        [in] IUnknown *superior,
+        [in] UINT width,
+        [in] UINT height,
+        [in] WINED3DFORMAT format,
+        [in] WINED3DMULTISAMPLE_TYPE multisample_type,
+        [in] DWORD multisample_quality,
+        [in] BOOL discard,
+        [out] IWineD3DSurface **surface
+    );
+
+    HRESULT CreateVolume(
+        [in] IUnknown *superior,
+        [in] UINT width,
+        [in] UINT height,
+        [in] UINT depth,
+        [in] WINED3DFORMAT format,
+        [in] WINED3DPOOL pool,
+        [in] DWORD usage,
+        [out] IWineD3DVolume **volume
+    );
+
+    HRESULT CreateSwapChain(
+        [in, out] WINED3DPRESENT_PARAMETERS *present_parameters,
+        [out] IWineD3DSwapChain **swapchain
+    );
+}
 typedef ULONG (*D3DCB_DESTROYSURFACEFN)(IWineD3DSurface *pSurface);
 typedef ULONG (*D3DCB_DESTROYSURFACEFN)(IWineD3DSurface *pSurface);
-typedef HRESULT (*D3DCB_CREATEVOLUMEFN)(IUnknown *pDevice, IUnknown *pSuperior, UINT Width,
-        UINT Height, UINT Depth, WINED3DFORMAT Format, WINED3DPOOL Pool, DWORD Usage,
-        IWineD3DVolume **ppVolume, HANDLE *pSharedHandle);
 typedef ULONG (*D3DCB_DESTROYVOLUMEFN)(IWineD3DVolume *pVolume);
 typedef ULONG (*D3DCB_DESTROYVOLUMEFN)(IWineD3DVolume *pVolume);
-typedef HRESULT (*D3DCB_CREATESWAPCHAIN)(IUnknown *pDevice, WINED3DPRESENT_PARAMETERS *pPresentationParameters,
-        IWineD3DSwapChain **pSwapChain);
 typedef ULONG (*D3DCB_DESTROYSWAPCHAINFN)(IWineD3DSwapChain *pSwapChain);
 typedef HRESULT (*D3DCB_ENUMRESOURCES)(IWineD3DResource *resource, void *pData);
 
 typedef ULONG (*D3DCB_DESTROYSWAPCHAINFN)(IWineD3DSwapChain *pSwapChain);
 typedef HRESULT (*D3DCB_ENUMRESOURCES)(IWineD3DResource *resource, void *pData);
 
@@ -2228,8 +2264,9 @@ interface IWineD3D : IWineD3DBase
         [in] WINED3DDEVTYPE device_type,
         [in] HWND focus_window,
         [in] DWORD behaviour_flags,
         [in] WINED3DDEVTYPE device_type,
         [in] HWND focus_window,
         [in] DWORD behaviour_flags,
-        [out] IWineD3DDevice **device,
-        [in] IUnknown *parent
+        [in] IUnknown *parent,
+        [in] IWineD3DDeviceParent *device_parent,
+        [out] IWineD3DDevice **device
     );
 }
 
     );
 }
 
@@ -2460,9 +2497,6 @@ interface IWineD3DSurface : IWineD3DResource
     HRESULT GetClipper(
         [out] IWineD3DClipper **clipper
     );
     HRESULT GetClipper(
         [out] IWineD3DClipper **clipper
     );
-    HRESULT AddDirtyRect(
-        [in] const RECT *dirty_rect
-    );
     HRESULT LoadTexture(
         [in] BOOL srgb_mode
     );
     HRESULT LoadTexture(
         [in] BOOL srgb_mode
     );
@@ -2519,11 +2553,6 @@ interface IWineD3DVolume : IWineD3DResource
     );
     HRESULT UnlockBox(
     );
     );
     HRESULT UnlockBox(
     );
-    HRESULT AddDirtyBox(
-        [in] const WINED3DBOX *dirty_box
-    );
-    HRESULT CleanDirtyBox(
-    );
     HRESULT LoadTexture(
         [in] int gl_level,
         [in] BOOL srgb_mode
     HRESULT LoadTexture(
         [in] int gl_level,
         [in] BOOL srgb_mode
@@ -2825,8 +2854,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
 ]
 interface IWineD3DPixelShader : IWineD3DBaseShader
 {
 ]
 interface IWineD3DPixelShader : IWineD3DBaseShader
 {
-    HRESULT UpdateSamplers(
-    );
     HRESULT GetDevice(
         [out] IWineD3DDevice **device
     );
     HRESULT GetDevice(
         [out] IWineD3DDevice **device
     );
@@ -2892,8 +2919,7 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DPOOL pool,
         [out] IWineD3DTexture **texture,
         [in] HANDLE *shared_handle,
         [in] WINED3DPOOL pool,
         [out] IWineD3DTexture **texture,
         [in] HANDLE *shared_handle,
-        [in] IUnknown *parent,
-        [in] D3DCB_CREATESURFACEFN create_surface_callback
+        [in] IUnknown *parent
     );
     HRESULT CreateVolumeTexture(
         [in] UINT width,
     );
     HRESULT CreateVolumeTexture(
         [in] UINT width,
@@ -2905,8 +2931,7 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolumeTexture **texture,
         [in] HANDLE *shared_handle,
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolumeTexture **texture,
         [in] HANDLE *shared_handle,
-        [in] IUnknown *parent,
-        [in] D3DCB_CREATEVOLUMEFN create_volume_callback
+        [in] IUnknown *parent
     );
     HRESULT CreateVolume(
         [in] UINT width,
     );
     HRESULT CreateVolume(
         [in] UINT width,
@@ -2927,8 +2952,7 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DPOOL pool,
         [out] IWineD3DCubeTexture **texture,
         [in] HANDLE *shared_handle,
         [in] WINED3DPOOL pool,
         [out] IWineD3DCubeTexture **texture,
         [in] HANDLE *shared_handle,
-        [in] IUnknown *parent,
-        [in] D3DCB_CREATESURFACEFN create_surface_callback
+        [in] IUnknown *parent
     );
     HRESULT CreateQuery(
         [in] WINED3DQUERYTYPE type,
     );
     HRESULT CreateQuery(
         [in] WINED3DQUERYTYPE type,
@@ -2939,8 +2963,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DPRESENT_PARAMETERS *present_parameters,
         [out] IWineD3DSwapChain **swapchain,
         [in] IUnknown *parent,
         [in] WINED3DPRESENT_PARAMETERS *present_parameters,
         [out] IWineD3DSwapChain **swapchain,
         [in] IUnknown *parent,
-        [in] D3DCB_CREATERENDERTARGETFN create_render_target_callback,
-        [in] D3DCB_CREATEDEPTHSTENCILSURFACEFN create_depth_stencil_callback,
         [in] WINED3DSURFTYPE surface_type
     );
     HRESULT CreateVertexDeclaration(
         [in] WINED3DSURFTYPE surface_type
     );
     HRESULT CreateVertexDeclaration(
@@ -2972,12 +2994,10 @@ interface IWineD3DDevice : IWineD3DBase
         [in] IUnknown *parent
     );
     HRESULT Init3D(
         [in] IUnknown *parent
     );
     HRESULT Init3D(
-        [in] WINED3DPRESENT_PARAMETERS *present_parameters,
-        [in] D3DCB_CREATESWAPCHAIN create_swapchain_callback
+        [in] WINED3DPRESENT_PARAMETERS *present_parameters
     );
     HRESULT InitGDI(
     );
     HRESULT InitGDI(
-        [in] WINED3DPRESENT_PARAMETERS *present_parameters,
-        [in] D3DCB_CREATESWAPCHAIN create_swapchain_callback
+        [in] WINED3DPRESENT_PARAMETERS *present_parameters
     );
     HRESULT Uninit3D(
         [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback,
     );
     HRESULT Uninit3D(
         [in] D3DCB_DESTROYSURFACEFN destroy_surface_callback,
@@ -3072,12 +3092,6 @@ interface IWineD3DDevice : IWineD3DBase
     HRESULT GetDepthStencilSurface(
         [out] IWineD3DSurface **depth_stencil
     );
     HRESULT GetDepthStencilSurface(
         [out] IWineD3DSurface **depth_stencil
     );
-    HRESULT SetFVF(
-        [in] DWORD fvf
-    );
-    HRESULT GetFVF(
-        [out] DWORD *fvf
-    );
     void SetGammaRamp(
         [in] UINT swapchain_idx,
         [in] DWORD flags,
     void SetGammaRamp(
         [in] UINT swapchain_idx,
         [in] DWORD flags,