- update wined3d/d3d8/d3d9 to Wine 1.1.15
authorKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 15 Feb 2009 14:01:23 +0000 (14:01 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 15 Feb 2009 14:01:23 +0000 (14:01 +0000)
svn path=/trunk/; revision=39607

20 files changed:
reactos/dll/directx/wine/d3d8/device.c
reactos/dll/directx/wine/d3d9/device.c
reactos/dll/directx/wine/d3d9/directx.c
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/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/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/surface.c
reactos/dll/directx/wine/wined3d/surface_base.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_private.h

index 5ef6311..9e3fb69 100644 (file)
@@ -2265,19 +2265,19 @@ static inline struct IDirect3DDevice8Impl *device_from_device_parent(IWineD3DDev
             - FIELD_OFFSET(struct IDirect3DDevice8Impl, device_parent_vtbl));
 }
 
             - FIELD_OFFSET(struct IDirect3DDevice8Impl, device_parent_vtbl));
 }
 
-HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
+static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_QueryInterface((IDirect3DDevice8 *)This, riid, object);
 }
 
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_QueryInterface((IDirect3DDevice8 *)This, riid, object);
 }
 
-ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
+static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_AddRef((IDirect3DDevice8 *)This);
 }
 
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_AddRef((IDirect3DDevice8 *)This);
 }
 
-ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
+static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_Release((IDirect3DDevice8 *)This);
 {
     struct IDirect3DDevice8Impl *This = device_from_device_parent(iface);
     return IDirect3DDevice8Impl_Release((IDirect3DDevice8 *)This);
index 768bf9d..b68caab 100644 (file)
@@ -265,7 +265,7 @@ static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac
 }
 
 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
 }
 
 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
-    BOOL *resources_ok = (BOOL *) data;
+    BOOL *resources_ok = data;
     WINED3DRESOURCETYPE type;
     HRESULT ret = S_OK;
     WINED3DSURFACE_DESC surface_desc;
     WINED3DRESOURCETYPE type;
     HRESULT ret = S_OK;
     WINED3DSURFACE_DESC surface_desc;
@@ -617,7 +617,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9EX ifa
 
     TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
     EnterCriticalSection(&d3d9_cs);
 
     TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DSurface_Blt(dst->wineD3DSurface, (RECT *) pDestRect, src->wineD3DSurface, (RECT *) pSourceRect, 0, NULL, Filter);
+    hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1338,7 +1338,7 @@ static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This,
 
 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
 
 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    HRESULT hr;
+    HRESULT hr = S_OK;
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
index 36db33b..bd9ba59 100644 (file)
@@ -37,7 +37,7 @@ static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9EX iface, REFIID
         return S_OK;
     } else if(IsEqualGUID(riid, &IID_IDirect3D9Ex)) {
         if(This->extended) {
         return S_OK;
     } else if(IsEqualGUID(riid, &IID_IDirect3D9Ex)) {
         if(This->extended) {
-            *ppobj = (IDirect3D9Ex *) This;
+            *ppobj = This;
             TRACE("Returning IDirect3D9Ex interface at %p\n", *ppobj);
             IDirect3D9Ex_AddRef((IDirect3D9Ex *)*ppobj);
         } else {
             TRACE("Returning IDirect3D9Ex interface at %p\n", *ppobj);
             IDirect3D9Ex_AddRef((IDirect3D9Ex *)*ppobj);
         } else {
index 7ff3cd4..6bc152a 100644 (file)
@@ -510,7 +510,7 @@ static void vshader_program_add_param(const SHADER_OPCODE_ARG *arg, const DWORD
     break;
   case WINED3DSPR_INPUT:
 
     break;
   case WINED3DSPR_INPUT:
 
-    if (This->swizzle_map & (1 << reg)) is_color = TRUE;
+    if (This->cur_args->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);
@@ -1741,18 +1741,19 @@ static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en
 
 static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
+    struct shader_arb_priv *priv = This->shader_priv;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (useVS) {
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (useVS) {
-        TRACE("Using vertex shader\n");
-        IWineD3DVertexShaderImpl_CompileShader(This->stateBlock->vertexShader);
+        struct vs_compile_args compile_args;
 
 
-        priv->current_vprogram_id = ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->prgId;
+        TRACE("Using vertex shader\n");
+        find_vs_compile_args((IWineD3DVertexShaderImpl *) This->stateBlock->vertexShader, This->stateBlock, &compile_args);
+        priv->current_vprogram_id = find_gl_vshader((IWineD3DVertexShaderImpl *) This->stateBlock->vertexShader, &compile_args);
 
         /* Bind the vertex program */
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
 
         /* Bind the vertex program */
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
-        checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);");
+        checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);");
 
         /* Enable OpenGL vertex programs */
         glEnable(GL_VERTEX_PROGRAM_ARB);
 
         /* Enable OpenGL vertex programs */
         glEnable(GL_VERTEX_PROGRAM_ARB);
@@ -1773,7 +1774,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
 
         /* Bind the fragment program */
         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
 
         /* Bind the fragment program */
         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
-        checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);");
+        checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);");
 
         if(!priv->use_arbfp_fixed_func) {
             /* Enable OpenGL fragment programs */
 
         if(!priv->use_arbfp_fixed_func) {
             /* Enable OpenGL fragment programs */
@@ -1794,7 +1795,7 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
 
 static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
+    struct shader_arb_priv *priv = This->shader_priv;
     GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
@@ -1809,7 +1810,7 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te
 
 static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
+    struct shader_arb_priv *priv = This->shader_priv;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (priv->current_vprogram_id) {
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (priv->current_vprogram_id) {
@@ -1857,16 +1858,22 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
         HeapFree(GetProcessHeap(), 0, This->gl_shaders);
         This->gl_shaders = NULL;
         This->num_gl_shaders = 0;
         HeapFree(GetProcessHeap(), 0, This->gl_shaders);
         This->gl_shaders = NULL;
         This->num_gl_shaders = 0;
+        This->shader_array_size = 0;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
+        UINT i;
 
         ENTER_GL();
 
         ENTER_GL();
-        GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId));
-        checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->prgId))");
-        ((IWineD3DVertexShaderImpl *) This)->prgId = 0;
+        for(i = 0; i < This->num_gl_shaders; i++) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
+            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
+        }
         LEAVE_GL();
         LEAVE_GL();
+        HeapFree(GetProcessHeap(), 0, This->gl_shaders);
+        This->gl_shaders = NULL;
+        This->num_gl_shaders = 0;
+        This->shader_array_size = 0;
     }
     }
-    baseShader->baseShader.is_compiled = FALSE;
 }
 
 static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
 }
 
 static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
@@ -1878,7 +1885,7 @@ static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
 static void shader_arb_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 static void shader_arb_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-    struct shader_arb_priv *priv = (struct shader_arb_priv *) This->shader_priv;
+    struct shader_arb_priv *priv = This->shader_priv;
     int i;
 
     if(priv->depth_blt_vprogram_id) {
     int i;
 
     if(priv->depth_blt_vprogram_id) {
@@ -2007,13 +2014,14 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
     return retval;
 }
 
     return retval;
 }
 
-static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     const local_constant *lconst;
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     const local_constant *lconst;
+    GLuint ret;
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBvp1.0\n");
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBvp1.0\n");
@@ -2060,9 +2068,16 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
     /* Base Shader Body */
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
 
-    /* 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)
+    /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
+     * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
+     * the fog frag coord is thrown away. If the fog frag coord is used, but not written by
+     * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
+     */
+    if(args->fog_src == VS_FOG_Z) {
         shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
         shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
+    } else if (!reg_maps->fog) {
+        shader_addline(buffer, "MOV result.fogcoord, 0.0;\n");
+    }
 
     /* Write the final position.
      *
 
     /* Write the final position.
      *
@@ -2085,12 +2100,12 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
     shader_addline(buffer, "END\n");
 
     /* TODO: change to resource.glObjectHandle or something like that */
-    GL_EXTCALL(glGenProgramsARB(1, &This->prgId));
+    GL_EXTCALL(glGenProgramsARB(1, &ret));
 
 
-    TRACE("Creating a hw vertex shader, prg=%d\n", This->prgId);
-    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->prgId));
+    TRACE("Creating a hw vertex shader, prg=%d\n", ret);
+    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ret));
 
 
-    TRACE("Created hw vertex shader, prg=%d\n", This->prgId);
+    TRACE("Created hw vertex shader, prg=%d\n", ret);
     /* Create the program and check for errors */
     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                buffer->bsize, buffer->buffer));
     /* Create the program and check for errors */
     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                buffer->bsize, buffer->buffer));
@@ -2100,16 +2115,17 @@ static void shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFF
         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
         FIXME("HW VertexShader Error at position %d: %s\n",
               errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
         FIXME("HW VertexShader Error at position %d: %s\n",
               errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
-        This->prgId = -1;
-    }
-
-    /* Load immediate constants */
-    if(!This->baseShader.load_local_constsF) {
-        LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-            const float *value = (const float *)lconst->value;
-            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value));
+        ret = -1;
+    } else {
+        /* Load immediate constants */
+        if(!This->baseShader.load_local_constsF) {
+            LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+                const float *value = (const float *)lconst->value;
+                GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value));
+            }
         }
     }
         }
     }
+    return ret;
 }
 
 static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
 }
 
 static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
@@ -2294,7 +2310,7 @@ static HRESULT arbfp_alloc(IWineD3DDevice *iface) {
         This->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv));
         if(!This->fragment_priv) return E_OUTOFMEMORY;
     }
         This->fragment_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv));
         if(!This->fragment_priv) return E_OUTOFMEMORY;
     }
-    priv = (struct shader_arb_priv *) This->fragment_priv;
+    priv = This->fragment_priv;
     priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
     priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
@@ -2313,7 +2329,7 @@ static void arbfp_free_ffpshader(void *value, void *gli) {
 
 static void arbfp_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
 
 static void arbfp_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    struct shader_arb_priv *priv = (struct shader_arb_priv *) This->fragment_priv;
+    struct shader_arb_priv *priv = This->fragment_priv;
 
     hash_table_destroy(priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
     priv->use_arbfp_fixed_func = FALSE;
 
     hash_table_destroy(priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
     priv->use_arbfp_fixed_func = FALSE;
@@ -2952,7 +2968,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
 
 static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
 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;
+    struct shader_arb_priv *priv = device->fragment_priv;
     BOOL use_pshader = use_ps(stateblock);
     BOOL use_vshader = use_vs(stateblock);
     struct ffp_frag_settings settings;
     BOOL use_pshader = use_ps(stateblock);
     BOOL use_vshader = use_vs(stateblock);
     struct ffp_frag_settings settings;
@@ -3051,22 +3067,17 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
 
     if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
 
 
     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;
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
+        if(use_vs(stateblock)) {
+            new_source = FOGSOURCE_VS;
         } else {
         } else {
-            new_source = FOGSOURCE_FFP;
+            if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
+                new_source = FOGSOURCE_COORD;
+            } else {
+                new_source = FOGSOURCE_FFP;
+            }
         }
     } else {
         }
     } else {
-        context->last_was_foggy_shader = FALSE;
         new_source = FOGSOURCE_FFP;
     }
     if(new_source != context->fog_source) {
         new_source = FOGSOURCE_FFP;
     }
     if(new_source != context->fog_source) {
@@ -3263,7 +3274,7 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
 }
 static void arbfp_blit_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
 }
 static void arbfp_blit_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
-    struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
+    struct arbfp_blit_priv *priv = device->blit_priv;
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader));
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader));
@@ -3514,7 +3525,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
     GLenum shader;
     SHADER_BUFFER buffer;
     char luminance_component;
     GLenum shader;
     SHADER_BUFFER buffer;
     char luminance_component;
-    struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
+    struct arbfp_blit_priv *priv = device->blit_priv;
 
     /* Shader header */
     shader_buffer_init(&buffer);
 
     /* Shader header */
     shader_buffer_init(&buffer);
@@ -3649,7 +3660,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, WINED3DFORMAT fmt, GLenum t
     GLenum shader;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
     float size[4] = {width, height, 1, 1};
     GLenum shader;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
     float size[4] = {width, height, 1, 1};
-    struct arbfp_blit_priv *priv = (struct arbfp_blit_priv *) device->blit_priv;
+    struct arbfp_blit_priv *priv = device->blit_priv;
     const struct GlPixelFormatDesc *glDesc;
     enum yuv_fixup yuv_fixup;
 
     const struct GlPixelFormatDesc *glDesc;
     enum yuv_fixup yuv_fixup;
 
index c01ec1a..4fe5430 100644 (file)
@@ -803,7 +803,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
     IWineD3DDeviceImpl          *This = stateblock->wineD3DDevice;
     const struct atifs_ffp_desc *desc;
     struct ffp_frag_settings     settings;
     IWineD3DDeviceImpl          *This = stateblock->wineD3DDevice;
     const struct atifs_ffp_desc *desc;
     struct ffp_frag_settings     settings;
-    struct atifs_private_data   *priv = (struct atifs_private_data *) This->fragment_priv;
+    struct atifs_private_data   *priv = This->fragment_priv;
     DWORD mapped_stage;
     unsigned int i;
 
     DWORD mapped_stage;
     unsigned int i;
 
@@ -1107,7 +1107,7 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) {
         ERR("Out of memory\n");
         return E_OUTOFMEMORY;
     }
         ERR("Out of memory\n");
         return E_OUTOFMEMORY;
     }
-    priv = (struct atifs_private_data *) This->fragment_priv;
+    priv = This->fragment_priv;
     priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     return WINED3D_OK;
 }
     priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     return WINED3D_OK;
 }
@@ -1126,7 +1126,7 @@ static void atifs_free_ffpshader(void *value, void *device) {
 
 static void atifs_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
 
 static void atifs_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv;
+    struct atifs_private_data *priv = This->fragment_priv;
 
     hash_table_destroy(priv->fragment_shaders, atifs_free_ffpshader, This);
 
 
     hash_table_destroy(priv->fragment_shaders, atifs_free_ffpshader, This);
 
index a270b0c..f191b2c 100644 (file)
@@ -31,8 +31,6 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
-#define GLNAME_REQUIRE_GLSL  ((const char *)1)
-
 static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version);
 
 static inline BOOL shader_is_version_token(DWORD token) {
 static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version);
 
 static inline BOOL shader_is_version_token(DWORD token) {
@@ -1135,8 +1133,9 @@ static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     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;
 }
-static void shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
     FIXME("NONE shader backend asked to generate a vertex shader\n");
     FIXME("NONE shader backend asked to generate a vertex shader\n");
+    return 0;
 }
 
 #define GLINFO_LOCATION      (*gl_info)
 }
 
 #define GLINFO_LOCATION      (*gl_info)
index d4a57c9..71e69e3 100644 (file)
@@ -2104,7 +2104,7 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
     HDC dcb = NULL, dcs = NULL;
     WINEDDCOLORKEY colorkey;
 
     HDC dcb = NULL, dcs = NULL;
     WINEDDCOLORKEY colorkey;
 
-    hbm = (HBITMAP) LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+    hbm = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
     if(hbm)
     {
         GetObjectA(hbm, sizeof(BITMAP), &bm);
     if(hbm)
     {
         GetObjectA(hbm, sizeof(BITMAP), &bm);
@@ -6765,7 +6765,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
             {
                 const struct GlPixelFormatDesc *glDesc;
                 const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &GLINFO_LOCATION, &glDesc);
             {
                 const struct GlPixelFormatDesc *glDesc;
                 const StaticPixelFormatDesc *tableEntry = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &GLINFO_LOCATION, &glDesc);
-                char *mem, *bits = (char *)rect.pBits;
+                char *mem, *bits = rect.pBits;
                 GLint intfmt = glDesc->glInternal;
                 GLint format = glDesc->glFormat;
                 GLint type = glDesc->glType;
                 GLint intfmt = glDesc->glInternal;
                 GLint format = glDesc->glFormat;
                 GLint type = glDesc->glType;
index a78f4e5..dcd18a8 100644 (file)
@@ -1287,6 +1287,12 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
                     gl_info->gl_card = CARD_ATI_RADEON_X700;
                     vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
                 }
                     gl_info->gl_card = CARD_ATI_RADEON_X700;
                     vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
                 }
+                /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
+                else if(strstr(gl_info->gl_renderer, "Radeon Xpress"))
+                {
+                    gl_info->gl_card = CARD_ATI_RADEON_XPRESS_200M;
+                    vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
+                }
                 /* Radeon R3xx */ 
                 else {
                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
                 /* Radeon R3xx */ 
                 else {
                     gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
index b78078f..37f43b4 100644 (file)
@@ -324,8 +324,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
             idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
         }
 
             idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
         }
 
-        if (idxSize == 2) pIdxBufS = (const WORD *) idxData;
-        else pIdxBufL = (const DWORD *) idxData;
+        if (idxSize == 2) pIdxBufS = idxData;
+        else pIdxBufL = idxData;
     } else if (idxData) {
         ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
         return;
     } else if (idxData) {
         ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
         return;
@@ -519,31 +519,41 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid
 static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, const UINT index, const void *ptr) {
     switch(type) {
         case WINED3DDECLTYPE_FLOAT1:
 static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, const UINT index, const void *ptr) {
     switch(type) {
         case WINED3DDECLTYPE_FLOAT1:
-            GL_EXTCALL(glVertexAttrib1fvARB(index, (const float *)ptr));
+            GL_EXTCALL(glVertexAttrib1fvARB(index, ptr));
             break;
         case WINED3DDECLTYPE_FLOAT2:
             break;
         case WINED3DDECLTYPE_FLOAT2:
-            GL_EXTCALL(glVertexAttrib2fvARB(index, (const float *)ptr));
+            GL_EXTCALL(glVertexAttrib2fvARB(index, ptr));
             break;
         case WINED3DDECLTYPE_FLOAT3:
             break;
         case WINED3DDECLTYPE_FLOAT3:
-            GL_EXTCALL(glVertexAttrib3fvARB(index, (const float *)ptr));
+            GL_EXTCALL(glVertexAttrib3fvARB(index, ptr));
             break;
         case WINED3DDECLTYPE_FLOAT4:
             break;
         case WINED3DDECLTYPE_FLOAT4:
-            GL_EXTCALL(glVertexAttrib4fvARB(index, (const float *)ptr));
+            GL_EXTCALL(glVertexAttrib4fvARB(index, ptr));
             break;
 
         case WINED3DDECLTYPE_UBYTE4:
             GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
             break;
             break;
 
         case WINED3DDECLTYPE_UBYTE4:
             GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
             break;
-        case WINED3DDECLTYPE_UBYTE4N:
         case WINED3DDECLTYPE_D3DCOLOR:
         case WINED3DDECLTYPE_D3DCOLOR:
+            if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
+            {
+                const DWORD *src = ptr;
+                DWORD c = *src & 0xff00ff00;
+                c |= (*src & 0xff0000) >> 16;
+                c |= (*src & 0xff) << 16;
+                GL_EXTCALL(glVertexAttrib4NubvARB(index, (GLubyte *)&c));
+                break;
+            }
+            /* else fallthrough */
+        case WINED3DDECLTYPE_UBYTE4N:
             GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
             break;
 
         case WINED3DDECLTYPE_SHORT2:
             GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
             break;
 
         case WINED3DDECLTYPE_SHORT2:
-            GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
+            GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
             break;
         case WINED3DDECLTYPE_SHORT4:
             break;
         case WINED3DDECLTYPE_SHORT4:
-            GL_EXTCALL(glVertexAttrib4svARB(index, (const GLshort *)ptr));
+            GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
             break;
 
         case WINED3DDECLTYPE_SHORT2N:
             break;
 
         case WINED3DDECLTYPE_SHORT2N:
@@ -559,10 +569,10 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
             break;
         }
         case WINED3DDECLTYPE_SHORT4N:
             break;
         }
         case WINED3DDECLTYPE_SHORT4N:
-            GL_EXTCALL(glVertexAttrib4NsvARB(index, (const GLshort *)ptr));
+            GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr));
             break;
         case WINED3DDECLTYPE_USHORT4N:
             break;
         case WINED3DDECLTYPE_USHORT4N:
-            GL_EXTCALL(glVertexAttrib4NusvARB(index, (const GLushort *)ptr));
+            GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr));
             break;
 
         case WINED3DDECLTYPE_UDEC3:
             break;
 
         case WINED3DDECLTYPE_UDEC3:
@@ -579,7 +589,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
              * byte float according to the IEEE standard
              */
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
              * byte float according to the IEEE standard
              */
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
-                GL_EXTCALL(glVertexAttrib2hvNV(index, (const GLhalfNV *)ptr));
+                GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 float y = float_16_to_32(((const unsigned short *)ptr) + 1);
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 float y = float_16_to_32(((const unsigned short *)ptr) + 1);
@@ -588,7 +598,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co
             break;
         case WINED3DDECLTYPE_FLOAT16_4:
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
             break;
         case WINED3DDECLTYPE_FLOAT16_4:
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
-                GL_EXTCALL(glVertexAttrib4hvNV(index, (const GLhalfNV *)ptr));
+                GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 float y = float_16_to_32(((const unsigned short *)ptr) + 1);
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 float y = float_16_to_32(((const unsigned short *)ptr) + 1);
@@ -626,8 +636,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr
             idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory;
         }
 
             idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory;
         }
 
-        if (idxSize == 2) pIdxBufS = (const WORD *) idxData;
-        else pIdxBufL = (const DWORD *) idxData;
+        if (idxSize == 2) pIdxBufS = idxData;
+        else pIdxBufL = idxData;
     } else if (idxData) {
         ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
         return;
     } else if (idxData) {
         ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
         return;
@@ -954,7 +964,7 @@ void drawPrimitive(IWineD3DDevice *iface, int PrimitiveType, long NumPrimitives,
                     sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
                     TRACE("Saving texture %s\n", buffer);
                     if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) {
                     sprintf(buffer, "/tmp/texture_%p_%ld_%d.tga", This->stateBlock->textures[textureNo], primCounter, textureNo);
                     TRACE("Saving texture %s\n", buffer);
                     if (IWineD3DBaseTexture_GetType(This->stateBlock->textures[textureNo]) == WINED3DRTYPE_TEXTURE) {
-                            IWineD3DTexture_GetSurfaceLevel((IWineD3DTexture *)This->stateBlock->textures[textureNo], 0, &pSur);
+                            IWineD3DTexture_GetSurfaceLevel(This->stateBlock->textures[textureNo], 0, &pSur);
                             IWineD3DSurface_SaveSnapshot(pSur, buffer);
                             IWineD3DSurface_Release(pSur);
                     } else  {
                             IWineD3DSurface_SaveSnapshot(pSur, buffer);
                             IWineD3DSurface_Release(pSur);
                     } else  {
index 8dfb416..23beb46 100644 (file)
@@ -101,16 +101,18 @@ struct glsl_shader_prog_link {
     GLhandleARB                 luminanceoffset_location[MAX_TEXTURES];
     GLhandleARB                 ycorrection_location;
     GLenum                      vertex_color_clamp;
     GLhandleARB                 luminanceoffset_location[MAX_TEXTURES];
     GLhandleARB                 ycorrection_location;
     GLenum                      vertex_color_clamp;
-    GLhandleARB                 vshader;
+    IWineD3DVertexShader        *vshader;
     IWineD3DPixelShader         *pshader;
     IWineD3DPixelShader         *pshader;
+    struct vs_compile_args      vs_args;
     struct ps_compile_args      ps_args;
     UINT                        constant_version;
 };
 
 typedef struct {
     struct ps_compile_args      ps_args;
     UINT                        constant_version;
 };
 
 typedef struct {
-    GLhandleARB                 vshader;
+    IWineD3DVertexShader        *vshader;
     IWineD3DPixelShader         *pshader;
     struct ps_compile_args      ps_args;
     IWineD3DPixelShader         *pshader;
     struct ps_compile_args      ps_args;
+    struct vs_compile_args      vs_args;
 } glsl_program_key_t;
 
 
 } glsl_program_key_t;
 
 
@@ -471,7 +473,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine
 
 static void reset_program_constant_version(void *value, void *context)
 {
 
 static void reset_program_constant_version(void *value, void *context)
 {
-    struct glsl_shader_prog_link *entry = (struct glsl_shader_prog_link *)value;
+    struct glsl_shader_prog_link *entry = value;
     entry->constant_version = 0;
 }
 
     entry->constant_version = 0;
 }
 
@@ -484,7 +486,7 @@ static void shader_glsl_load_constants(
     char useVertexShader) {
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
     char useVertexShader) {
    
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)deviceImpl->shader_priv;
+    struct shader_glsl_priv *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;
 
@@ -621,7 +623,7 @@ static inline void update_heap_entry(struct constant_heap *heap, unsigned int id
 static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 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 shader_glsl_priv *priv = This->shader_priv;
     struct constant_heap *heap = &priv->vconst_heap;
     UINT i;
 
     struct constant_heap *heap = &priv->vconst_heap;
     UINT i;
 
@@ -637,7 +639,7 @@ static void shader_glsl_update_float_vertex_constants(IWineD3DDevice *iface, UIN
 static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 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 shader_glsl_priv *priv = This->shader_priv;
     struct constant_heap *heap = &priv->pconst_heap;
     UINT i;
 
     struct constant_heap *heap = &priv->pconst_heap;
     UINT i;
 
@@ -1030,7 +1032,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 (((IWineD3DVertexShaderImpl *)This)->swizzle_map & (1 << reg)) *is_color = TRUE;
+            if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg)) *is_color = TRUE;
             sprintf(tmpStr, "attrib%u", reg);
         } 
         break;
             sprintf(tmpStr, "attrib%u", reg);
         } 
         break;
@@ -2918,20 +2920,23 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
+    key->vs_args = entry->vs_args;
     key->ps_args = entry->ps_args;
 
     hash_table_put(priv->glsl_program_lookup, key, entry);
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
     key->ps_args = entry->ps_args;
 
     hash_table_put(priv->glsl_program_lookup, key, entry);
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
-        GLhandleARB vshader, IWineD3DPixelShader *pshader, struct ps_compile_args *ps_args) {
+        IWineD3DVertexShader *vshader, IWineD3DPixelShader *pshader, struct vs_compile_args *vs_args,
+        struct ps_compile_args *ps_args) {
     glsl_program_key_t key;
 
     key.vshader = vshader;
     key.pshader = pshader;
     glsl_program_key_t key;
 
     key.vshader = vshader;
     key.pshader = pshader;
+    key.vs_args = *vs_args;
     key.ps_args = *ps_args;
 
     key.ps_args = *ps_args;
 
-    return (struct glsl_shader_prog_link *)hash_table_get(priv->glsl_program_lookup, &key);
+    return hash_table_get(priv->glsl_program_lookup, &key);
 }
 
 static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info,
 }
 
 static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info,
@@ -2942,6 +2947,7 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
     key = HeapAlloc(GetProcessHeap(), 0, sizeof(glsl_program_key_t));
     key->vshader = entry->vshader;
     key->pshader = entry->pshader;
+    key->vs_args = entry->vs_args;
     key->ps_args = entry->ps_args;
     hash_table_remove(priv->glsl_program_lookup, key);
 
     key->ps_args = entry->ps_args;
     hash_table_remove(priv->glsl_program_lookup, key);
 
@@ -3248,7 +3254,7 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
     checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
     GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL));
     ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
     checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
     GL_EXTCALL(glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL));
-    checkGLcall("glShaderSourceARB(ret, 1, (const char**)&buffer.buffer, NULL)");
+    checkGLcall("glShaderSourceARB(ret, 1, &buffer.buffer, NULL)");
     GL_EXTCALL(glCompileShaderARB(ret));
     checkGLcall("glCompileShaderARB(ret)");
 
     GL_EXTCALL(glCompileShaderARB(ret));
     checkGLcall("glCompileShaderARB(ret)");
 
@@ -3283,7 +3289,7 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD
  */
 static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
     IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
  */
 static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
     IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
-    struct shader_glsl_priv *priv          = (struct shader_glsl_priv *)This->shader_priv;
+    struct shader_glsl_priv *priv          = This->shader_priv;
     const WineD3D_GL_Info *gl_info         = &This->adapter->gl_info;
     IWineD3DPixelShader  *pshader          = This->stateBlock->pixelShader;
     IWineD3DVertexShader *vshader          = This->stateBlock->vertexShader;
     const WineD3D_GL_Info *gl_info         = &This->adapter->gl_info;
     IWineD3DPixelShader  *pshader          = This->stateBlock->pixelShader;
     IWineD3DVertexShader *vshader          = This->stateBlock->vertexShader;
@@ -3293,21 +3299,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     int i;
     char glsl_name[8];
     GLhandleARB vshader_id, pshader_id;
     int i;
     char glsl_name[8];
     GLhandleARB vshader_id, pshader_id;
-    struct ps_compile_args compile_args;
+    struct ps_compile_args ps_compile_args;
+    struct vs_compile_args vs_compile_args;
 
     if(use_vs) {
 
     if(use_vs) {
-        IWineD3DVertexShaderImpl_CompileShader(vshader);
-        vshader_id = ((IWineD3DVertexShaderImpl*)vshader)->prgId;
+        find_vs_compile_args((IWineD3DVertexShaderImpl*)This->stateBlock->vertexShader, This->stateBlock, &vs_compile_args);
     } else {
     } else {
-        vshader_id = 0;
+        /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
+        memset(&vs_compile_args, 0, sizeof(vs_compile_args));
     }
     if(use_ps) {
     }
     if(use_ps) {
-        find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &compile_args);
+        find_ps_compile_args((IWineD3DPixelShaderImpl*)This->stateBlock->pixelShader, This->stateBlock, &ps_compile_args);
     } else {
         /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
     } else {
         /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
-        memset(&compile_args, 0, sizeof(compile_args));
+        memset(&ps_compile_args, 0, sizeof(ps_compile_args));
     }
     }
-    entry = get_glsl_program_entry(priv, vshader_id, pshader, &compile_args);
+    entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args);
     if (entry) {
         priv->glsl_program = entry;
         return;
     if (entry) {
         priv->glsl_program = entry;
         return;
@@ -3320,9 +3327,10 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     /* Create the entry */
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
     entry->programId = programId;
     /* Create the entry */
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
     entry->programId = programId;
-    entry->vshader = vshader_id;
+    entry->vshader = vshader;
     entry->pshader = pshader;
     entry->pshader = pshader;
-    entry->ps_args = compile_args;
+    entry->vs_args = vs_compile_args;
+    entry->ps_args = ps_compile_args;
     entry->constant_version = 0;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
     entry->constant_version = 0;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
@@ -3330,6 +3338,12 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     /* Set the current program */
     priv->glsl_program = entry;
 
     /* Set the current program */
     priv->glsl_program = entry;
 
+    if(use_vs) {
+        vshader_id = find_gl_vshader((IWineD3DVertexShaderImpl *) vshader, &vs_compile_args);
+    } else {
+        vshader_id = 0;
+    }
+
     /* Attach GLSL vshader */
     if (vshader_id) {
         int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
     /* Attach GLSL vshader */
     if (vshader_id) {
         int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
@@ -3369,7 +3383,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     }
 
     if(use_ps) {
     }
 
     if(use_ps) {
-        pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &compile_args);
+        pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args);
     } else {
         pshader_id = 0;
     }
     } else {
         pshader_id = 0;
     }
@@ -3543,7 +3557,7 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t
 
 static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
+    struct shader_glsl_priv *priv = This->shader_priv;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
@@ -3573,7 +3587,7 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
 static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv;
+    struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
 
     if (!*blt_program) {
     GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
 
     if (!*blt_program) {
@@ -3590,7 +3604,7 @@ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types t
 static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *) This->shader_priv;
+    struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB program_id;
 
     program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
     GLhandleARB program_id;
 
     program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
@@ -3604,7 +3618,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     const struct list *linked_programs;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     const struct list *linked_programs;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)device->shader_priv;
+    struct shader_glsl_priv *priv = device->shader_priv;
     const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
     const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
@@ -3619,7 +3633,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
         if(ps->num_gl_shaders == 0) return;
     } else {
         vs = (IWineD3DVertexShaderImpl *) This;
         if(ps->num_gl_shaders == 0) return;
     } else {
         vs = (IWineD3DVertexShaderImpl *) This;
-        if(vs->prgId == 0) return;
+        if(vs->num_gl_shaders == 0) return;
     }
 
     linked_programs = &This->baseShader.linked_programs;
     }
 
     linked_programs = &This->baseShader.linked_programs;
@@ -3652,22 +3666,29 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
         HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
         ps->gl_shaders = NULL;
         ps->num_gl_shaders = 0;
         HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
         ps->gl_shaders = NULL;
         ps->num_gl_shaders = 0;
+        ps->shader_array_size = 0;
     } else {
     } else {
-        TRACE("Deleting shader object %u\n", vs->prgId);
+        UINT i;
+
         ENTER_GL();
         ENTER_GL();
-        GL_EXTCALL(glDeleteObjectARB(vs->prgId));
-        checkGLcall("glDeleteObjectARB");
+        for(i = 0; i < vs->num_gl_shaders; i++) {
+            TRACE("deleting vshader %u\n", vs->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(vs->gl_shaders[i].prgId));
+            checkGLcall("glDeleteObjectARB");
+        }
         LEAVE_GL();
         LEAVE_GL();
-        vs->prgId = 0;
-        vs->baseShader.is_compiled = FALSE;
+        HeapFree(GetProcessHeap(), 0, vs->gl_shaders);
+        vs->gl_shaders = NULL;
+        vs->num_gl_shaders = 0;
+        vs->shader_array_size = 0;
     }
 }
 
 static unsigned int glsl_program_key_hash(const void *key)
 {
     }
 }
 
 static unsigned int glsl_program_key_hash(const void *key)
 {
-    const glsl_program_key_t *k = (const glsl_program_key_t *)key;
+    const glsl_program_key_t *k = key;
 
 
-    unsigned int hash = k->vshader | ((DWORD_PTR) k->pshader) << 16;
+    unsigned int hash = ((DWORD_PTR) k->vshader) | ((DWORD_PTR) k->pshader) << 16;
     hash += ~(hash << 15);
     hash ^=  (hash >> 10);
     hash +=  (hash << 3);
     hash += ~(hash << 15);
     hash ^=  (hash >> 10);
     hash +=  (hash << 3);
@@ -3680,11 +3701,12 @@ static unsigned int glsl_program_key_hash(const void *key)
 
 static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
 {
 
 static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
 {
-    const glsl_program_key_t *ka = (const glsl_program_key_t *)keya;
-    const glsl_program_key_t *kb = (const glsl_program_key_t *)keyb;
+    const glsl_program_key_t *ka = keya;
+    const glsl_program_key_t *kb = keyb;
 
     return ka->vshader == kb->vshader && ka->pshader == kb->pshader &&
 
     return ka->vshader == kb->vshader && ka->pshader == kb->pshader &&
-           (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0);
+           (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0) &&
+           (memcmp(&ka->vs_args, &kb->vs_args, sizeof(kb->vs_args)) == 0);
 }
 
 static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
 }
 
 static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
@@ -3752,7 +3774,7 @@ static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
 static void shader_glsl_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 static void shader_glsl_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-    struct shader_glsl_priv *priv = (struct shader_glsl_priv *)This->shader_priv;
+    struct shader_glsl_priv *priv = This->shader_priv;
     int i;
 
     for (i = 0; i < tex_type_count; ++i)
     int i;
 
     for (i = 0; i < tex_type_count; ++i)
@@ -3850,10 +3872,16 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
                 shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
                 break;
             case FOG_EXP:
                 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");
+                /* Fog = e^(-gl_Fog.density * gl_FogFragCoord) */
+                shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_FogFragCoord);\n");
+                shader_addline(buffer, "Fog = clamp(Fog, 0.0, 1.0);\n");
+                shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
                 break;
             case FOG_EXP2:
                 break;
             case FOG_EXP2:
-                FIXME("Implement EXP2 fog in glsl\n");
+                /* Fog = e^(-(gl_Fog.density * gl_FogFragCoord)^2) */
+                shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n");
+                shader_addline(buffer, "Fog = clamp(Fog, 0.0, 1.0);\n");
+                shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
                 break;
         }
     }
                 break;
         }
     }
@@ -3869,7 +3897,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     return shader_obj;
 }
 
     return shader_obj;
 }
 
-static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer) {
+static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
@@ -3890,9 +3918,16 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
     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 (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)
+    /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
+     * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
+     * the fog frag coord is thrown away. If the fog frag coord is used, but not written by
+     * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
+     */
+    if(args->fog_src == VS_FOG_Z) {
         shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n");
         shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n");
+    } else if (!reg_maps->fog) {
+        shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
+    }
 
     /* Write the final position.
      *
 
     /* Write the final position.
      *
@@ -3919,8 +3954,7 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
     GL_EXTCALL(glCompileShaderARB(shader_obj));
     print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
 
     GL_EXTCALL(glCompileShaderARB(shader_obj));
     print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
 
-    /* Store the shader object */
-    This->prgId = shader_obj;
+    return shader_obj;
 }
 
 static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
 }
 
 static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
index 9f96c59..0be352c 100644 (file)
@@ -34,8 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
 #define GLINFO_LOCATION ((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info
 
 
 #define GLINFO_LOCATION ((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info
 
-#define GLNAME_REQUIRE_GLSL  ((const char *)1)
-
 static HRESULT  WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) {
     TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), ppobj);
 
 static HRESULT  WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) {
     TRACE("iface %p, riid %s, ppobj %p\n", iface, debugstr_guid(riid), ppobj);
 
@@ -439,8 +437,6 @@ static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps
     retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
     shader_buffer_free(&buffer);
 
     retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
     shader_buffer_free(&buffer);
 
-    This->baseShader.is_compiled = TRUE;
-
     return retval;
 }
 
     return retval;
 }
 
@@ -520,10 +516,12 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
 GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
 {
     UINT i;
 GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
 {
     UINT i;
-    struct ps_compiled_shader *old_array;
+    DWORD new_size;
+    struct ps_compiled_shader *new_array;
 
     /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
 
     /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
-     * so a linear search is more performant than a hashmap
+     * so a linear search is more performant than a hashmap or a binary search
+     * (cache coherency etc)
      */
     for(i = 0; i < shader->num_gl_shaders; i++) {
         if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
      */
     for(i = 0; i < shader->num_gl_shaders; i++) {
         if(memcmp(&shader->gl_shaders[i].args, args, sizeof(*args)) == 0) {
@@ -532,17 +530,22 @@ GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_
     }
 
     TRACE("No matching GL shader found, compiling a new shader\n");
     }
 
     TRACE("No matching GL shader found, compiling a new shader\n");
-    old_array = shader->gl_shaders;
-    if(old_array) {
-        shader->gl_shaders = HeapReAlloc(GetProcessHeap(), 0, old_array,
-                                         (shader->num_gl_shaders + 1) * sizeof(*shader->gl_shaders));
-    } else {
-        shader->gl_shaders = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
-    }
+    if(shader->shader_array_size == shader->num_gl_shaders) {
+        if(shader->gl_shaders) {
+            new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
+                                    new_size * sizeof(*shader->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
+            new_size = 1;
+        }
 
 
-    if(!shader->gl_shaders) {
-        ERR("Out of memory\n");
-        return 0;
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader->gl_shaders = new_array;
+        shader->shader_array_size = new_size;
     }
 
     shader->gl_shaders[shader->num_gl_shaders].args = *args;
     }
 
     shader->gl_shaders[shader->num_gl_shaders].args = *args;
index 05e114c..481177f 100644 (file)
@@ -133,7 +133,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     case WINED3DQUERYTYPE_VCACHE:
     {
 
     case WINED3DQUERYTYPE_VCACHE:
     {
 
-        WINED3DDEVINFO_VCACHE *data = (WINED3DDEVINFO_VCACHE *)pData;
+        WINED3DDEVINFO_VCACHE *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
         if(pData == NULL || dwSize == 0) break;
         data->Pattern     = WINEMAKEFOURCC('C','A','C','H');
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
         if(pData == NULL || dwSize == 0) break;
         data->Pattern     = WINEMAKEFOURCC('C','A','C','H');
@@ -145,7 +145,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_RESOURCEMANAGER:
     {
     break;
     case WINED3DQUERYTYPE_RESOURCEMANAGER:
     {
-        WINED3DDEVINFO_RESOURCEMANAGER *data = (WINED3DDEVINFO_RESOURCEMANAGER *)pData;
+        WINED3DDEVINFO_RESOURCEMANAGER *data = pData;
         int i;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
         if(pData == NULL || dwSize == 0) break;
         int i;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
         if(pData == NULL || dwSize == 0) break;
@@ -169,7 +169,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_VERTEXSTATS:
     {
     break;
     case WINED3DQUERYTYPE_VERTEXSTATS:
     {
-        WINED3DDEVINFO_VERTEXSTATS *data = (WINED3DDEVINFO_VERTEXSTATS *)pData;
+        WINED3DDEVINFO_VERTEXSTATS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
         if(pData == NULL || dwSize == 0) break;
         data->NumRenderedTriangles      = 1;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
         if(pData == NULL || dwSize == 0) break;
         data->NumRenderedTriangles      = 1;
@@ -203,7 +203,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_PIPELINETIMINGS:
     {
     break;
     case WINED3DQUERYTYPE_PIPELINETIMINGS:
     {
-        WINED3DDEVINFO_PIPELINETIMINGS *data = (WINED3DDEVINFO_PIPELINETIMINGS *)pData;
+        WINED3DDEVINFO_PIPELINETIMINGS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
         if(pData == NULL || dwSize == 0) break;
 
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
         if(pData == NULL || dwSize == 0) break;
 
@@ -215,7 +215,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_INTERFACETIMINGS:
     {
     break;
     case WINED3DQUERYTYPE_INTERFACETIMINGS:
     {
-        WINED3DDEVINFO_INTERFACETIMINGS *data = (WINED3DDEVINFO_INTERFACETIMINGS *)pData;
+        WINED3DDEVINFO_INTERFACETIMINGS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
@@ -229,7 +229,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_VERTEXTIMINGS:
     {
     break;
     case WINED3DQUERYTYPE_VERTEXTIMINGS:
     {
-        WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
+        WINED3DDEVINFO_STAGETIMINGS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
@@ -240,7 +240,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_PIXELTIMINGS:
     {
     break;
     case WINED3DQUERYTYPE_PIXELTIMINGS:
     {
-        WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
+        WINED3DDEVINFO_STAGETIMINGS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
@@ -250,7 +250,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
     {
     break;
     case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
     {
-        WINED3DDEVINFO_BANDWIDTHTIMINGS *data = (WINED3DDEVINFO_BANDWIDTHTIMINGS *)pData;
+        WINED3DDEVINFO_BANDWIDTHTIMINGS *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
 
         if(pData == NULL || dwSize == 0) break;
@@ -263,7 +263,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     break;
     case WINED3DQUERYTYPE_CACHEUTILIZATION:
     {
     break;
     case WINED3DQUERYTYPE_CACHEUTILIZATION:
     {
-        WINED3DDEVINFO_CACHEUTILIZATION *data = (WINED3DDEVINFO_CACHEUTILIZATION *)pData;
+        WINED3DDEVINFO_CACHEUTILIZATION *data = pData;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
 
         if(pData == NULL || dwSize == 0) break;
         FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
 
         if(pData == NULL || dwSize == 0) break;
index 1231b34..b4e49b1 100644 (file)
@@ -25,7 +25,6 @@
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 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)
 
 HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
index 67fc1c7..e1aeeab 100644 (file)
@@ -1019,75 +1019,72 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
      * and 2) disables the fog computation (in either the fixed function or programmable
      * rasterizer) if using a vertex program.
      *
      * and 2) disables the fog computation (in either the fixed function or programmable
      * rasterizer) if using a vertex program.
      *
+     * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
+     * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
+     * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
+     * the specular color, a vertex shader counts as pretransformed geometry in this case.
+     * There are some GL differences between specular fog coords and vertex shaders though.
+     *
+     * With table fog the vertex shader fog coordinate is ignored.
      *
      * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
      * without shaders).
      */
 
      *
      * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
      * without shaders).
      */
 
-    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");
-        } 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)");
-        }
-        context->last_was_foggy_shader = TRUE;
-        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."
      */
     /* 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) {
-        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:
-                if(!context->last_was_rhw) {
-                    glFogi(GL_FOG_MODE, GL_EXP);
-                    checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
-                    new_source = FOGSOURCE_FFP;
-                    break;
-                }
-                /* drop through */
-
-            case WINED3DFOG_EXP2:
-                if(!context->last_was_rhw) {
-                    glFogi(GL_FOG_MODE, GL_EXP2);
-                    checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
-                    new_source = FOGSOURCE_FFP;
-                    break;
-                }
-                /* drop through */
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
+        if(use_vs(stateblock)) {
+            glFogi(GL_FOG_MODE, GL_LINEAR);
+            checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+            new_source = FOGSOURCE_VS;
+        } else {
+            switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
+                /* If processed vertices are used, fall through to the NONE case */
+                case WINED3DFOG_EXP:
+                    if(!context->last_was_rhw) {
+                        glFogi(GL_FOG_MODE, GL_EXP);
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
+                        new_source = FOGSOURCE_FFP;
+                        break;
+                    }
+                    /* drop through */
+
+                case WINED3DFOG_EXP2:
+                    if(!context->last_was_rhw) {
+                        glFogi(GL_FOG_MODE, GL_EXP2);
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
+                        new_source = FOGSOURCE_FFP;
+                        break;
+                    }
+                    /* drop through */
+
+                case WINED3DFOG_LINEAR:
+                    if(!context->last_was_rhw) {
+                        glFogi(GL_FOG_MODE, GL_LINEAR);
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+                        new_source = FOGSOURCE_FFP;
+                        break;
+                    }
+                    /* drop through */
 
 
-            case WINED3DFOG_LINEAR:
-                if(!context->last_was_rhw) {
+                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
+                     */
+                    new_source = FOGSOURCE_COORD;
                     glFogi(GL_FOG_MODE, GL_LINEAR);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
                     glFogi(GL_FOG_MODE, GL_LINEAR);
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-                    new_source = FOGSOURCE_FFP;
                     break;
                     break;
-                }
-                /* 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
-                 */
-                new_source = FOGSOURCE_COORD;
-                glFogi(GL_FOG_MODE, GL_LINEAR);
-                checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
-                break;
-
-            default:
-                FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
-                new_source = FOGSOURCE_FFP; /* Make the compiler happy */
+                default:
+                    FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
+                    new_source = FOGSOURCE_FFP; /* Make the compiler happy */
+            }
         }
     } else {
         }
     } 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]) {
         new_source = FOGSOURCE_FFP;
 
         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
@@ -3928,8 +3925,18 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
                 case WINED3DDECLTYPE_UBYTE4:
                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
                     break;
                 case WINED3DDECLTYPE_UBYTE4:
                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
                     break;
-                case WINED3DDECLTYPE_UBYTE4N:
                 case WINED3DDECLTYPE_D3DCOLOR:
                 case WINED3DDECLTYPE_D3DCOLOR:
+                    if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
+                    {
+                        const DWORD *src = (const DWORD *)ptr;
+                        DWORD c = *src & 0xff00ff00;
+                        c |= (*src & 0xff0000) >> 16;
+                        c |= (*src & 0xff) << 16;
+                        GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
+                        break;
+                    }
+                    /* else fallthrough */
+                case WINED3DDECLTYPE_UBYTE4N:
                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
                     break;
 
                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
                     break;
 
@@ -4270,10 +4277,12 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
             load_numbered = TRUE;
             device->useDrawStridedSlow = FALSE;
         }
             load_numbered = TRUE;
             device->useDrawStridedSlow = FALSE;
         }
-    } 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)) {
+    } else if (fixup || (!dataLocations->u.s.pSize.lpData
+            && !dataLocations->position_transformed
+            && (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)
+            || (!dataLocations->u.s.diffuse.lpData
+            && !dataLocations->u.s.specular.lpData))))
+    {
         /* Load the vertex data using named arrays */
         load_named = TRUE;
         device->useDrawStridedSlow = FALSE;
         /* Load the vertex data using named arrays */
         load_named = TRUE;
         device->useDrawStridedSlow = FALSE;
@@ -4331,15 +4340,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
 
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
 
-    if (useVertexShaderFunction)
-    {
-        if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
-            updateFog = TRUE;
-        }
-    } else if(context->last_was_foggy_shader) {
-        updateFog = TRUE;
-    }
-
     transformed = device->strided_streams.position_transformed;
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
         updateFog = TRUE;
     transformed = device->strided_streams.position_transformed;
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
         updateFog = TRUE;
@@ -4405,8 +4405,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
         }
 
             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
         }
 
-        if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
-            state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
+        if(context->last_was_vshader) {
+            updateFog = TRUE;
+            if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
+                state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
+            }
         }
         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
         }
         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
@@ -4440,6 +4443,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
                     transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
                 }
             }
                     transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
                 }
             }
+            updateFog = TRUE;
         }
     }
 
         }
     }
 
index 03d483a..c3d56ee 100644 (file)
@@ -2228,7 +2228,7 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
             glEnable(GL_FRAGMENT_PROGRAM_ARB);
             GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
             GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
             glEnable(GL_FRAGMENT_PROGRAM_ARB);
             GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
             GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
-            GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), (const GLbyte *)fragment_palette_conversion));
+            GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), fragment_palette_conversion));
             glDisable(GL_FRAGMENT_PROGRAM_ARB);
         }
 
             glDisable(GL_FRAGMENT_PROGRAM_ARB);
         }
 
index f023c2e..1291701 100644 (file)
@@ -29,7 +29,6 @@
 #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>
 
@@ -46,7 +45,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(isinf(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);
 
     if(tmp < pow(2, 10)) {
         do
 
     if(tmp < pow(2, 10)) {
         do
@@ -1145,7 +1144,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D
     assert(width <= dlock.Pitch);
 
     if (DestRect && Src != This)
     assert(width <= dlock.Pitch);
 
     if (DestRect && Src != This)
-        dbuf = (BYTE*)dlock.pBits;
+        dbuf = dlock.pBits;
     else
         dbuf = (BYTE*)dlock.pBits+(xdst.top*dlock.Pitch)+(xdst.left*bpp);
 
     else
         dbuf = (BYTE*)dlock.pBits+(xdst.top*dlock.Pitch)+(xdst.left*bpp);
 
index cc09584..808b8c7 100644 (file)
@@ -1365,8 +1365,6 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B
 }
 #undef GLINFO_LOCATION
 
 }
 #undef GLINFO_LOCATION
 
-#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
-
 /* This small helper function is used to convert a bitmask into the number of masked bits */
 unsigned int count_bits(unsigned int mask)
 {
 /* This small helper function is used to convert a bitmask into the number of masked bits */
 unsigned int count_bits(unsigned int mask)
 {
@@ -1457,8 +1455,6 @@ BOOL getDepthStencilBits(WINED3DFORMAT fmt, short *depthSize, short *stencilSize
     return TRUE;
 }
 
     return TRUE;
 }
 
-#undef GLINFO_LOCATION
-
 /* DirectDraw stuff */
 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
     switch(depth) {
 /* DirectDraw stuff */
 WINED3DFORMAT pixelformat_for_depth(DWORD depth) {
     switch(depth) {
@@ -2096,17 +2092,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
         settings->fog = FOG_OFF;
     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
     if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
         settings->fog = FOG_OFF;
     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
-        switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
-            case WINED3DFOG_NONE:
-            case WINED3DFOG_LINEAR:
-                settings->fog = FOG_LINEAR;
-                break;
-            case WINED3DFOG_EXP:
-                settings->fog = FOG_EXP;
-                break;
-            case WINED3DFOG_EXP2:
-                settings->fog = FOG_EXP2;
-                break;
+        if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->position_transformed) {
+            settings->fog = FOG_LINEAR;
+        } else {
+            switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
+                case WINED3DFOG_NONE:
+                case WINED3DFOG_LINEAR:
+                    settings->fog = FOG_LINEAR;
+                    break;
+                case WINED3DFOG_EXP:
+                    settings->fog = FOG_EXP;
+                    break;
+                case WINED3DFOG_EXP2:
+                    settings->fog = FOG_EXP2;
+                    break;
+            }
         }
     } else {
         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
         }
     } else {
         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
@@ -2132,7 +2132,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
         const struct ffp_frag_settings *settings)
 {
 const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
         const struct ffp_frag_settings *settings)
 {
-    return (const struct ffp_frag_desc *)hash_table_get(fragment_shaders, settings);
+    return hash_table_get(fragment_shaders, settings);
 }
 
 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
 }
 
 void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
@@ -2241,7 +2241,7 @@ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
 
 unsigned int ffp_frag_program_key_hash(const void *key)
 {
 
 unsigned int ffp_frag_program_key_hash(const void *key)
 {
-    const struct ffp_frag_settings *k = (const struct ffp_frag_settings *)key;
+    const struct ffp_frag_settings *k = key;
     unsigned int hash = 0, i;
     const DWORD *blob;
 
     unsigned int hash = 0, i;
     const DWORD *blob;
 
@@ -2268,8 +2268,8 @@ unsigned int ffp_frag_program_key_hash(const void *key)
 
 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
 {
 
 BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
 {
-    const struct ffp_frag_settings *ka = (const struct ffp_frag_settings *)keya;
-    const struct ffp_frag_settings *kb = (const struct ffp_frag_settings *)keyb;
+    const struct ffp_frag_settings *ka = keya;
+    const struct ffp_frag_settings *kb = keyb;
 
     return memcmp(ka, kb, sizeof(*ka)) == 0;
 }
 
     return memcmp(ka, kb, sizeof(*ka)) == 0;
 }
index 339d955..e8d4b84 100644 (file)
@@ -37,8 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 /* TODO: Vertex and Pixel shaders are almost identical, the only exception being the way that some of the data is looked up or the availability of some of the data i.e. some instructions are only valid for pshaders and some for vshaders
 because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't surprise me if the program can be cross compiled using a large body of shared code */
 
 /* TODO: Vertex and Pixel shaders are almost identical, the only exception being the way that some of the data is looked up or the availability of some of the data i.e. some instructions are only valid for pshaders and some for vshaders
 because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't surprise me if the program can be cross compiled using a large body of shared code */
 
-#define GLNAME_REQUIRE_GLSL  ((const char *)1)
-
 CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
     /* This table is not order or position dependent. */
 
 CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
     /* This table is not order or position dependent. */
 
@@ -218,21 +216,6 @@ BOOL vshader_get_input(
     return FALSE;
 }
 
     return FALSE;
 }
 
-/** 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;
-    SHADER_BUFFER buffer;
-
-    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);
-    shader_buffer_free(&buffer);
-}
-
 /* *******************************************
    IWineD3DVertexShader IUnknown parts follow
    ******************************************* */
 /* *******************************************
    IWineD3DVertexShader IUnknown parts follow
    ******************************************* */
@@ -418,40 +401,20 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
-    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    CONST DWORD *function = This->baseShader.function;
+static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) {
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
-
-    TRACE("(%p) : function %p\n", iface, function);
-
-    /* We're already compiled. */
-    if (This->baseShader.is_compiled) {
-        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;
-
-        recompile:
-        if(This->recompile_count < 50) {
-            This->recompile_count++;
-        } else {
-            FIXME("Vertexshader %p recompiled more than 50 times\n", This);
-        }
-
-        deviceImpl->shader_backend->shader_destroy((IWineD3DBaseShader *) iface);
-    }
+    SHADER_BUFFER buffer;
+    GLuint ret;
 
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
 
     /* Generate the HW shader */
     TRACE("(%p) : Generating hardware program\n", This);
-    IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
-
-    This->baseShader.is_compiled = TRUE;
+    shader_buffer_init(&buffer);
+    This->cur_args = args;
+    ret = deviceImpl->shader_backend->shader_generate_vshader((IWineD3DVertexShader *)This, &buffer, args);
+    This->cur_args = NULL;
+    shader_buffer_free(&buffer);
 
 
-    return WINED3D_OK;
+    return ret;
 }
 
 const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
 }
 
 const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
@@ -470,3 +433,56 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
     IWineD3DVertexShaderImpl_FakeSemantics,
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
     IWineD3DVertexShaderImpl_FakeSemantics,
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
+
+void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args) {
+    args->fog_src = stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
+    args->swizzle_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.swizzle_map;
+}
+
+static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new,
+                                 const DWORD use_map) {
+    if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE;
+    return stored->fog_src == new->fog_src;
+}
+
+GLuint find_gl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args)
+{
+    UINT i;
+    DWORD new_size = shader->shader_array_size;
+    struct vs_compiled_shader *new_array;
+    DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map;
+
+    /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
+     * so a linear search is more performant than a hashmap or a binary search
+     * (cache coherency etc)
+     */
+    for(i = 0; i < shader->num_gl_shaders; i++) {
+        if(vs_args_equal(&shader->gl_shaders[i].args, args, use_map)) {
+            return shader->gl_shaders[i].prgId;
+        }
+    }
+
+    TRACE("No matching GL shader found, compiling a new shader\n");
+
+    if(shader->shader_array_size == shader->num_gl_shaders) {
+        if(shader->gl_shaders) {
+            new_size = shader->shader_array_size + max(1, shader->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), 0, shader->gl_shaders,
+                                    new_size * sizeof(*shader->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader->gl_shaders));
+            new_size = 1;
+        }
+
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader->gl_shaders = new_array;
+        shader->shader_array_size = new_size;
+    }
+
+    shader->gl_shaders[shader->num_gl_shaders].args = *args;
+    shader->gl_shaders[shader->num_gl_shaders].prgId = vertexshader_compile(shader, args);
+    return shader->gl_shaders[shader->num_gl_shaders++].prgId;
+}
index 07ca0d5..dd3946e 100644 (file)
@@ -3257,6 +3257,7 @@ typedef enum _GL_Cards {
   CARD_ATI_RADEON_7200            = 0x5144,
   CARD_ATI_RADEON_8500            = 0x514c,
   CARD_ATI_RADEON_9500            = 0x4144,
   CARD_ATI_RADEON_7200            = 0x5144,
   CARD_ATI_RADEON_8500            = 0x514c,
   CARD_ATI_RADEON_9500            = 0x4144,
+  CARD_ATI_RADEON_XPRESS_200M     = 0x5955,
   CARD_ATI_RADEON_X700            = 0x5e4c,
   CARD_ATI_RADEON_X1600           = 0x71c2,
   CARD_ATI_RADEON_HD2300          = 0x7210,
   CARD_ATI_RADEON_X700            = 0x5e4c,
   CARD_ATI_RADEON_X1600           = 0x71c2,
   CARD_ATI_RADEON_HD2300          = 0x7210,
index 0965a77..99015ac 100644 (file)
@@ -461,6 +461,18 @@ struct ps_compile_args {
     /* Texture types(2D, Cube, 3D) in ps 1.x */
 };
 
     /* Texture types(2D, Cube, 3D) in ps 1.x */
 };
 
+#define MAX_ATTRIBS 16
+
+enum fog_src_type {
+    VS_FOG_Z        = 0,
+    VS_FOG_COORD    = 1
+};
+
+struct vs_compile_args {
+    WORD                        fog_src;
+    WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
+};
+
 typedef struct {
     const SHADER_HANDLER *shader_instruction_handler_table;
     void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
 typedef struct {
     const SHADER_HANDLER *shader_instruction_handler_table;
     void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
@@ -475,7 +487,7 @@ typedef struct {
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
     GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
     GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
-    void (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer);
+    GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args);
     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);
 } shader_backend_t;
     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);
 } shader_backend_t;
@@ -804,7 +816,6 @@ struct WineD3DContext {
     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_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 namedArraysLoaded : 1;
     WORD numberedArraysLoaded : 1;
     WORD last_was_blit : 1;
@@ -813,7 +824,7 @@ struct WineD3DContext {
     WORD isPBuffer : 1;
     WORD fog_enabled : 1;
     WORD num_untracked_materials : 2;   /* Max value 2 */
     WORD isPBuffer : 1;
     WORD fog_enabled : 1;
     WORD num_untracked_materials : 2;   /* Max value 2 */
-    WORD padding : 2;
+    WORD padding : 3;
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
     BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */
     DWORD                   numbered_array_mask;
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
     BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */
     DWORD                   numbered_array_mask;
@@ -2210,7 +2221,6 @@ typedef struct IWineD3DBaseShaderClass
     CONST SHADER_OPCODE             *shader_ins;
     DWORD                          *function;
     UINT                            functionLength;
     CONST SHADER_OPCODE             *shader_ins;
     DWORD                          *function;
     UINT                            functionLength;
-    BOOL                            is_compiled;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
     BOOL                            uses_bool_consts, uses_int_consts;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
     BOOL                            uses_bool_consts, uses_int_consts;
@@ -2326,8 +2336,14 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
- * IDirect3DVertexShader implementation structure
+ * IDirect3DVertexShader implementation structures
  */
  */
+
+struct vs_compiled_shader {
+    struct vs_compile_args      args;
+    GLuint                      prgId;
+};
+
 typedef struct IWineD3DVertexShaderImpl {
     /* IUnknown parts*/   
     const IWineD3DVertexShaderVtbl *lpVtbl;
 typedef struct IWineD3DVertexShaderImpl {
     /* IUnknown parts*/   
     const IWineD3DVertexShaderVtbl *lpVtbl;
@@ -2341,22 +2357,25 @@ typedef struct IWineD3DVertexShaderImpl {
     DWORD                       usage;
 
     /* The GL shader */
     DWORD                       usage;
 
     /* The GL shader */
-    GLuint                          prgId;
+    struct vs_compiled_shader   *gl_shaders;
+    UINT                        num_gl_shaders, shader_array_size;
 
     /* Vertex shader input and output semantics */
     semantic semantics_in [MAX_ATTRIBS];
     semantic semantics_out [MAX_REG_OUTPUT];
 
 
     /* Vertex shader input and output semantics */
     semantic semantics_in [MAX_ATTRIBS];
     semantic semantics_out [MAX_REG_OUTPUT];
 
-    WORD swizzle_map;   /* MAX_ATTRIBS, 16 */
-
     UINT                       min_rel_offset, max_rel_offset;
     UINT                       rel_offset;
 
     UINT                       recompile_count;
     UINT                       min_rel_offset, max_rel_offset;
     UINT                       rel_offset;
 
     UINT                       recompile_count;
+
+    const struct vs_compile_args    *cur_args;
 } IWineD3DVertexShaderImpl;
 extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
 extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
 } IWineD3DVertexShaderImpl;
 extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
 extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
-HRESULT IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface);
+
+void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args);
+GLuint find_gl_vshader(IWineD3DVertexShaderImpl *shader, const struct vs_compile_args *args);
 
 /*****************************************************************************
  * IDirect3DPixelShader implementation structure
 
 /*****************************************************************************
  * IDirect3DPixelShader implementation structure
@@ -2384,7 +2403,7 @@ typedef struct IWineD3DPixelShaderImpl {
 
     /* The GL shader */
     struct ps_compiled_shader   *gl_shaders;
 
     /* The GL shader */
     struct ps_compiled_shader   *gl_shaders;
-    UINT                        num_gl_shaders;
+    UINT                        num_gl_shaders, shader_array_size;
 
     /* Some information about the shader behavior */
     struct stb_const_desc       bumpenvmatconst[MAX_TEXTURES];
 
     /* Some information about the shader behavior */
     struct stb_const_desc       bumpenvmatconst[MAX_TEXTURES];