- update wined3d, d3d8, d3d9, ddraw to Wine 1.1.28
authorKamil Hornicek <kamil.hornicek@reactos.org>
Thu, 3 Sep 2009 09:18:38 +0000 (09:18 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Thu, 3 Sep 2009 09:18:38 +0000 (09:18 +0000)
svn path=/trunk/; revision=42983

77 files changed:
reactos/dll/directx/wine/d3d8/cubetexture.c
reactos/dll/directx/wine/d3d8/d3d8_main.c
reactos/dll/directx/wine/d3d8/d3d8_private.h
reactos/dll/directx/wine/d3d8/device.c
reactos/dll/directx/wine/d3d8/directx.c
reactos/dll/directx/wine/d3d8/indexbuffer.c
reactos/dll/directx/wine/d3d8/pixelshader.c
reactos/dll/directx/wine/d3d8/stateblock.c
reactos/dll/directx/wine/d3d8/surface.c
reactos/dll/directx/wine/d3d8/swapchain.c
reactos/dll/directx/wine/d3d8/texture.c
reactos/dll/directx/wine/d3d8/vertexbuffer.c
reactos/dll/directx/wine/d3d8/vertexdeclaration.c
reactos/dll/directx/wine/d3d8/vertexshader.c
reactos/dll/directx/wine/d3d8/volume.c
reactos/dll/directx/wine/d3d8/volumetexture.c
reactos/dll/directx/wine/d3d9/cubetexture.c
reactos/dll/directx/wine/d3d9/d3d9_main.c
reactos/dll/directx/wine/d3d9/d3d9_private.h
reactos/dll/directx/wine/d3d9/device.c
reactos/dll/directx/wine/d3d9/directx.c
reactos/dll/directx/wine/d3d9/indexbuffer.c
reactos/dll/directx/wine/d3d9/pixelshader.c
reactos/dll/directx/wine/d3d9/query.c
reactos/dll/directx/wine/d3d9/stateblock.c
reactos/dll/directx/wine/d3d9/surface.c
reactos/dll/directx/wine/d3d9/swapchain.c
reactos/dll/directx/wine/d3d9/texture.c
reactos/dll/directx/wine/d3d9/vertexbuffer.c
reactos/dll/directx/wine/d3d9/vertexdeclaration.c
reactos/dll/directx/wine/d3d9/vertexshader.c
reactos/dll/directx/wine/d3d9/volume.c
reactos/dll/directx/wine/d3d9/volumetexture.c
reactos/dll/directx/wine/ddraw/ddraw.c
reactos/dll/directx/wine/ddraw/device.c
reactos/dll/directx/wine/ddraw/direct3d.c
reactos/dll/directx/wine/ddraw/executebuffer.c
reactos/dll/directx/wine/ddraw/light.c
reactos/dll/directx/wine/ddraw/parent.c
reactos/dll/directx/wine/ddraw/surface.c
reactos/dll/directx/wine/ddraw/utils.c
reactos/dll/directx/wine/ddraw/viewport.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/basetexture.c
reactos/dll/directx/wine/wined3d/buffer.c
reactos/dll/directx/wine/wined3d/context.c
reactos/dll/directx/wine/wined3d/cubetexture.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/gl_compat.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c
reactos/dll/directx/wine/wined3d/palette.c
reactos/dll/directx/wine/wined3d/pixelshader.c
reactos/dll/directx/wine/wined3d/query.c
reactos/dll/directx/wine/wined3d/resource.c
reactos/dll/directx/wine/wined3d/shader_sm1.c
reactos/dll/directx/wine/wined3d/shader_sm4.c
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/stateblock.c
reactos/dll/directx/wine/wined3d/surface.c
reactos/dll/directx/wine/wined3d/surface_base.c
reactos/dll/directx/wine/wined3d/surface_gdi.c
reactos/dll/directx/wine/wined3d/swapchain.c
reactos/dll/directx/wine/wined3d/texture.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/volume.c
reactos/dll/directx/wine/wined3d/volumetexture.c
reactos/dll/directx/wine/wined3d/wined3d.spec
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_main.c
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/include/reactos/wine/wined3d.idl

index 32511d6..d0b8f72 100644 (file)
@@ -57,9 +57,11 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 ifa
 
     if (ref == 0) {
         TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
 
     if (ref == 0) {
         TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
-        EnterCriticalSection(&d3d8_cs);
+
+        wined3d_mutex_lock();
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,14 +75,15 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetDevice(LPDIRECT3DCUBETEXTURE8
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -89,9 +92,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_SetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -100,9 +104,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -111,9 +116,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_FreePrivateData(LPDIRECT3DCUBETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -122,9 +128,10 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_SetPriority(LPDIRECT3DCUBETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -133,9 +140,10 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetPriority(LPDIRECT3DCUBETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret =  IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
     ret =  IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -143,9 +151,9 @@ static void WINAPI IDirect3DCubeTexture8Impl_PreLoad(LPDIRECT3DCUBETEXTURE8 ifac
     IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETEXTURE8 iface) {
@@ -153,9 +161,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETE
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     type = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
     type = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return type;
 }
 
     return type;
 }
 
@@ -165,9 +174,10 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_SetLOD(LPDIRECT3DCUBETEXTURE8 ifac
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     lod = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
     lod = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return lod;
 }
 
     return lod;
 }
 
@@ -176,9 +186,10 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLOD(LPDIRECT3DCUBETEXTURE8 ifac
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     lod = IWineD3DCubeTexture_GetLOD((LPDIRECT3DBASETEXTURE8) This);
     lod = IWineD3DCubeTexture_GetLOD((LPDIRECT3DBASETEXTURE8) This);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return lod;
 }
 
     return lod;
 }
 
@@ -187,9 +198,10 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLevelCount(LPDIRECT3DCUBETEXTUR
     DWORD cnt;
     TRACE("(%p) Relay\n", This);
 
     DWORD cnt;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     cnt = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
     cnt = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return cnt;
 }
 
     return cnt;
 }
 
@@ -201,22 +213,21 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetLevelDesc(LPDIRECT3DCUBETEXTU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &pDesc->Size;
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.MultiSampleQuality  = NULL; /* DirectX9 only */
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->Size = wined3ddesc.size;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -228,13 +239,14 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetCubeMapSurface(LPDIRECT3DCUBE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppCubeMapSurface) {
        IWineD3DCubeTexture_GetParent(mySurface, (IUnknown **)ppCubeMapSurface);
        IWineD3DCubeTexture_Release(mySurface);
     }
     hrc = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppCubeMapSurface) {
        IWineD3DCubeTexture_GetParent(mySurface, (IUnknown **)ppCubeMapSurface);
        IWineD3DCubeTexture_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -243,9 +255,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_LockRect(LPDIRECT3DCUBETEXTURE8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_LockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DCubeTexture_LockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -254,9 +267,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_UnlockRect(LPDIRECT3DCUBETEXTURE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -265,9 +279,10 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(LPDIRECT3DCUBETEXTU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
index 8e32dc3..6300371 100644 (file)
 #include "d3d8_private.h"
 #include "wine/debug.h"
 
 #include "d3d8_private.h"
 #include "wine/debug.h"
 
-static CRITICAL_SECTION_DEBUG d3d8_cs_debug =
-{
-    0, 0, &d3d8_cs,
-    { &d3d8_cs_debug.ProcessLocksList,
-      &d3d8_cs_debug.ProcessLocksList },
-    0, 0, { (DWORD_PTR)(__FILE__ ": d3d8_cs") }
-};
-CRITICAL_SECTION d3d8_cs = { &d3d8_cs_debug, -1, 0, 0, 0, 0 };
-
 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
 
 HRESULT WINAPI D3D8GetSWInfo(void) {
 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
 
 HRESULT WINAPI D3D8GetSWInfo(void) {
@@ -48,7 +39,8 @@ IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) {
     IDirect3D8Impl* object;
     TRACE("SDKVersion = %x\n", SDKVersion);
 
     IDirect3D8Impl* object;
     TRACE("SDKVersion = %x\n", SDKVersion);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
+
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl));
 
     object->lpVtbl = &Direct3D8_Vtbl;
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl));
 
     object->lpVtbl = &Direct3D8_Vtbl;
@@ -56,7 +48,8 @@ IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) {
     object->WineD3D = WineDirect3DCreate(8, (IUnknown *)object);
 
     TRACE("Created Direct3D object @ %p, WineObj @ %p\n", object, object->WineD3D);
     object->WineD3D = WineDirect3DCreate(8, (IUnknown *)object);
 
     TRACE("Created Direct3D object @ %p, WineObj @ %p\n", object, object->WineD3D);
-    LeaveCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_unlock();
 
     if (!object->WineD3D)
     {
 
     if (!object->WineD3D)
     {
@@ -77,14 +70,14 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
 }
 
 /***********************************************************************
 }
 
 /***********************************************************************
- *             ValidateVertexShader (D3D8.@)
+ *              ValidateVertexShader (D3D8.@)
  *
  * I've seen reserved1 and reserved2 always passed as 0's
  *
  * I've seen reserved1 and reserved2 always passed as 0's
- * bool seems always passed as 0 or 1, but other values work as well...
+ * bool seems always passed as 0 or 1, but other values work as well...
  * toto       result?
  */
 HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
  * toto       result?
  */
 HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
-{ 
+{
   HRESULT ret;
   FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
 
   HRESULT ret;
   FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
 
@@ -96,7 +89,7 @@ HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD
 
   switch(*vertexshader) {
         case 0xFFFE0101:
 
   switch(*vertexshader) {
         case 0xFFFE0101:
-        case 0xFFFE0100: 
+        case 0xFFFE0100:
             ret=S_OK;
             break;
         default:
             ret=S_OK;
             break;
         default:
@@ -108,7 +101,7 @@ HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD
 }
 
 /***********************************************************************
 }
 
 /***********************************************************************
- *             ValidatePixelShader (D3D8.@)
+ *              ValidatePixelShader (D3D8.@)
  *
  * PARAMS
  * toto       result?
  *
  * PARAMS
  * toto       result?
@@ -117,12 +110,12 @@ HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bo
 {
   HRESULT ret;
   FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
 {
   HRESULT ret;
   FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
-  
+
   if (!pixelshader)
       return E_FAIL;
 
   if (reserved1)
   if (!pixelshader)
       return E_FAIL;
 
   if (reserved1)
-      return E_FAIL;   
+      return E_FAIL;
 
   switch(*pixelshader) {
         case 0xFFFF0100:
 
   switch(*pixelshader) {
         case 0xFFFF0100:
index c38d8cc..52abb84 100644 (file)
@@ -97,6 +97,8 @@
     _pD3D8Caps->PixelShaderVersion                = _pWineCaps->PixelShaderVersion; \
     _pD3D8Caps->MaxPixelShaderValue               = _pWineCaps->PixelShader1xMaxValue;
 
     _pD3D8Caps->PixelShaderVersion                = _pWineCaps->PixelShaderVersion; \
     _pD3D8Caps->MaxPixelShaderValue               = _pWineCaps->PixelShader1xMaxValue;
 
+void fixup_caps(WINED3DCAPS *pWineCaps);
+
 /* Direct3D8 Interfaces: */
 typedef struct IDirect3DBaseTexture8Impl IDirect3DBaseTexture8Impl;
 typedef struct IDirect3DVolumeTexture8Impl IDirect3DVolumeTexture8Impl;
 /* Direct3D8 Interfaces: */
 typedef struct IDirect3DBaseTexture8Impl IDirect3DBaseTexture8Impl;
 typedef struct IDirect3DVolumeTexture8Impl IDirect3DVolumeTexture8Impl;
@@ -120,9 +122,6 @@ typedef struct IDirect3DVertexShaderDeclarationImpl IDirect3DVertexShaderDeclara
 /* Advance declaration of structures to satisfy compiler */
 typedef struct IDirect3DVertexShader8Impl IDirect3DVertexShader8Impl;
 
 /* Advance declaration of structures to satisfy compiler */
 typedef struct IDirect3DVertexShader8Impl IDirect3DVertexShader8Impl;
 
-/* Global critical section */
-extern CRITICAL_SECTION d3d8_cs;
-
 /* ===========================================================================
     The interfaces themselves
    =========================================================================== */
 /* ===========================================================================
     The interfaces themselves
    =========================================================================== */
@@ -166,10 +165,24 @@ extern const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl;
 #define D3D8_INITIAL_HANDLE_TABLE_SIZE 64
 #define D3D8_INVALID_HANDLE ~0U
 
 #define D3D8_INITIAL_HANDLE_TABLE_SIZE 64
 #define D3D8_INVALID_HANDLE ~0U
 
+enum d3d8_handle_type
+{
+    D3D8_HANDLE_FREE,
+    D3D8_HANDLE_VS,
+    D3D8_HANDLE_PS,
+    D3D8_HANDLE_SB,
+};
+
+struct d3d8_handle_entry
+{
+    void *object;
+    enum d3d8_handle_type type;
+};
+
 struct d3d8_handle_table
 {
 struct d3d8_handle_table
 {
-    void **entries;
-    void **free_entries;
+    struct d3d8_handle_entry *entries;
+    struct d3d8_handle_entry *free_entries;
     UINT table_size;
     UINT entry_count;
 };
     UINT table_size;
     UINT entry_count;
 };
@@ -455,7 +468,7 @@ struct IDirect3DVolumeTexture8Impl
 
 /* TODO: Generate a valid GUIDs */
 /* {83B073CE-6F30-11d9-C687-00046142C14F} */
 
 /* TODO: Generate a valid GUIDs */
 /* {83B073CE-6F30-11d9-C687-00046142C14F} */
-DEFINE_GUID(IID_IDirect3DStateBlock8, 
+DEFINE_GUID(IID_IDirect3DStateBlock8,
 0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
 
 DEFINE_GUID(IID_IDirect3DVertexDeclaration8,
 0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
 
 DEFINE_GUID(IID_IDirect3DVertexDeclaration8,
index 206697d..675eac1 100644 (file)
@@ -69,6 +69,7 @@ D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format)
         case WINED3DFMT_X8L8V8U8: return D3DFMT_X8L8V8U8;
         case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
         case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
         case WINED3DFMT_X8L8V8U8: return D3DFMT_X8L8V8U8;
         case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
         case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
+        case WINED3DFMT_W11V11U10: return D3DFMT_W11V11U10;
         case WINED3DFMT_A2W10V10U10: return D3DFMT_A2W10V10U10;
         case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
         case WINED3DFMT_D32: return D3DFMT_D32;
         case WINED3DFMT_A2W10V10U10: return D3DFMT_A2W10V10U10;
         case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
         case WINED3DFMT_D32: return D3DFMT_D32;
@@ -119,6 +120,7 @@ WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format)
         case D3DFMT_X8L8V8U8: return WINED3DFMT_X8L8V8U8;
         case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
         case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
         case D3DFMT_X8L8V8U8: return WINED3DFMT_X8L8V8U8;
         case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
         case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
+        case D3DFMT_W11V11U10: return WINED3DFMT_W11V11U10;
         case D3DFMT_A2W10V10U10: return WINED3DFMT_A2W10V10U10;
         case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
         case D3DFMT_D32: return WINED3DFMT_D32;
         case D3DFMT_A2W10V10U10: return WINED3DFMT_A2W10V10U10;
         case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
         case D3DFMT_D32: return WINED3DFMT_D32;
@@ -163,14 +165,23 @@ static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, U
 }
 
 /* Handle table functions */
 }
 
 /* Handle table functions */
-static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object)
+static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type)
 {
 {
+    struct d3d8_handle_entry *entry;
+
     if (t->free_entries)
     {
         /* Use a free handle */
     if (t->free_entries)
     {
         /* Use a free handle */
-        void **entry = t->free_entries;
-        t->free_entries = *entry;
-        *entry = object;
+        entry = t->free_entries;
+        if (entry->type != D3D8_HANDLE_FREE)
+        {
+            ERR("Handle %u(%p) is in the free list, but has type %#x.\n", (entry - t->entries), entry, entry->type);
+            return D3D8_INVALID_HANDLE;
+        }
+        t->free_entries = entry->object;
+        entry->object = object;
+        entry->type = type;
+
         return entry - t->entries;
     }
 
         return entry - t->entries;
     }
 
@@ -178,34 +189,68 @@ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object)
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
     {
         /* Grow the table */
         UINT new_size = t->table_size + (t->table_size >> 1);
-        void **new_entries = HeapReAlloc(GetProcessHeap(), 0, t->entries, new_size * sizeof(void *));
-        if (!new_entries) return D3D8_INVALID_HANDLE;
+        struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
+                0, t->entries, new_size * sizeof(*t->entries));
+        if (!new_entries)
+        {
+            ERR("Failed to grow the handle table.\n");
+            return D3D8_INVALID_HANDLE;
+        }
         t->entries = new_entries;
         t->table_size = new_size;
     }
 
         t->entries = new_entries;
         t->table_size = new_size;
     }
 
-    t->entries[t->entry_count] = object;
+    entry = &t->entries[t->entry_count];
+    entry->object = object;
+    entry->type = type;
+
     return t->entry_count++;
 }
 
     return t->entry_count++;
 }
 
-static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle)
+static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
 {
 {
-    void **entry, *object;
+    struct d3d8_handle_entry *entry;
+    void *object;
 
 
-    if (handle >= t->entry_count) return NULL;
+    if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
+    {
+        WARN("Invalid handle %u passed.\n", handle);
+        return NULL;
+    }
 
     entry = &t->entries[handle];
 
     entry = &t->entries[handle];
-    object = *entry;
-    *entry = t->free_entries;
+    if (entry->type != type)
+    {
+        WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
+        return NULL;
+    }
+
+    object = entry->object;
+    entry->object = t->free_entries;
+    entry->type = D3D8_HANDLE_FREE;
     t->free_entries = entry;
 
     return object;
 }
 
     t->free_entries = entry;
 
     return object;
 }
 
-static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle)
+static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
 {
 {
-    if (handle >= t->entry_count) return NULL;
-    return t->entries[handle];
+    struct d3d8_handle_entry *entry;
+
+    if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
+    {
+        WARN("Invalid handle %u passed.\n", handle);
+        return NULL;
+    }
+
+    entry = &t->entries[handle];
+    if (entry->type != type)
+    {
+        WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
+        return NULL;
+    }
+
+    return entry->object;
 }
 
 /* IDirect3D IUnknown parts follow: */
 }
 
 /* IDirect3D IUnknown parts follow: */
@@ -254,7 +299,9 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
         unsigned i;
 
         TRACE("Releasing wined3d device %p\n", This->WineD3DDevice);
         unsigned i;
 
         TRACE("Releasing wined3d device %p\n", This->WineD3DDevice);
-        EnterCriticalSection(&d3d8_cs);
+
+        wined3d_mutex_lock();
+
         This->inDestruction = TRUE;
 
         for(i = 0; i < This->numConvertedDecls; i++) {
         This->inDestruction = TRUE;
 
         for(i = 0; i < This->numConvertedDecls; i++) {
@@ -266,7 +313,8 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
         IWineD3DDevice_Release(This->WineD3DDevice);
         HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
         HeapFree(GetProcessHeap(), 0, This);
         IWineD3DDevice_Release(This->WineD3DDevice);
         HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
         HeapFree(GetProcessHeap(), 0, This);
-        LeaveCriticalSection(&d3d8_cs);
+
+        wined3d_mutex_unlock();
     }
     return ref;
 }
     }
     return ref;
 }
@@ -277,9 +325,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE
     HRESULT hr;
 
     TRACE("(%p) : Relay\n", This);
     HRESULT hr;
 
     TRACE("(%p) : Relay\n", This);
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -288,9 +338,11 @@ static UINT WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -299,9 +351,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3
     HRESULT hr;
 
     TRACE("(%p) : Relay bytes(%d)\n", This, Bytes);
     HRESULT hr;
 
     TRACE("(%p) : Relay bytes(%d)\n", This, Bytes);
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -316,7 +370,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface,
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
@@ -326,8 +380,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface,
         FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
         *ppD3D8 = NULL;
     }
         FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
         *ppD3D8 = NULL;
     }
+    wined3d_mutex_unlock();
+
     TRACE("(%p) returning %p\n",This , *ppD3D8);
     TRACE("(%p) returning %p\n",This , *ppD3D8);
-    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -346,21 +401,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
         return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
     }
 
         return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
+    fixup_caps(pWineCaps);
     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
-    /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
-    if(pCaps->PixelShaderVersion > D3DPS_VERSION(1,4)){
-        pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
-    }
-    if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
-        pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
-    }
-    pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
-
     TRACE("Returning %p %p\n", This, pCaps);
     return hrc;
 }
     TRACE("Returning %p %p\n", This, pCaps);
     return hrc;
 }
@@ -370,9 +418,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -384,9 +432,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVIC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -400,9 +449,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,pSurface->wineD3DSurface);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -410,9 +460,9 @@ static void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 ifac
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
 }
 
 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
@@ -420,9 +470,10 @@ static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -465,10 +516,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown *)object, SURFACE_OPENGL);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown *)object, SURFACE_OPENGL);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -520,9 +571,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRE
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -546,9 +597,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONS
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -559,13 +611,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, 0, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
     if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
         IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
         IWineD3DSurface_Release(retSurface);
     }
     rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, 0, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
     if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
         IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
         IWineD3DSurface_Release(retSurface);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return rc;
 }
 
     return rc;
 }
 
@@ -574,9 +627,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -585,9 +639,9 @@ static void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DW
     TRACE("(%p) Relay\n", This);
 
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
     TRACE("(%p) Relay\n", This);
 
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (CONST WINED3DGAMMARAMP *) pRamp);
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (CONST WINED3DGAMMARAMP *) pRamp);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
 }
 
 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
@@ -595,9 +649,9 @@ static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3
     TRACE("(%p) Relay\n", This);
 
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
     TRACE("(%p) Relay\n", This);
 
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
@@ -619,13 +673,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
 
     object->lpVtbl = &Direct3DTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DTexture8_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (FAILED(hrc)) {
 
     if (FAILED(hrc)) {
-        /* free up object */ 
+        /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
         HeapFree(GetProcessHeap(), 0, object);
 /*      *ppTexture = NULL; */
         FIXME("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
         HeapFree(GetProcessHeap(), 0, object);
 /*      *ppTexture = NULL; */
@@ -639,10 +694,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
    return hrc;
 }
 
    return hrc;
 }
 
-static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, 
-                                                          UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, 
-                                                          D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) {
-
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(IDirect3DDevice8 *iface,
+        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format,
+        D3DPOOL Pool, IDirect3DVolumeTexture8 **ppVolumeTexture)
+{
     IDirect3DVolumeTexture8Impl *object;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVolumeTexture8Impl *object;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc = D3D_OK;
@@ -659,11 +714,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8
 
     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
             Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
             Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
             Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
             Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (hrc != D3D_OK) {
 
 
     if (hrc != D3D_OK) {
 
@@ -680,9 +736,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8
     return hrc;
 }
 
     return hrc;
 }
 
-static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, 
-                                                        D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
-
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(IDirect3DDevice8 *iface, UINT EdgeLength,
+        UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8 **ppCubeTexture)
+{
     IDirect3DCubeTexture8Impl *object;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr = D3D_OK;
     IDirect3DCubeTexture8Impl *object;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr = D3D_OK;
@@ -700,10 +756,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 i
 
     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (hr != D3D_OK){
 
 
     if (hr != D3D_OK){
 
@@ -737,10 +794,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8
 
     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
             0 /* fvf for ddraw only */, (WINED3DPOOL)Pool, &object->wineD3DVertexBuffer, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
             0 /* fvf for ddraw only */, (WINED3DPOOL)Pool, &object->wineD3DVertexBuffer, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     object->fvf = FVF;
 
     if (D3D_OK != hrc) {
     object->fvf = FVF;
 
     if (D3D_OK != hrc) {
@@ -775,10 +834,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i
     object->ref = 1;
     object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
     object->ref = 1;
     object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
             (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
             (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (D3D_OK != hrc) {
 
 
     if (D3D_OK != hrc) {
 
@@ -794,7 +854,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i
     return hrc;
 }
 
     return hrc;
 }
 
-static HRESULT IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)  {
+static HRESULT IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height,
+        D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,
+        UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)
+{
     HRESULT hrc;
     IDirect3DSurface8Impl *object;
     IDirect3DDevice8Impl  *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc;
     IDirect3DSurface8Impl *object;
     IDirect3DDevice8Impl  *This = (IDirect3DDevice8Impl *)iface;
@@ -823,11 +886,12 @@ static HRESULT IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
-            Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
-            (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
-    LeaveCriticalSection(&d3d8_cs);
+            Lockable, Discard, Level, &object->wineD3DSurface, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
+            MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
+    wined3d_mutex_unlock();
+
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
        /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
        /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
@@ -845,7 +909,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8
     HRESULT hr;
     TRACE("Relay\n");
 
     HRESULT hr;
     TRACE("Relay\n");
 
-    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
+    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */,
+            0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
+
     return hr;
 }
 
     return hr;
 }
 
@@ -854,9 +920,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DD
     TRACE("Relay\n");
 
     /* TODO: Verify that Discard is false */
     TRACE("Relay\n");
 
     /* TODO: Verify that Discard is false */
-    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
-                                               ,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
-                                                D3DPOOL_DEFAULT, MultiSample, 0);
+    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE,
+            0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, 0);
+
     return hr;
 }
 
     return hr;
 }
 
@@ -865,8 +931,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8
     HRESULT hr;
     TRACE("Relay\n");
 
     HRESULT hr;
     TRACE("Relay\n");
 
-    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface,
-                                            D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
+            0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE,
+            0 /* MultisampleQuality */);
+
     return hr;
 }
 
     return hr;
 }
 
@@ -886,25 +954,23 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, ID
 
 
     /* Check that the source texture is in WINED3DPOOL_SYSTEMMEM and the destination texture is in WINED3DPOOL_DEFAULT */
 
 
     /* Check that the source texture is in WINED3DPOOL_SYSTEMMEM and the destination texture is in WINED3DPOOL_DEFAULT */
-    memset(&winedesc, 0, sizeof(winedesc));
 
 
-    winedesc.Format = &srcFormat;
-    winedesc.Width  = &srcWidth;
-    winedesc.Height = &srcHeight;
-    winedesc.Size   = &srcSize;
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DSurface_GetDesc(Source->wineD3DSurface, &winedesc);
     IWineD3DSurface_GetDesc(Source->wineD3DSurface, &winedesc);
+    srcFormat = winedesc.format;
+    srcWidth = winedesc.width;
+    srcHeight = winedesc.height;
+    srcSize = winedesc.size;
 
 
-    winedesc.Format = &destFormat;
-    winedesc.Width  = &destWidth;
-    winedesc.Height = &destHeight;
-    winedesc.Size   = NULL;
     IWineD3DSurface_GetDesc(Dest->wineD3DSurface, &winedesc);
     IWineD3DSurface_GetDesc(Dest->wineD3DSurface, &winedesc);
+    destFormat = winedesc.format;
+    destWidth = winedesc.width;
+    destHeight = winedesc.height;
 
     /* Check that the source and destination formats match */
     if (srcFormat != destFormat && WINED3DFMT_UNKNOWN != destFormat) {
         WARN("(%p) source %p format must match the dest %p format, returning WINED3DERR_INVALIDCALL\n", iface, pSourceSurface, pDestinationSurface);
 
     /* Check that the source and destination formats match */
     if (srcFormat != destFormat && WINED3DFMT_UNKNOWN != destFormat) {
         WARN("(%p) source %p format must match the dest %p format, returning WINED3DERR_INVALIDCALL\n", iface, pSourceSurface, pDestinationSurface);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return WINED3DERR_INVALIDCALL;
     } else if (WINED3DFMT_UNKNOWN == destFormat) {
         TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", iface);
         return WINED3DERR_INVALIDCALL;
     } else if (WINED3DFMT_UNKNOWN == destFormat) {
         TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", iface);
@@ -928,7 +994,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, ID
             }
         }
     }
             }
         }
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -938,9 +1004,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -956,9 +1023,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -970,7 +1038,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice, &original_ds);
     if (hr == WINED3D_OK || hr == WINED3DERR_NOTFOUND)
 
     hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice, &original_ds);
     if (hr == WINED3D_OK || hr == WINED3DERR_NOTFOUND)
@@ -982,7 +1050,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 ifa
     }
     if (original_ds) IWineD3DSurface_Release(original_ds);
 
     }
     if (original_ds) IWineD3DSurface_Release(original_ds);
 
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -996,7 +1065,8 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 i
     if (ppRenderTarget == NULL) {
         return D3DERR_INVALIDCALL;
     }
     if (ppRenderTarget == NULL) {
         return D3DERR_INVALIDCALL;
     }
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetRenderTarget(This->WineD3DDevice, 0, &pRenderTarget);
 
     if (hr == D3D_OK && pRenderTarget != NULL) {
     hr = IWineD3DDevice_GetRenderTarget(This->WineD3DDevice, 0, &pRenderTarget);
 
     if (hr == D3D_OK && pRenderTarget != NULL) {
@@ -1006,7 +1076,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 i
         FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
         *ppRenderTarget = NULL;
     }
         FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
         *ppRenderTarget = NULL;
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -1021,7 +1091,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDE
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
     if (hr == WINED3D_OK) {
         IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
     hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
     if (hr == WINED3D_OK) {
         IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
@@ -1031,7 +1101,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDE
                 FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
         *ppZStencilSurface = NULL;
     }
                 FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
         *ppZStencilSurface = NULL;
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -1041,9 +1111,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1052,9 +1123,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1064,9 +1136,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DRECT is compatible with WINED3DRECT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DRECT is compatible with WINED3DRECT */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
     hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1076,9 +1149,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1088,9 +1162,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1100,9 +1175,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 i
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1112,9 +1188,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1124,9 +1201,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT8 is compatible with WINED3DVIEWPORT */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1136,9 +1214,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1148,9 +1227,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL8 is compatible with WINED3DMATERIAL */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1158,11 +1238,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWO
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
+
     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1172,9 +1253,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWO
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT8 is compatible with WINED3DLIGHT */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1183,9 +1265,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1194,9 +1277,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1205,9 +1289,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1216,9 +1301,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1227,9 +1313,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1238,9 +1325,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1249,9 +1337,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1266,11 +1355,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
     /* Tell wineD3D to endstateblock before anything else (in case we run out
      * of memory later and cause locking problems)
      */
     /* Tell wineD3D to endstateblock before anything else (in case we run out
      * of memory later and cause locking problems)
      */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice , &wineD3DStateBlock);
     if (hr != D3D_OK) {
         WARN("IWineD3DDevice_EndStateBlock returned an error\n");
     hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice , &wineD3DStateBlock);
     if (hr != D3D_OK) {
         WARN("IWineD3DDevice_EndStateBlock returned an error\n");
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return hr;
     }
 
         return hr;
     }
 
@@ -1281,8 +1370,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
 
     object->wineD3DStateBlock = wineD3DStateBlock;
 
 
     object->wineD3DStateBlock = wineD3DStateBlock;
 
-    *pToken = d3d8_allocate_handle(&This->handle_table, object);
-    LeaveCriticalSection(&d3d8_cs);
+    *pToken = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_SB);
+    wined3d_mutex_unlock();
 
     if (*pToken == D3D8_INVALID_HANDLE)
     {
 
     if (*pToken == D3D8_INVALID_HANDLE)
     {
@@ -1304,16 +1393,17 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 ifa
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
-    EnterCriticalSection(&d3d8_cs);
-    pSB = d3d8_get_object(&This->handle_table, Token - 1);
+    wined3d_mutex_lock();
+    pSB = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1324,16 +1414,17 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 i
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
-    EnterCriticalSection(&d3d8_cs);
-    pSB = d3d8_get_object(&This->handle_table, Token - 1);
+    wined3d_mutex_lock();
+    pSB = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1343,9 +1434,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 if
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-    pSB = d3d8_free_handle(&This->handle_table, Token - 1);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
+    pSB = d3d8_free_handle(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
+    wined3d_mutex_unlock();
 
     if (!pSB)
     {
 
     if (!pSB)
     {
@@ -1388,19 +1479,19 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(IDirect3DDevice8 *if
     object->lpVtbl = &Direct3DStateBlock8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DStateBlock8_Vtbl;
     object->ref = 1;
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type,
             &object->wineD3DStateBlock, (IUnknown *)object);
     if (FAILED(hr))
     {
     hr = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type,
             &object->wineD3DStateBlock, (IUnknown *)object);
     if (FAILED(hr))
     {
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         return hr;
     }
 
         ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         return hr;
     }
 
-    *handle = d3d8_allocate_handle(&This->handle_table, object);
-    LeaveCriticalSection(&d3d8_cs);
+    *handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_SB);
+    wined3d_mutex_unlock();
 
     if (*handle == D3D8_INVALID_HANDLE)
     {
 
     if (*handle == D3D8_INVALID_HANDLE)
     {
@@ -1420,9 +1511,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 /* FIXME: Verify that D3DCLIPSTATUS8 ~= WINED3DCLIPSTATUS */
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 /* FIXME: Verify that D3DCLIPSTATUS8 ~= WINED3DCLIPSTATUS */
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1431,9 +1524,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1448,7 +1542,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, D
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
     if (rc == D3D_OK && NULL != retTexture) {
         IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
     rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
     if (rc == D3D_OK && NULL != retTexture) {
         IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
@@ -1457,7 +1551,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, D
         FIXME("Call to get texture  (%d) failed (%p)\n", Stage, retTexture);
         *ppTexture = NULL;
     }
         FIXME("Call to get texture  (%d) failed (%p)\n", Stage, retTexture);
         *ppTexture = NULL;
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return rc;
 }
 
     return rc;
 }
@@ -1467,10 +1561,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, D
     HRESULT hr;
     TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
 
     HRESULT hr;
     TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1518,12 +1613,11 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
-
+    wined3d_mutex_lock();
     if (l->sampler_state) hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Stage, l->state, pValue);
     else hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, l->state, pValue);
     if (l->sampler_state) hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Stage, l->state, pValue);
     else hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, l->state, pValue);
+    wined3d_mutex_unlock();
 
 
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1533,12 +1627,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
-
+    wined3d_mutex_lock();
     if (l->sampler_state) hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Stage, l->state, Value);
     else hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, l->state, Value);
     if (l->sampler_state) hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Stage, l->state, Value);
     else hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, l->state, Value);
+    wined3d_mutex_unlock();
 
 
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1547,9 +1640,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1564,9 +1658,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1575,9 +1670,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1586,9 +1682,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1597,22 +1694,26 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
-    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; 
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(IDirect3DDevice8 *iface, D3DPRIMITIVETYPE PrimitiveType,
+        UINT StartVertex, UINT PrimitiveCount)
+{
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1622,11 +1723,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
             startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
             startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1635,12 +1737,13 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
             pVertexStreamZeroData, VertexStreamZeroStride);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
             pVertexStreamZeroData, VertexStreamZeroStride);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1652,12 +1755,13 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1667,9 +1771,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 ifa
     IDirect3DVertexBuffer8Impl *dest = (IDirect3DVertexBuffer8Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
     IDirect3DVertexBuffer8Impl *dest = (IDirect3DVertexBuffer8Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, NULL, Flags, dest->fvf);
     hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, NULL, Flags, dest->fvf);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1704,10 +1809,11 @@ static HRESULT IDirect3DDevice8Impl_CreateVertexDeclaration(IDirect3DDevice8 *if
 
     CopyMemory(object->elements, declaration, object->elements_size);
 
 
     CopyMemory(object->elements, declaration, object->elements_size);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wined3d_vertex_declaration,
             (IUnknown *)object, wined3d_elements, wined3d_element_count);
     hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wined3d_vertex_declaration,
             (IUnknown *)object, wined3d_elements, wined3d_element_count);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
     if (FAILED(hr)) {
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
     if (FAILED(hr)) {
@@ -1726,7 +1832,6 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVertexShader8Impl *object;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVertexShader8Impl *object;
-    IWineD3DVertexDeclaration *wined3d_vertex_declaration;
     const DWORD *token = pDeclaration;
     DWORD handle;
 
     const DWORD *token = pDeclaration;
     DWORD handle;
 
@@ -1766,12 +1871,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
-    handle = d3d8_allocate_handle(&This->handle_table, object);
+    wined3d_mutex_lock();
+    handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_VS);
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
         HeapFree(GetProcessHeap(), 0, object);
         *ppShader = 0;
         IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
         HeapFree(GetProcessHeap(), 0, object);
         *ppShader = 0;
@@ -1783,19 +1888,17 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->shader_handle = shader_handle;
     }
 
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->shader_handle = shader_handle;
     }
 
-    wined3d_vertex_declaration = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->wined3d_vertex_declaration;
-
     if (pFunction)
     {
         /* Usage is missing ... Use SetRenderState to set the sw vp render state in SetVertexShader */
     if (pFunction)
     {
         /* Usage is missing ... Use SetRenderState to set the sw vp render state in SetVertexShader */
-        hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration,
-                pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
+        hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pFunction,
+                NULL /* output signature */, &object->wineD3DVertexShader, (IUnknown *)object);
 
         if (FAILED(hrc))
         {
             /* free up object */
             FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
 
         if (FAILED(hrc))
         {
             /* free up object */
             FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
-            d3d8_free_handle(&This->handle_table, handle);
+            d3d8_free_handle(&This->handle_table, handle, D3D8_HANDLE_VS);
             IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
             HeapFree(GetProcessHeap(), 0, object);
             *ppShader = 0;
             IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
             HeapFree(GetProcessHeap(), 0, object);
             *ppShader = 0;
@@ -1807,7 +1910,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         }
     }
 
         }
     }
 
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hrc;
 }
 
     return hrc;
 }
@@ -1891,29 +1994,31 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 ifa
     if (VS_HIGHESTFIXEDFXF >= pShader) {
         TRACE("Setting FVF, %#x\n", pShader);
 
     if (VS_HIGHESTFIXEDFXF >= pShader) {
         TRACE("Setting FVF, %#x\n", pShader);
 
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
                 IDirect3DDevice8Impl_FindDecl(This, pShader)->wined3d_vertex_declaration);
         IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
         IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
                 IDirect3DDevice8Impl_FindDecl(This, pShader)->wined3d_vertex_declaration);
         IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return D3D_OK;
     }
 
     TRACE("Setting shader\n");
 
         return D3D_OK;
     }
 
     TRACE("Setting shader\n");
 
-    EnterCriticalSection(&d3d8_cs);
-    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    wined3d_mutex_lock();
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
             ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
     if (SUCCEEDED(hr)) hr = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, shader->wineD3DVertexShader);
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
             ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
     if (SUCCEEDED(hr)) hr = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, shader->wineD3DVertexShader);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     TRACE("Returning hr %#x\n", hr);
 
 
     TRACE("Returning hr %#x\n", hr);
 
@@ -1927,12 +2032,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 ifa
     HRESULT hrc;
 
     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
     HRESULT hrc;
 
     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
-    EnterCriticalSection(&d3d8_cs);
 
 
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &wined3d_declaration);
     if (FAILED(hrc))
     {
     hrc = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &wined3d_declaration);
     if (FAILED(hrc))
     {
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         WARN("(%p) : Call to IWineD3DDevice_GetVertexDeclaration failed %#x (device %p)\n",
                 This, hrc, This->WineD3DDevice);
         return hrc;
         WARN("(%p) : Call to IWineD3DDevice_GetVertexDeclaration failed %#x (device %p)\n",
                 This, hrc, This->WineD3DDevice);
         return hrc;
@@ -1940,14 +2045,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 ifa
 
     if (!wined3d_declaration)
     {
 
     if (!wined3d_declaration)
     {
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         *ppShader = 0;
         return D3D_OK;
     }
 
     hrc = IWineD3DVertexDeclaration_GetParent(wined3d_declaration, (IUnknown **)&d3d8_declaration);
     IWineD3DVertexDeclaration_Release(wined3d_declaration);
         *ppShader = 0;
         return D3D_OK;
     }
 
     hrc = IWineD3DVertexDeclaration_GetParent(wined3d_declaration, (IUnknown **)&d3d8_declaration);
     IWineD3DVertexDeclaration_Release(wined3d_declaration);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
     if (SUCCEEDED(hrc))
     {
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
     if (SUCCEEDED(hrc))
     {
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
@@ -1966,13 +2071,13 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    EnterCriticalSection(&d3d8_cs);
-
-    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    wined3d_mutex_lock();
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
@@ -1984,7 +2089,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE
         IWineD3DVertexShader_Release(cur);
     }
 
         IWineD3DVertexShader_Release(cur);
     }
 
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (IUnknown_Release((IUnknown *)shader))
     {
 
     if (IUnknown_Release((IUnknown *)shader))
     {
@@ -2005,9 +2110,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2022,9 +2128,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2035,10 +2142,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3D
 
     TRACE("(%p) : pVertexShader 0x%08x, pData %p, *pSizeOfData %u\n", This, pVertexShader, pData, *pSizeOfData);
 
 
     TRACE("(%p) : pVertexShader 0x%08x, pData %p, *pSizeOfData %u\n", This, pVertexShader, pData, *pSizeOfData);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
+    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
+    wined3d_mutex_unlock();
 
 
-    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1));
-    LeaveCriticalSection(&d3d8_cs);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
@@ -2071,26 +2178,26 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEV
 
     TRACE("(%p) : pVertexShader %#x, pData %p, pSizeOfData %p\n", This, pVertexShader, pData, pSizeOfData);
 
 
     TRACE("(%p) : pVertexShader %#x, pData %p, pSizeOfData %p\n", This, pVertexShader, pData, pSizeOfData);
 
-    EnterCriticalSection(&d3d8_cs);
-
-    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1));
+    wined3d_mutex_lock();
+    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return D3DERR_INVALIDCALL;
     }
 
     if (!shader->wineD3DVertexShader)
     {
         return D3DERR_INVALIDCALL;
     }
 
     if (!shader->wineD3DVertexShader)
     {
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         *pSizeOfData = 0;
         return D3D_OK;
     }
 
     hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
         *pSizeOfData = 0;
         return D3D_OK;
     }
 
     hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
+    wined3d_mutex_unlock();
 
 
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2100,18 +2207,19 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, I
     IDirect3DIndexBuffer8Impl *ib = (IDirect3DIndexBuffer8Impl *)pIndexData;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DIndexBuffer8Impl *ib = (IDirect3DIndexBuffer8Impl *)pIndexData;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
     /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
      * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
      * vertex buffers can't be created to address them with an index that requires the 32nd bit
      * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
      * problem)
      */
     /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
      * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
      * vertex buffers can't be created to address them with an index that requires the 32nd bit
      * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
      * problem)
      */
+    wined3d_mutex_lock();
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex);
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
             ib ? ib->wineD3DIndexBuffer : NULL,
             ib ? ib->format : WINED3DFMT_UNKNOWN);
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex);
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
             ib ? ib->wineD3DIndexBuffer : NULL,
             ib ? ib->format : WINED3DFMT_UNKNOWN);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2126,8 +2234,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
     /* The case from UINT to INT is safe because d3d8 will never set negative values */
     /* The case from UINT to INT is safe because d3d8 will never set negative values */
+    wined3d_mutex_lock();
     IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex);
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
     IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex);
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
@@ -2137,7 +2245,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
     }
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return rc;
 }
 
     return rc;
 }
@@ -2164,20 +2272,21 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader8_Vtbl;
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader8_Vtbl;
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
             NULL, &object->wineD3DPixelShader, (IUnknown *)object);
     if (FAILED(hr))
     {
     hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
             NULL, &object->wineD3DPixelShader, (IUnknown *)object);
     if (FAILED(hr))
     {
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
         HeapFree(GetProcessHeap(), 0 , object);
         *ppShader = 0;
         return hr;
     }
 
         FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
         HeapFree(GetProcessHeap(), 0 , object);
         *ppShader = 0;
         return hr;
     }
 
-    handle = d3d8_allocate_handle(&This->handle_table, object);
-    LeaveCriticalSection(&d3d8_cs);
+    handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_PS);
+    wined3d_mutex_unlock();
+
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
@@ -2198,26 +2307,27 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 ifac
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
 
     if (!pShader)
     {
         hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, NULL);
 
     if (!pShader)
     {
         hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, NULL);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return hr;
     }
 
         return hr;
     }
 
-    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
 
     TRACE("(%p) : Setting shader %p\n", This, shader);
     hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader->wineD3DPixelShader);
         return D3DERR_INVALIDCALL;
     }
 
     TRACE("(%p) : Setting shader %p\n", This, shader);
     hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader->wineD3DPixelShader);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2232,7 +2342,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (D3D_OK == hrc && NULL != object) {
         IDirect3DPixelShader8Impl *d3d8_shader;
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (D3D_OK == hrc && NULL != object) {
         IDirect3DPixelShader8Impl *d3d8_shader;
@@ -2243,9 +2353,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 ifac
     } else {
         *ppShader = 0;
     }
     } else {
         *ppShader = 0;
     }
+    wined3d_mutex_unlock();
 
     TRACE("(%p) : returning %#x\n", This, *ppShader);
 
     TRACE("(%p) : returning %#x\n", This, *ppShader);
-    LeaveCriticalSection(&d3d8_cs);
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -2256,14 +2367,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 i
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
 
 
-    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        LeaveCriticalSection(&d3d8_cs);
-        return D3DERR_INVALIDCALL;
+        wined3d_mutex_unlock();
+        return D3D_OK;
     }
 
     IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
     }
 
     IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
@@ -2274,7 +2385,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 i
         IWineD3DPixelShader_Release(cur);
     }
 
         IWineD3DPixelShader_Release(cur);
     }
 
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (IUnknown_Release((IUnknown *)shader))
     {
 
     if (IUnknown_Release((IUnknown *)shader))
     {
@@ -2289,9 +2400,10 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2300,9 +2412,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2313,17 +2426,19 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVI
 
     TRACE("(%p) : pPixelShader %#x, pData %p, pSizeOfData %p\n", This, pPixelShader, pData, pSizeOfData);
 
 
     TRACE("(%p) : pPixelShader %#x, pData %p, pSizeOfData %p\n", This, pPixelShader, pData, pSizeOfData);
 
-    EnterCriticalSection(&d3d8_cs);
-    shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1));
+    wined3d_mutex_lock();
+    shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pPixelShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pPixelShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2332,9 +2447,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2343,9 +2459,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2354,9 +2471,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2365,11 +2483,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
                                         NULL == pStreamData ? NULL : ((IDirect3DVertexBuffer8Impl *)pStreamData)->wineD3DVertexBuffer,
                                         0/* Offset in bytes */, Stride);
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
                                         NULL == pStreamData ? NULL : ((IDirect3DVertexBuffer8Impl *)pStreamData)->wineD3DVertexBuffer,
                                         0/* Offset in bytes */, Stride);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -2384,7 +2503,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
         IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
         IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
@@ -2395,7 +2514,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa
         }
         *pStream = NULL;
     }
         }
         *pStream = NULL;
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return rc;
 }
 
     return rc;
 }
@@ -2564,8 +2683,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
 
     hr = IDirect3DDevice8Impl_CreateSurface((IDirect3DDevice8 *)This, width, height,
             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
 
     hr = IDirect3DDevice8Impl_CreateSurface((IDirect3DDevice8 *)This, width, height,
             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
-            (IDirect3DSurface8 **)&d3d_surface, D3DRTYPE_SURFACE, usage, pool,
-            D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+            (IDirect3DSurface8 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
index d39d3d6..3368794 100644 (file)
@@ -71,9 +71,11 @@ static ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) {
 
     if (ref == 0) {
         TRACE("Releasing wined3d %p\n", This->WineD3D);
 
     if (ref == 0) {
         TRACE("Releasing wined3d %p\n", This->WineD3D);
-        EnterCriticalSection(&d3d8_cs);
+
+        wined3d_mutex_lock();
         IWineD3D_Release(This->WineD3D);
         IWineD3D_Release(This->WineD3D);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -86,9 +88,10 @@ static HRESULT WINAPI IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -97,36 +100,41 @@ static UINT WINAPI IDirect3D8Impl_GetAdapterCount (LPDIRECT3D8 iface) {
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3D8Impl_GetAdapterIdentifier       (LPDIRECT3D8 iface,
-                                                            UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8* pIdentifier) {
+static HRESULT WINAPI IDirect3D8Impl_GetAdapterIdentifier(LPDIRECT3D8 iface,
+        UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8 *pIdentifier)
+{
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
     TRACE("(%p)->(%d,%08x, %p\n", This, Adapter, Flags, pIdentifier);
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
     TRACE("(%p)->(%d,%08x, %p\n", This, Adapter, Flags, pIdentifier);
-    EnterCriticalSection(&d3d8_cs);
-    /* dx8 and dx9 have different structures to be filled in, with incompatible 
-       layouts so pass in pointers to the places to be filled via an internal 
-       structure                                                                */
-    adapter_id.Driver           = pIdentifier->Driver;
-    adapter_id.Description      = pIdentifier->Description;
-    adapter_id.DeviceName       = NULL; /* d3d9 only */
-    adapter_id.DriverVersion    = &pIdentifier->DriverVersion;
-    adapter_id.VendorId         = &pIdentifier->VendorId;
-    adapter_id.DeviceId         = &pIdentifier->DeviceId;
-    adapter_id.SubSysId         = &pIdentifier->SubSysId;
-    adapter_id.Revision         = &pIdentifier->Revision;
-    adapter_id.DeviceIdentifier = &pIdentifier->DeviceIdentifier;
-    adapter_id.WHQLLevel        = &pIdentifier->WHQLLevel;
 
 
+    adapter_id.driver = pIdentifier->Driver;
+    adapter_id.driver_size = sizeof(pIdentifier->Driver);
+    adapter_id.description = pIdentifier->Description;
+    adapter_id.description_size = sizeof(pIdentifier->Description);
+    adapter_id.device_name = NULL; /* d3d9 only */
+    adapter_id.device_name_size = 0; /* d3d9 only */
+
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
+    pIdentifier->DriverVersion = adapter_id.driver_version;
+    pIdentifier->VendorId = adapter_id.vendor_id;
+    pIdentifier->DeviceId = adapter_id.device_id;
+    pIdentifier->SubSysId = adapter_id.subsystem_id;
+    pIdentifier->Revision = adapter_id.revision;
+    memcpy(&pIdentifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(pIdentifier->DeviceIdentifier));
+    pIdentifier->WHQLLevel = adapter_id.whql_level;
+
     return hr;
 }
 
     return hr;
 }
 
@@ -135,9 +143,10 @@ static UINT WINAPI IDirect3D8Impl_GetAdapterModeCount (LPDIRECT3D8 iface,UINT Ad
     HRESULT hr;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
     HRESULT hr;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -146,9 +155,9 @@ static HRESULT WINAPI IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface, UINT A
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %p)\n", This, Adapter, Mode, pMode);
 
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %p)\n", This, Adapter, Mode, pMode);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -160,9 +169,9 @@ static HRESULT WINAPI IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface, U
     HRESULT hr;
     TRACE("(%p)->(%d,%p)\n", This, Adapter, pMode);
 
     HRESULT hr;
     TRACE("(%p)->(%d,%p)\n", This, Adapter, pMode);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -176,10 +185,11 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceType            (LPDIRECT3D8 i
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %d, %d, %s)\n", This, Adapter, CheckType, DisplayFormat, BackBufferFormat, Windowed ? "true" : "false");
 
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %d, %d, %s)\n", This, Adapter, CheckType, DisplayFormat, BackBufferFormat, Windowed ? "true" : "false");
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
             wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
     hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
             wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -191,6 +201,14 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 i
     WINED3DRESOURCETYPE WineD3DRType;
     TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
 
     WINED3DRESOURCETYPE WineD3DRType;
     TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
 
+    if(CheckFormat == D3DFMT_R8G8B8)
+    {
+        /* See comment in dlls/d3d9/directx.c, IDirect3D9Impl_CheckDeviceFormat for details */
+        WARN("D3DFMT_R8G8B8 is not available on windows, returning D3DERR_NOTAVAILABLE\n");
+        return D3DERR_NOTAVAILABLE;
+    }
+
+
     switch(RType) {
         case D3DRTYPE_VERTEXBUFFER:
         case D3DRTYPE_INDEXBUFFER:
     switch(RType) {
         case D3DRTYPE_VERTEXBUFFER:
         case D3DRTYPE_INDEXBUFFER:
@@ -202,42 +220,59 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 i
             break;
     }
 
             break;
     }
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
             Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
             Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 iface,
-                                                          UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
-                                                          BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType) {
+static HRESULT WINAPI IDirect3D8Impl_CheckDeviceMultiSampleType(IDirect3D8 *iface, UINT Adapter,
+        D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType)
+{
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hr;
     TRACE("(%p)-<(%d, %d, %d, %s, %d)\n", This, Adapter, DeviceType, SurfaceFormat, Windowed ? "true" : "false", MultiSampleType);
 
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hr;
     TRACE("(%p)-<(%d, %d, %d, %s, %d)\n", This, Adapter, DeviceType, SurfaceFormat, Windowed ? "true" : "false", MultiSampleType);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SurfaceFormat), Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
     hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SurfaceFormat), Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface, 
-                                                      UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
-                                                      D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
+static HRESULT WINAPI IDirect3D8Impl_CheckDepthStencilMatch(IDirect3D8 *iface, UINT Adapter, D3DDEVTYPE DeviceType,
+        D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
+{
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hr;
     TRACE("(%p)-<(%d, %d, %d, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
 
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hr;
     TRACE("(%p)-<(%d, %d, %d, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
             wined3dformat_from_d3dformat(DepthStencilFormat));
     hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
             wined3dformat_from_d3dformat(DepthStencilFormat));
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
+void fixup_caps(WINED3DCAPS *caps)
+{
+    /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
+    if (caps->PixelShaderVersion > D3DPS_VERSION(1,4)) {
+        caps->PixelShaderVersion = D3DPS_VERSION(1,4);
+    }
+    if (caps->VertexShaderVersion > D3DVS_VERSION(1,1)) {
+        caps->VertexShaderVersion = D3DVS_VERSION(1,1);
+    }
+    caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
+
+    caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
+}
+
 static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) {
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hrc = D3D_OK;
 static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) {
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hrc = D3D_OK;
@@ -252,21 +287,15 @@ static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Ada
     if(pWineCaps == NULL){
         return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
     }
     if(pWineCaps == NULL){
         return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
     }
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
+    fixup_caps(pWineCaps);
     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
-    /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
-    if(pCaps->PixelShaderVersion > D3DPS_VERSION(1,4)){
-        pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
-    }
-    if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
-        pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
-    }
-    pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
-
     TRACE("(%p) returning %p\n", This, pCaps);
     return hrc;
 }
     TRACE("(%p) returning %p\n", This, pCaps);
     return hrc;
 }
@@ -276,9 +305,10 @@ static HMONITOR WINAPI  IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT
     HMONITOR ret;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
     HMONITOR ret;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -344,14 +374,15 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     *ppReturnedDeviceInterface = (IDirect3DDevice8 *)object;
 
     /* Allocate an associated WineD3DDevice object */
     *ppReturnedDeviceInterface = (IDirect3DDevice8 *)object;
 
     /* Allocate an associated WineD3DDevice object */
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags,
             (IUnknown *)object, (IWineD3DDeviceParent *)&object->device_parent_vtbl, &object->WineD3DDevice);
 
     if (hr != D3D_OK) {
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
     hr = IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags,
             (IUnknown *)object, (IWineD3DDeviceParent *)&object->device_parent_vtbl, &object->WineD3DDevice);
 
     if (hr != D3D_OK) {
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         return hr;
     }
 
         return hr;
     }
 
@@ -378,7 +409,7 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     }
 
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
     }
 
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -404,9 +435,11 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls));
     if(!object->decls) {
         ERR("Out of memory\n");
     object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls));
     if(!object->decls) {
         ERR("Out of memory\n");
-        EnterCriticalSection(&d3d8_cs);
+
+        wined3d_mutex_lock();
         IWineD3DDevice_Release(object->WineD3DDevice);
         IWineD3DDevice_Release(object->WineD3DDevice);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
         hr = E_OUTOFMEMORY;
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
         hr = E_OUTOFMEMORY;
index a0de5c5..b59b1ab 100644 (file)
@@ -56,9 +56,10 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 ifa
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -72,14 +73,15 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -88,9 +90,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -99,9 +102,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -110,9 +114,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXB
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -121,9 +126,10 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -132,9 +138,10 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -142,9 +149,9 @@ static void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 ifac
     IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
@@ -160,9 +167,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -171,9 +179,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -183,9 +192,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 i
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
index ae8d15f..2f0fb1c 100644 (file)
@@ -56,9 +56,10 @@ static ULONG WINAPI IDirect3DPixelShader8Impl_Release(IDirect3DPixelShader8 * if
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
index ace9211..04c4e48 100644 (file)
@@ -58,9 +58,10 @@ static ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -74,16 +75,14 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *i
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -94,11 +93,9 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
-
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -109,11 +106,9 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
-
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
index 4b382ec..3185a1f 100644 (file)
@@ -76,9 +76,10 @@ static ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
             if (This->parentDevice) IUnknown_Release(This->parentDevice);
             /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
             if (!This->isImplicit) {
             if (This->parentDevice) IUnknown_Release(This->parentDevice);
             /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
             if (!This->isImplicit) {
-                EnterCriticalSection(&d3d8_cs);
+                wined3d_mutex_lock();
                 IWineD3DSurface_Release(This->wineD3DSurface);
                 IWineD3DSurface_Release(This->wineD3DSurface);
-                LeaveCriticalSection(&d3d8_cs);
+                wined3d_mutex_unlock();
+
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
@@ -94,14 +95,15 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -110,9 +112,10 @@ static HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(LPDIRECT3DSURFACE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -121,9 +124,10 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(LPDIRECT3DSURFACE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -132,9 +136,10 @@ static HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -159,22 +164,21 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    memset(&wined3ddesc, 0, sizeof(wined3ddesc));
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &pDesc->Size;
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->Size = wined3ddesc.size;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -185,7 +189,7 @@ static HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D
     TRACE("(%p) Relay\n", This);
     TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
 
     TRACE("(%p) Relay\n", This);
     TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     if (pRect) {
         D3DSURFACE_DESC desc;
         IDirect3DSurface8_GetDesc(iface, &desc);
     if (pRect) {
         D3DSURFACE_DESC desc;
         IDirect3DSurface8_GetDesc(iface, &desc);
@@ -197,13 +201,15 @@ static HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D
                 || (pRect->right > desc.Width)
                 || (pRect->bottom > desc.Height)) {
             WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
                 || (pRect->right > desc.Width)
                 || (pRect->bottom > desc.Height)) {
             WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
-            LeaveCriticalSection(&d3d8_cs);
+            wined3d_mutex_unlock();
+
             return D3DERR_INVALIDCALL;
         }
     }
 
     hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
             return D3DERR_INVALIDCALL;
         }
     }
 
     hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -212,9 +218,10 @@ static HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
index 25d2a0e..67f3429 100644 (file)
@@ -56,9 +56,10 @@ static ULONG WINAPI IDirect3DSwapChain8Impl_Release(LPDIRECT3DSWAPCHAIN8 iface)
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
         IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         if (This->parentDevice) IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         if (This->parentDevice) IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -71,9 +72,10 @@ static HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -84,13 +86,14 @@ static HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE )Type, &mySurface);
     if (hrc == D3D_OK && NULL != mySurface) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
        IWineD3DSurface_Release(mySurface);
     }
     hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE )Type, &mySurface);
     if (hrc == D3D_OK && NULL != mySurface) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
        IWineD3DSurface_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
index c1bb91e..c22c491 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -72,14 +73,16 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetDevice(LPDIRECT3DTEXTURE8 iface,
     IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
     IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -88,9 +91,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_SetPrivateData(LPDIRECT3DTEXTURE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -99,9 +103,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetPrivateData(LPDIRECT3DTEXTURE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -110,9 +115,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_FreePrivateData(LPDIRECT3DTEXTURE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -121,9 +127,10 @@ static DWORD WINAPI IDirect3DTexture8Impl_SetPriority(LPDIRECT3DTEXTURE8 iface,
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -132,9 +139,10 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetPriority(LPDIRECT3DTEXTURE8 iface)
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -142,9 +150,9 @@ static void WINAPI IDirect3DTexture8Impl_PreLoad(LPDIRECT3DTEXTURE8 iface) {
     IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) {
@@ -152,9 +160,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 i
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     type = IWineD3DTexture_GetType(This->wineD3DTexture);
     type = IWineD3DTexture_GetType(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return type;
 }
 
     return type;
 }
 
@@ -164,9 +173,10 @@ static DWORD WINAPI IDirect3DTexture8Impl_SetLOD(LPDIRECT3DTEXTURE8 iface, DWORD
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -175,9 +185,10 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetLOD(LPDIRECT3DTEXTURE8 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -186,9 +197,10 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetLevelCount(LPDIRECT3DTEXTURE8 iface
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -200,22 +212,21 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetLevelDesc(LPDIRECT3DTEXTURE8 ifac
     WINED3DSURFACE_DESC    wined3ddesc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DSURFACE_DESC    wined3ddesc;
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    memset(&wined3ddesc, 0, sizeof(wined3ddesc));
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &pDesc->Size;
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->Size = wined3ddesc.size;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -226,13 +237,15 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE8 i
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
-    EnterCriticalSection(&d3d8_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppSurfaceLevel) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel);
        IWineD3DSurface_Release(mySurface);
     }
     hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppSurfaceLevel) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel);
        IWineD3DSurface_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -241,9 +254,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_LockRect(LPDIRECT3DTEXTURE8 iface, U
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -252,9 +266,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_UnlockRect(LPDIRECT3DTEXTURE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -263,9 +278,10 @@ static HRESULT WINAPI IDirect3DTexture8Impl_AddDirtyRect(LPDIRECT3DTEXTURE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
index a282cda..617aff3 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 i
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,14 +75,15 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -90,9 +92,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -101,9 +104,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -112,9 +116,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -123,9 +128,10 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -134,9 +140,10 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -144,9 +151,9 @@ static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 if
     IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
@@ -162,9 +169,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -173,9 +181,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -185,9 +194,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) {
         pDesc->Type = D3DRTYPE_VERTEXBUFFER;
 
     if (SUCCEEDED(hr)) {
         pDesc->Type = D3DRTYPE_VERTEXBUFFER;
index e9d56d0..2eea098 100644 (file)
@@ -61,9 +61,10 @@ static ULONG WINAPI IDirect3DVertexDeclaration8Impl_Release(IDirect3DVertexDecla
     TRACE("(%p) : Releasing to %d\n", This, ref_count);
 
     if (!ref_count) {
     TRACE("(%p) : Releasing to %d\n", This, ref_count);
 
     if (!ref_count) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
         IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, This->elements);
         HeapFree(GetProcessHeap(), 0, This);
     }
         HeapFree(GetProcessHeap(), 0, This->elements);
         HeapFree(GetProcessHeap(), 0, This);
     }
index 4ea8b52..1a9b5ea 100644 (file)
@@ -59,9 +59,9 @@ static ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *i
         IDirect3DVertexDeclaration8_Release(This->vertex_declaration);
         if (This->wineD3DVertexShader)
         {
         IDirect3DVertexDeclaration8_Release(This->vertex_declaration);
         if (This->wineD3DVertexShader)
         {
-            EnterCriticalSection(&d3d8_cs);
+            wined3d_mutex_lock();
             IWineD3DVertexShader_Release(This->wineD3DVertexShader);
             IWineD3DVertexShader_Release(This->wineD3DVertexShader);
-            LeaveCriticalSection(&d3d8_cs);
+            wined3d_mutex_unlock();
         }
         HeapFree(GetProcessHeap(), 0, This);
     }
         }
         HeapFree(GetProcessHeap(), 0, This);
     }
index 474aad8..968b534 100644 (file)
@@ -72,9 +72,10 @@ static ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
         TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
         if (ref == 0) {
         TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
         if (ref == 0) {
-            EnterCriticalSection(&d3d8_cs);
+            wined3d_mutex_lock();
             IWineD3DVolume_Release(This->wineD3DVolume);
             IWineD3DVolume_Release(This->wineD3DVolume);
-            LeaveCriticalSection(&d3d8_cs);
+            wined3d_mutex_unlock();
+
             HeapFree(GetProcessHeap(), 0, This);
         }
 
             HeapFree(GetProcessHeap(), 0, This);
         }
 
@@ -87,11 +88,12 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, ID
     IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
     IWineD3DDevice       *myDevice = NULL;
 
     IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
     IWineD3DDevice       *myDevice = NULL;
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
     IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return D3D_OK;
 }
 
     return D3D_OK;
 }
 
@@ -100,9 +102,10 @@ static HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -111,9 +114,10 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetPrivateData(LPDIRECT3DVOLUME8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -122,9 +126,10 @@ static HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -154,21 +159,21 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DV
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &pDesc->Size;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-    wined3ddesc.Depth               = &pDesc->Depth;
-
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
-    LeaveCriticalSection(&d3d8_cs);
-
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    wined3d_mutex_unlock();
+
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format);
+        pDesc->Type = wined3ddesc.Type;
+        pDesc->Usage = wined3ddesc.Usage;
+        pDesc->Pool = wined3ddesc.Pool;
+        pDesc->Size = wined3ddesc.Size;
+        pDesc->Width = wined3ddesc.Width;
+        pDesc->Height = wined3ddesc.Height;
+        pDesc->Depth = wined3ddesc.Depth;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -178,9 +183,10 @@ static HRESULT WINAPI IDirect3DVolume8Impl_LockBox(LPDIRECT3DVOLUME8 iface, D3DL
     HRESULT hr;
     TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
 
     HRESULT hr;
     TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -189,9 +195,10 @@ static HRESULT WINAPI IDirect3DVolume8Impl_UnlockBox(LPDIRECT3DVOLUME8 iface) {
     HRESULT hr;
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
     HRESULT hr;
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
index 098827a..1875081 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DVolumeTexture8Impl_Release(LPDIRECT3DVOLUMETEXTURE8
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d8_cs);
+        wined3d_mutex_lock();
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
-        LeaveCriticalSection(&d3d8_cs);
+        wined3d_mutex_unlock();
+
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,14 +74,15 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetDevice(LPDIRECT3DVOLUMETEXT
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DVolumeTexture_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -89,9 +91,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_SetPrivateData(LPDIRECT3DVOLUM
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -100,9 +103,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetPrivateData(LPDIRECT3DVOLUM
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -111,9 +115,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_FreePrivateData(LPDIRECT3DVOLU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -122,9 +127,10 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetPriority(LPDIRECT3DVOLUMETEXT
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
     ret = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -133,9 +139,10 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetPriority(LPDIRECT3DVOLUMETEXT
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -143,9 +150,9 @@ static void WINAPI IDirect3DVolumeTexture8Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE8
     IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTURE8 iface) {
@@ -153,9 +160,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLU
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return type;
 }
 
     return type;
 }
 
@@ -165,9 +173,10 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
     ret = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -176,9 +185,10 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -187,9 +197,10 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLevelCount(LPDIRECT3DVOLUMETE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -197,26 +208,25 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLevelCount(LPDIRECT3DVOLUMETE
 static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
 static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
-    UINT                   tmpInt = -1;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d8 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-    wined3ddesc.Depth               = &pDesc->Depth;
-
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format);
+        pDesc->Type = wined3ddesc.Type;
+        pDesc->Usage = wined3ddesc.Usage;
+        pDesc->Pool = wined3ddesc.Pool;
+        pDesc->Size = wined3ddesc.Size;
+        pDesc->Width = wined3ddesc.Width;
+        pDesc->Height = wined3ddesc.Height;
+        pDesc->Depth = wined3ddesc.Depth;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -228,13 +238,14 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetVolumeLevel(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
     if (hrc == D3D_OK && NULL != ppVolumeLevel) {
        IWineD3DVolumeTexture_GetParent(myVolume, (IUnknown **)ppVolumeLevel);
        IWineD3DVolumeTexture_Release(myVolume);
     }
     hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
     if (hrc == D3D_OK && NULL != ppVolumeLevel) {
        IWineD3DVolumeTexture_GetParent(myVolume, (IUnknown **)ppVolumeLevel);
        IWineD3DVolumeTexture_Release(myVolume);
     }
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -243,9 +254,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_LockBox(LPDIRECT3DVOLUMETEXTUR
     HRESULT hr;
     TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
 
     HRESULT hr;
     TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
     hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -254,9 +266,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_UnlockBox(LPDIRECT3DVOLUMETEXT
     HRESULT hr;
     TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
 
     HRESULT hr;
     TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -265,9 +278,10 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_AddDirtyBox(LPDIRECT3DVOLUMETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *) pDirtyBox);
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *) pDirtyBox);
-    LeaveCriticalSection(&d3d8_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
index bbd171e..8209d0b 100644 (file)
@@ -61,10 +61,10 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa
     if (ref == 0) {
         TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
 
     if (ref == 0) {
         TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
 
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
         IDirect3DDevice9Ex_Release(This->parentDevice);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -78,14 +78,15 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetDevice(LPDIRECT3DCUBETEXTURE9
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -94,9 +95,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_SetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -105,9 +107,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -116,9 +119,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_FreePrivateData(LPDIRECT3DCUBETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -127,9 +131,10 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_SetPriority(LPDIRECT3DCUBETEXTURE9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -138,9 +143,10 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetPriority(LPDIRECT3DCUBETEXTURE9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -148,9 +154,9 @@ static void WINAPI IDirect3DCubeTexture9Impl_PreLoad(LPDIRECT3DCUBETEXTURE9 ifac
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETEXTURE9 iface) {
@@ -158,9 +164,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETE
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -170,9 +177,10 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_SetLOD(LPDIRECT3DCUBETEXTURE9 ifac
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
     ret = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -181,9 +189,10 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetLOD(LPDIRECT3DCUBETEXTURE9 ifac
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_GetLOD(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetLOD(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -192,9 +201,10 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetLevelCount(LPDIRECT3DCUBETEXTUR
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -203,9 +213,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_SetAutoGenFilterType(LPDIRECT3DC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_SetAutoGenFilterType(This->wineD3DCubeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
     hr = IWineD3DCubeTexture_SetAutoGenFilterType(This->wineD3DCubeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -214,9 +225,10 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DCubeTexture9Impl_GetAutoGenFilterTyp
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DCubeTexture_GetAutoGenFilterType(This->wineD3DCubeTexture);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DCubeTexture_GetAutoGenFilterType(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -224,37 +236,34 @@ static void WINAPI IDirect3DCubeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DCUBE
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DCubeTexture_GenerateMipSubLevels(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_GenerateMipSubLevels(This->wineD3DCubeTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 /* IDirect3DCubeTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetLevelDesc(LPDIRECT3DCUBETEXTURE9 iface, UINT Level, D3DSURFACE_DESC* pDesc) {
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
 }
 
 /* IDirect3DCubeTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetLevelDesc(LPDIRECT3DCUBETEXTURE9 iface, UINT Level, D3DSURFACE_DESC* pDesc) {
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
-    WINED3DSURFACE_DESC    wined3ddesc;
-    UINT                   tmpInt = -1;
-    WINED3DFORMAT format;
+    WINED3DSURFACE_DESC wined3ddesc;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = &format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *) &pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt;
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.MultiSampleQuality  = &pDesc->MultiSampleQuality;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->MultiSampleQuality = wined3ddesc.multisample_quality;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -266,13 +275,14 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetCubeMapSurface(LPDIRECT3DCUBE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppCubeMapSurface) {
        IWineD3DCubeTexture_GetParent(mySurface, (IUnknown **)ppCubeMapSurface);
        IWineD3DCubeTexture_Release(mySurface);
     }
     hrc = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppCubeMapSurface) {
        IWineD3DCubeTexture_GetParent(mySurface, (IUnknown **)ppCubeMapSurface);
        IWineD3DCubeTexture_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -281,9 +291,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_LockRect(LPDIRECT3DCUBETEXTURE9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_LockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DCubeTexture_LockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -292,9 +303,10 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_UnlockRect(LPDIRECT3DCUBETEXTURE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -303,9 +315,10 @@ static HRESULT  WINAPI IDirect3DCubeTexture9Impl_AddDirtyRect(LPDIRECT3DCUBETEXT
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -363,10 +376,11 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac
     }
     object->lpVtbl = &Direct3DCubeTexture9_Vtbl;
     object->ref = 1;
     }
     object->lpVtbl = &Direct3DCubeTexture9_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (hr != D3D_OK){
 
 
     if (hr != D3D_OK){
 
index 40d73a5..f59fc46 100644 (file)
 #include "initguid.h"
 #include "d3d9_private.h"
 
 #include "initguid.h"
 #include "d3d9_private.h"
 
-static CRITICAL_SECTION_DEBUG d3d9_cs_debug =
-{
-    0, 0, &d3d9_cs,
-    { &d3d9_cs_debug.ProcessLocksList,
-    &d3d9_cs_debug.ProcessLocksList },
-    0, 0, { (DWORD_PTR)(__FILE__ ": d3d9_cs") }
-};
-CRITICAL_SECTION d3d9_cs = { &d3d9_cs_debug, -1, 0, 0, 0, 0 };
-
 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
 static int D3DPERF_event_level = 0;
 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
 static int D3DPERF_event_level = 0;
@@ -47,9 +38,10 @@ IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) {
 
     object->lpVtbl = &Direct3D9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3D9_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     object->WineD3D = WineDirect3DCreate(9, (IUnknown *)object);
     object->WineD3D = WineDirect3DCreate(9, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     TRACE("SDKVersion = %x, Created Direct3D object @ %p, WineObj @ %p\n", SDKVersion, object, object->WineD3D);
 
 
     TRACE("SDKVersion = %x, Created Direct3D object @ %p, WineObj @ %p\n", SDKVersion, object, object->WineD3D);
 
index 7e43974..b6ef7cf 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2002-2003 Jason Edmeades
  * Copyright 2002-2003 Raphael Junqueira
  *
  * Copyright 2002-2003 Jason Edmeades
  * Copyright 2002-2003 Raphael Junqueira
- * Copyright 2005 Oliver Stieber 
+ * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -44,7 +44,6 @@
 extern HRESULT vdecl_convert_fvf(
     DWORD FVF,
     D3DVERTEXELEMENT9** ppVertexElements);
 extern HRESULT vdecl_convert_fvf(
     DWORD FVF,
     D3DVERTEXELEMENT9** ppVertexElements);
-extern CRITICAL_SECTION d3d9_cs;
 D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format);
 WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format);
 
 D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format);
 WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format);
 
@@ -369,7 +368,6 @@ typedef struct IDirect3DBaseTexture9Impl
 
     /* IDirect3DResource9 fields */
     IWineD3DBaseTexture    *wineD3DBaseTexture;
 
     /* IDirect3DResource9 fields */
     IWineD3DBaseTexture    *wineD3DBaseTexture;
-    
 } IDirect3DBaseTexture9Impl;
 
 /* --------------------- */
 } IDirect3DBaseTexture9Impl;
 
 /* --------------------- */
index e5ca4c4..5a87a8f 100644 (file)
@@ -248,7 +248,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
       unsigned i;
       This->inDestruction = TRUE;
 
       unsigned i;
       This->inDestruction = TRUE;
 
-      EnterCriticalSection(&d3d9_cs);
+      wined3d_mutex_lock();
       for(i = 0; i < This->numConvertedDecls; i++) {
           /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
            * device
       for(i = 0; i < This->numConvertedDecls; i++) {
           /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
            * device
@@ -259,7 +259,8 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
 
       IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain);
       IWineD3DDevice_Release(This->WineD3DDevice);
 
       IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain);
       IWineD3DDevice_Release(This->WineD3DDevice);
-      LeaveCriticalSection(&d3d9_cs);
+      wined3d_mutex_unlock();
+
       HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
       HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -271,9 +272,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_TestCooperativeLevel(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     if(hr == WINED3D_OK && This->notreset) {
         TRACE("D3D9 Device is marked not reset\n");
         hr = D3DERR_DEVICENOTRESET;
     if(hr == WINED3D_OK && This->notreset) {
         TRACE("D3D9 Device is marked not reset\n");
         hr = D3DERR_DEVICENOTRESET;
@@ -287,9 +289,10 @@ static UINT     WINAPI  IDirect3DDevice9Impl_GetAvailableTextureMem(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -298,9 +301,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_EvictManagedResources(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -315,7 +319,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9EX iface
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
@@ -326,7 +330,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9EX iface
         *ppD3D9 = NULL;
     }
     TRACE("(%p) returning %p\n", This, *ppD3D9);
         *ppD3D9 = NULL;
     }
     TRACE("(%p) returning %p\n", This, *ppD3D9);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -345,9 +350,11 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9EX i
     }
 
     memset(pCaps, 0, sizeof(*pCaps));
     }
 
     memset(pCaps, 0, sizeof(*pCaps));
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
@@ -365,9 +372,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -379,9 +386,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCreationParameters(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -396,9 +404,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCursorProperties(LPDIRECT3DDEVIC
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -406,9 +415,9 @@ static void     WINAPI  IDirect3DDevice9Impl_SetCursorPosition(LPDIRECT3DDEVICE9
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
 }
 
 static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
@@ -416,53 +425,35 @@ static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
     BOOL *resources_ok = data;
     return ret;
 }
 
 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
     BOOL *resources_ok = data;
-    WINED3DRESOURCETYPE type;
+    D3DRESOURCETYPE type;
     HRESULT ret = S_OK;
     WINED3DSURFACE_DESC surface_desc;
     WINED3DVOLUME_DESC volume_desc;
     D3DINDEXBUFFER_DESC index_desc;
     D3DVERTEXBUFFER_DESC vertex_desc;
     HRESULT ret = S_OK;
     WINED3DSURFACE_DESC surface_desc;
     WINED3DVOLUME_DESC volume_desc;
     D3DINDEXBUFFER_DESC index_desc;
     D3DVERTEXBUFFER_DESC vertex_desc;
-    WINED3DFORMAT dummy_format;
-    WINED3DMULTISAMPLE_TYPE dummy_multisampletype;
-    DWORD dummy_dword;
-    WINED3DPOOL pool = WINED3DPOOL_SCRATCH; /* a harmless pool */
+    WINED3DPOOL pool;
     IDirect3DResource9 *parent;
 
     IWineD3DResource_GetParent(resource, (IUnknown **) &parent);
     type = IDirect3DResource9_GetType(parent);
     switch(type) {
         case D3DRTYPE_SURFACE:
     IDirect3DResource9 *parent;
 
     IWineD3DResource_GetParent(resource, (IUnknown **) &parent);
     type = IDirect3DResource9_GetType(parent);
     switch(type) {
         case D3DRTYPE_SURFACE:
-            surface_desc.Format = &dummy_format;
-            surface_desc.Type = &type;
-            surface_desc.Usage = &dummy_dword;
-            surface_desc.Pool = &pool;
-            surface_desc.Size = &dummy_dword;
-            surface_desc.MultiSampleType = &dummy_multisampletype;
-            surface_desc.MultiSampleQuality = &dummy_dword;
-            surface_desc.Width = &dummy_dword;
-            surface_desc.Height = &dummy_dword;
-
             IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
             IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
+            pool = surface_desc.pool;
             break;
 
         case D3DRTYPE_VOLUME:
             break;
 
         case D3DRTYPE_VOLUME:
-            volume_desc.Format = &dummy_format;
-            volume_desc.Type = &type;
-            volume_desc.Usage = &dummy_dword;
-            volume_desc.Pool = &pool;
-            volume_desc.Size = &dummy_dword;
-            volume_desc.Width = &dummy_dword;
-            volume_desc.Height = &dummy_dword;
-            volume_desc.Depth = &dummy_dword;
             IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
             IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
+            pool = volume_desc.Pool;
             break;
 
         case D3DRTYPE_INDEXBUFFER:
             break;
 
         case D3DRTYPE_INDEXBUFFER:
@@ -479,6 +470,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
          * is a D3DPOOL_DEFAULT surface or volume as well
          */
         default:
          * is a D3DPOOL_DEFAULT surface or volume as well
          */
         default:
+            pool = WINED3DPOOL_SCRATCH; /* a harmless pool */
             break;
     }
 
             break;
     }
 
@@ -515,7 +507,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
      * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
      * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
      */
      * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
      * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
      */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
     for(i = 0; i < 16; i++) {
         IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
     IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
     for(i = 0; i < 16; i++) {
         IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
@@ -528,7 +520,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
     if(!resources_ok) {
         WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset\n");
         This->notreset = TRUE;
     if(!resources_ok) {
         WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset\n");
         This->notreset = TRUE;
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -570,7 +563,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
         This->notreset = FALSE;
     }
 
         This->notreset = FALSE;
     }
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -581,9 +574,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
  }
 
     return hr;
  }
 
@@ -594,13 +588,14 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetBackBuffer(LPDIRECT3DDEVICE9EX i
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, iSwapChain, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
     if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
         IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
         IWineD3DSurface_Release(retSurface);
     }
     rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, iSwapChain, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
     if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
         IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
         IWineD3DSurface_Release(retSurface);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return rc;
 }
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) {
     return rc;
 }
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) {
@@ -608,9 +603,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -619,48 +615,49 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
     hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
-    
+static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
+        DWORD Flags, const D3DGAMMARAMP *pRamp)
+{
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
+    wined3d_mutex_lock();
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, iSwapChain, Flags, (CONST WINED3DGAMMARAMP *)pRamp);
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, iSwapChain, Flags, (CONST WINED3DGAMMARAMP *)pRamp);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
 }
 
 static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
     /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
+    wined3d_mutex_lock();
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, iSwapChain, (WINED3DGAMMARAMP *) pRamp);
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, iSwapChain, (WINED3DGAMMARAMP *) pRamp);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 
 }
 
 
-static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,D3DRESOURCETYPE Type, UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,HANDLE* pSharedHandle )  {
+static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
+        D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,
+        UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)
+{
     HRESULT hrc;
     IDirect3DSurface9Impl *object;
     IDirect3DDevice9Impl  *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
     HRESULT hrc;
     IDirect3DSurface9Impl *object;
     IDirect3DDevice9Impl  *This = (IDirect3DDevice9Impl *)iface;
     TRACE("(%p) Relay\n", This);
-    
-    if(MultisampleQuality > 0){
+
+    if (MultisampleQuality > 0)
+    {
         FIXME("MultisampleQuality set to %d, bstituting 0\n", MultisampleQuality);
         FIXME("MultisampleQuality set to %d, bstituting 0\n", MultisampleQuality);
-    /*
-    MultisampleQuality
- [in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces, and the MultiSample type must all match.
- */
-        MultisampleQuality=0;
+        MultisampleQuality = 0;
     }
     /*FIXME: Check MAX bounds of MultisampleQuality*/
 
     }
     /*FIXME: Check MAX bounds of MultisampleQuality*/
 
@@ -676,11 +673,11 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
-            Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
-            (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+            Lockable, Discard, Level, &object->wineD3DSurface, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
+            MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
+    wined3d_mutex_unlock();
 
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
 
 
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
 
@@ -696,17 +693,17 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
     return hrc;
 }
 
     return hrc;
 }
 
-
-
-static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateRenderTarget(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
-                                                         D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, 
-                                                         DWORD MultisampleQuality, BOOL Lockable, 
-                                                         IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
+static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width, UINT Height,
+        D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable,
+        IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
+{
     HRESULT hr;
     TRACE("Relay\n");
 
     HRESULT hr;
     TRACE("Relay\n");
 
-   hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,Lockable,FALSE/*Discard*/, 0/*Level*/, ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_RENDERTARGET,D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
-   return hr;
+    hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */,
+            0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
+
+    return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
@@ -716,10 +713,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3
     HRESULT hr;
     TRACE("Relay\n");
 
     HRESULT hr;
     TRACE("Relay\n");
 
-     hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/* Lockable */,Discard, 0/* Level */
-                                               ,ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_DEPTHSTENCIL,
-                                                D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
-     return hr;
+    hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, Discard,
+            0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
+
+    return hr;
 }
 
 
 }
 
 
@@ -728,9 +725,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
     hr = IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -739,9 +737,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -752,9 +751,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTargetData(LPDIRECT3DDEVIC
     HRESULT hr;
     TRACE("(%p)->(%p,%p)\n" , This, renderTarget, destSurface);
 
     HRESULT hr;
     TRACE("(%p)->(%p,%p)\n" , This, renderTarget, destSurface);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
     hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -764,9 +764,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -777,9 +778,11 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9EX ifa
     HRESULT hr;
 
     TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
     HRESULT hr;
 
     TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
     hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -793,19 +796,18 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    memset(&desc, 0, sizeof(desc));
-    desc.Usage = &usage;
-    desc.Pool = &pool;
-    desc.Type = &restype;
+    wined3d_mutex_lock();
 
 
-    EnterCriticalSection(&d3d9_cs);
     IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
     IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
+    usage = desc.usage;
+    pool = desc.pool;
+    restype = desc.resource_type;
 
     /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
      * in D3DPOOL_DEFAULT
      */
 
     /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
      * in D3DPOOL_DEFAULT
      */
-    if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != D3DPOOL_DEFAULT || restype != D3DRTYPE_SURFACE)) {
-        LeaveCriticalSection(&d3d9_cs);
+    if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != WINED3DPOOL_DEFAULT || restype != WINED3DRTYPE_SURFACE)) {
+        wined3d_mutex_unlock();
         WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
         return D3DERR_INVALIDCALL;
     }
         WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
         return D3DERR_INVALIDCALL;
     }
@@ -813,7 +815,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface
     /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
     /* Note: D3DRECT is compatible with WINED3DRECT */
     hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
     /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
     /* Note: D3DRECT is compatible with WINED3DRECT */
     hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
-    LeaveCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -823,15 +827,17 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIREC
     if(Pool == D3DPOOL_MANAGED ){
         FIXME("Attempting to create a managed offscreen plain surface\n");
         return D3DERR_INVALIDCALL;
     if(Pool == D3DPOOL_MANAGED ){
         FIXME("Attempting to create a managed offscreen plain surface\n");
         return D3DERR_INVALIDCALL;
-    }    
+    }
         /*
         'Off-screen plain surfaces are always lockable, regardless of their pool types.'
         but then...
         D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
         Why, their always lockable?
         /*
         'Off-screen plain surfaces are always lockable, regardless of their pool types.'
         but then...
         D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
         Why, their always lockable?
-        should I change the usage to dynamic?        
+        should I change the usage to dynamic?
         */
         */
-    hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/*Loackable*/,FALSE/*Discard*/,0/*Level*/ , ppSurface,D3DRTYPE_SURFACE, 0/*Usage (undefined/none)*/,(WINED3DPOOL) Pool,D3DMULTISAMPLE_NONE,0/*MultisampleQuality*/,pSharedHandle);
+    hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
+            0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, (WINED3DPOOL)Pool, D3DMULTISAMPLE_NONE,
+            0 /* MultisampleQuality */);
 
     return hr;
 }
 
     return hr;
 }
@@ -843,16 +849,17 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL);
     hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    HRESULT hr = D3D_OK;
     IWineD3DSurface *pRenderTarget;
     IWineD3DSurface *pRenderTarget;
+    HRESULT hr;
 
     TRACE("(%p) Relay\n" , This);
 
 
     TRACE("(%p) Relay\n" , This);
 
@@ -860,17 +867,25 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
+
     hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
 
     hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
 
-    if (hr == D3D_OK && pRenderTarget != NULL) {
-        IWineD3DSurface_GetParent(pRenderTarget,(IUnknown**)ppRenderTarget);
-        IWineD3DSurface_Release(pRenderTarget);
-    } else {
-        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+    if (FAILED(hr))
+    {
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed, hr %#x\n", hr);
+    }
+    else if (!pRenderTarget)
+    {
         *ppRenderTarget = NULL;
     }
         *ppRenderTarget = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    else
+    {
+        IWineD3DSurface_GetParent(pRenderTarget, (IUnknown **)ppRenderTarget);
+        IWineD3DSurface_Release(pRenderTarget);
+    }
+
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -882,9 +897,11 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDE
     TRACE("(%p) Relay\n" , This);
 
     pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
     TRACE("(%p) Relay\n" , This);
 
     pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -898,7 +915,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
     if (hr == WINED3D_OK) {
         IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
     hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
     if (hr == WINED3D_OK) {
         IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
@@ -908,7 +925,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE
                 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
         *ppZStencilSurface = NULL;
     }
                 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
         *ppZStencilSurface = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -917,9 +935,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -928,9 +947,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface)
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -940,9 +960,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Clear(LPDIRECT3DDEVICE9EX iface, DW
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DRECT is compatible with WINED3DRECT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DRECT is compatible with WINED3DRECT */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
     hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -952,9 +973,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9EX if
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -964,10 +986,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9EX if
 
     TRACE("(%p) Relay\n" , This);
 
 
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -978,9 +1000,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -990,9 +1013,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetViewport(LPDIRECT3DDEVICE9EX ifa
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1002,9 +1026,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetViewport(LPDIRECT3DDEVICE9EX ifa
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1014,9 +1039,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetMaterial(LPDIRECT3DDEVICE9EX ifa
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1026,9 +1052,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetMaterial(LPDIRECT3DDEVICE9EX ifa
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1038,9 +1065,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetLight(LPDIRECT3DDEVICE9EX iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1050,9 +1078,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetLight(LPDIRECT3DDEVICE9EX iface,
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
     TRACE("(%p) Relay\n" , This);
 
     /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1061,9 +1090,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9EX ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1072,9 +1102,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1083,9 +1114,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1094,9 +1126,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1105,9 +1138,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1116,9 +1150,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1127,9 +1162,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1138,9 +1174,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1155,7 +1192,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
     if (SUCCEEDED(rc) && NULL != retTexture) {
         IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
     rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
     if (SUCCEEDED(rc) && NULL != retTexture) {
         IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
@@ -1166,7 +1203,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX ifac
         }
         *ppTexture = NULL;
     }
         }
         *ppTexture = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return rc;
 }
 
     return rc;
 }
@@ -1176,10 +1213,11 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9EX ifac
     HRESULT hr;
     TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
 
     HRESULT hr;
     TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1225,9 +1263,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
     hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1236,20 +1275,24 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
     hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3DDevice9Impl_GetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
+        D3DSAMPLERSTATETYPE Type, DWORD *pValue)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
     hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1258,9 +1301,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
     hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1269,20 +1313,24 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3DDevice9Impl_SetPaletteEntries(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface, UINT PaletteNumber,
+        const PALETTEENTRY *pEntries)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1291,9 +1339,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1302,9 +1351,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1313,9 +1363,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1324,9 +1375,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
     hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1335,9 +1387,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
     hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1346,9 +1399,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIREC
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
     hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1357,9 +1411,10 @@ static BOOL     WINAPI  IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIREC
     BOOL ret;
     TRACE("(%p) Relay\n" , This);
 
     BOOL ret;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
     ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -1368,9 +1423,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
     hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1379,22 +1435,26 @@ static float    WINAPI  IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9EX i
     float ret;
     TRACE("(%p) Relay\n" , This);
 
     float ret;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
     ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
+        UINT StartVertex, UINT PrimitiveCount)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1405,26 +1465,30 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVI
     TRACE("(%p) Relay\n" , This);
 
     /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
     TRACE("(%p) Relay\n" , This);
 
     /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
             startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
             startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
+        UINT PrimitiveCount, const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
             pVertexStreamZeroData, VertexStreamZeroStride);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
             pVertexStreamZeroData, VertexStreamZeroStride);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1435,12 +1499,13 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
     IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
     hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1451,9 +1516,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX
     IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
     IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
     hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1527,9 +1593,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWO
         return D3D_OK;
     }
 
         return D3D_OK;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     decl = getConvertedDecl(This, FVF);
     decl = getConvertedDecl(This, FVF);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (!decl)
     {
 
     if (!decl)
     {
@@ -1578,11 +1644,12 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
-                                          pStreamData==NULL ? NULL:((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer, 
-                                          OffsetInBytes, Stride);
-    LeaveCriticalSection(&d3d9_cs);
+            pStreamData ? ((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer : NULL,
+            OffsetInBytes, Stride);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1597,7 +1664,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
         IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
         IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
@@ -1608,19 +1675,22 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i
         }
         *pStream = NULL;
     }
         }
         *pStream = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return rc;
 }
 
 
     return rc;
 }
 
-static HRESULT  WINAPI  IDirect3DDevice9Impl_SetStreamSourceFreq(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, UINT Divider) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT StreamNumber,
+        UINT Divider)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
     hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1629,9 +1699,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVIC
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
     hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1641,11 +1712,12 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX ifac
     IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
             ib ? ib->wineD3DIndexBuffer : NULL,
             ib ? ib->format : WINED3DFMT_UNKNOWN);
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
             ib ? ib->wineD3DIndexBuffer : NULL,
             ib ? ib->format : WINED3DFMT_UNKNOWN);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1660,7 +1732,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
         IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
         IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
@@ -1669,7 +1741,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX ifac
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
     }
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return rc;
 }
 
     return rc;
 }
 
@@ -1678,9 +1751,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1689,9 +1763,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1700,9 +1775,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -1995,12 +2071,12 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
             "\tpool %#x, level %u, face %u, surface %p\n",
             iface, superior, width, height, format, usage, pool, level, face, surface);
 
             "\tpool %#x, level %u, face %u, surface %p\n",
             iface, superior, width, height, format, usage, pool, level, face, surface);
 
-    if (pool == D3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC)) lockable = FALSE;
+    if (pool == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
+        lockable = FALSE;
 
     hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
 
     hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
-            (IDirect3DSurface9 **)&d3d_surface, D3DRTYPE_SURFACE, usage, pool,
-            D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */, NULL);
+            (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
index e9547a7..fe22916 100644 (file)
@@ -69,9 +69,10 @@ static ULONG WINAPI IDirect3D9Impl_Release(LPDIRECT3D9EX iface) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3D_Release(This->WineD3D);
         IWineD3D_Release(This->WineD3D);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -84,9 +85,10 @@ static HRESULT  WINAPI  IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9EX ifac
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -95,9 +97,10 @@ static UINT     WINAPI  IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9EX iface) {
     HRESULT hr;
     TRACE("%p\n", This);
 
     HRESULT hr;
     TRACE("%p\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -106,23 +109,25 @@ static HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9EX iface, U
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
-    /* dx8 and dx9 have different structures to be filled in, with incompatible 
-       layouts so pass in pointers to the places to be filled via an internal 
-       structure                                                                */
-    adapter_id.Driver           = pIdentifier->Driver;          
-    adapter_id.Description      = pIdentifier->Description;     
-    adapter_id.DeviceName       = pIdentifier->DeviceName;      
-    adapter_id.DriverVersion    = &pIdentifier->DriverVersion;   
-    adapter_id.VendorId         = &pIdentifier->VendorId;        
-    adapter_id.DeviceId         = &pIdentifier->DeviceId;        
-    adapter_id.SubSysId         = &pIdentifier->SubSysId;        
-    adapter_id.Revision         = &pIdentifier->Revision;        
-    adapter_id.DeviceIdentifier = &pIdentifier->DeviceIdentifier;
-    adapter_id.WHQLLevel        = &pIdentifier->WHQLLevel;       
-
-    EnterCriticalSection(&d3d9_cs);
+    adapter_id.driver = pIdentifier->Driver;
+    adapter_id.driver_size = sizeof(pIdentifier->Driver);
+    adapter_id.description = pIdentifier->Description;
+    adapter_id.description_size = sizeof(pIdentifier->Description);
+    adapter_id.device_name = pIdentifier->DeviceName;
+    adapter_id.device_name_size = sizeof(pIdentifier->DeviceName);
+
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
+    pIdentifier->DriverVersion = adapter_id.driver_version;
+    pIdentifier->VendorId = adapter_id.vendor_id;
+    pIdentifier->DeviceId = adapter_id.device_id;
+    pIdentifier->SubSysId = adapter_id.subsystem_id;
+    pIdentifier->Revision = adapter_id.revision;
+    memcpy(&pIdentifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(pIdentifier->DeviceIdentifier));
+    pIdentifier->WHQLLevel = adapter_id.whql_level;
+
     return hr;
 }
 
     return hr;
 }
 
@@ -136,9 +141,10 @@ static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9EX iface, UINT
         return 0;
     }
 
         return 0;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format));
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format));
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -151,10 +157,10 @@ static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9EX iface, UINT
     if(Format != D3DFMT_X8R8G8B8 && Format != D3DFMT_R5G6B5)
         return D3DERR_INVALIDCALL;
 
     if(Format != D3DFMT_X8R8G8B8 && Format != D3DFMT_R5G6B5)
         return D3DERR_INVALIDCALL;
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format),
             Mode, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format),
             Mode, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -165,38 +171,51 @@ static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9EX iface,
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
     return hr;
 }
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9EX iface,
-                                             UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
-                                             D3DFORMAT BackBufferFormat, BOOL Windowed) {
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(IDirect3D9Ex *iface, UINT Adapter,
+        D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
+{
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %d, %d, %s\n", This, Adapter, CheckType, DisplayFormat,
           BackBufferFormat, Windowed ? "true" : "false");
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("(%p)->(%d, %d, %d, %d, %s\n", This, Adapter, CheckType, DisplayFormat,
           BackBufferFormat, Windowed ? "true" : "false");
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
             wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
     hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
             wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface,
-                                                 UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
-                                                 DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(IDirect3D9Ex *iface, UINT Adapter, D3DDEVTYPE DeviceType,
+        D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
+{
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     WINED3DRESOURCETYPE WineD3DRType;
     TRACE("%p\n", This);
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     WINED3DRESOURCETYPE WineD3DRType;
     TRACE("%p\n", This);
 
+    /* This format is nothing special and it is supported perfectly.
+     * However, ati and nvidia driver on windows do not mark this format as
+     * supported (tested with the dxCapsViewer) and pretending to
+     * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
+     * So do the same as Windows drivers and pretend not to support it on dx8 and 9
+     */
+    if(CheckFormat == D3DFMT_R8G8B8)
+    {
+        WARN("D3DFMT_R8G8B8 is not available on windows, returning D3DERR_NOTAVAILABLE\n");
+        return D3DERR_NOTAVAILABLE;
+    }
+
     switch(RType) {
         case D3DRTYPE_VERTEXBUFFER:
         case D3DRTYPE_INDEXBUFFER:
     switch(RType) {
         case D3DRTYPE_VERTEXBUFFER:
         case D3DRTYPE_INDEXBUFFER:
@@ -208,39 +227,43 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface,
             break;
     }
 
             break;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
             Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
             Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9EX iface,
-                                                          UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
-                                                          BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(IDirect3D9Ex *iface, UINT Adapter,
+        D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType,
+        DWORD *pQualityLevels)
+{
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("%p\n", This);
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("%p\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SurfaceFormat), Windowed, MultiSampleType, pQualityLevels);
     hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SurfaceFormat), Windowed, MultiSampleType, pQualityLevels);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9EX iface,
-                                                      UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
-                                                      D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
+static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(IDirect3D9Ex *iface, UINT Adapter,
+        D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
+{
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("%p\n", This);
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
     TRACE("%p\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
             wined3dformat_from_d3dformat(DepthStencilFormat));
     hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
             wined3dformat_from_d3dformat(DepthStencilFormat));
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -249,10 +272,11 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9EX i
     HRESULT hr;
     TRACE("%p\n", This);
 
     HRESULT hr;
     TRACE("%p\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CheckDeviceFormatConversion(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SourceFormat), wined3dformat_from_d3dformat(TargetFormat));
     hr = IWineD3D_CheckDeviceFormatConversion(This->WineD3D, Adapter, DeviceType,
             wined3dformat_from_d3dformat(SourceFormat), wined3dformat_from_d3dformat(TargetFormat));
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -330,9 +354,11 @@ static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Ada
         return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
     }
     memset(pCaps, 0, sizeof(*pCaps));
         return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
     }
     memset(pCaps, 0, sizeof(*pCaps));
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
@@ -350,9 +376,10 @@ static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9EX iface, UIN
     HMONITOR ret;
     TRACE("%p\n", This);
 
     HMONITOR ret;
     TRACE("%p\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -418,13 +445,14 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9EX iface, UINT Adap
     *ppReturnedDeviceInterface = (IDirect3DDevice9 *)object;
 
     /* Allocate an associated WineD3DDevice object */
     *ppReturnedDeviceInterface = (IDirect3DDevice9 *)object;
 
     /* Allocate an associated WineD3DDevice object */
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags,
             (IUnknown *)object, (IWineD3DDeviceParent *)&object->device_parent_vtbl, &object->WineD3DDevice);
     if (hr != D3D_OK) {
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
     hr = IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags,
             (IUnknown *)object, (IWineD3DDeviceParent *)&object->device_parent_vtbl, &object->WineD3DDevice);
     if (hr != D3D_OK) {
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         return hr;
     }
 
         return hr;
     }
 
@@ -492,7 +520,7 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9EX iface, UINT Adap
      * can be used without further checking
      */
     object->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
      * can be used without further checking
      */
     object->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
index 8802bd1..49f6fc8 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,14 +74,15 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDevice(LPDIRECT3DINDEXBUFFER9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -89,9 +91,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_SetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -100,9 +103,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -111,9 +115,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_FreePrivateData(LPDIRECT3DINDEXB
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -122,9 +127,10 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_SetPriority(LPDIRECT3DINDEXBUFFER9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -133,9 +139,10 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_GetPriority(LPDIRECT3DINDEXBUFFER9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -143,9 +150,9 @@ static void WINAPI IDirect3DIndexBuffer9Impl_PreLoad(LPDIRECT3DINDEXBUFFER9 ifac
     IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) {
@@ -161,9 +168,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Lock(LPDIRECT3DINDEXBUFFER9 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -172,9 +180,10 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -184,9 +193,9 @@ static HRESULT  WINAPI        IDirect3DIndexBuffer9Impl_GetDesc(LPDIRECT3DINDEXB
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
@@ -223,14 +232,13 @@ static const IDirect3DIndexBuffer9Vtbl Direct3DIndexBuffer9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DIndexBuffer9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DIndexBuffer9 Methods follow: */
-HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
-                              UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool,
-                              IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) {
-    
+HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT Length, DWORD Usage,
+        D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9 **ppIndexBuffer, HANDLE *pSharedHandle)
+{
     IDirect3DIndexBuffer9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DIndexBuffer9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
-    
+
     TRACE("(%p) Relay\n", This);
     /* Allocate the storage for the device */
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     TRACE("(%p) Relay\n", This);
     /* Allocate the storage for the device */
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
@@ -243,10 +251,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
     object->ref = 1;
     object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
     object->ref = 1;
     object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
             (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
             (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     if (hrc != D3D_OK) {
 
         /* free up object */
     if (hrc != D3D_OK) {
 
         /* free up object */
index 3939f59..3795045 100644 (file)
@@ -56,9 +56,10 @@ static ULONG WINAPI IDirect3DPixelShader9Impl_Release(LPDIRECT3DPIXELSHADER9 ifa
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -72,11 +73,12 @@ static HRESULT WINAPI IDirect3DPixelShader9Impl_GetDevice(LPDIRECT3DPIXELSHADER9
 
     TRACE("(%p) : Relay\n", This);
 
 
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DPixelShader_GetDevice(This->wineD3DPixelShader, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
     IWineD3DPixelShader_GetDevice(This->wineD3DPixelShader, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return D3D_OK;
 }
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return D3D_OK;
 }
@@ -86,9 +88,10 @@ static HRESULT WINAPI IDirect3DPixelShader9Impl_GetFunction(LPDIRECT3DPIXELSHADE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData);
     hr = IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -127,12 +130,14 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(LPDIRECT3DDEVICE9EX iface,
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
             &object->wineD3DPixelShader, (IUnknown *)object);
     hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
             &object->wineD3DPixelShader, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
-    if (hrc != D3D_OK) {
+    wined3d_mutex_unlock();
 
 
+    if (hrc != D3D_OK)
+    {
         /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
         HeapFree(GetProcessHeap(), 0 , object);
         /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
         HeapFree(GetProcessHeap(), 0 , object);
@@ -152,9 +157,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShader(LPDIRECT3DDEVICE9EX iface, ID
     IDirect3DPixelShader9Impl *shader = (IDirect3DPixelShader9Impl *)pShader;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DPixelShader9Impl *shader = (IDirect3DPixelShader9Impl *)pShader;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
     IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return D3D_OK;
 }
 
     return D3D_OK;
 }
 
@@ -169,7 +175,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(LPDIRECT3DDEVICE9EX iface, ID
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (SUCCEEDED(hrc))
     {
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (SUCCEEDED(hrc))
     {
@@ -187,7 +193,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(LPDIRECT3DDEVICE9EX iface, ID
     {
         WARN("(%p) : Call to IWineD3DDevice_GetPixelShader failed %u (device %p)\n", This, hrc, This->WineD3DDevice);
     }
     {
         WARN("(%p) : Call to IWineD3DDevice_GetPixelShader failed %u (device %p)\n", This, hrc, This->WineD3DDevice);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
@@ -196,11 +202,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(LPDIRECT3DDEVICE9EX iface, ID
 HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantF(LPDIRECT3DDEVICE9EX iface, UINT Register, CONST float* pConstantData, UINT Vector4fCount) {
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
 HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantF(LPDIRECT3DDEVICE9EX iface, UINT Register, CONST float* pConstantData, UINT Vector4fCount) {
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
-    TRACE("(%p) Relay\n", This);   
+    TRACE("(%p) Relay\n", This);
 
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -210,9 +217,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantF(LPDIRECT3DDEVICE9EX
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -222,9 +229,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_SetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -233,9 +241,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_GetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -244,9 +253,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_SetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -255,8 +265,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_GetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
     return hr;
 }
index 6e4b20a..a17d2e8 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DQuery9Impl_Release(LPDIRECT3DQUERY9 iface) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DQuery_Release(This->wineD3DQuery);
         IWineD3DQuery_Release(This->wineD3DQuery);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,7 +75,7 @@ static HRESULT WINAPI IDirect3DQuery9Impl_GetDevice(LPDIRECT3DQUERY9 iface, IDir
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DQuery_GetDevice(This->wineD3DQuery, &pDevice);
     if(hr != D3D_OK){
         *ppDevice = NULL;
     hr = IWineD3DQuery_GetDevice(This->wineD3DQuery, &pDevice);
     if(hr != D3D_OK){
         *ppDevice = NULL;
@@ -82,7 +83,8 @@ static HRESULT WINAPI IDirect3DQuery9Impl_GetDevice(LPDIRECT3DQUERY9 iface, IDir
         hr = IWineD3DDevice_GetParent(pDevice, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(pDevice);
     }
         hr = IWineD3DDevice_GetParent(pDevice, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(pDevice);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -91,9 +93,10 @@ static D3DQUERYTYPE WINAPI IDirect3DQuery9Impl_GetType(LPDIRECT3DQUERY9 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DQuery_GetType(This->wineD3DQuery);
     hr = IWineD3DQuery_GetType(This->wineD3DQuery);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -102,9 +105,10 @@ static DWORD WINAPI IDirect3DQuery9Impl_GetDataSize(LPDIRECT3DQUERY9 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DQuery_GetDataSize(This->wineD3DQuery);
     ret = IWineD3DQuery_GetDataSize(This->wineD3DQuery);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -113,9 +117,10 @@ static HRESULT WINAPI IDirect3DQuery9Impl_Issue(LPDIRECT3DQUERY9 iface, DWORD dw
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DQuery_Issue(This->wineD3DQuery, dwIssueFlags);
     hr = IWineD3DQuery_Issue(This->wineD3DQuery, dwIssueFlags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -124,9 +129,10 @@ static HRESULT WINAPI IDirect3DQuery9Impl_GetData(LPDIRECT3DQUERY9 iface, void*
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DQuery_GetData(This->wineD3DQuery, pData, dwSize, dwGetDataFlags);
     hr = IWineD3DQuery_GetData(This->wineD3DQuery, pData, dwSize, dwGetDataFlags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -154,9 +160,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(LPDIRECT3DDEVICE9EX iface, D3DQU
 
     if (!ppQuery)
     {
 
     if (!ppQuery)
     {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, NULL, NULL);
         hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, NULL, NULL);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         return hr;
     }
 
         return hr;
     }
 
@@ -169,9 +176,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(LPDIRECT3DDEVICE9EX iface, D3DQU
 
     object->lpVtbl = &Direct3DQuery9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DQuery9_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, &object->wineD3DQuery, (IUnknown *)object);
     hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, &object->wineD3DQuery, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (FAILED(hr)) {
 
 
     if (FAILED(hr)) {
 
index d17233f..29ff5b3 100644 (file)
@@ -57,9 +57,10 @@ static ULONG WINAPI IDirect3DStateBlock9Impl_Release(LPDIRECT3DSTATEBLOCK9 iface
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,25 +74,27 @@ static HRESULT WINAPI IDirect3DStateBlock9Impl_GetDevice(LPDIRECT3DSTATEBLOCK9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DStateBlock9Impl_Capture(LPDIRECT3DSTATEBLOCK9 iface) {
     IDirect3DStateBlock9Impl *This = (IDirect3DStateBlock9Impl *)iface;
     HRESULT hr;
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DStateBlock9Impl_Capture(LPDIRECT3DSTATEBLOCK9 iface) {
     IDirect3DStateBlock9Impl *This = (IDirect3DStateBlock9Impl *)iface;
     HRESULT hr;
-    TRACE("(%p) Relay\n", This); 
+    TRACE("(%p) Relay\n", This);
 
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -100,9 +103,10 @@ static HRESULT WINAPI IDirect3DStateBlock9Impl_Apply(LPDIRECT3DSTATEBLOCK9 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -125,7 +129,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(LPDIRECT3DDEVICE9EX iface,
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
    IDirect3DStateBlock9Impl* object;
    HRESULT hrc = D3D_OK;
    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
    IDirect3DStateBlock9Impl* object;
    HRESULT hrc = D3D_OK;
-   
+
    TRACE("(%p) Relay\n", This);
 
    if(Type != D3DSBT_ALL         && Type != D3DSBT_PIXELSTATE &&
    TRACE("(%p) Relay\n", This);
 
    if(Type != D3DSBT_ALL         && Type != D3DSBT_PIXELSTATE &&
@@ -133,15 +137,16 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(LPDIRECT3DDEVICE9EX iface,
        WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
        return D3DERR_INVALIDCALL;
    }
        WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
        return D3DERR_INVALIDCALL;
    }
-   
+
    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock9Impl));
    if (NULL == object) return E_OUTOFMEMORY;
    object->lpVtbl = &Direct3DStateBlock9_Vtbl;
    object->ref = 1;
    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock9Impl));
    if (NULL == object) return E_OUTOFMEMORY;
    object->lpVtbl = &Direct3DStateBlock9_Vtbl;
    object->ref = 1;
-   
-   EnterCriticalSection(&d3d9_cs);
+
+   wined3d_mutex_lock();
    hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown*)object);
    hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown*)object);
-   LeaveCriticalSection(&d3d9_cs);
+   wined3d_mutex_unlock();
+
    if(hrc != D3D_OK){
        FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This);
        HeapFree(GetProcessHeap(), 0, object);
    if(hrc != D3D_OK){
        FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This);
        HeapFree(GetProcessHeap(), 0, object);
@@ -155,37 +160,41 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(LPDIRECT3DDEVICE9EX iface,
    return hrc;
 }
 
    return hrc;
 }
 
-HRESULT  WINAPI  IDirect3DDevice9Impl_BeginStateBlock(LPDIRECT3DDEVICE9EX iface) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
+HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
-HRESULT  WINAPI  IDirect3DDevice9Impl_EndStateBlock(LPDIRECT3DDEVICE9EX iface, IDirect3DStateBlock9** ppSB) {
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;   
+HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **ppSB)
+{
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+    IWineD3DStateBlock *wineD3DStateBlock;
+    IDirect3DStateBlock9Impl *object;
     HRESULT hr;
     HRESULT hr;
-    IWineD3DStateBlock* wineD3DStateBlock;    
-    IDirect3DStateBlock9Impl* object;
 
 
-    TRACE("(%p) Relay\n", This); 
-    
+    TRACE("(%p) Relay\n", This);
+
     /* Tell wineD3D to endstateblock before anything else (in case we run out
     /* Tell wineD3D to endstateblock before anything else (in case we run out
-     * of memory later and cause locking problems)
-     */
-    EnterCriticalSection(&d3d9_cs);
+     * of memory later and cause locking problems) */
+    wined3d_mutex_lock();
     hr=IWineD3DDevice_EndStateBlock(This->WineD3DDevice,&wineD3DStateBlock);
     hr=IWineD3DDevice_EndStateBlock(This->WineD3DDevice,&wineD3DStateBlock);
-    LeaveCriticalSection(&d3d9_cs);
-    if(hr!= D3D_OK){
+    wined3d_mutex_unlock();
+
+    if (hr!= D3D_OK)
+    {
        WARN("IWineD3DDevice_EndStateBlock returned an error\n");
        return hr;
        WARN("IWineD3DDevice_EndStateBlock returned an error\n");
        return hr;
-    }    
+    }
     /* allocate a new IDirectD3DStateBlock */
     /* allocate a new IDirectD3DStateBlock */
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY ,sizeof(IDirect3DStateBlock9Impl));      
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock9Impl));
     if (!object) return E_OUTOFMEMORY;
     object->ref = 1;
     object->lpVtbl = &Direct3DStateBlock9_Vtbl;
     if (!object) return E_OUTOFMEMORY;
     object->ref = 1;
     object->lpVtbl = &Direct3DStateBlock9_Vtbl;
index f95c387..b4defaf 100644 (file)
@@ -78,9 +78,10 @@ static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
         if (ref == 0) {
             if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
             if (!This->isImplicit) {
         if (ref == 0) {
             if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
             if (!This->isImplicit) {
-                EnterCriticalSection(&d3d9_cs);
+                wined3d_mutex_lock();
                 IWineD3DSurface_Release(This->wineD3DSurface);
                 IWineD3DSurface_Release(This->wineD3DSurface);
-                LeaveCriticalSection(&d3d9_cs);
+                wined3d_mutex_unlock();
+
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
@@ -96,14 +97,15 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDevice(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -112,9 +114,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_SetPrivateData(LPDIRECT3DSURFACE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -123,9 +126,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetPrivateData(LPDIRECT3DSURFACE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -134,9 +138,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_FreePrivateData(LPDIRECT3DSURFACE9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -145,9 +150,10 @@ static DWORD WINAPI IDirect3DSurface9Impl_SetPriority(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_SetPriority(This->wineD3DSurface, PriorityNew);
     hr = IWineD3DSurface_SetPriority(This->wineD3DSurface, PriorityNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -156,9 +162,10 @@ static DWORD WINAPI IDirect3DSurface9Impl_GetPriority(LPDIRECT3DSURFACE9 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetPriority(This->wineD3DSurface);
     hr = IWineD3DSurface_GetPriority(This->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -166,10 +173,9 @@ static void WINAPI IDirect3DSurface9Impl_PreLoad(LPDIRECT3DSURFACE9 iface) {
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DSurface_PreLoad(This->wineD3DSurface);
     IWineD3DSurface_PreLoad(This->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
-    return ;
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 iface) {
@@ -177,9 +183,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 i
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DSurface_GetType(This->wineD3DSurface);
     ret = IWineD3DSurface_GetType(This->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -205,28 +212,25 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetContainer(LPDIRECT3DSURFACE9 ifac
 
 static HRESULT WINAPI IDirect3DSurface9Impl_GetDesc(LPDIRECT3DSURFACE9 iface, D3DSURFACE_DESC* pDesc) {
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
 
 static HRESULT WINAPI IDirect3DSurface9Impl_GetDesc(LPDIRECT3DSURFACE9 iface, D3DSURFACE_DESC* pDesc) {
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
-    WINED3DSURFACE_DESC    wined3ddesc;
-    UINT                   tmpInt = -1;
-    WINED3DFORMAT format;
+    WINED3DSURFACE_DESC wined3ddesc;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = &format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt;
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.MultiSampleQuality  = &pDesc->MultiSampleQuality;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->MultiSampleQuality = wined3ddesc.multisample_quality;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -236,10 +240,11 @@ static HRESULT WINAPI IDirect3DSurface9Impl_LockRect(LPDIRECT3DSURFACE9 iface, D
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
     hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
     hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -248,9 +253,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_UnlockRect(LPDIRECT3DSURFACE9 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
@@ -263,9 +269,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDC(LPDIRECT3DSURFACE9 iface, HDC*
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_GetDC(This->wineD3DSurface, phdc);
     hr = IWineD3DSurface_GetDC(This->wineD3DSurface, phdc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -274,9 +281,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_ReleaseDC(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSurface_ReleaseDC(This->wineD3DSurface, hdc);
     hr = IWineD3DSurface_ReleaseDC(This->wineD3DSurface, hdc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     switch(hr) {
         case WINEDDERR_NODC:    return WINED3DERR_INVALIDCALL;
         default:                return hr;
     switch(hr) {
         case WINEDDERR_NODC:    return WINED3DERR_INVALIDCALL;
         default:                return hr;
index 4f639b1..fb66807 100644 (file)
@@ -62,9 +62,10 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface)
     if (ref == 0) {
         if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
         if (!This->isImplicit) {
     if (ref == 0) {
         if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
         if (!This->isImplicit) {
-            EnterCriticalSection(&d3d9_cs);
+            wined3d_mutex_lock();
             IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D9CB_DestroyRenderTarget);
             IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D9CB_DestroyRenderTarget);
-            LeaveCriticalSection(&d3d9_cs);
+            wined3d_mutex_unlock();
+
             HeapFree(GetProcessHeap(), 0, This);
         }
     }
             HeapFree(GetProcessHeap(), 0, This);
         }
     }
@@ -78,9 +79,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -90,9 +91,10 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain,  ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
     hr = IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain,  ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -103,13 +105,14 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &mySurface);
     if (hrc == D3D_OK && NULL != mySurface) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
        IWineD3DSurface_Release(mySurface);
     }
     hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &mySurface);
     if (hrc == D3D_OK && NULL != mySurface) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
        IWineD3DSurface_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */
     return hrc;
 }
     /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */
     return hrc;
 }
@@ -119,9 +122,10 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAI
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -130,9 +134,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, (WINED3DDISPLAYMODE *) pMode);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -146,13 +150,14 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DSwapChain_GetDevice(This->wineD3DSwapChain, &device);
     if (hrc == D3D_OK && NULL != device) {
        IWineD3DDevice_GetParent(device, (IUnknown **)ppDevice);
        IWineD3DDevice_Release(device);
     }
     hrc = IWineD3DSwapChain_GetDevice(This->wineD3DSwapChain, &device);
     if (hrc == D3D_OK && NULL != device) {
        IWineD3DDevice_GetParent(device, (IUnknown **)ppDevice);
        IWineD3DDevice_Release(device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -163,9 +168,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWA
 
     TRACE("(%p)->(%p): Relay\n", This, pPresentationParameters);
 
 
     TRACE("(%p)->(%p): Relay\n", This, pPresentationParameters);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, &winePresentParameters);
     hr = IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, &winePresentParameters);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     pPresentationParameters->BackBufferWidth            = winePresentParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = winePresentParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth            = winePresentParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = winePresentParameters.BackBufferHeight;
@@ -240,10 +245,10 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
     localParameters.AutoRestoreDisplayMode              = TRUE;
 
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
     localParameters.AutoRestoreDisplayMode              = TRUE;
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown*)object, SURFACE_OPENGL);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown*)object, SURFACE_OPENGL);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
@@ -280,7 +285,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UI
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetSwapChain(This->WineD3DDevice, iSwapChain, &swapchain);
     if (hrc == D3D_OK && NULL != swapchain) {
        IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)pSwapChain);
     hrc = IWineD3DDevice_GetSwapChain(This->WineD3DDevice, iSwapChain, &swapchain);
     if (hrc == D3D_OK && NULL != swapchain) {
        IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)pSwapChain);
@@ -288,7 +293,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UI
     } else {
         *pSwapChain = NULL;
     }
     } else {
         *pSwapChain = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -297,8 +303,9 @@ UINT     WINAPI  IDirect3DDevice9Impl_GetNumberOfSwapChains(LPDIRECT3DDEVICE9EX
     UINT ret;
     TRACE("(%p) Relay\n", This);
 
     UINT ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
     ret = IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
     return ret;
 }
index f0a9c38..7db7037 100644 (file)
@@ -59,9 +59,10 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,14 +76,15 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetDevice(LPDIRECT3DTEXTURE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -91,9 +93,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_SetPrivateData(LPDIRECT3DTEXTURE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -102,9 +105,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetPrivateData(LPDIRECT3DTEXTURE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -113,9 +117,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_FreePrivateData(LPDIRECT3DTEXTURE9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -124,9 +129,10 @@ static DWORD WINAPI IDirect3DTexture9Impl_SetPriority(LPDIRECT3DTEXTURE9 iface,
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -135,9 +141,10 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetPriority(LPDIRECT3DTEXTURE9 iface)
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -145,9 +152,9 @@ static void WINAPI IDirect3DTexture9Impl_PreLoad(LPDIRECT3DTEXTURE9 iface) {
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 iface) {
@@ -155,9 +162,10 @@ static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 i
     HRESULT ret;
     TRACE("(%p) Relay\n", This);
 
     HRESULT ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetType(This->wineD3DTexture);
     ret = IWineD3DTexture_GetType(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -167,9 +175,10 @@ static DWORD WINAPI IDirect3DTexture9Impl_SetLOD(LPDIRECT3DTEXTURE9 iface, DWORD
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -178,9 +187,10 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetLOD(LPDIRECT3DTEXTURE9 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -189,9 +199,10 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetLevelCount(LPDIRECT3DTEXTURE9 iface
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -200,9 +211,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_SetAutoGenFilterType(LPDIRECT3DTEXTU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_SetAutoGenFilterType(This->wineD3DTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
     hr = IWineD3DTexture_SetAutoGenFilterType(This->wineD3DTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -211,9 +223,10 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DTexture9Impl_GetAutoGenFilterType(LP
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DTexture_GetAutoGenFilterType(This->wineD3DTexture);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DTexture_GetAutoGenFilterType(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return ret;
 }
 
     return ret;
 }
 
@@ -221,38 +234,34 @@ static void WINAPI IDirect3DTexture9Impl_GenerateMipSubLevels(LPDIRECT3DTEXTURE9
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DTexture_GenerateMipSubLevels(This->wineD3DTexture);
     IWineD3DTexture_GenerateMipSubLevels(This->wineD3DTexture);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 /* IDirect3DTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DTexture9Impl_GetLevelDesc(LPDIRECT3DTEXTURE9 iface, UINT Level, D3DSURFACE_DESC* pDesc) {
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
 }
 
 /* IDirect3DTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DTexture9Impl_GetLevelDesc(LPDIRECT3DTEXTURE9 iface, UINT Level, D3DSURFACE_DESC* pDesc) {
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
-
-    WINED3DSURFACE_DESC    wined3ddesc;
-    UINT                   tmpInt = -1;
-    HRESULT                hr;
-    WINED3DFORMAT format;
+    WINED3DSURFACE_DESC wined3ddesc;
+    HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = &format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt; /* required for d3d8 */
-    wined3ddesc.MultiSampleType     = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
-    wined3ddesc.MultiSampleQuality  = &pDesc->MultiSampleQuality;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
+        pDesc->Type = wined3ddesc.resource_type;
+        pDesc->Usage = wined3ddesc.usage;
+        pDesc->Pool = wined3ddesc.pool;
+        pDesc->MultiSampleType = wined3ddesc.multisample_type;
+        pDesc->MultiSampleQuality = wined3ddesc.multisample_quality;
+        pDesc->Width = wined3ddesc.width;
+        pDesc->Height = wined3ddesc.height;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -263,13 +272,15 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE9 i
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppSurfaceLevel) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel);
        IWineD3DSurface_Release(mySurface);
     }
     hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface);
     if (hrc == D3D_OK && NULL != ppSurfaceLevel) {
        IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel);
        IWineD3DSurface_Release(mySurface);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hrc;
 }
 
     return hrc;
 }
 
@@ -278,9 +289,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_LockRect(LPDIRECT3DTEXTURE9 iface, U
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -289,9 +301,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_UnlockRect(LPDIRECT3DTEXTURE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -300,9 +313,10 @@ static HRESULT WINAPI IDirect3DTexture9Impl_AddDirtyRect(LPDIRECT3DTEXTURE9 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -343,7 +357,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
     IDirect3DTexture9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DTexture9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
-    
+
     TRACE("(%p) : W(%d) H(%d), Lvl(%d) d(%d), Fmt(%#x), Pool(%d)\n", This, Width, Height, Levels, Usage, Format,  Pool);
 
     /* Allocate the storage for the device */
     TRACE("(%p) : W(%d) H(%d), Lvl(%d) d(%d), Fmt(%#x), Pool(%d)\n", This, Width, Height, Levels, Usage, Format,  Pool);
 
     /* Allocate the storage for the device */
@@ -356,12 +370,14 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
 
     object->lpVtbl = &Direct3DTexture9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DTexture9_Vtbl;
     object->ref = 1;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
             wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
-    if (FAILED(hrc)) {
+    wined3d_mutex_unlock();
 
 
+    if (FAILED(hrc))
+    {
         /* free up object */
         WARN("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
         HeapFree(GetProcessHeap(), 0, object);
         /* free up object */
         WARN("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
         HeapFree(GetProcessHeap(), 0, object);
index 501db41..226e113 100644 (file)
@@ -58,9 +58,10 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,14 +75,15 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDevice(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -91,9 +93,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEX
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -103,9 +105,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -114,9 +117,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_FreePrivateData(LPDIRECT3DVERTE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -125,9 +129,10 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -136,9 +141,10 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -146,10 +152,9 @@ static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 if
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
-    return ;
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
@@ -165,9 +170,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Lock(LPDIRECT3DVERTEXBUFFER9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -176,9 +182,10 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -188,9 +195,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = D3DFMT_VERTEXDATA;
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = D3DFMT_VERTEXDATA;
@@ -228,10 +235,9 @@ static const IDirect3DVertexBuffer9Vtbl Direct3DVertexBuffer9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DVertexBuffer9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DVertexBuffer9 Methods follow: */
-HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface,
-                                UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool,
-                                IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) {
-    
+HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT Size, DWORD Usage,
+        DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle)
+{
     IDirect3DVertexBuffer9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVertexBuffer9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
@@ -246,11 +252,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface
     object->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
     object->ref = 1;
     object->fvf = FVF;
     object->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
     object->ref = 1;
     object->fvf = FVF;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
             0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), (IUnknown *)object);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
             0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
-    
+    wined3d_mutex_unlock();
+
     if (hrc != D3D_OK) {
 
         /* free up object */
     if (hrc != D3D_OK) {
 
         /* free up object */
index 38f0751..4ae4751 100644 (file)
@@ -87,8 +87,7 @@ HRESULT vdecl_convert_fvf(
 
     /* convert the declaration */
     elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(D3DVERTEXELEMENT9));
 
     /* convert the declaration */
     elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(D3DVERTEXELEMENT9));
-    if (!elements) 
-        return D3DERR_OUTOFVIDEOMEMORY;
+    if (!elements) return D3DERR_OUTOFVIDEOMEMORY;
 
     elements[size-1] = end_element;
     idx = 0;
 
     elements[size-1] = end_element;
     idx = 0;
@@ -230,9 +229,11 @@ void IDirect3DVertexDeclaration9Impl_Destroy(LPDIRECT3DVERTEXDECLARATION9 iface)
         /* Should not happen unless wine has a bug or the application releases references it does not own */
         ERR("Destroying vdecl with ref != 0\n");
     }
         /* Should not happen unless wine has a bug or the application releases references it does not own */
         ERR("Destroying vdecl with ref != 0\n");
     }
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration);
     IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     HeapFree(GetProcessHeap(), 0, This->elements);
     HeapFree(GetProcessHeap(), 0, This);
 }
     HeapFree(GetProcessHeap(), 0, This->elements);
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -262,13 +263,14 @@ static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDevice(LPDIRECT3DVERTEX
 
     TRACE("(%p) : Relay\n", iface);
 
 
     TRACE("(%p) : Relay\n", iface);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVertexDeclaration_GetDevice(This->wineD3DVertexDeclaration, &myDevice);
     if (hr == D3D_OK && myDevice != NULL) {
         hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(myDevice);
     }
     hr = IWineD3DVertexDeclaration_GetDevice(This->wineD3DVertexDeclaration, &myDevice);
     if (hr == D3D_OK && myDevice != NULL) {
         hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(myDevice);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -348,8 +350,9 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elem
 }
 
 /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */
 }
 
 /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */
-HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9EX iface, CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) {
-    
+HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
+        const D3DVERTEXELEMENT9 *pVertexElements, IDirect3DVertexDeclaration9 **ppDecl)
+{
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DVertexDeclaration9Impl *object = NULL;
     WINED3DVERTEXELEMENT* wined3d_elements;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DVertexDeclaration9Impl *object = NULL;
     WINED3DVERTEXELEMENT* wined3d_elements;
@@ -392,10 +395,10 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9E
     CopyMemory(object->elements, pVertexElements, element_count * sizeof(D3DVERTEXELEMENT9));
     object->element_count = element_count;
 
     CopyMemory(object->elements, pVertexElements, element_count * sizeof(D3DVERTEXELEMENT9));
     object->element_count = element_count;
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wineD3DVertexDeclaration,
             (IUnknown *)object, wined3d_elements, wined3d_element_count);
     hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wineD3DVertexDeclaration,
             (IUnknown *)object, wined3d_elements, wined3d_element_count);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
 
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
@@ -421,9 +424,10 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_SetVertexDeclaration(LPDIRECT3DDEVICE9EX i
 
     TRACE("(%p) : Relay\n", iface);
 
 
     TRACE("(%p) : Relay\n", iface);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration);
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -439,7 +443,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetVertexDeclaration(LPDIRECT3DDEVICE9EX i
     }
 
     *ppDecl = NULL;
     }
 
     *ppDecl = NULL;
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &pTest);
     if (hr == D3D_OK && NULL != pTest) {
         IWineD3DVertexDeclaration_GetParent(pTest, (IUnknown **)ppDecl);
     hr = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &pTest);
     if (hr == D3D_OK && NULL != pTest) {
         IWineD3DVertexDeclaration_GetParent(pTest, (IUnknown **)ppDecl);
@@ -447,7 +452,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetVertexDeclaration(LPDIRECT3DDEVICE9EX i
     } else {
         *ppDecl = NULL;
     }
     } else {
         *ppDecl = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     TRACE("(%p) : returning %p\n", This, *ppDecl);
     return hr;
 }
     TRACE("(%p) : returning %p\n", This, *ppDecl);
     return hr;
 }
index fd2837d..8a5d5bc 100644 (file)
@@ -56,9 +56,10 @@ static ULONG WINAPI IDirect3DVertexShader9Impl_Release(LPDIRECT3DVERTEXSHADER9 i
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DVertexShader_Release(This->wineD3DVertexShader);
         IWineD3DVertexShader_Release(This->wineD3DVertexShader);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -72,7 +73,7 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetDevice(LPDIRECT3DVERTEXSHADE
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVertexShader_GetDevice(This->wineD3DVertexShader, &myDevice);
     if (WINED3D_OK == hr && myDevice != NULL) {
         hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     hr = IWineD3DVertexShader_GetDevice(This->wineD3DVertexShader, &myDevice);
     if (WINED3D_OK == hr && myDevice != NULL) {
         hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
@@ -80,7 +81,8 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetDevice(LPDIRECT3DVERTEXSHADE
     } else {
         *ppDevice = NULL;
     }
     } else {
         *ppDevice = NULL;
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return hr;
 }
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return hr;
 }
@@ -90,9 +92,10 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetFunction(LPDIRECT3DVERTEXSHA
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData);
     hr = IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -125,9 +128,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(LPDIRECT3DDEVICE9EX iface
 
     object->ref = 1;
     object->lpVtbl = &Direct3DVertexShader9_Vtbl;
 
     object->ref = 1;
     object->lpVtbl = &Direct3DVertexShader9_Vtbl;
-    EnterCriticalSection(&d3d9_cs);
-    hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, NULL /* declaration */, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
-    LeaveCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
+    hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pFunction,
+            NULL /* output signature */, &object->wineD3DVertexShader, (IUnknown *)object);
+    wined3d_mutex_unlock();
 
     if (FAILED(hrc)) {
 
 
     if (FAILED(hrc)) {
 
@@ -150,9 +155,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShader(LPDIRECT3DDEVICE9EX iface, I
     HRESULT hrc = D3D_OK;
 
     TRACE("(%p) : Relay\n", This);
     HRESULT hrc = D3D_OK;
 
     TRACE("(%p) : Relay\n", This);
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, pShader==NULL?NULL:((IDirect3DVertexShader9Impl *)pShader)->wineD3DVertexShader);
     hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, pShader==NULL?NULL:((IDirect3DVertexShader9Impl *)pShader)->wineD3DVertexShader);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
     return hrc;
 
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
     return hrc;
@@ -164,7 +170,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShader(LPDIRECT3DDEVICE9EX iface, I
     HRESULT hrc = D3D_OK;
 
     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
     HRESULT hrc = D3D_OK;
 
     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
     if (SUCCEEDED(hrc))
     {
     hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
     if (SUCCEEDED(hrc))
     {
@@ -182,7 +189,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShader(LPDIRECT3DDEVICE9EX iface, I
     {
         WARN("(%p) : Call to IWineD3DDevice_GetVertexShader failed %u (device %p)\n", This, hrc, This->WineD3DDevice);
     }
     {
         WARN("(%p) : Call to IWineD3DDevice_GetVertexShader failed %u (device %p)\n", This, hrc, This->WineD3DDevice);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 }
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 }
@@ -198,9 +206,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -215,9 +224,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     }
 
     TRACE("(%p) : Relay\n", This);
     }
 
     TRACE("(%p) : Relay\n", This);
-    EnterCriticalSection(&d3d9_cs);
+
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -226,9 +237,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_SetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -237,9 +249,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_GetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -248,9 +261,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_SetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_SetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
 
     return hr;
 }
 
@@ -259,8 +273,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DDevice_GetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_GetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
+
     return hr;
 }
     return hr;
 }
index 93b06b5..9f1252a 100644 (file)
@@ -72,9 +72,10 @@ static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) {
         TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
         if (ref == 0) {
         TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
         if (ref == 0) {
-            EnterCriticalSection(&d3d9_cs);
+            wined3d_mutex_lock();
             IWineD3DVolume_Release(This->wineD3DVolume);
             IWineD3DVolume_Release(This->wineD3DVolume);
-            LeaveCriticalSection(&d3d9_cs);
+            wined3d_mutex_unlock();
+
             HeapFree(GetProcessHeap(), 0, This);
         }
 
             HeapFree(GetProcessHeap(), 0, This);
         }
 
@@ -89,13 +90,13 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetDevice(LPDIRECT3DVOLUME9 iface, ID
 
     TRACE("iface %p, ppDevice %p\n", iface, ppDevice);
 
 
     TRACE("iface %p, ppDevice %p\n", iface, ppDevice);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
 
 
     IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return D3D_OK;
 }
 
     return D3D_OK;
 }
@@ -106,11 +107,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_SetPrivateData(LPDIRECT3DVOLUME9 ifac
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
 
 
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -121,11 +122,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetPrivateData(LPDIRECT3DVOLUME9 ifac
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
 
 
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -136,11 +137,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_FreePrivateData(LPDIRECT3DVOLUME9 ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
 
 
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -167,29 +168,26 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetContainer(LPDIRECT3DVOLUME9 iface,
 static HRESULT WINAPI IDirect3DVolume9Impl_GetDesc(LPDIRECT3DVOLUME9 iface, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
 static HRESULT WINAPI IDirect3DVolume9Impl_GetDesc(LPDIRECT3DVOLUME9 iface, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
-    UINT                   tmpInt = -1;
-    WINED3DFORMAT format;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = &format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-    wined3ddesc.Depth               = &pDesc->Depth;
-
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
 
 
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
 
-    LeaveCriticalSection(&d3d9_cs);
-
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+    wined3d_mutex_unlock();
+
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format);
+        pDesc->Type = wined3ddesc.Type;
+        pDesc->Usage = wined3ddesc.Usage;
+        pDesc->Pool = wined3ddesc.Pool;
+        pDesc->Width = wined3ddesc.Width;
+        pDesc->Height = wined3ddesc.Height;
+        pDesc->Depth = wined3ddesc.Depth;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -200,12 +198,12 @@ static HRESULT WINAPI IDirect3DVolume9Impl_LockBox(LPDIRECT3DVOLUME9 iface, D3DL
 
     TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
 
 
     TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
 
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -216,11 +214,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_UnlockBox(LPDIRECT3DVOLUME9 iface) {
 
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
 
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
 
 
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
index 07b686f..31b90bc 100644 (file)
@@ -58,9 +58,10 @@ static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
-        EnterCriticalSection(&d3d9_cs);
+        wined3d_mutex_lock();
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
-        LeaveCriticalSection(&d3d9_cs);
+        wined3d_mutex_unlock();
+
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,14 +76,14 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetDevice(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
     hr = IWineD3DStateBlock_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
         IWineD3DDevice_Release(wined3d_device);
     }
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -93,11 +94,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetPrivateData(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
 
 
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -108,11 +109,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetPrivateData(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
 
 
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -123,11 +124,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_FreePrivateData(LPDIRECT3DVOLU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
 
 
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -138,11 +139,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetPriority(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     priority = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
 
 
     priority = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return priority;
 }
 
     return priority;
 }
@@ -153,11 +154,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetPriority(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     priority = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
 
 
     priority = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return priority;
 }
 
     return priority;
 }
@@ -167,11 +168,11 @@ static void WINAPI IDirect3DVolumeTexture9Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
 
 
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
@@ -180,11 +181,11 @@ static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
 
 
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return type;
 }
 
     return type;
 }
@@ -196,11 +197,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     lod = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
 
 
     lod = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return lod;
 }
 
     return lod;
 }
@@ -211,11 +212,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     lod = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
 
 
     lod = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return lod;
 }
 
     return lod;
 }
@@ -226,11 +227,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLevelCount(LPDIRECT3DVOLUMETE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     level_count = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
 
 
     level_count = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return level_count;
 }
 
     return level_count;
 }
@@ -241,11 +242,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetAutoGenFilterType(LPDIRECT3
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
 
 
     hr = IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -256,11 +257,11 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DVolumeTexture9Impl_GetAutoGenFilterT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     filter_type = (D3DTEXTUREFILTERTYPE)IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
 
 
     filter_type = (D3DTEXTUREFILTERTYPE)IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return filter_type;
 }
 
     return filter_type;
 }
@@ -270,40 +271,37 @@ static void WINAPI IDirect3DVolumeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DVO
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     IWineD3DVolumeTexture_GenerateMipSubLevels(This->wineD3DVolumeTexture);
 
 
     IWineD3DVolumeTexture_GenerateMipSubLevels(This->wineD3DVolumeTexture);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 }
 
 /* IDirect3DVolumeTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE9 iface, UINT Level, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
 }
 
 /* IDirect3DVolumeTexture9 Interface follow: */
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE9 iface, UINT Level, D3DVOLUME_DESC* pDesc) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
-    UINT                   tmpInt = -1;
-    WINED3DFORMAT format;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
-    /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = &format;
-    wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
-    wined3ddesc.Usage               = &pDesc->Usage;
-    wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
-    wined3ddesc.Size                = &tmpInt;
-    wined3ddesc.Width               = &pDesc->Width;
-    wined3ddesc.Height              = &pDesc->Height;
-    wined3ddesc.Depth               = &pDesc->Depth;
-
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
 
 
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+    if (SUCCEEDED(hr))
+    {
+        pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format);
+        pDesc->Type = wined3ddesc.Type;
+        pDesc->Usage = wined3ddesc.Usage;
+        pDesc->Pool = wined3ddesc.Pool;
+        pDesc->Width = wined3ddesc.Width;
+        pDesc->Height = wined3ddesc.Height;
+        pDesc->Depth = wined3ddesc.Depth;
+    }
 
     return hr;
 }
 
     return hr;
 }
@@ -315,7 +313,7 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
     if (hrc == D3D_OK && NULL != ppVolumeLevel) {
 
     hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
     if (hrc == D3D_OK && NULL != ppVolumeLevel) {
@@ -323,7 +321,7 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUM
        IWineD3DVolumeTexture_Release(myVolume);
     }
 
        IWineD3DVolumeTexture_Release(myVolume);
     }
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hrc;
 }
 
     return hrc;
 }
@@ -334,12 +332,12 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_LockBox(LPDIRECT3DVOLUMETEXTUR
 
     TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
 
 
     TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
 
     hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -350,11 +348,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_UnlockBox(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
 
 
     TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
 
 
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -365,11 +363,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_AddDirtyBox(LPDIRECT3DVOLUMETE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
 
 
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     return hr;
 }
 
     return hr;
 }
@@ -407,11 +405,10 @@ static const IDirect3DVolumeTexture9Vtbl Direct3DVolumeTexture9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DVolumeTexture9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DVolumeTexture9 Methods follow: */
-HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX iface,
-                                                          UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, 
-                                                          D3DFORMAT Format, D3DPOOL Pool, 
-                                                          IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) {
-
+HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
+        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format,
+        D3DPOOL Pool, IDirect3DVolumeTexture9 **ppVolumeTexture, HANDLE *pSharedHandle)
+{
     IDirect3DVolumeTexture9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
     IDirect3DVolumeTexture9Impl *object;
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hrc = D3D_OK;
@@ -428,13 +425,13 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX if
     object->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
     object->ref = 1;
 
-    EnterCriticalSection(&d3d9_cs);
+    wined3d_mutex_lock();
 
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
             Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
             Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
 
 
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
             Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
             Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
 
-    LeaveCriticalSection(&d3d9_cs);
+    wined3d_mutex_unlock();
 
     if (hrc != D3D_OK) {
 
 
     if (hrc != D3D_OK) {
 
index 7011afa..0d1b6dd 100644 (file)
@@ -816,7 +816,7 @@ IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
 
     EnterCriticalSection(&ddraw_cs);
     /* This seems sane */
 
     EnterCriticalSection(&ddraw_cs);
     /* This seems sane */
-    if(!DDSD) 
+    if (!DDSD)
     {
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
     {
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
@@ -841,7 +841,7 @@ IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
     DDSD->dwSize = Size;
     DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE;
     DDSD->dwWidth = Mode.Width;
     DDSD->dwSize = Size;
     DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE;
     DDSD->dwWidth = Mode.Width;
-    DDSD->dwHeight = Mode.Height; 
+    DDSD->dwHeight = Mode.Height;
     DDSD->u2.dwRefreshRate = 60;
     DDSD->ddsCaps.dwCaps = 0;
     DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat);
     DDSD->u2.dwRefreshRate = 60;
     DDSD->ddsCaps.dwCaps = 0;
     DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat);
@@ -1101,7 +1101,7 @@ IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
  * Returns:
  *  Always returns DD_OK
  *
  * Returns:
  *  Always returns DD_OK
  *
- *****************************************************************************/ 
+ *****************************************************************************/
 static HRESULT WINAPI
 IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
                                      DWORD Flags,
 static HRESULT WINAPI
 IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
                                      DWORD Flags,
@@ -1135,7 +1135,7 @@ IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
  * Returns:
  *  Always returns DD_OK
  *
  * Returns:
  *  Always returns DD_OK
  *
- *****************************************************************************/ 
+ *****************************************************************************/
 static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
 static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
@@ -1155,7 +1155,7 @@ static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Sc
                                   &Mode);
 
     /* Fake the line sweeping of the monitor */
                                   &Mode);
 
     /* Fake the line sweeping of the monitor */
-    /* FIXME: We should synchronize with a source to keep the refresh rate */ 
+    /* FIXME: We should synchronize with a source to keep the refresh rate */
     *Scanline = This->cur_scanline++;
     /* Assume 20 scan lines in the vertical blank */
     if (This->cur_scanline >= Mode.Height + 20)
     *Scanline = This->cur_scanline++;
     /* Assume 20 scan lines in the vertical blank */
     if (This->cur_scanline >= Mode.Height + 20)
@@ -1176,7 +1176,7 @@ static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Sc
  *  DDERR_NOEXCLUSIVEMODE or DDERR_EXCLUSIVEMODEALREADYSET
  *  if the state is not correct(See below)
  *
  *  DDERR_NOEXCLUSIVEMODE or DDERR_EXCLUSIVEMODEALREADYSET
  *  if the state is not correct(See below)
  *
- *****************************************************************************/ 
+ *****************************************************************************/
 static HRESULT WINAPI
 IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
 {
 static HRESULT WINAPI
 IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
 {
@@ -1187,8 +1187,8 @@ IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
     EnterCriticalSection(&ddraw_cs);
     /* Description from MSDN:
      * For fullscreen apps return DDERR_NOEXCLUSIVEMODE if the user switched
     EnterCriticalSection(&ddraw_cs);
     /* Description from MSDN:
      * For fullscreen apps return DDERR_NOEXCLUSIVEMODE if the user switched
-     * away from the app with e.g. alt-tab. Windowed apps receive 
-     * DDERR_EXCLUSIVEMODEALREADYSET if another application created a 
+     * away from the app with e.g. alt-tab. Windowed apps receive
+     * DDERR_EXCLUSIVEMODEALREADYSET if another application created a
      * DirectDraw object in exclusive mode. DDERR_WRONGMODE is returned,
      * when the video mode has changed
      */
      * DirectDraw object in exclusive mode. DDERR_WRONGMODE is returned,
      * when the video mode has changed
      */
@@ -1243,7 +1243,7 @@ IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
  *  DD_OK if the surface was found
  *  DDERR_NOTFOUND if the GDI surface wasn't found
  *
  *  DD_OK if the surface was found
  *  DDERR_NOTFOUND if the GDI surface wasn't found
  *
- *****************************************************************************/ 
+ *****************************************************************************/
 static HRESULT WINAPI
 IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
                               IDirectDrawSurface7 **GDISurface)
 static HRESULT WINAPI
 IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
                               IDirectDrawSurface7 **GDISurface)
@@ -1311,7 +1311,7 @@ IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
  *  DD_OK on success
  *  DDERR_INVALIDPARAMS if the callback wasn't set
  *
  *  DD_OK on success
  *  DDERR_INVALIDPARAMS if the callback wasn't set
  *
- *****************************************************************************/ 
+ *****************************************************************************/
 static HRESULT WINAPI
 IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
                                  DWORD Flags,
 static HRESULT WINAPI
 IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
                                  DWORD Flags,
@@ -1664,10 +1664,8 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
 
     WINED3DSURFACE_DESC     Desc;
     WINED3DFORMAT           Format;
 
     WINED3DSURFACE_DESC     Desc;
     WINED3DFORMAT           Format;
-    WINED3DRESOURCETYPE     Type;
     DWORD                   Usage;
     WINED3DPOOL             Pool;
     DWORD                   Usage;
     WINED3DPOOL             Pool;
-    UINT                    Size;
 
     WINED3DMULTISAMPLE_TYPE MultiSampleType;
     DWORD                   MultiSampleQuality;
 
     WINED3DMULTISAMPLE_TYPE MultiSampleType;
     DWORD                   MultiSampleQuality;
@@ -1702,19 +1700,17 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
     IWineD3DSurface_GetClipper(wineD3DSurface, &clipper);
 
     /* Get the surface properties */
     IWineD3DSurface_GetClipper(wineD3DSurface, &clipper);
 
     /* Get the surface properties */
-    Desc.Format = &Format;
-    Desc.Type = &Type;
-    Desc.Usage = &Usage;
-    Desc.Pool = &Pool;
-    Desc.Size = &Size;
-    Desc.MultiSampleType = &MultiSampleType;
-    Desc.MultiSampleQuality = &MultiSampleQuality;
-    Desc.Width = &Width;
-    Desc.Height = &Height;
-
     hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc);
     if(hr != D3D_OK) return hr;
 
     hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc);
     if(hr != D3D_OK) return hr;
 
+    Format = Desc.format;
+    Usage = Desc.usage;
+    Pool = Desc.pool;
+    MultiSampleType = Desc.multisample_type;
+    MultiSampleQuality = Desc.multisample_quality;
+    Width = Desc.width;
+    Height = Desc.height;
+
     if(swapchain) {
         /* If there's a swapchain, it owns the IParent interface. Create a new one for the
          * new surface
     if(swapchain) {
         /* If there's a swapchain, it owns the IParent interface. Create a new one for the
          * new surface
@@ -1729,7 +1725,7 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
     /* Create the new surface */
     hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format,
             TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface,
     /* Create the new surface */
     hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format,
             TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface,
-            Type, Usage, Pool, MultiSampleType, MultiSampleQuality, This->ImplType, Parent);
+            Usage, Pool, MultiSampleType, MultiSampleQuality, This->ImplType, Parent);
 
     if(hr != D3D_OK)
         return hr;
 
     if(hr != D3D_OK)
         return hr;
@@ -1840,9 +1836,8 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
                                  UINT level)
 {
     HRESULT hr;
                                  UINT level)
 {
     HRESULT hr;
-    UINT Width = 0, Height = 0;
+    UINT Width, Height;
     WINED3DFORMAT Format = WINED3DFMT_UNKNOWN;
     WINED3DFORMAT Format = WINED3DFMT_UNKNOWN;
-    WINED3DRESOURCETYPE ResType = WINED3DRTYPE_SURFACE;
     DWORD Usage = 0;
     WINED3DSURFTYPE ImplType = This->ImplType;
     WINED3DSURFACE_DESC Desc;
     DWORD Usage = 0;
     WINED3DSURFTYPE ImplType = This->ImplType;
     WINED3DSURFACE_DESC Desc;
@@ -1850,12 +1845,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
     IParentImpl *parImpl = NULL;
     WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
 
     IParentImpl *parImpl = NULL;
     WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
 
-    /* Dummies for GetDesc */
-    WINED3DPOOL dummy_d3dpool;
-    WINED3DMULTISAMPLE_TYPE dummy_mst;
-    UINT dummy_uint;
-    DWORD dummy_dword;
-
     if (TRACE_ON(ddraw))
     {
         TRACE(" (%p) Requesting surface desc :\n", This);
     if (TRACE_ON(ddraw))
     {
         TRACE(" (%p) Requesting surface desc :\n", This);
@@ -1897,8 +1886,9 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
     }
     else
     {
     }
     else
     {
-         if((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE ) && 
-            (This->ImplType != SURFACE_OPENGL ) && DefaultSurfaceType == SURFACE_UNKNOWN)
+        if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
+                && (This->ImplType != SURFACE_OPENGL)
+                && DefaultSurfaceType == SURFACE_UNKNOWN)
         {
             /* We have to change to OpenGL,
              * and re-create all WineD3DSurfaces
         {
             /* We have to change to OpenGL,
              * and re-create all WineD3DSurfaces
@@ -2026,8 +2016,8 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
 
     /* Now create the WineD3D Surface */
     hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
 
     /* Now create the WineD3D Surface */
     hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
-            TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface, ResType, Usage,
-            Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType, Parent);
+            TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface,
+            Usage, Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType, Parent);
 
     if(hr != D3D_OK)
     {
 
     if(hr != D3D_OK)
     {
@@ -2058,16 +2048,6 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
      * Don't use the Format choosen above, WineD3D might have
      * changed it
      */
      * Don't use the Format choosen above, WineD3D might have
      * changed it
      */
-    Desc.Format = &Format;
-    Desc.Type = &ResType;
-    Desc.Usage = &Usage;
-    Desc.Pool = &dummy_d3dpool;
-    Desc.Size = &dummy_uint;
-    Desc.MultiSampleType = &dummy_mst;
-    Desc.MultiSampleQuality = &dummy_dword;
-    Desc.Width = &Width;
-    Desc.Height = &Height;
-
     (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
     hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc);
     if(hr != D3D_OK)
     (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
     hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc);
     if(hr != D3D_OK)
@@ -2077,6 +2057,10 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
         return hr;
     }
 
         return hr;
     }
 
+    Format = Desc.format;
+    Width = Desc.width;
+    Height = Desc.height;
+
     if(Format == WINED3DFMT_UNKNOWN)
     {
         FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n");
     if(Format == WINED3DFMT_UNKNOWN)
     {
         FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n");
index 3b7778f..09bc3e6 100644 (file)
@@ -94,7 +94,7 @@ static inline WORD d3d_fpu_setup(void)
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
- * IUnknown Methods. Common for Version 1, 2, 3 and 7 
+ * IUnknown Methods. Common for Version 1, 2, 3 and 7
  *****************************************************************************/
 
 /*****************************************************************************
  *****************************************************************************/
 
 /*****************************************************************************
@@ -2558,7 +2558,6 @@ IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
                 BOOL tex_alpha = FALSE;
                 IWineD3DBaseTexture *tex = NULL;
                 WINED3DSURFACE_DESC desc;
                 BOOL tex_alpha = FALSE;
                 IWineD3DBaseTexture *tex = NULL;
                 WINED3DSURFACE_DESC desc;
-                WINED3DFORMAT fmt;
                 DDPIXELFORMAT ddfmt;
 
                 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
                 DDPIXELFORMAT ddfmt;
 
                 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
@@ -2567,13 +2566,11 @@ IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
 
                 if(hr == WINED3D_OK && tex)
                 {
 
                 if(hr == WINED3D_OK && tex)
                 {
-                    memset(&desc, 0, sizeof(desc));
-                    desc.Format = &fmt;
                     hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
                     if (SUCCEEDED(hr))
                     {
                         ddfmt.dwSize = sizeof(ddfmt);
                     hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
                     if (SUCCEEDED(hr))
                     {
                         ddfmt.dwSize = sizeof(ddfmt);
-                        PixelFormat_WineD3DtoDD(&ddfmt, fmt);
+                        PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
                         if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
                     }
 
                         if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
                     }
 
@@ -2642,7 +2639,7 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
     {
         case D3DRENDERSTATE_TEXTUREMAG:
         {
     {
         case D3DRENDERSTATE_TEXTUREMAG:
         {
-            WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
+            WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT;
 
             switch ((D3DTEXTUREFILTER) Value)
             {
 
             switch ((D3DTEXTUREFILTER) Value)
             {
@@ -2666,7 +2663,7 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
 
         case D3DRENDERSTATE_TEXTUREMIN:
         {
 
         case D3DRENDERSTATE_TEXTUREMIN:
         {
-            WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
+            WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT;
             WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
 
             switch ((D3DTEXTUREFILTER) Value)
             WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
 
             switch ((D3DTEXTUREFILTER) Value)
@@ -2678,11 +2675,11 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
                     tex_min = WINED3DTEXF_LINEAR;
                     break;
                 case D3DFILTER_MIPNEAREST:
                     tex_min = WINED3DTEXF_LINEAR;
                     break;
                 case D3DFILTER_MIPNEAREST:
-                    tex_min = WINED3DTEXF_NONE;
+                    tex_min = WINED3DTEXF_POINT;
                     tex_mip = WINED3DTEXF_POINT;
                     break;
                 case D3DFILTER_MIPLINEAR:
                     tex_mip = WINED3DTEXF_POINT;
                     break;
                 case D3DFILTER_MIPLINEAR:
-                    tex_min = WINED3DTEXF_NONE;
+                    tex_min = WINED3DTEXF_POINT;
                     tex_mip = WINED3DTEXF_LINEAR;
                     break;
                 case D3DFILTER_LINEARMIPNEAREST:
                     tex_mip = WINED3DTEXF_LINEAR;
                     break;
                 case D3DFILTER_LINEARMIPNEAREST:
@@ -2833,7 +2830,6 @@ IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
                     BOOL tex_alpha = FALSE;
                     IWineD3DBaseTexture *tex = NULL;
                     WINED3DSURFACE_DESC desc;
                     BOOL tex_alpha = FALSE;
                     IWineD3DBaseTexture *tex = NULL;
                     WINED3DSURFACE_DESC desc;
-                    WINED3DFORMAT fmt;
                     DDPIXELFORMAT ddfmt;
 
                     hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
                     DDPIXELFORMAT ddfmt;
 
                     hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
@@ -2843,12 +2839,11 @@ IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
                     if(hr == WINED3D_OK && tex)
                     {
                         memset(&desc, 0, sizeof(desc));
                     if(hr == WINED3D_OK && tex)
                     {
                         memset(&desc, 0, sizeof(desc));
-                        desc.Format = &fmt;
                         hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
                         if (SUCCEEDED(hr))
                         {
                             ddfmt.dwSize = sizeof(ddfmt);
                         hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
                         if (SUCCEEDED(hr))
                         {
                             ddfmt.dwSize = sizeof(ddfmt);
-                            PixelFormat_WineD3DtoDD(&ddfmt, fmt);
+                            PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
                             if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
                         }
 
                             if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
                         }
 
@@ -2961,7 +2956,7 @@ IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
 
     TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
 
 
     TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
 
-    if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
+    if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
     {
         TRACE("Unexpected Light State Type\n");
         return DDERR_INVALIDPARAMS;
     {
         TRACE("Unexpected Light State Type\n");
         return DDERR_INVALIDPARAMS;
@@ -3094,7 +3089,7 @@ IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
 
     TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
 
 
     TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
 
-    if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
+    if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
     {
         TRACE("Unexpected Light State Type\n");
         return DDERR_INVALIDPARAMS;
     {
         TRACE("Unexpected Light State Type\n");
         return DDERR_INVALIDPARAMS;
@@ -4507,7 +4502,7 @@ IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
 
     EnterCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
 
     EnterCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
-    if( (hr != D3D_OK) || (!Surf) ) 
+    if( (hr != D3D_OK) || (!Surf) )
     {
         *Texture = NULL;
         LeaveCriticalSection(&ddraw_cs);
     {
         *Texture = NULL;
         LeaveCriticalSection(&ddraw_cs);
@@ -4648,7 +4643,6 @@ IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
         BOOL tex_alpha = FALSE;
         IWineD3DBaseTexture *tex = NULL;
         WINED3DSURFACE_DESC desc;
         BOOL tex_alpha = FALSE;
         IWineD3DBaseTexture *tex = NULL;
         WINED3DSURFACE_DESC desc;
-        WINED3DFORMAT fmt;
         DDPIXELFORMAT ddfmt;
         HRESULT result;
 
         DDPIXELFORMAT ddfmt;
         HRESULT result;
 
@@ -4659,12 +4653,11 @@ IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
         if(result == WINED3D_OK && tex)
         {
             memset(&desc, 0, sizeof(desc));
         if(result == WINED3D_OK && tex)
         {
             memset(&desc, 0, sizeof(desc));
-            desc.Format = &fmt;
             result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
             if (SUCCEEDED(result))
             {
                 ddfmt.dwSize = sizeof(ddfmt);
             result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
             if (SUCCEEDED(result))
             {
                 ddfmt.dwSize = sizeof(ddfmt);
-                PixelFormat_WineD3DtoDD(&ddfmt, fmt);
+                PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
                 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
             }
 
                 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
             }
 
@@ -5309,7 +5302,7 @@ IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
     TRACE("(%p)->(%p): Relay!\n", This, Mat);
 
     EnterCriticalSection(&ddraw_cs);
     TRACE("(%p)->(%p): Relay!\n", This, Mat);
 
     EnterCriticalSection(&ddraw_cs);
-    /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */ 
+    /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
     hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
                                     (WINED3DMATERIAL*) Mat);
     LeaveCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
                                     (WINED3DMATERIAL*) Mat);
     LeaveCriticalSection(&ddraw_cs);
@@ -5944,8 +5937,8 @@ static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
                               IDirectDrawSurfaceImpl *dest,
                               IDirectDrawSurfaceImpl *src,
 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
                               IDirectDrawSurfaceImpl *dest,
                               IDirectDrawSurfaceImpl *src,
-                              POINT *DestPoint,
-                              RECT *SrcRect)
+                              const POINT *DestPoint,
+                              const RECT *SrcRect)
 {
     IDirectDrawSurfaceImpl *src_level, *dest_level;
     IDirectDrawSurface7 *temp;
 {
     IDirectDrawSurfaceImpl *src_level, *dest_level;
     IDirectDrawSurface7 *temp;
index 9ce0d36..88d5f2f 100644 (file)
@@ -1324,7 +1324,7 @@ IDirect3DImpl_GetCaps(IWineD3D *WineD3D,
     Desc7->dwStencilCaps &= (
         D3DSTENCILCAPS_KEEP              | D3DSTENCILCAPS_ZERO                 | D3DSTENCILCAPS_REPLACE              |
         D3DSTENCILCAPS_INCRSAT           | D3DSTENCILCAPS_DECRSAT              | D3DSTENCILCAPS_INVERT               |
     Desc7->dwStencilCaps &= (
         D3DSTENCILCAPS_KEEP              | D3DSTENCILCAPS_ZERO                 | D3DSTENCILCAPS_REPLACE              |
         D3DSTENCILCAPS_INCRSAT           | D3DSTENCILCAPS_DECRSAT              | D3DSTENCILCAPS_INVERT               |
-        D3DSTENCILCAPS_INCR              | D3DSTENCILCAPS_DECR                 | D3DSTENCILCAPS_TWOSIDED);
+        D3DSTENCILCAPS_INCR              | D3DSTENCILCAPS_DECR);
 
     /* FVF caps ?*/
 
 
     /* FVF caps ?*/
 
index 3ff794d..996c558 100644 (file)
@@ -227,14 +227,14 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
                     } else if(lpDevice->Handles[ci->u2.dwArg[0] - 1].type != DDrawHandle_Matrix) {
                         ERR("Handle %d is not a matrix handle\n", ci->u2.dwArg[0]);
                     } else {
                     } else if(lpDevice->Handles[ci->u2.dwArg[0] - 1].type != DDrawHandle_Matrix) {
                         ERR("Handle %d is not a matrix handle\n", ci->u2.dwArg[0]);
                     } else {
-                        if(ci->u1.drstRenderStateType == D3DTRANSFORMSTATE_WORLD)
+                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD)
                             lpDevice->world = ci->u2.dwArg[0];
                             lpDevice->world = ci->u2.dwArg[0];
-                        if(ci->u1.drstRenderStateType == D3DTRANSFORMSTATE_VIEW)
+                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW)
                             lpDevice->view = ci->u2.dwArg[0];
                             lpDevice->view = ci->u2.dwArg[0];
-                        if(ci->u1.drstRenderStateType == D3DTRANSFORMSTATE_PROJECTION)
+                        if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION)
                             lpDevice->proj = ci->u2.dwArg[0];
                         IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)lpDevice,
                             lpDevice->proj = ci->u2.dwArg[0];
                         IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)lpDevice,
-                                ci->u1.drstRenderStateType, (LPD3DMATRIX)lpDevice->Handles[ci->u2.dwArg[0] - 1].ptr);
+                                ci->u1.dtstTransformStateType, (LPD3DMATRIX)lpDevice->Handles[ci->u2.dwArg[0] - 1].ptr);
                     }
                    instr += size;
                }
                     }
                    instr += size;
                }
@@ -249,7 +249,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 
                    TRACE("(%08x,%08x)\n", ci->u1.dlstLightStateType, ci->u2.dwArg[0]);
 
 
                    TRACE("(%08x,%08x)\n", ci->u1.dlstLightStateType, ci->u2.dwArg[0]);
 
-                   if (!ci->u1.dlstLightStateType && (ci->u1.dlstLightStateType > D3DLIGHTSTATE_COLORVERTEX))
+                   if (!ci->u1.dlstLightStateType || (ci->u1.dlstLightStateType > D3DLIGHTSTATE_COLORVERTEX))
                        ERR("Unexpected Light State Type\n");
                    else if (ci->u1.dlstLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
                        DWORD matHandle = ci->u2.dwArg[0];
                        ERR("Unexpected Light State Type\n");
                    else if (ci->u1.dlstLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) {
                        DWORD matHandle = ci->u2.dwArg[0];
@@ -317,7 +317,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 
                for (i = 0; i < count; i++) {
                    LPD3DSTATE ci = (LPD3DSTATE) instr;
 
                for (i = 0; i < count; i++) {
                    LPD3DSTATE ci = (LPD3DSTATE) instr;
-                   
+
                     IDirect3DDevice2_SetRenderState(d3d_device2, ci->u1.drstRenderStateType, ci->u2.dwArg[0]);
 
                    instr += size;
                     IDirect3DDevice2_SetRenderState(d3d_device2, ci->u1.drstRenderStateType, ci->u2.dwArg[0]);
 
                    instr += size;
@@ -369,33 +369,33 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
                            TRACE("UPDATEEXTENTS ");
                        TRACE("\n");
                    }
                            TRACE("UPDATEEXTENTS ");
                        TRACE("\n");
                    }
-                   
+
                    /* This is where doing Direct3D on top on OpenGL is quite difficult.
                       This method transforms a set of vertices using the CURRENT state
                       (lighting, projection, ...) but does not rasterize them.
                       They will only be put on screen later (with the POINT / LINE and
                       TRIANGLE op-codes). The problem is that you can have a triangle
                       with each point having been transformed using another state...
                    /* This is where doing Direct3D on top on OpenGL is quite difficult.
                       This method transforms a set of vertices using the CURRENT state
                       (lighting, projection, ...) but does not rasterize them.
                       They will only be put on screen later (with the POINT / LINE and
                       TRIANGLE op-codes). The problem is that you can have a triangle
                       with each point having been transformed using another state...
-                      
+
                       In this implementation, I will emulate only ONE thing : each
                       vertex can have its own "WORLD" transformation (this is used in the
                       TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
                       execute buffer use the same state.
                       In this implementation, I will emulate only ONE thing : each
                       vertex can have its own "WORLD" transformation (this is used in the
                       TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
                       execute buffer use the same state.
-                      
+
                       If I find applications that change other states, I will try to do a
                       more 'fine-tuned' state emulation (but I may become quite tricky if
                       it changes a light position in the middle of a triangle).
                       If I find applications that change other states, I will try to do a
                       more 'fine-tuned' state emulation (but I may become quite tricky if
                       it changes a light position in the middle of a triangle).
-                      
+
                       In this case, a 'direct' approach (i.e. without using OpenGL, but
                       writing our own 3D rasterizer) would be easier. */
                       In this case, a 'direct' approach (i.e. without using OpenGL, but
                       writing our own 3D rasterizer) would be easier. */
-                   
+
                    /* The current method (with the hypothesis that only the WORLD matrix
                       will change between two points) is like this :
                       - I transform 'manually' all the vertices with the current WORLD
                         matrix and store them in the vertex buffer
                       - during the rasterization phase, the WORLD matrix will be set to
                         the Identity matrix */
                    /* The current method (with the hypothesis that only the WORLD matrix
                       will change between two points) is like this :
                       - I transform 'manually' all the vertices with the current WORLD
                         matrix and store them in the vertex buffer
                       - during the rasterization phase, the WORLD matrix will be set to
                         the Identity matrix */
-                   
+
                    /* Enough for the moment */
                    if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
                        unsigned int nb;
                    /* Enough for the moment */
                    if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
                        unsigned int nb;
@@ -439,7 +439,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 
                            src++;
                            dst++;
 
                            src++;
                            dst++;
-                           
+
                        }
                    } else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
                        unsigned int nb;
                        }
                    } else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
                        unsigned int nb;
@@ -465,7 +465,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
                            dst->u6.specular = src->u5.specular;
                            dst->u7.tu = src->u6.tu;
                            dst->u8.tv = src->u7.tv;
                            dst->u6.specular = src->u5.specular;
                            dst->u7.tu = src->u6.tu;
                            dst->u8.tv = src->u7.tv;
-                           
+
                            /* Now, the matrix multiplication */
                            dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
                            dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
                            /* Now, the matrix multiplication */
                            dst->u1.sx = (src->u1.x * mat._11) + (src->u2.y * mat._21) + (src->u3.z * mat._31) + (1.0 * mat._41);
                            dst->u2.sy = (src->u1.x * mat._12) + (src->u2.y * mat._22) + (src->u3.z * mat._32) + (1.0 * mat._42);
@@ -551,7 +551,7 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
 
                for (i = 0; i < count; i++) {
                    LPD3DSTATUS ci = (LPD3DSTATUS) instr;
 
                for (i = 0; i < count; i++) {
                    LPD3DSTATUS ci = (LPD3DSTATUS) instr;
-                   
+
                    This->data.dsStatus = *ci;
 
                    instr += size;
                    This->data.dsStatus = *ci;
 
                    instr += size;
@@ -705,7 +705,7 @@ IDirect3DExecuteBufferImpl_Lock(IDirect3DExecuteBuffer *iface,
     dwSize = lpDesc->dwSize;
     memset(lpDesc, 0, dwSize);
     memcpy(lpDesc, &This->desc, dwSize);
     dwSize = lpDesc->dwSize;
     memset(lpDesc, 0, dwSize);
     memcpy(lpDesc, &This->desc, dwSize);
-    
+
     if (TRACE_ON(d3d7)) {
         TRACE("  Returning description :\n");
        _dump_D3DEXECUTEBUFFERDESC(lpDesc);
     if (TRACE_ON(d3d7)) {
         TRACE("  Returning description :\n");
        _dump_D3DEXECUTEBUFFERDESC(lpDesc);
@@ -756,7 +756,7 @@ IDirect3DExecuteBufferImpl_SetExecuteData(IDirect3DExecuteBuffer *iface,
 
     /* Get the number of vertices in the execute buffer */
     nbvert = This->data.dwVertexCount;
 
     /* Get the number of vertices in the execute buffer */
     nbvert = This->data.dwVertexCount;
-    
+
     /* Prepares the transformed vertex buffer */
     HeapFree(GetProcessHeap(), 0, This->vertex_data);
     This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX));
     /* Prepares the transformed vertex buffer */
     HeapFree(GetProcessHeap(), 0, This->vertex_data);
     This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX));
index 4a759eb..030dcf0 100644 (file)
@@ -179,17 +179,17 @@ IDirect3DLightImpl_SetLight(IDirect3DLight *iface,
 
     if ( (lpLight->dltType == 0) || (lpLight->dltType > D3DLIGHT_PARALLELPOINT) )
          return DDERR_INVALIDPARAMS;
 
     if ( (lpLight->dltType == 0) || (lpLight->dltType > D3DLIGHT_PARALLELPOINT) )
          return DDERR_INVALIDPARAMS;
-    
+
     if ( lpLight->dltType == D3DLIGHT_PARALLELPOINT )
     if ( lpLight->dltType == D3DLIGHT_PARALLELPOINT )
-        FIXME("D3DLIGHT_PARALLELPOINT no supported\n");
-    
+        FIXME("D3DLIGHT_PARALLELPOINT no supported\n");
+
     /* Translate D3DLIGH2 structure to D3DLIGHT7 */
     light7->dltType        = lpLight->dltType;
     light7->dcvDiffuse     = lpLight->dcvColor;
     /* Translate D3DLIGH2 structure to D3DLIGHT7 */
     light7->dltType        = lpLight->dltType;
     light7->dcvDiffuse     = lpLight->dcvColor;
-    if ((((LPD3DLIGHT2)lpLight)->dwFlags & D3DLIGHT_NO_SPECULAR) != 0)     
+    if ((((LPD3DLIGHT2)lpLight)->dwFlags & D3DLIGHT_NO_SPECULAR) != 0)
       light7->dcvSpecular    = lpLight->dcvColor;
     else
       light7->dcvSpecular    = lpLight->dcvColor;
     else
-      light7->dcvSpecular    = *(const D3DCOLORVALUE*)zero_value;          
+      light7->dcvSpecular    = *(const D3DCOLORVALUE*)zero_value;
     light7->dcvAmbient     = lpLight->dcvColor;
     light7->dvPosition     = lpLight->dvPosition;
     light7->dvDirection    = lpLight->dvDirection;
     light7->dcvAmbient     = lpLight->dcvColor;
     light7->dvPosition     = lpLight->dvPosition;
     light7->dvDirection    = lpLight->dvDirection;
@@ -204,7 +204,7 @@ IDirect3DLightImpl_SetLight(IDirect3DLight *iface,
     EnterCriticalSection(&ddraw_cs);
     memcpy(&This->light, lpLight, lpLight->dwSize);
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
     EnterCriticalSection(&ddraw_cs);
     memcpy(&This->light, lpLight, lpLight->dwSize);
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
-        This->update(This);        
+        This->update(This);
     }
     LeaveCriticalSection(&ddraw_cs);
     return D3D_OK;
     }
     LeaveCriticalSection(&ddraw_cs);
     return D3D_OK;
@@ -274,7 +274,7 @@ void light_activate(IDirect3DLightImpl* This)
     if (!This->active_viewport || !This->active_viewport->active_device)
         return;
     device =  This->active_viewport->active_device;
     if (!This->active_viewport || !This->active_viewport->active_device)
         return;
     device =  This->active_viewport->active_device;
-    
+
     light_update(This);
     /* If was not active, activate it */
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
     light_update(This);
     /* If was not active, activate it */
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
@@ -299,7 +299,7 @@ void light_desactivate(IDirect3DLightImpl* This)
     if (!This->active_viewport || !This->active_viewport->active_device)
         return;
     device =  This->active_viewport->active_device;
     if (!This->active_viewport || !This->active_viewport->active_device)
         return;
     device =  This->active_viewport->active_device;
-    
+
     /* If was not active, activate it */
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
         IDirect3DDevice7_LightEnable((IDirect3DDevice7 *)device, This->dwLightIndex, FALSE);
     /* If was not active, activate it */
     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
         IDirect3DDevice7_LightEnable((IDirect3DDevice7 *)device, This->dwLightIndex, FALSE);
index ec4cfde..473152e 100644 (file)
@@ -117,8 +117,7 @@ IParentImpl_AddRef(IParent *iface)
  *  The new refcount
  *
  *****************************************************************************/
  *  The new refcount
  *
  *****************************************************************************/
-static ULONG WINAPI 
-IParentImpl_Release(IParent *iface)
+static ULONG WINAPI IParentImpl_Release(IParent *iface)
 {
     IParentImpl *This = (IParentImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->ref);
 {
     IParentImpl *This = (IParentImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->ref);
index 14fc721..6d92c0d 100644 (file)
@@ -920,9 +920,6 @@ IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl *This,
         IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice);
     }
 
         IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice);
     }
 
-    /* MSDN: 
-     * "This method increments the reference count of the surface being attached."
-     */
     IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)Surf);
     LeaveCriticalSection(&ddraw_cs);
     return DD_OK;
     IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)Surf);
     LeaveCriticalSection(&ddraw_cs);
     return DD_OK;
@@ -1033,7 +1030,7 @@ IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7 *iface,
     IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
     TRACE("(%p)->(%p)\n",This,Rect);
 
     IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface;
     TRACE("(%p)->(%p)\n",This,Rect);
 
-    /* MSDN says it's not implemented. I could forward it to WineD3D, 
+    /* MSDN says it's not implemented. I could forward it to WineD3D,
      * then we'd implement it, but I don't think that's a good idea
      * (Stefan Dösinger)
      */
      * then we'd implement it, but I don't think that's a good idea
      * (Stefan Dösinger)
      */
index 1811492..17b4d34 100644 (file)
@@ -349,7 +349,7 @@ PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat,
 WINED3DFORMAT
 PixelFormat_DD2WineD3D(const DDPIXELFORMAT *DDPixelFormat)
 {
 WINED3DFORMAT
 PixelFormat_DD2WineD3D(const DDPIXELFORMAT *DDPixelFormat)
 {
-    TRACE("Convert a DirectDraw Pixelformat to a WineD3D Pixelformat\n");    
+    TRACE("Convert a DirectDraw Pixelformat to a WineD3D Pixelformat\n");
     if(TRACE_ON(ddraw))
     {
         DDRAW_dump_pixelformat(DDPixelFormat);
     if(TRACE_ON(ddraw))
     {
         DDRAW_dump_pixelformat(DDPixelFormat);
index c6e346e..9b06989 100644 (file)
@@ -84,7 +84,7 @@ void viewport_activate(IDirect3DViewportImpl* This, BOOL ignore_lights) {
        vp.dvMinZ = This->viewports.vp1.dvMinZ;
        vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
     }
        vp.dvMinZ = This->viewports.vp1.dvMinZ;
        vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
     }
-    
+
     /* And also set the viewport */
     IDirect3DDevice7_SetViewport((IDirect3DDevice7 *)This->active_device, &vp);
 }
     /* And also set the viewport */
     IDirect3DDevice7_SetViewport((IDirect3DDevice7 *)This->active_device, &vp);
 }
@@ -657,11 +657,8 @@ IDirect3DViewportImpl_GetBackgroundDepth(IDirect3DViewport3 *iface,
  *  The return value of IDirect3DDevice7::Clear
  *
  *****************************************************************************/
  *  The return value of IDirect3DDevice7::Clear
  *
  *****************************************************************************/
-static HRESULT WINAPI
-IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
-                            DWORD dwCount, 
-                            D3DRECT *lpRects,
-                            DWORD dwFlags)
+static HRESULT WINAPI IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
+        DWORD dwCount, D3DRECT *lpRects, DWORD dwFlags)
 {
     IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface;
     DWORD color = 0x00000000;
 {
     IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface;
     DWORD color = 0x00000000;
@@ -679,14 +676,15 @@ IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
     EnterCriticalSection(&ddraw_cs);
     if (dwFlags & D3DCLEAR_TARGET) {
         if (This->background == NULL) {
     EnterCriticalSection(&ddraw_cs);
     if (dwFlags & D3DCLEAR_TARGET) {
         if (This->background == NULL) {
-           ERR(" Trying to clear the color buffer without background material !\n");
-       } else {
-           color = 
-             ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
-             ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8) |
-             ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0) |
-             ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
-       }
+            ERR(" Trying to clear the color buffer without background material !\n");
+        }
+        else
+        {
+            color = ((int)((This->background->mat.u.diffuse.u1.r) * 255) << 16)
+                    | ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8)
+                    | ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0)
+                    | ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
+        }
     }
 
     /* Need to temporarily activate viewport to clear it. Previously active one will be restored
     }
 
     /* Need to temporarily activate viewport to clear it. Previously active one will be restored
@@ -729,7 +727,7 @@ IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
     IDirect3DLightImpl *lpDirect3DLightImpl = (IDirect3DLightImpl *)lpDirect3DLight;
     DWORD i = 0;
     DWORD map = This->map_lights;
     IDirect3DLightImpl *lpDirect3DLightImpl = (IDirect3DLightImpl *)lpDirect3DLight;
     DWORD i = 0;
     DWORD map = This->map_lights;
-    
+
     TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
 
     EnterCriticalSection(&ddraw_cs);
     TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
 
     EnterCriticalSection(&ddraw_cs);
@@ -755,7 +753,7 @@ IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
 
     /* Attach the light to the viewport */
     lpDirect3DLightImpl->active_viewport = This;
 
     /* Attach the light to the viewport */
     lpDirect3DLightImpl->active_viewport = This;
-    
+
     /* If active, activate the light */
     if (This->active_device != NULL) {
         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
     /* If active, activate the light */
     if (This->active_device != NULL) {
         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
@@ -785,7 +783,7 @@ IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface,
     IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface;
     IDirect3DLightImpl *lpDirect3DLightImpl = (IDirect3DLightImpl *)lpDirect3DLight;
     IDirect3DLightImpl *cur_light, *prev_light = NULL;
     IDirect3DViewportImpl *This = (IDirect3DViewportImpl *)iface;
     IDirect3DLightImpl *lpDirect3DLightImpl = (IDirect3DLightImpl *)lpDirect3DLight;
     IDirect3DLightImpl *cur_light, *prev_light = NULL;
-    
+
     TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
 
     EnterCriticalSection(&ddraw_cs);
     TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
 
     EnterCriticalSection(&ddraw_cs);
index 56ee162..dd35113 100644 (file)
@@ -41,48 +41,242 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION      (*gl_info)
 
 
 #define GLINFO_LOCATION      (*gl_info)
 
-/* We have to subtract any other PARAMs that we might use in our shader programs.
- * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
- * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
-#define ARB_SHADER_RESERVED_VS_CONSTS 3
+/* GL locking for state handlers is done by the caller. */
+static BOOL need_mova_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info)
+{
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) shader;
+    if(!This->baseShader.reg_maps.usesmova) return FALSE;
+    return !GL_SUPPORT(NV_VERTEX_PROGRAM2_OPTION);
+}
 
 
-/* The arb shader only loads the bump mapping environment matrix into the shader if it finds
- * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
- */
-#define ARB_SHADER_RESERVED_PS_CONSTS 2
+/* Returns TRUE if result.clip from GL_NV_vertex_program2 should be used and FALSE otherwise */
+static inline BOOL use_nv_clip(const struct wined3d_gl_info *gl_info)
+{
+    return GL_SUPPORT(NV_VERTEX_PROGRAM2_OPTION);
+}
+
+static BOOL need_helper_const(const struct wined3d_gl_info *gl_info)
+{
+    if (!GL_SUPPORT(NV_VERTEX_PROGRAM) /* Need to init colors. */
+        || gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT /* Load the immval offset. */
+        || gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W /* Have to init texcoords. */
+        || (!use_nv_clip(gl_info)) /* Init the clip texcoord */)
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static unsigned int reserved_vs_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info)
+{
+    unsigned int ret = 1;
+    /* We use one PARAM for the pos fixup, and in some cases one to load
+     * some immediate values into the shader
+     */
+    if(need_helper_const(gl_info)) ret++;
+    if(need_mova_const(shader, gl_info)) ret++;
+    return ret;
+}
+
+static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock)
+{
+    return stateblock->lowest_disabled_stage < 7;
+}
 
 /* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1,
  * so upload them above that
  */
 
 /* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1,
  * so upload them above that
  */
-#define ARB_SHADER_PRIVCONST_BASE (GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS)
+#define ARB_SHADER_PRIVCONST_BASE (GL_LIMITS(vshader_constantsF) - 1)
 #define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0
 
 /* ARB_program_shader private data */
 #define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0
 
 /* ARB_program_shader private data */
-struct shader_arb_priv {
+
+struct control_frame
+{
+    struct                          list entry;
+    enum
+    {
+        IF,
+        IFC,
+        LOOP,
+        REP
+    } type;
+    BOOL                            muting;
+    BOOL                            outer_loop;
+    union
+    {
+        unsigned int                loop_no;
+        unsigned int                ifc_no;
+    };
+    struct wined3d_shader_loop_control loop_control;
+    BOOL                            had_else;
+};
+
+struct arb_ps_np2fixup_info
+{
+    struct ps_np2fixup_info         super;
+    /* For ARB we need a offset value:
+     * With both GLSL and ARB mode the NP2 fixup information (the texture dimensions) are stored in a
+     * consecutive way (GLSL uses a uniform array). Since ARB doesn't know the notion of a "standalone"
+     * array we need an offset to the index inside the program local parameter array. */
+    UINT                            offset;
+};
+
+struct arb_ps_compile_args
+{
+    struct ps_compile_args          super;
+    DWORD                           bools; /* WORD is enough, use DWORD for alignment */
+    unsigned char                   loop_ctrl[MAX_CONST_I][3];
+};
+
+struct stb_const_desc
+{
+    unsigned char           texunit;
+    UINT                    const_num;
+};
+
+struct arb_ps_compiled_shader
+{
+    struct arb_ps_compile_args      args;
+    struct arb_ps_np2fixup_info     np2fixup_info;
+    struct stb_const_desc           bumpenvmatconst[MAX_TEXTURES];
+    struct stb_const_desc           luminanceconst[MAX_TEXTURES];
+    UINT                            int_consts[MAX_CONST_I];
+    GLuint                          prgId;
+    UINT                            ycorrection;
+    unsigned char                   numbumpenvmatconsts;
+    char                            num_int_consts;
+};
+
+struct arb_vs_compile_args
+{
+    struct vs_compile_args          super;
+    union
+    {
+        struct
+        {
+            WORD                    bools;
+            char                    clip_control[2];
+        }                           boolclip;
+        DWORD                       boolclip_compare;
+    };
+    DWORD                           ps_signature;
+    union
+    {
+        unsigned char               vertex_samplers[4];
+        DWORD                       vertex_samplers_compare;
+    };
+    unsigned char                   loop_ctrl[MAX_CONST_I][3];
+};
+
+struct arb_vs_compiled_shader
+{
+    struct arb_vs_compile_args      args;
+    GLuint                          prgId;
+    UINT                            int_consts[MAX_CONST_I];
+    char                            num_int_consts;
+    char                            need_color_unclamp;
+    UINT                            pos_fixup;
+};
+
+struct recorded_instruction
+{
+    struct wined3d_shader_instruction ins;
+    struct list entry;
+};
+
+struct shader_arb_ctx_priv
+{
+    char addr_reg[20];
+    enum
+    {
+        /* plain GL_ARB_vertex_program or GL_ARB_fragment_program */
+        ARB,
+        /* GL_NV_vertex_progam2_option or GL_NV_fragment_program_option */
+        NV2,
+        /* GL_NV_vertex_program3 or GL_NV_fragment_program2 */
+        NV3
+    } target_version;
+
+    const struct arb_vs_compile_args    *cur_vs_args;
+    const struct arb_ps_compile_args    *cur_ps_args;
+    const struct arb_ps_compiled_shader *compiled_fprog;
+    const struct arb_vs_compiled_shader *compiled_vprog;
+    struct arb_ps_np2fixup_info         *cur_np2fixup_info;
+    struct list                         control_frames;
+    struct list                         record;
+    BOOL                                recording;
+    BOOL                                muted;
+    unsigned int                        num_loops, loop_depth, num_ifcs;
+    int                                 aL;
+
+    unsigned int                        vs_clipplanes;
+    BOOL                                footer_written;
+    BOOL                                in_main_func;
+
+    /* For 3.0 vertex shaders */
+    const char                          *vs_output[MAX_REG_OUTPUT];
+    /* For 2.x and earlier vertex shaders */
+    const char                          *texcrd_output[8], *color_output[2], *fog_output;
+
+    /* 3.0 pshader input for compatibility with fixed function */
+    const char                          *ps_input[MAX_REG_INPUT];
+};
+
+struct ps_signature
+{
+    struct wined3d_shader_signature_element *sig;
+    DWORD                               idx;
+    struct wine_rb_entry                entry;
+};
+
+struct arb_pshader_private {
+    struct arb_ps_compiled_shader   *gl_shaders;
+    UINT                            num_gl_shaders, shader_array_size;
+    BOOL                            has_signature_idx;
+    DWORD                           input_signature_idx;
+    DWORD                           clipplane_emulation;
+    BOOL                            clamp_consts;
+};
+
+struct arb_vshader_private {
+    struct arb_vs_compiled_shader   *gl_shaders;
+    UINT                            num_gl_shaders, shader_array_size;
+};
+
+struct shader_arb_priv
+{
     GLuint                  current_vprogram_id;
     GLuint                  current_fprogram_id;
     GLuint                  current_vprogram_id;
     GLuint                  current_fprogram_id;
+    const struct arb_ps_compiled_shader *compiled_fprog;
+    const struct arb_vs_compiled_shader *compiled_vprog;
     GLuint                  depth_blt_vprogram_id;
     GLuint                  depth_blt_fprogram_id[tex_type_count];
     BOOL                    use_arbfp_fixed_func;
     GLuint                  depth_blt_vprogram_id;
     GLuint                  depth_blt_fprogram_id[tex_type_count];
     BOOL                    use_arbfp_fixed_func;
-    struct hash_table_t     *fragment_shaders;
+    struct wine_rb_tree     fragment_shaders;
+    BOOL                    last_ps_const_clamped;
+    BOOL                    last_vs_color_unclamp;
+
+    struct wine_rb_tree     signature_tree;
+    DWORD ps_sig_number;
 };
 
 /********************************************************
  * ARB_[vertex/fragment]_program helper functions follow
  ********************************************************/
 
 };
 
 /********************************************************
  * ARB_[vertex/fragment]_program helper functions follow
  ********************************************************/
 
-/** 
- * Loads floating point constants into the currently set ARB_vertex/fragment_program.
+/* Loads floating point constants into the currently set ARB_vertex/fragment_program.
  * When constant_list == NULL, it will load all the constants.
  * When constant_list == NULL, it will load all the constants.
- *  
+ *
  * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
  *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
  */
  * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
  *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
  */
-static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
     local_constant* lconst;
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
     local_constant* lconst;
-    DWORD i, j;
+    DWORD i = 0, j;
     unsigned int ret;
 
     if (TRACE_ON(d3d_shader)) {
     unsigned int ret;
 
     if (TRACE_ON(d3d_shader)) {
@@ -97,54 +291,65 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con
     if (target_type == GL_FRAGMENT_PROGRAM_ARB && This->baseShader.reg_maps.shader_version.major == 1)
     {
         float lcl_const[4];
     if (target_type == GL_FRAGMENT_PROGRAM_ARB && This->baseShader.reg_maps.shader_version.major == 1)
     {
         float lcl_const[4];
-        for(i = 0; i < max_constants; i++) {
+        /* ps 1.x supports only 8 constants, clamp only those. When switching between 1.x and higher
+         * shaders, the first 8 constants are marked dirty for reload
+         */
+        for(; i < min(8, max_constants); i++) {
             if(!dirty_consts[i]) continue;
             dirty_consts[i] = 0;
 
             j = 4 * i;
             if(!dirty_consts[i]) continue;
             dirty_consts[i] = 0;
 
             j = 4 * i;
-            if(constants[j + 0] > 1.0) lcl_const[0] = 1.0;
-            else if(constants[j + 0] < -1.0) lcl_const[0] = -1.0;
+            if (constants[j + 0] > 1.0f) lcl_const[0] = 1.0f;
+            else if (constants[j + 0] < -1.0f) lcl_const[0] = -1.0f;
             else lcl_const[0] = constants[j + 0];
 
             else lcl_const[0] = constants[j + 0];
 
-            if(constants[j + 1] > 1.0) lcl_const[1] = 1.0;
-            else if(constants[j + 1] < -1.0) lcl_const[1] = -1.0;
+            if (constants[j + 1] > 1.0f) lcl_const[1] = 1.0f;
+            else if (constants[j + 1] < -1.0f) lcl_const[1] = -1.0f;
             else lcl_const[1] = constants[j + 1];
 
             else lcl_const[1] = constants[j + 1];
 
-            if(constants[j + 2] > 1.0) lcl_const[2] = 1.0;
-            else if(constants[j + 2] < -1.0) lcl_const[2] = -1.0;
+            if (constants[j + 2] > 1.0f) lcl_const[2] = 1.0f;
+            else if (constants[j + 2] < -1.0f) lcl_const[2] = -1.0f;
             else lcl_const[2] = constants[j + 2];
 
             else lcl_const[2] = constants[j + 2];
 
-            if(constants[j + 3] > 1.0) lcl_const[3] = 1.0;
-            else if(constants[j + 3] < -1.0) lcl_const[3] = -1.0;
+            if (constants[j + 3] > 1.0f) lcl_const[3] = 1.0f;
+            else if (constants[j + 3] < -1.0f) lcl_const[3] = -1.0f;
             else lcl_const[3] = constants[j + 3];
 
             GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, lcl_const));
         }
             else lcl_const[3] = constants[j + 3];
 
             GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, lcl_const));
         }
-    } else {
-        if(GL_SUPPORT(EXT_GPU_PROGRAM_PARAMETERS)) {
-            /* TODO: Benchmark if we're better of with finding the dirty constants ourselves,
-             * or just reloading *all* constants at once
-             *
-            GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, 0, max_constants, constants));
-             */
-            for(i = 0; i < max_constants; i++) {
-                if(!dirty_consts[i]) continue;
 
 
-                /* Find the next block of dirty constants */
-                dirty_consts[i] = 0;
-                j = i;
-                for(i++; (i < max_constants) && dirty_consts[i]; i++) {
-                    dirty_consts[i] = 0;
-                }
+        /* If further constants are dirty, reload them without clamping.
+         *
+         * The alternative is not to touch them, but then we cannot reset the dirty constant count
+         * to zero. That's bad for apps that only use PS 1.x shaders, because in that case the code
+         * above would always re-check the first 8 constants since max_constant remains at the init
+         * value
+         */
+    }
 
 
-                GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, constants + (j * 4)));
+    if(GL_SUPPORT(EXT_GPU_PROGRAM_PARAMETERS)) {
+        /* TODO: Benchmark if we're better of with finding the dirty constants ourselves,
+         * or just reloading *all* constants at once
+         *
+        GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, i, max_constants, constants + (i * 4)));
+         */
+        for(; i < max_constants; i++) {
+            if(!dirty_consts[i]) continue;
+
+            /* Find the next block of dirty constants */
+            dirty_consts[i] = 0;
+            j = i;
+            for(i++; (i < max_constants) && dirty_consts[i]; i++) {
+                dirty_consts[i] = 0;
             }
             }
-        } else {
-            for(i = 0; i < max_constants; i++) {
-                if(dirty_consts[i]) {
-                    dirty_consts[i] = 0;
-                    GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
-                }
+
+            GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, constants + (j * 4)));
+        }
+    } else {
+        for(; i < max_constants; i++) {
+            if(dirty_consts[i]) {
+                dirty_consts[i] = 0;
+                GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
             }
         }
     }
             }
         }
     }
@@ -180,93 +385,203 @@ static void shader_arb_load_np2fixup_constants(
     IWineD3DDevice* device,
     char usePixelShader,
     char useVertexShader) {
     IWineD3DDevice* device,
     char usePixelShader,
     char useVertexShader) {
-    /* not implemented */
+
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl *) device;
+    const struct shader_arb_priv* const priv = (const struct shader_arb_priv *) deviceImpl->shader_priv;
+    IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
+    const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+
+    if (!usePixelShader) {
+        /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
+        return;
+    }
+
+    if (priv->compiled_fprog && priv->compiled_fprog->np2fixup_info.super.active) {
+        const struct arb_ps_np2fixup_info* const fixup = &priv->compiled_fprog->np2fixup_info;
+        UINT i;
+        WORD active = fixup->super.active;
+        GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+
+        for (i = 0; active; active >>= 1, ++i) {
+            const unsigned char idx = fixup->super.idx[i];
+            const IWineD3DTextureImpl* const tex = (const IWineD3DTextureImpl*) stateBlock->textures[i];
+            GLfloat* tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+
+            if (!(active & 1)) continue;
+
+            if (!tex) {
+                FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
+                continue;
+            }
+
+            if (idx % 2) {
+                tex_dim[2] = tex->baseTexture.pow2Matrix[0]; tex_dim[3] = tex->baseTexture.pow2Matrix[5];
+            } else {
+                tex_dim[0] = tex->baseTexture.pow2Matrix[0]; tex_dim[1] = tex->baseTexture.pow2Matrix[5];
+            }
+        }
+
+        for (i = 0; i < fixup->super.num_consts; ++i) {
+            GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+                                                   fixup->offset + i, &np2fixup_constants[i * 4]));
+        }
+    }
+}
+
+/* GL locking is done by the caller. */
+static inline void shader_arb_ps_local_constants(IWineD3DDeviceImpl* deviceImpl)
+{
+    const struct wined3d_context *context = context_get_current();
+    IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned char i;
+    struct shader_arb_priv *priv = deviceImpl->shader_priv;
+    const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog;
+
+    for(i = 0; i < gl_shader->numbumpenvmatconsts; i++)
+    {
+        int texunit = gl_shader->bumpenvmatconst[i].texunit;
+
+        /* The state manager takes care that this function is always called if the bump env matrix changes */
+        const float *data = (const float *)&stateBlock->textureState[texunit][WINED3DTSS_BUMPENVMAT00];
+        GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->bumpenvmatconst[i].const_num, data));
+
+        if (gl_shader->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED)
+        {
+            /* WINED3DTSS_BUMPENVLSCALE and WINED3DTSS_BUMPENVLOFFSET are next to each other.
+             * point gl to the scale, and load 4 floats. x = scale, y = offset, z and w are junk, we
+             * don't care about them. The pointers are valid for sure because the stateblock is bigger.
+             * (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and WINED3DTSS_ADDRESSW, so most likely 0 or NaN
+            */
+            const float *scale = (const float *)&stateBlock->textureState[texunit][WINED3DTSS_BUMPENVLSCALE];
+            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->luminanceconst[i].const_num, scale));
+        }
+    }
+    checkGLcall("Load bumpmap consts");
+
+    if(gl_shader->ycorrection != WINED3D_CONST_NUM_UNUSED)
+    {
+        /* ycorrection.x: Backbuffer height(onscreen) or 0(offscreen).
+        * ycorrection.y: -1.0(onscreen), 1.0(offscreen)
+        * ycorrection.z: 1.0
+        * ycorrection.w: 0.0
+        */
+        float val[4];
+        val[0] = context->render_offscreen ? 0.0f
+                : ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
+        val[1] = context->render_offscreen ? 1.0f : -1.0f;
+        val[2] = 1.0f;
+        val[3] = 0.0f;
+        GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->ycorrection, val));
+        checkGLcall("y correction loading");
+    }
+
+    if(gl_shader->num_int_consts == 0) return;
+
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
+        {
+            float val[4];
+            val[0] = stateBlock->pixelShaderConstantI[4 * i];
+            val[1] = stateBlock->pixelShaderConstantI[4 * i + 1];
+            val[2] = stateBlock->pixelShaderConstantI[4 * i + 2];
+            val[3] = -1.0f;
+
+            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->int_consts[i], val));
+        }
+    }
+    checkGLcall("Load ps int consts");
+}
+
+/* GL locking is done by the caller. */
+static inline void shader_arb_vs_local_constants(IWineD3DDeviceImpl* deviceImpl)
+{
+    IWineD3DStateBlockImpl* stateBlock;
+    const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+    unsigned char i;
+    struct shader_arb_priv *priv = deviceImpl->shader_priv;
+    const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog;
+
+    /* Upload the position fixup */
+    GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, deviceImpl->posFixup));
+
+    if(gl_shader->num_int_consts == 0) return;
+
+    stateBlock = deviceImpl->stateBlock;
+
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
+        {
+            float val[4];
+            val[0] = stateBlock->vertexShaderConstantI[4 * i];
+            val[1] = stateBlock->vertexShaderConstantI[4 * i + 1];
+            val[2] = stateBlock->vertexShaderConstantI[4 * i + 2];
+            val[3] = -1.0f;
+
+            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->int_consts[i], val));
+        }
+    }
+    checkGLcall("Load vs int consts");
 }
 
 /**
  * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
 }
 
 /**
  * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
- * 
- * We only support float constants in ARB at the moment, so don't 
+ *
+ * We only support float constants in ARB at the moment, so don't
  * worry about the Integers or Booleans
  */
  * worry about the Integers or Booleans
  */
-static void shader_arb_load_constants(
-    IWineD3DDevice* device,
-    char usePixelShader,
-    char useVertexShader) {
-   
-    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device; 
-    IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
-    const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
-    unsigned char i;
+/* GL locking is done by the caller (state handler) */
+static void shader_arb_load_constants(const struct wined3d_context *context, char usePixelShader, char useVertexShader)
+{
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    IWineD3DStateBlockImpl* stateBlock = device->stateBlock;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
 
         /* Load DirectX 9 float constants for vertex shader */
 
     if (useVertexShader) {
         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
 
         /* Load DirectX 9 float constants for vertex shader */
-        deviceImpl->highest_dirty_vs_const = shader_arb_load_constantsF(
-                vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
-                deviceImpl->highest_dirty_vs_const,
-                stateBlock->vertexShaderConstantF,
-                deviceImpl->activeContext->vshader_const_dirty);
-
-        /* Upload the position fixup */
-        GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, ARB_SHADER_PRIVCONST_POS, deviceImpl->posFixup));
+        device->highest_dirty_vs_const = shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
+                device->highest_dirty_vs_const, stateBlock->vertexShaderConstantF, context->vshader_const_dirty);
+        shader_arb_vs_local_constants(device);
     }
 
     if (usePixelShader) {
     }
 
     if (usePixelShader) {
-
         IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
         IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
-        IWineD3DPixelShaderImpl *psi = (IWineD3DPixelShaderImpl *) pshader;
 
         /* Load DirectX 9 float constants for pixel shader */
 
         /* Load DirectX 9 float constants for pixel shader */
-        deviceImpl->highest_dirty_ps_const = shader_arb_load_constantsF(
-                pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
-                deviceImpl->highest_dirty_ps_const,
-                stateBlock->pixelShaderConstantF,
-                deviceImpl->activeContext->pshader_const_dirty);
-
-        for(i = 0; i < psi->numbumpenvmatconsts; i++) {
-            /* The state manager takes care that this function is always called if the bump env matrix changes
-             */
-            const float *data = (const float *)&stateBlock->textureState[(int) psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
-            GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->bumpenvmatconst[i].const_num, data));
-            deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].const_num] = 1;
-
-            if (psi->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED)
-            {
-                /* WINED3DTSS_BUMPENVLSCALE and WINED3DTSS_BUMPENVLOFFSET are next to each other.
-                 * point gl to the scale, and load 4 floats. x = scale, y = offset, z and w are junk, we
-                 * don't care about them. The pointers are valid for sure because the stateblock is bigger.
-                 * (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and WINED3DTSS_ADDRESSW, so most likely 0 or NaN
-                 */
-                const float *scale = (const float *)&stateBlock->textureState[(int) psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];
-                GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, psi->luminanceconst[i].const_num, scale));
-                deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].const_num] = 1;
-            }
-        }
+        device->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
+                device->highest_dirty_ps_const, stateBlock->pixelShaderConstantF, context->pshader_const_dirty);
+        shader_arb_ps_local_constants(device);
     }
 }
 
 static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     }
 }
 
 static void shader_arb_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct wined3d_context *context = context_get_current();
 
     /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
      * context. On a context switch the old context will be fully dirtified */
 
     /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
      * context. On a context switch the old context will be fully dirtified */
-    memset(This->activeContext->vshader_const_dirty + start, 1,
-            sizeof(*This->activeContext->vshader_const_dirty) * count);
-    This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count + 1);
+    if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice != This) return;
+
+    memset(context->vshader_const_dirty + start, 1, sizeof(*context->vshader_const_dirty) * count);
+    This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count);
 }
 
 static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 }
 
 static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct wined3d_context *context = context_get_current();
 
     /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
      * context. On a context switch the old context will be fully dirtified */
 
     /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
      * context. On a context switch the old context will be fully dirtified */
-    memset(This->activeContext->pshader_const_dirty + start, 1,
-            sizeof(*This->activeContext->pshader_const_dirty) * count);
-    This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
+    if (!context || ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice != This) return;
+
+    memset(context->pshader_const_dirty + start, 1, sizeof(*context->pshader_const_dirty) * count);
+    This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count);
 }
 
 static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
 }
 
 static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
@@ -277,7 +592,7 @@ static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
 
     if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL;
 
 
     if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL;
 
-    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.temporary);
+    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.constant_float);
     if(!ret) {
         ERR("Out of memory\n");
         return NULL;
     if(!ret) {
         ERR("Out of memory\n");
         return NULL;
@@ -290,83 +605,75 @@ static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
 }
 
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
 }
 
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
-static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
-        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, DWORD *lconst_map)
+static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
+        struct wined3d_shader_buffer *buffer, const struct wined3d_gl_info *gl_info, DWORD *lconst_map,
+        DWORD *num_clipplanes, struct shader_arb_ctx_priv *ctx)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
-    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
-    DWORD i, cur;
+    DWORD i, next_local = 0;
     char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
     char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
-    unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
-            (pshader ? GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS :
-                       GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS));
-    UINT extra_constants_needed = 0;
+    unsigned max_constantsF;
     const local_constant *lconst;
     const local_constant *lconst;
+    DWORD map;
 
 
-    /* Temporary Output register */
-    shader_addline(buffer, "TEMP TMP_OUT;\n");
+    /* In pixel shaders, all private constants are program local, we don't need anything
+     * from program.env. Thus we can advertise the full set of constants in pixel shaders.
+     * If we need a private constant the GL implementation will squeeze it in somewhere
+     *
+     * With vertex shaders we need the posFixup and on some GL implementations 4 helper
+     * immediate values. The posFixup is loaded using program.env for now, so always
+     * subtract one from the number of constants. If the shader uses indirect addressing,
+     * account for the helper const too because we have to declare all availabke d3d constants
+     * and don't know which are actually used.
+     */
+    if(pshader) {
+        max_constantsF = GL_LIMITS(pshader_constantsF);
+    } else {
+        if(This->baseShader.reg_maps.usesrelconstF) {
+            DWORD highest_constf = 0, clip_limit;
+            max_constantsF = GL_LIMITS(vshader_constantsF) - reserved_vs_const(iface, gl_info);
+            max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants);
 
 
-    for(i = 0; i < This->baseShader.limits.temporary; i++) {
-        if (reg_maps->temporary[i])
-            shader_addline(buffer, "TEMP R%u;\n", i);
-    }
+            for(i = 0; i < This->baseShader.limits.constant_float; i++)
+            {
+                DWORD idx = i >> 5;
+                DWORD shift = i & 0x1f;
+                if(reg_maps->constf[idx] & (1 << shift)) highest_constf = i;
+            }
 
 
-    for (i = 0; i < This->baseShader.limits.address; i++) {
-        if (reg_maps->address[i])
-            shader_addline(buffer, "ADDRESS A%d;\n", i);
+            clip_limit = GL_LIMITS(clipplanes);
+            if(ctx->target_version == ARB) clip_limit = min(clip_limit, 4);
+            *num_clipplanes = min(clip_limit, max_constantsF - highest_constf - 1);
+            max_constantsF -= *num_clipplanes;
+            if(*num_clipplanes < clip_limit)
+            {
+                WARN("Only %u clipplanes out of %u enabled\n", *num_clipplanes, GL_LIMITS(clipplanes));
+            }
+        }
+        else
+        {
+            if(ctx->target_version >= NV2) *num_clipplanes = GL_LIMITS(clipplanes);
+            else *num_clipplanes = min(GL_LIMITS(clipplanes), 4);
+            max_constantsF = GL_LIMITS(vshader_constantsF);
+        }
     }
 
     }
 
-    for(i = 0; i < This->baseShader.limits.texcoord; i++) {
-        if (reg_maps->texcoord[i])
-            shader_addline(buffer,"TEMP T%u;\n", i);
+    for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "TEMP R%u;\n", i);
     }
 
     }
 
-    /* Texture coordinate registers must be pre-loaded */
-    for (i = 0; i < This->baseShader.limits.texcoord; i++) {
-        if (reg_maps->texcoord[i])
-            shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", i, i);
+    for (i = 0, map = reg_maps->address; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "ADDRESS A%u;\n", i);
     }
 
     }
 
-    for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
-        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This;
-        if(!reg_maps->bumpmat[i]) continue;
-
-        cur = ps->numbumpenvmatconsts;
-        ps->bumpenvmatconst[cur].const_num = -1;
-        ps->bumpenvmatconst[cur].texunit = i;
-        ps->luminanceconst[cur].const_num = -1;
-        ps->luminanceconst[cur].texunit = i;
-
-        /* If the shader does not use all available constants, use the next free constant to load the bump mapping environment matrix from
-         * the stateblock into the shader. If no constant is available don't load, texbem will then just sample the texture without applying
-         * bump mapping.
-         */
-        if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) {
-            ps->bumpenvmatconst[cur].const_num = max_constantsF + extra_constants_needed;
-            shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n",
-                           i, ps->bumpenvmatconst[cur].const_num);
-            extra_constants_needed++;
-
-            if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) {
-                ((IWineD3DPixelShaderImpl *)This)->luminanceconst[cur].const_num = max_constantsF + extra_constants_needed;
-                shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n",
-                               i, ps->luminanceconst[cur].const_num);
-                extra_constants_needed++;
-            } else if(reg_maps->luminanceparams) {
-                FIXME("No free constant to load the luminance parameters\n");
-            }
-        } else {
-            FIXME("No free constant found to load environment bump mapping matrix into the shader. texbem instruction will not apply bump mapping\n");
+    if (pshader && reg_maps->shader_version.major == 1 && reg_maps->shader_version.minor <= 3)
+    {
+        for (i = 0, map = reg_maps->texcoord; map; map >>= 1, ++i)
+        {
+            if (map & 1) shader_addline(buffer, "TEMP T%u;\n", i);
         }
         }
-
-        ps->numbumpenvmatconsts = cur + 1;
-    }
-
-    if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
-        shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
-                       srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
-        shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
-                       srgb_sub_high, 0.0, 0.0, 0.0);
     }
 
     /* Load local constants using the program-local space,
     }
 
     /* Load local constants using the program-local space,
@@ -376,6 +683,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
             shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx,
                            lconst_map[lconst->idx]);
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
             shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx,
                            lconst_map[lconst->idx]);
+            next_local = max(next_local, lconst_map[lconst->idx] + 1);
         }
     }
 
         }
     }
 
@@ -399,6 +707,8 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
             }
         }
     }
             }
         }
     }
+
+    return next_local;
 }
 
 static const char * const shift_tab[] = {
 }
 
 static const char * const shift_tab[] = {
@@ -424,14 +734,8 @@ static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *i
         const struct wined3d_shader_dst_param *dst, char *write_mask)
 {
     char *ptr = write_mask;
         const struct wined3d_shader_dst_param *dst, char *write_mask)
 {
     char *ptr = write_mask;
-    char vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
 
 
-    if (vshader && dst->reg.type == WINED3DSPR_ADDR)
-    {
-        *ptr++ = '.';
-        *ptr++ = 'x';
-    }
-    else if (dst->write_mask != WINED3DSP_WRITEMASK_ALL)
+    if (dst->write_mask != WINED3DSP_WRITEMASK_ALL)
     {
         *ptr++ = '.';
         if (dst->write_mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
     {
         *ptr++ = '.';
         if (dst->write_mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
@@ -476,73 +780,207 @@ static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param,
     *ptr = '\0';
 }
 
     *ptr = '\0';
 }
 
-static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADER_PARAM_REGISTER_TYPE register_type,
-        UINT register_idx, BOOL rel_addr, char *register_name, BOOL *is_color)
+static void shader_arb_request_a0(const struct wined3d_shader_instruction *ins, const char *src)
+{
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+
+    if(strcmp(priv->addr_reg, src) == 0) return;
+
+    strcpy(priv->addr_reg, src);
+    shader_addline(buffer, "ARL A0.x, %s;\n", src);
+}
+
+static void shader_arb_get_src_param(const struct wined3d_shader_instruction *ins,
+        const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr);
+
+static void shader_arb_get_register_name(const struct wined3d_shader_instruction *ins,
+        const struct wined3d_shader_register *reg, char *register_name, BOOL *is_color)
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     BOOL pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
     BOOL pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
+    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
 
     *is_color = FALSE;
 
 
     *is_color = FALSE;
 
-    switch (register_type)
+    switch (reg->type)
     {
         case WINED3DSPR_TEMP:
     {
         case WINED3DSPR_TEMP:
-            sprintf(register_name, "R%u", register_idx);
+            sprintf(register_name, "R%u", reg->idx);
             break;
 
         case WINED3DSPR_INPUT:
             if (pshader)
             {
             break;
 
         case WINED3DSPR_INPUT:
             if (pshader)
             {
-                if (register_idx == 0) strcpy(register_name, "fragment.color.primary");
-                else strcpy(register_name, "fragment.color.secondary");
+                if(This->baseShader.reg_maps.shader_version.major < 3)
+                {
+                    if (reg->idx == 0) strcpy(register_name, "fragment.color.primary");
+                    else strcpy(register_name, "fragment.color.secondary");
+                }
+                else
+                {
+                    if(reg->rel_addr)
+                    {
+                        char rel_reg[50];
+                        shader_arb_get_src_param(ins, reg->rel_addr, 0, rel_reg);
+
+                        if(strcmp(rel_reg, "**aL_emul**") == 0)
+                        {
+                            DWORD idx = ctx->aL + reg->idx;
+                            if(idx < MAX_REG_INPUT)
+                            {
+                                strcpy(register_name, ctx->ps_input[idx]);
+                            }
+                            else
+                            {
+                                ERR("Pixel shader input register out of bounds: %u\n", idx);
+                                sprintf(register_name, "out_of_bounds_%u", idx);
+                            }
+                        }
+                        else if(This->baseShader.reg_maps.input_registers & 0x0300)
+                        {
+                            /* There are two ways basically:
+                             *
+                             * 1) Use the unrolling code that is used for loop emulation and unroll the loop.
+                             *    That means trouble if the loop also contains a breakc or if the control values
+                             *    aren't local constants.
+                             * 2) Generate an if block that checks if aL.y < 8, == 8 or == 9 and selects the
+                             *    source dynamically. The trouble is that we cannot simply read aL.y because it
+                             *    is an ADDRESS register. We could however push it, load .zw with a value and use
+                             *    ADAC to load the condition code register and pop it again afterwards
+                             */
+                            FIXME("Relative input register addressing with more than 8 registers\n");
+
+                            /* This is better than nothing for now */
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                        }
+                        else if(ctx->cur_ps_args->super.vp_mode != vertexshader)
+                        {
+                            /* This is problematic because we'd have to consult the ctx->ps_input strings
+                             * for where to find the varying. Some may be "0.0", others can be texcoords or
+                             * colors. This needs either a pipeline replacement to make the vertex shader feed
+                             * proper varyings, or loop unrolling
+                             *
+                             * For now use the texcoords and hope for the best
+                             */
+                            FIXME("Non-vertex shader varying input with indirect addressing\n");
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                        }
+                        else
+                        {
+                            /* D3D supports indirect addressing only with aL in loop registers. The loop instruction
+                             * pulls GL_NV_fragment_program2 in
+                             */
+                            sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx);
+                        }
+                    }
+                    else
+                    {
+                        if(reg->idx < MAX_REG_INPUT)
+                        {
+                            strcpy(register_name, ctx->ps_input[reg->idx]);
+                        }
+                        else
+                        {
+                            ERR("Pixel shader input register out of bounds: %u\n", reg->idx);
+                            sprintf(register_name, "out_of_bounds_%u", reg->idx);
+                        }
+                    }
+                }
             }
             else
             {
             }
             else
             {
-                if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
-                sprintf(register_name, "vertex.attrib[%u]", register_idx);
+                if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx)) *is_color = TRUE;
+                sprintf(register_name, "vertex.attrib[%u]", reg->idx);
             }
             break;
 
         case WINED3DSPR_CONST:
             }
             break;
 
         case WINED3DSPR_CONST:
-            if (!pshader && rel_addr)
+            if (!pshader && reg->rel_addr)
             {
             {
+                BOOL aL = FALSE;
+                char rel_reg[50];
                 UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset;
                 UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset;
-                if (register_idx >= rel_offset)
-                    sprintf(register_name, "C[A0.x + %u]", register_idx - rel_offset);
+                if(This->baseShader.reg_maps.shader_version.major < 2) {
+                    sprintf(rel_reg, "A0.x");
+                } else {
+                    shader_arb_get_src_param(ins, reg->rel_addr, 0, rel_reg);
+                    if(ctx->target_version == ARB) {
+                        if(strcmp(rel_reg, "**aL_emul**") == 0) {
+                            aL = TRUE;
+                        } else {
+                            shader_arb_request_a0(ins, rel_reg);
+                            sprintf(rel_reg, "A0.x");
+                        }
+                    }
+                }
+                if(aL)
+                    sprintf(register_name, "C[%u]", ctx->aL + reg->idx);
+                else if (reg->idx >= rel_offset)
+                    sprintf(register_name, "C[%s + %u]", rel_reg, reg->idx - rel_offset);
                 else
                 else
-                    sprintf(register_name, "C[A0.x - %u]", -register_idx + rel_offset);
+                    sprintf(register_name, "C[%s - %u]", rel_reg, -reg->idx + rel_offset);
             }
             else
             {
                 if (This->baseShader.reg_maps.usesrelconstF)
             }
             else
             {
                 if (This->baseShader.reg_maps.usesrelconstF)
-                    sprintf(register_name, "C[%u]", register_idx);
+                    sprintf(register_name, "C[%u]", reg->idx);
                 else
                 else
-                    sprintf(register_name, "C%u", register_idx);
+                    sprintf(register_name, "C%u", reg->idx);
             }
             break;
 
         case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
             }
             break;
 
         case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
-            if (pshader) sprintf(register_name, "T%u", register_idx);
-            else  sprintf(register_name, "A%u", register_idx);
+            if (pshader) {
+                if(This->baseShader.reg_maps.shader_version.major == 1 &&
+                   This->baseShader.reg_maps.shader_version.minor <= 3) {
+                    /* In ps <= 1.3, Tx is a temporary register as destination to all instructions,
+                     * and as source to most instructions. For some instructions it is the texcoord
+                     * input. Those instructions know about the special use
+                     */
+                    sprintf(register_name, "T%u", reg->idx);
+                } else {
+                    /* in ps 1.4 and 2.x Tx is always a (read-only) varying */
+                    sprintf(register_name, "fragment.texcoord[%u]", reg->idx);
+                }
+            }
+            else
+            {
+                if(This->baseShader.reg_maps.shader_version.major == 1 || ctx->target_version >= NV2)
+                {
+                    sprintf(register_name, "A%u", reg->idx);
+                }
+                else
+                {
+                    sprintf(register_name, "A%u_SHADOW", reg->idx);
+                }
+            }
             break;
 
         case WINED3DSPR_COLOROUT:
             break;
 
         case WINED3DSPR_COLOROUT:
-            if (register_idx == 0)
+            if(ctx->cur_ps_args->super.srgb_correction && reg->idx == 0)
             {
                 strcpy(register_name, "TMP_COLOR");
             }
             else
             {
             {
                 strcpy(register_name, "TMP_COLOR");
             }
             else
             {
-                /* TODO: See GL_ARB_draw_buffers */
-                FIXME("Unsupported write to render target %u\n", register_idx);
-                sprintf(register_name, "unsupported_register");
+                if(ctx->cur_ps_args->super.srgb_correction) FIXME("sRGB correction on higher render targets\n");
+                if(This->baseShader.reg_maps.highest_render_target > 0)
+                {
+                    sprintf(register_name, "result.color[%u]", reg->idx);
+                }
+                else
+                {
+                    strcpy(register_name, "result.color");
+                }
             }
             break;
 
         case WINED3DSPR_RASTOUT:
             }
             break;
 
         case WINED3DSPR_RASTOUT:
-            sprintf(register_name, "%s", rastout_reg_names[register_idx]);
+            if(reg->idx == 1) sprintf(register_name, "%s", ctx->fog_output);
+            else sprintf(register_name, "%s", rastout_reg_names[reg->idx]);
             break;
 
         case WINED3DSPR_DEPTHOUT:
             break;
 
         case WINED3DSPR_DEPTHOUT:
@@ -550,19 +988,71 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE
             break;
 
         case WINED3DSPR_ATTROUT:
             break;
 
         case WINED3DSPR_ATTROUT:
-            if (pshader) sprintf(register_name, "oD[%u]", register_idx);
-            else if (register_idx == 0) strcpy(register_name, "result.color.primary");
-            else strcpy(register_name, "result.color.secondary");
+        /* case WINED3DSPR_OUTPUT: */
+            if (pshader) sprintf(register_name, "oD[%u]", reg->idx);
+            else strcpy(register_name, ctx->color_output[reg->idx]);
             break;
 
         case WINED3DSPR_TEXCRDOUT:
             break;
 
         case WINED3DSPR_TEXCRDOUT:
-            if (pshader) sprintf(register_name, "oT[%u]", register_idx);
-            else sprintf(register_name, "result.texcoord[%u]", register_idx);
+            if (pshader)
+            {
+                sprintf(register_name, "oT[%u]", reg->idx);
+            }
+            else
+            {
+                if(This->baseShader.reg_maps.shader_version.major < 3)
+                {
+                    strcpy(register_name, ctx->texcrd_output[reg->idx]);
+                }
+                else
+                {
+                    strcpy(register_name, ctx->vs_output[reg->idx]);
+                }
+            }
+            break;
+
+        case WINED3DSPR_LOOP:
+            if(ctx->target_version >= NV2)
+            {
+                /* Pshader has an implicitly declared loop index counter A0.x that cannot be renamed */
+                if(pshader) sprintf(register_name, "A0.x");
+                else sprintf(register_name, "aL.y");
+            }
+            else
+            {
+                /* Unfortunately this code cannot return the value of ctx->aL here. An immediate value
+                 * would be valid, but if aL is used for indexing(its only use), there's likely an offset,
+                 * thus the result would be something like C[15 + 30], which is not valid in the ARB program
+                 * grammar. So return a marker for the emulated aL and intercept it in constant and varying
+                 * indexing
+                 */
+                sprintf(register_name, "**aL_emul**");
+            }
+
+            break;
+
+        case WINED3DSPR_CONSTINT:
+            sprintf(register_name, "I%u", reg->idx);
+            break;
+
+        case WINED3DSPR_MISCTYPE:
+            if(reg->idx == 0)
+            {
+                sprintf(register_name, "vpos");
+            }
+            else if(reg->idx == 1)
+            {
+                sprintf(register_name, "fragment.facing.x");
+            }
+            else
+            {
+                FIXME("Unknown MISCTYPE register index %u\n", reg->idx);
+            }
             break;
 
         default:
             break;
 
         default:
-            FIXME("Unhandled register type %#x[%u]\n", register_type, register_idx);
-            sprintf(register_name, "unrecognized_register[%u]", register_idx);
+            FIXME("Unhandled register type %#x[%u]\n", reg->type, reg->idx);
+            sprintf(register_name, "unrecognized_register[%u]", reg->idx);
             break;
     }
 }
             break;
     }
 }
@@ -574,8 +1064,7 @@ static void shader_arb_get_dst_param(const struct wined3d_shader_instruction *in
     char write_mask[6];
     BOOL is_color;
 
     char write_mask[6];
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->ctx->shader, wined3d_dst->reg.type,
-            wined3d_dst->reg.idx, !!wined3d_dst->reg.rel_addr, register_name, &is_color);
+    shader_arb_get_register_name(ins, &wined3d_dst->reg, register_name, &is_color);
     strcpy(str, register_name);
 
     shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
     strcpy(str, register_name);
 
     shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
@@ -598,8 +1087,8 @@ static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channe
     }
 }
 
     }
 }
 
-static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, DWORD dst_mask,
-                                 const char *one, const char *two, struct color_fixup_desc fixup)
+static void gen_color_correction(struct wined3d_shader_buffer *buffer, const char *reg,
+        DWORD dst_mask, const char *one, const char *two, struct color_fixup_desc fixup)
 {
     DWORD mask;
 
 {
     DWORD mask;
 
@@ -650,22 +1139,71 @@ static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, DWORD d
     }
 }
 
     }
 }
 
-static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
-        const char *dst_str, const char *coord_reg, BOOL projected, BOOL bias)
+static const char *shader_arb_get_modifier(const struct wined3d_shader_instruction *ins)
 {
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
-    const char *tex_type;
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
-    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+    DWORD mod;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    if (!ins->dst_count) return "";
 
 
-    switch(sampler_type) {
-        case WINED3DSTT_1D:
-            tex_type = "1D";
-            break;
+    mod = ins->dst[0].modifiers;
 
 
-        case WINED3DSTT_2D:
-            if(device->stateBlock->textures[sampler_idx] &&
+    /* Silently ignore PARTIALPRECISION if its not supported */
+    if(priv->target_version == ARB) mod &= ~WINED3DSPDM_PARTIALPRECISION;
+
+    if(mod & WINED3DSPDM_MSAMPCENTROID)
+    {
+        FIXME("Unhandled modifier WINED3DSPDM_MSAMPCENTROID\n");
+        mod &= ~WINED3DSPDM_MSAMPCENTROID;
+    }
+
+    switch(mod)
+    {
+        case WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION:
+            return "H_SAT";
+
+        case WINED3DSPDM_SATURATE:
+            return "_SAT";
+
+        case WINED3DSPDM_PARTIALPRECISION:
+            return "H";
+
+        case 0:
+            return "";
+
+        default:
+            FIXME("Unknown modifiers 0x%08x\n", mod);
+            return "";
+    }
+}
+
+#define TEX_PROJ        0x1
+#define TEX_BIAS        0x2
+#define TEX_LOD         0x4
+#define TEX_DERIV       0x10
+
+static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
+        const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+    const char *tex_type;
+    BOOL np2_fixup = FALSE;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    const char *mod;
+    BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
+    if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
+
+    switch(sampler_type) {
+        case WINED3DSTT_1D:
+            tex_type = "1D";
+            break;
+
+        case WINED3DSTT_2D:
+            if(device->stateBlock->textures[sampler_idx] &&
                IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
                 tex_type = "RECT";
             } else {
                IWineD3DBaseTexture_GetTextureDimensions(device->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
                 tex_type = "RECT";
             } else {
@@ -673,10 +1211,11 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             }
             if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
             {
             }
             if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
             {
-               const IWineD3DPixelShaderImpl* const ps = (const IWineD3DPixelShaderImpl*)This;
-               if(ps->cur_args->np2_fixup & (1 << sampler_idx)) {
-                   FIXME("NP2 texcoord fixup is currently not implemented in ARB mode (use GLSL instead).\n");
-               }
+                if (priv->cur_np2fixup_info->super.active & (1 << sampler_idx))
+                {
+                    if (flags) FIXME("Only ordinary sampling from NP2 textures is supported.\n");
+                    else np2_fixup = TRUE;
+                }
             }
             break;
 
             }
             break;
 
@@ -693,22 +1232,61 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             tex_type = "";
     }
 
             tex_type = "";
     }
 
-    if (bias) {
+    /* TEX, TXL, TXD and TXP do not support the "H" modifier,
+     * so don't use shader_arb_get_modifier
+     */
+    if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) mod = "_SAT";
+    else mod = "";
+
+    /* Fragment samplers always have indentity mapping */
+    if(sampler_idx >= MAX_FRAGMENT_SAMPLERS)
+    {
+        sampler_idx = priv->cur_vs_args->vertex_samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS];
+    }
+
+    if (flags & TEX_DERIV)
+    {
+        if(flags & TEX_PROJ) FIXME("Projected texture sampling with custom derivatives\n");
+        if(flags & TEX_BIAS) FIXME("Biased texture sampling with custom derivatives\n");
+        shader_addline(buffer, "TXD%s %s, %s, %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg,
+                       dsx, dsy,sampler_idx, tex_type);
+    }
+    else if(flags & TEX_LOD)
+    {
+        if(flags & TEX_PROJ) FIXME("Projected texture sampling with explicit lod\n");
+        if(flags & TEX_BIAS) FIXME("Biased texture sampling with explicit lod\n");
+        shader_addline(buffer, "TXL%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg,
+                       sampler_idx, tex_type);
+    }
+    else if (flags & TEX_BIAS)
+    {
         /* Shouldn't be possible, but let's check for it */
         /* Shouldn't be possible, but let's check for it */
-        if(projected) FIXME("Biased and Projected texture sampling\n");
+        if(flags & TEX_PROJ) FIXME("Biased and Projected texture sampling\n");
         /* TXB takes the 4th component of the source vector automatically, as d3d. Nothing more to do */
         /* TXB takes the 4th component of the source vector automatically, as d3d. Nothing more to do */
-        shader_addline(buffer, "TXB %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
-    } else if (projected) {
-        shader_addline(buffer, "TXP %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
-    } else {
-        shader_addline(buffer, "TEX %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
+        shader_addline(buffer, "TXB%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
+    }
+    else if (flags & TEX_PROJ)
+    {
+        shader_addline(buffer, "TXP%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
+    }
+    else
+    {
+        if (np2_fixup)
+        {
+            const unsigned char idx = priv->cur_np2fixup_info->super.idx[sampler_idx];
+            shader_addline(buffer, "MUL TA, np2fixup[%u].%s, %s;\n", idx >> 1,
+                           (idx % 2) ? "zwxy" : "xyzw", coord_reg);
+
+            shader_addline(buffer, "TEX%s %s, TA, texture[%u], %s;\n", mod, dst_str, sampler_idx, tex_type);
+        }
+        else
+            shader_addline(buffer, "TEX%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
     }
 
     }
 
-    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
+    if (pshader)
     {
     {
-        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
         gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
         gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
-                "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
+                "one", "coefmul.x", priv->cur_ps_args->super.color_fixup[sampler_idx]);
     }
 }
 
     }
 }
 
@@ -720,14 +1298,14 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in
     char regstr[256];
     char swzstr[20];
     int insert_line;
     char regstr[256];
     char swzstr[20];
     int insert_line;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
 
     /* Assume a new line will be added */
     insert_line = 1;
 
     /* Get register name */
 
     /* Assume a new line will be added */
     insert_line = 1;
 
     /* Get register name */
-    shader_arb_get_register_name(ins->ctx->shader, src->reg.type,
-            src->reg.idx, !!src->reg.rel_addr, regstr, &is_color);
+    shader_arb_get_register_name(ins, &src->reg, regstr, &is_color);
     shader_arb_get_swizzle(src, is_color, swzstr);
 
     switch (src->modifiers)
     shader_arb_get_swizzle(src, is_color, swzstr);
 
     switch (src->modifiers)
@@ -769,6 +1347,23 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in
         shader_addline(buffer, "RCP T%c, %s.w;\n", 'A' + tmpreg, regstr);
         shader_addline(buffer, "MUL T%c, %s, T%c;\n", 'A' + tmpreg, regstr, 'A' + tmpreg);
         break;
         shader_addline(buffer, "RCP T%c, %s.w;\n", 'A' + tmpreg, regstr);
         shader_addline(buffer, "MUL T%c, %s, T%c;\n", 'A' + tmpreg, regstr, 'A' + tmpreg);
         break;
+    case WINED3DSPSM_ABS:
+        if(ctx->target_version >= NV2) {
+            sprintf(outregstr, "|%s%s|", regstr, swzstr);
+            insert_line = 0;
+        } else {
+            shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr);
+        }
+        break;
+    case WINED3DSPSM_ABSNEG:
+        if(ctx->target_version >= NV2) {
+            sprintf(outregstr, "-|%s%s|", regstr, swzstr);
+        } else {
+            shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr);
+            sprintf(outregstr, "-T%c%s", 'A' + tmpreg, swzstr);
+        }
+        insert_line = 0;
+        break;
     default:
         sprintf(outregstr, "%s%s", regstr, swzstr);
         insert_line = 0;
     default:
         sprintf(outregstr, "%s%s", regstr, swzstr);
         insert_line = 0;
@@ -781,106 +1376,116 @@ static void shader_arb_get_src_param(const struct wined3d_shader_instruction *in
 
 static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[2][50];
     char dst_name[50];
     char src_name[2][50];
-    char dst_wmask[20];
     DWORD sampler_code = dst->reg.idx;
     DWORD sampler_code = dst->reg.idx;
-    BOOL has_bumpmat = FALSE;
-    BOOL is_color;
-    int i;
-
-    for(i = 0; i < This->numbumpenvmatconsts; i++) {
-        if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
-                && This->bumpenvmatconst[i].texunit == sampler_code)
-        {
-            has_bumpmat = TRUE;
-            break;
-        }
-    }
 
 
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
-    strcat(dst_name, dst_wmask);
+    shader_arb_get_dst_param(ins, dst, dst_name);
 
 
-    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+    /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed
+     *
+     * Keep in mind that src_name[1] can be "TB" and src_name[0] can be "TA" because modifiers like _x2 are valid
+     * with bem. So delay loading the first parameter until after the perturbation calculation which needs two
+     * temps is done.
+     */
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+    shader_addline(buffer, "SWZ TA, bumpenvmat%d, x, z, 0, 0;\n", sampler_code);
+    shader_addline(buffer, "DP3 TC.r, TA, %s;\n", src_name[1]);
+    shader_addline(buffer, "SWZ TA, bumpenvmat%d, y, w, 0, 0;\n", sampler_code);
+    shader_addline(buffer, "DP3 TC.g, TA, %s;\n", src_name[1]);
 
 
-    if(has_bumpmat) {
-        /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
-        shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", sampler_code);
-        shader_addline(buffer, "DP3 TMP.r, TMP2, %s;\n", src_name[1]);
-        shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", sampler_code);
-        shader_addline(buffer, "DP3 TMP.g, TMP2, %s;\n", src_name[1]);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+    shader_addline(buffer, "ADD %s, %s, TC;\n", dst_name, src_name[0]);
+}
 
 
-        shader_addline(buffer, "ADD %s, %s, TMP;\n", dst_name, src_name[0]);
-    } else {
-        shader_addline(buffer, "MOV %s, %s;\n", dst_name, src_name[0]);
+static DWORD negate_modifiers(DWORD mod, char *extra_char)
+{
+    *extra_char = ' ';
+    switch(mod)
+    {
+        case WINED3DSPSM_NONE:      return WINED3DSPSM_NEG;
+        case WINED3DSPSM_NEG:       return WINED3DSPSM_NONE;
+        case WINED3DSPSM_BIAS:      return WINED3DSPSM_BIASNEG;
+        case WINED3DSPSM_BIASNEG:   return WINED3DSPSM_BIAS;
+        case WINED3DSPSM_SIGN:      return WINED3DSPSM_SIGNNEG;
+        case WINED3DSPSM_SIGNNEG:   return WINED3DSPSM_SIGN;
+        case WINED3DSPSM_COMP:      *extra_char = '-'; return WINED3DSPSM_COMP;
+        case WINED3DSPSM_X2:        return WINED3DSPSM_X2NEG;
+        case WINED3DSPSM_X2NEG:     return WINED3DSPSM_X2;
+        case WINED3DSPSM_DZ:        *extra_char = '-'; return WINED3DSPSM_DZ;
+        case WINED3DSPSM_DW:        *extra_char = '-'; return WINED3DSPSM_DW;
+        case WINED3DSPSM_ABS:       return WINED3DSPSM_ABSNEG;
+        case WINED3DSPSM_ABSNEG:    return WINED3DSPSM_ABS;
     }
     }
+    FIXME("Unknown modifier %u\n", mod);
+    return mod;
 }
 
 static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 }
 
 static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_wmask[20];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[3][50];
     char dst_name[50];
     char src_name[3][50];
-    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
-    BOOL is_color;
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
+    BOOL is_color;
 
 
-    /* FIXME: support output modifiers */
-
-    /* Handle output register */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
-
-    /* Generate input register names (with modifiers) */
-    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+    shader_arb_get_dst_param(ins, dst, dst_name);
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
-    shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
     if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue)
     {
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
     if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue)
     {
-        shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
+        shader_addline(buffer, "MOV%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[1]);
     } else {
     } else {
-        shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
-        shader_addline(buffer, "CMP%s %s%s, TMP, %s, %s;\n",
-                                sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1], src_name[2]);
+        struct wined3d_shader_src_param src0_copy = ins->src[0];
+        char extra_neg;
+
+        /* src0 may have a negate srcmod set, so we can't blindly add "-" to the name */
+        src0_copy.modifiers = negate_modifiers(src0_copy.modifiers, &extra_neg);
+
+        shader_arb_get_src_param(ins, &src0_copy, 0, src_name[0]);
+        shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+        shader_addline(buffer, "ADD TA, %c%s, coefdiv.x;\n", extra_neg, src_name[0]);
+        /* No modifiers supported on CMP */
+        shader_addline(buffer, "CMP %s, TA, %s, %s;\n", dst_name, src_name[1], src_name[2]);
+
+        /* _SAT on CMP doesn't make much sense, but it is not a pure NOP */
+        if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE)
+        {
+            shader_arb_get_register_name(ins, &dst->reg, src_name[0], &is_color);
+            shader_addline(buffer, "MOV_SAT %s, %s;\n", dst_name, dst_name);
+        }
     }
 }
 
 static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     }
 }
 
 static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_wmask[20];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[3][50];
     char dst_name[50];
     char src_name[3][50];
-    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     BOOL is_color;
 
-    /* FIXME: support output modifiers */
-
-    /* Handle output register */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
+    shader_arb_get_dst_param(ins, dst, dst_name);
 
     /* Generate input register names (with modifiers) */
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
     shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
 
     /* Generate input register names (with modifiers) */
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
     shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
     shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
-    shader_addline(buffer, "CMP%s %s%s, %s, %s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
+    /* No modifiers are supported on CMP */
+    shader_addline(buffer, "CMP %s, %s, %s, %s;\n", dst_name,
                    src_name[0], src_name[2], src_name[1]);
                    src_name[0], src_name[2], src_name[1]);
+
+    if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE)
+    {
+        shader_arb_get_register_name(ins, &dst->reg, src_name[0], &is_color);
+        shader_addline(buffer, "MOV_SAT %s, %s;\n", dst_name, src_name[0]);
+    }
 }
 
 /** Process the WINED3DSIO_DP2ADD instruction in ARB.
 }
 
 /** Process the WINED3DSIO_DP2ADD instruction in ARB.
@@ -888,37 +1493,64 @@ static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_wmask[20];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[3][50];
     char dst_name[50];
     char src_name[3][50];
-    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
-    BOOL is_color;
-
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
+    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
 
 
+    shader_arb_get_dst_param(ins, dst, dst_name);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
-    shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
     shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
     shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
-    /* Emulate a DP2 with a DP3 and 0.0 */
-    shader_addline(buffer, "MOV TMP, %s;\n", src_name[0]);
-    shader_addline(buffer, "MOV TMP.z, 0.0;\n");
-    shader_addline(buffer, "DP3 TMP2, TMP, %s;\n", src_name[1]);
-    shader_addline(buffer, "ADD%s %s%s, TMP2, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[2]);
+    if(ctx->target_version >= NV3)
+    {
+        /* GL_NV_fragment_program2 has a 1:1 matching instruction */
+        shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+        shader_addline(buffer, "DP2A%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins),
+                       dst_name, src_name[0], src_name[1], src_name[2]);
+    }
+    else if(ctx->target_version >= NV2)
+    {
+        /* dst.x = src2.?, src0.x, src1.x + src0.y * src1.y
+         * dst.y = src2.?, src0.x, src1.z + src0.y * src1.w
+         * dst.z = src2.?, src0.x, src1.x + src0.y * src1.y
+         * dst.z = src2.?, src0.x, src1.z + src0.y * src1.w
+         *
+         * Make sure that src1.zw = src1.xy, then we get a classic dp2add
+         *
+         * .xyxy and other swizzles that we could get with this are not valid in
+         * plain ARBfp, but luckily the NV extension grammar lifts this limitation.
+         */
+        struct wined3d_shader_src_param tmp_param = ins->src[1];
+        DWORD swizzle = tmp_param.swizzle & 0xf; /* Selects .xy */
+        tmp_param.swizzle = swizzle | (swizzle << 4); /* Creates .xyxy */
+
+        shader_arb_get_src_param(ins, &tmp_param, 1, src_name[1]);
+
+        shader_addline(buffer, "X2D%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins),
+                       dst_name, src_name[2], src_name[0], src_name[1]);
+    }
+    else
+    {
+        shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+        /* Emulate a DP2 with a DP3 and 0.0. Don't use the dest as temp register, it could be src[1] or src[2]
+        * src_name[0] can be TA, but TA is a private temp for modifiers, so it is save to overwrite
+        */
+        shader_addline(buffer, "MOV TA, %s;\n", src_name[0]);
+        shader_addline(buffer, "MOV TA.z, 0.0;\n");
+        shader_addline(buffer, "DP3 TA, TA, %s;\n", src_name[1]);
+        shader_addline(buffer, "ADD%s %s, TA, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[2]);
+    }
 }
 
 /* Map the opcode 1-to-1 to the GL code */
 static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
 {
 }
 
 /* Map the opcode 1-to-1 to the GL code */
 static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     const char *instruction;
     char arguments[256], dst_str[50];
     unsigned int i;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     const char *instruction;
     char arguments[256], dst_str[50];
     unsigned int i;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    const char *modifier;
 
     switch (ins->handler_idx)
     {
 
     switch (ins->handler_idx)
     {
@@ -928,31 +1560,25 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         case WINED3DSIH_DP3: instruction = "DP3"; break;
         case WINED3DSIH_DP4: instruction = "DP4"; break;
         case WINED3DSIH_DST: instruction = "DST"; break;
         case WINED3DSIH_DP3: instruction = "DP3"; break;
         case WINED3DSIH_DP4: instruction = "DP4"; break;
         case WINED3DSIH_DST: instruction = "DST"; break;
-        case WINED3DSIH_EXP: instruction = "EX2"; break;
-        case WINED3DSIH_EXPP: instruction = "EXP"; break;
         case WINED3DSIH_FRC: instruction = "FRC"; break;
         case WINED3DSIH_LIT: instruction = "LIT"; break;
         case WINED3DSIH_FRC: instruction = "FRC"; break;
         case WINED3DSIH_LIT: instruction = "LIT"; break;
-        case WINED3DSIH_LOG: instruction = "LG2"; break;
-        case WINED3DSIH_LOGP: instruction = "LOG"; break;
         case WINED3DSIH_LRP: instruction = "LRP"; break;
         case WINED3DSIH_MAD: instruction = "MAD"; break;
         case WINED3DSIH_MAX: instruction = "MAX"; break;
         case WINED3DSIH_MIN: instruction = "MIN"; break;
         case WINED3DSIH_MOV: instruction = "MOV"; break;
         case WINED3DSIH_MUL: instruction = "MUL"; break;
         case WINED3DSIH_LRP: instruction = "LRP"; break;
         case WINED3DSIH_MAD: instruction = "MAD"; break;
         case WINED3DSIH_MAX: instruction = "MAX"; break;
         case WINED3DSIH_MIN: instruction = "MIN"; break;
         case WINED3DSIH_MOV: instruction = "MOV"; break;
         case WINED3DSIH_MUL: instruction = "MUL"; break;
-        case WINED3DSIH_POW: instruction = "POW"; break;
         case WINED3DSIH_SGE: instruction = "SGE"; break;
         case WINED3DSIH_SLT: instruction = "SLT"; break;
         case WINED3DSIH_SUB: instruction = "SUB"; break;
         case WINED3DSIH_SGE: instruction = "SGE"; break;
         case WINED3DSIH_SLT: instruction = "SLT"; break;
         case WINED3DSIH_SUB: instruction = "SUB"; break;
+        case WINED3DSIH_MOVA:instruction = "ARR"; break;
+        case WINED3DSIH_SGN: instruction = "SSG"; break;
+        case WINED3DSIH_DSX: instruction = "DDX"; break;
         default: instruction = "";
             FIXME("Unhandled opcode %#x\n", ins->handler_idx);
             break;
     }
 
         default: instruction = "";
             FIXME("Unhandled opcode %#x\n", ins->handler_idx);
             break;
     }
 
-    /* All instructions handled by this function have a destination parameter */
-    if(dst->modifiers & WINED3DSPDM_SATURATE) modifier = "_SAT";
-    else modifier = "";
-
     /* Note that shader_arb_add_dst_param() adds spaces. */
     arguments[0] = '\0';
     shader_arb_get_dst_param(ins, dst, dst_str);
     /* Note that shader_arb_add_dst_param() adds spaces. */
     arguments[0] = '\0';
     shader_arb_get_dst_param(ins, dst, dst_str);
@@ -963,36 +1589,67 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         shader_arb_get_src_param(ins, &ins->src[i], i, operand);
         strcat(arguments, operand);
     }
         shader_arb_get_src_param(ins, &ins->src[i], i, operand);
         strcat(arguments, operand);
     }
-    shader_addline(buffer, "%s%s %s%s;\n", instruction, modifier, dst_str, arguments);
+    shader_addline(buffer, "%s%s %s%s;\n", instruction, shader_arb_get_modifier(ins), dst_str, arguments);
 }
 
 static void shader_hw_nop(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_hw_nop(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     shader_addline(buffer, "NOP;\n");
 }
 
 static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     shader_addline(buffer, "NOP;\n");
 }
 
 static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
+    BOOL pshader = shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type);
+    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
 
 
-    if ((ins->ctx->reg_maps->shader_version.major == 1
-            && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
-            && ins->dst[0].reg.type == WINED3DSPR_ADDR)
-            || ins->handler_idx == WINED3DSIH_MOVA)
-    {
-        SHADER_BUFFER *buffer = ins->ctx->buffer;
-        char src0_param[256];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src0_param[256];
+
+    if(ins->handler_idx == WINED3DSIH_MOVA) {
+        char write_mask[6];
+
+        if(ctx->target_version >= NV2) {
+            shader_hw_map2gl(ins);
+            return;
+        }
+        shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
+        shader_arb_get_write_mask(ins, &ins->dst[0], write_mask);
+
+        /* This implements the mova formula used in GLSL. The first two instructions
+         * prepare the sign() part. Note that it is fine to have my_sign(0.0) = 1.0
+         * in this case:
+         * mova A0.x, 0.0
+         *
+         * A0.x = arl(floor(abs(0.0) + 0.5) * 1.0) = floor(0.5) = 0.0 since arl does a floor
+         *
+         * The ARL is performed when A0 is used - the requested component is read from A0_SHADOW into
+         * A0.x. We can use the overwritten component of A0_shadow as temporary storage for the sign.
+         */
+        shader_addline(buffer, "SGE A0_SHADOW%s, %s, mova_const.y;\n", write_mask, src0_param);
+        shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, mova_const.z, -mova_const.w;\n", write_mask);
 
 
-        if (ins->handler_idx == WINED3DSIH_MOVA)
-            FIXME("mova should round\n");
+        shader_addline(buffer, "ABS TA%s, %s;\n", write_mask, src0_param);
+        shader_addline(buffer, "ADD TA%s, TA, mova_const.x;\n", write_mask);
+        shader_addline(buffer, "FLR TA%s, TA;\n", write_mask);
+        if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
+        {
+            shader_addline(buffer, "ADD TA%s, TA, helper_const.z;\n", write_mask);
+        }
+        shader_addline(buffer, "MUL A0_SHADOW%s, TA, A0_SHADOW;\n", write_mask);
 
 
+        ((struct shader_arb_ctx_priv *)ins->ctx->backend_data)->addr_reg[0] = '\0';
+    } else if (ins->ctx->reg_maps->shader_version.major == 1
+          && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
+          && ins->dst[0].reg.type == WINED3DSPR_ADDR)
+    {
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
             shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
             shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
-            shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
-            shader_addline(buffer, "ARL A0.x, TMP.x;\n");
+            shader_addline(buffer, "ADD TA.x, %s, helper_const.z;\n", src0_param);
+            shader_addline(buffer, "ARL A0.x, TA.x;\n");
         }
         else
         {
         }
         else
         {
@@ -1005,6 +1662,16 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
+    else if(ins->dst[0].reg.type == WINED3DSPR_COLOROUT && ins->dst[0].reg.idx == 0 && pshader)
+    {
+        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) shader;
+        if(ctx->cur_ps_args->super.srgb_correction && ps->color0_mov)
+        {
+            shader_addline(buffer, "#mov handled in srgb write code\n");
+            return;
+        }
+        shader_hw_map2gl(ins);
+    }
     else
     {
         shader_hw_map2gl(ins);
     else
     {
         shader_hw_map2gl(ins);
@@ -1014,7 +1681,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char reg_dest[40];
 
     /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
     char reg_dest[40];
 
     /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
@@ -1024,14 +1691,42 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
 
     if (ins->ctx->reg_maps->shader_version.major >= 2)
     {
 
     if (ins->ctx->reg_maps->shader_version.major >= 2)
     {
-        /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
-        shader_addline(buffer, "KIL %s;\n", reg_dest);
+        const char *kilsrc = "TA";
+        BOOL is_color;
+
+        shader_arb_get_register_name(ins, &dst->reg, reg_dest, &is_color);
+        if(dst->write_mask == WINED3DSP_WRITEMASK_ALL)
+        {
+            kilsrc = reg_dest;
+        }
+        else
+        {
+            /* Sigh. KIL doesn't support swizzles/writemasks. KIL passes a writemask, but ".xy" for example
+             * is not valid as a swizzle in ARB (needs ".xyyy"). Use SWZ to load the register properly, and set
+             * masked out components to 0(won't kill)
+             */
+            char x = '0', y = '0', z = '0', w = '0';
+            if(dst->write_mask & WINED3DSP_WRITEMASK_0) x = 'x';
+            if(dst->write_mask & WINED3DSP_WRITEMASK_1) y = 'y';
+            if(dst->write_mask & WINED3DSP_WRITEMASK_2) z = 'z';
+            if(dst->write_mask & WINED3DSP_WRITEMASK_3) w = 'w';
+            shader_addline(buffer, "SWZ TA, %s, %c, %c, %c, %c;\n", reg_dest, x, y, z, w);
+        }
+        shader_addline(buffer, "KIL %s;\n", kilsrc);
     } else {
         /* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
          * copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
     } else {
         /* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
          * copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
+         *
+         * ps_1_3 shaders use the texcoord incarnation of the Tx register. ps_1_4 shaders can use the same,
+         * or pass in any temporary register(in shader phase 2)
          */
          */
-        shader_addline(buffer, "SWZ TMP, %s, x, y, z, 1;\n", reg_dest);
-        shader_addline(buffer, "KIL TMP;\n");
+        if(ins->ctx->reg_maps->shader_version.minor <= 3) {
+            sprintf(reg_dest, "fragment.texcoord[%u]", dst->reg.idx);
+        } else {
+            shader_arb_get_dst_param(ins, dst, reg_dest);
+        }
+        shader_addline(buffer, "SWZ TA, %s, x, y, z, 1;\n", reg_dest);
+        shader_addline(buffer, "KIL TA;\n");
     }
 }
 
     }
 }
 
@@ -1040,217 +1735,213 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    BOOL is_color;
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
-    BOOL projected = FALSE, bias = FALSE;
+    struct wined3d_shader_src_param src;
 
     char reg_dest[40];
     char reg_coord[40];
     DWORD reg_sampler_code;
 
     char reg_dest[40];
     char reg_coord[40];
     DWORD reg_sampler_code;
+    DWORD myflags = 0;
 
     /* All versions have a destination register */
 
     /* All versions have a destination register */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, reg_dest, &is_color);
+    shader_arb_get_dst_param(ins, dst, reg_dest);
+
+    /* 1.0-1.4: Use destination register number as texture code.
+       2.0+: Use provided sampler number as texure code. */
+    if (shader_version < WINED3D_SHADER_VERSION(2,0))
+        reg_sampler_code = dst->reg.idx;
+    else
+        reg_sampler_code = ins->src[1].reg.idx;
 
 
-    /* 1.0-1.3: Use destination register as coordinate source.
+    /* 1.0-1.3: Use the texcoord varying.
        1.4+: Use provided coordinate source register. */
        1.4+: Use provided coordinate source register. */
-   if (shader_version < WINED3D_SHADER_VERSION(1,4))
-      strcpy(reg_coord, reg_dest);
-   else
-      shader_arb_get_src_param(ins, &ins->src[0], 0, reg_coord);
-
-  /* 1.0-1.4: Use destination register number as texture code.
-     2.0+: Use provided sampler number as texure code. */
-  if (shader_version < WINED3D_SHADER_VERSION(2,0))
-     reg_sampler_code = dst->reg.idx;
-  else
-     reg_sampler_code = ins->src[1].reg.idx;
-
-  /* projection flag:
-   * 1.1, 1.2, 1.3: Use WINED3DTSS_TEXTURETRANSFORMFLAGS
-   * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
-   * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
-   */
-  if (shader_version < WINED3D_SHADER_VERSION(1,4))
-  {
-      DWORD flags = 0;
-      if(reg_sampler_code < MAX_TEXTURES) {
-        flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
-      }
-      if (flags & WINED3DTTFF_PROJECTED) {
-          projected = TRUE;
-      }
-  }
-  else if (shader_version < WINED3D_SHADER_VERSION(2,0))
-  {
-      DWORD src_mod = ins->src[0].modifiers;
-      if (src_mod == WINED3DSPSM_DZ) {
-          projected = TRUE;
-      } else if(src_mod == WINED3DSPSM_DW) {
-          projected = TRUE;
-      }
-  } else {
-      if (ins->flags & WINED3DSI_TEXLD_PROJECT) projected = TRUE;
-      if (ins->flags & WINED3DSI_TEXLD_BIAS) bias = TRUE;
-  }
-  shader_hw_sample(ins, reg_sampler_code, reg_dest, reg_coord, projected, bias);
+    if (shader_version < WINED3D_SHADER_VERSION(1,4))
+        sprintf(reg_coord, "fragment.texcoord[%u]", reg_sampler_code);
+    else {
+        /* TEX is the only instruction that can handle DW and DZ natively */
+        src = ins->src[0];
+        if(src.modifiers == WINED3DSPSM_DW) src.modifiers = WINED3DSPSM_NONE;
+        if(src.modifiers == WINED3DSPSM_DZ) src.modifiers = WINED3DSPSM_NONE;
+        shader_arb_get_src_param(ins, &src, 0, reg_coord);
+    }
+
+    /* projection flag:
+     * 1.1, 1.2, 1.3: Use WINED3DTSS_TEXTURETRANSFORMFLAGS
+     * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
+     * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
+     */
+    if (shader_version < WINED3D_SHADER_VERSION(1,4))
+    {
+        DWORD flags = 0;
+        if(reg_sampler_code < MAX_TEXTURES) {
+            flags = deviceImpl->stateBlock->textureState[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
+        }
+        if (flags & WINED3DTTFF_PROJECTED) {
+            myflags |= TEX_PROJ;
+        }
+    }
+    else if (shader_version < WINED3D_SHADER_VERSION(2,0))
+    {
+        DWORD src_mod = ins->src[0].modifiers;
+        if (src_mod == WINED3DSPSM_DZ) {
+            /* TXP cannot handle DZ natively, so move the z coordinate to .w. reg_coord is a read-only
+             * varying register, so we need a temp reg
+             */
+            shader_addline(ins->ctx->buffer, "SWZ TA, %s, x, y, z, z;\n", reg_coord);
+            strcpy(reg_coord, "TA");
+            myflags |= TEX_PROJ;
+        } else if(src_mod == WINED3DSPSM_DW) {
+            myflags |= TEX_PROJ;
+        }
+    } else {
+        if (ins->flags & WINED3DSI_TEXLD_PROJECT) myflags |= TEX_PROJ;
+        if (ins->flags & WINED3DSI_TEXLD_BIAS) myflags |= TEX_BIAS;
+    }
+    shader_hw_sample(ins, reg_sampler_code, reg_dest, reg_coord, myflags, NULL, NULL);
 }
 
 static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 }
 
 static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
+    char dst_str[50];
 
 
-    char tmp[20];
-    shader_arb_get_write_mask(ins, dst, tmp);
-    if (shader_version != WINED3D_SHADER_VERSION(1,4))
+    if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
         DWORD reg = dst->reg.idx;
     {
         DWORD reg = dst->reg.idx;
-        shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
+
+        shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+        shader_addline(buffer, "MOV_SAT %s, fragment.texcoord[%u];\n", dst_str, reg);
     } else {
         char reg_src[40];
 
         shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src);
     } else {
         char reg_src[40];
 
         shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src);
-        shader_addline(buffer, "MOV R%u%s, %s;\n", dst->reg.idx, tmp, reg_src);
+        shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+        shader_addline(buffer, "MOV %s, %s;\n", dst_str, reg_src);
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
-     SHADER_BUFFER *buffer = ins->ctx->buffer;
+     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
      IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
      IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
      DWORD flags;
 
      DWORD reg1 = ins->dst[0].reg.idx;
      IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
      IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
      DWORD flags;
 
      DWORD reg1 = ins->dst[0].reg.idx;
-     char dst_str[8];
+     char dst_str[50];
      char src_str[50];
 
      char src_str[50];
 
-     sprintf(dst_str, "T%u", reg1);
+     /* Note that texreg2ar treats Tx as a temporary register, not as a varying */
+     shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
      shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
      shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
-     shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str);
-     shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str);
+     /* Move .x first in case src_str is "TA" */
+     shader_addline(buffer, "MOV TA.y, %s.x;\n", src_str);
+     shader_addline(buffer, "MOV TA.x, %s.w;\n", src_str);
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-     shader_hw_sample(ins, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
+     shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
 }
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
-     SHADER_BUFFER *buffer = ins->ctx->buffer;
+     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
 
      DWORD reg1 = ins->dst[0].reg.idx;
 
      DWORD reg1 = ins->dst[0].reg.idx;
-     char dst_str[8];
+     char dst_str[50];
      char src_str[50];
 
      char src_str[50];
 
-     sprintf(dst_str, "T%u", reg1);
+     /* Note that texreg2gb treats Tx as a temporary register, not as a varying */
+     shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
      shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
      shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
-     shader_addline(buffer, "MOV TMP.x, %s.y;\n", src_str);
-     shader_addline(buffer, "MOV TMP.y, %s.z;\n", src_str);
-     shader_hw_sample(ins, reg1, dst_str, "TMP", FALSE, FALSE);
+     shader_addline(buffer, "MOV TA.x, %s.y;\n", src_str);
+     shader_addline(buffer, "MOV TA.y, %s.z;\n", src_str);
+     shader_hw_sample(ins, reg1, dst_str, "TA", 0, NULL, NULL);
 }
 
 static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
     DWORD reg1 = ins->dst[0].reg.idx;
 }
 
 static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
     DWORD reg1 = ins->dst[0].reg.idx;
-    char dst_str[8];
+    char dst_str[50];
     char src_str[50];
 
     char src_str[50];
 
-    sprintf(dst_str, "T%u", reg1);
+    /* Note that texreg2rg treats Tx as a temporary register, not as a varying */
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
-    shader_hw_sample(ins, reg1, dst_str, src_str, FALSE, FALSE);
+    shader_hw_sample(ins, reg1, dst_str, src_str, 0, NULL, NULL);
 }
 
 static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 }
 
 static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    BOOL has_bumpmat = FALSE;
-    BOOL has_luminance = FALSE;
-    BOOL is_color;
-    int i;
-
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-
-    char reg_coord[40];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char reg_coord[40], dst_reg[50], src_reg[50];
     DWORD reg_dest_code;
 
     DWORD reg_dest_code;
 
-    /* All versions have a destination register */
+    /* All versions have a destination register. The Tx where the texture coordinates come
+     * from is the varying incarnation of the texture register
+     */
     reg_dest_code = dst->reg.idx;
     reg_dest_code = dst->reg.idx;
-    /* Can directly use the name because texbem is only valid for <= 1.3 shaders */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, reg_coord, &is_color);
-
-    for(i = 0; i < This->numbumpenvmatconsts; i++) {
-        if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
-                && reg_dest_code == This->bumpenvmatconst[i].texunit)
-        {
-            has_bumpmat = TRUE;
-            break;
-        }
-    }
-    for(i = 0; i < This->numbumpenvmatconsts; i++) {
-        if (This->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED
-                && reg_dest_code == This->luminanceconst[i].texunit)
-        {
-            has_luminance = TRUE;
-            break;
-        }
-    }
-
-    if(has_bumpmat) {
-        DWORD src = ins->src[0].reg.idx;
-
-        /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_reg);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_reg);
+    sprintf(reg_coord, "fragment.texcoord[%u]", reg_dest_code);
 
 
-        shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
-        shader_addline(buffer, "DP3 TMP.x, TMP2, T%u;\n", src);
-        shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
-        shader_addline(buffer, "DP3 TMP.y, TMP2, T%u;\n", src);
-
-        /* with projective textures, texbem only divides the static texture coord, not the displacement,
-         * so we can't let the GL handle this.
-         */
-        if (((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
-              & WINED3DTTFF_PROJECTED) {
-            shader_addline(buffer, "RCP TMP2.w, %s.w;\n", reg_coord);
-            shader_addline(buffer, "MUL TMP2.xy, %s, TMP2.w;\n", reg_coord);
-            shader_addline(buffer, "ADD TMP.xy, TMP, TMP2;\n");
-        } else {
-            shader_addline(buffer, "ADD TMP.xy, TMP, %s;\n", reg_coord);
-        }
+    /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed
+     * The Tx in which the perturbation map is stored is the tempreg incarnation of the texture register
+     *
+     * GL_NV_fragment_program_option could handle this in one instruction via X2D:
+     * X2D TA.xy, fragment.texcoord, T%u, bumpenvmat%u.xzyw
+     *
+     * However, the NV extensions are never enabled for <= 2.0 shaders because of the performance penalty that
+     * comes with it, and texbem is an 1.x only instruction. No 1.x instruction forces us to enable the NV
+     * extension.
+     */
+    shader_addline(buffer, "SWZ TB, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
+    shader_addline(buffer, "DP3 TA.x, TB, %s;\n", src_reg);
+    shader_addline(buffer, "SWZ TB, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
+    shader_addline(buffer, "DP3 TA.y, TB, %s;\n", src_reg);
 
 
-        shader_hw_sample(ins, reg_dest_code, reg_coord, "TMP", FALSE, FALSE);
+    /* with projective textures, texbem only divides the static texture coord, not the displacement,
+     * so we can't let the GL handle this.
+     */
+    if (((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
+            & WINED3DTTFF_PROJECTED) {
+        shader_addline(buffer, "RCP TB.w, %s.w;\n", reg_coord);
+        shader_addline(buffer, "MUL TB.xy, %s, TB.w;\n", reg_coord);
+        shader_addline(buffer, "ADD TA.xy, TA, TB;\n");
+    } else {
+        shader_addline(buffer, "ADD TA.xy, TA, %s;\n", reg_coord);
+    }
 
 
-        if (ins->handler_idx == WINED3DSIH_TEXBEML && has_luminance)
-        {
-            shader_addline(buffer, "MAD TMP, T%u.z, luminance%d.x, luminance%d.y;\n",
-                           src, reg_dest_code, reg_dest_code);
-            shader_addline(buffer, "MUL %s, %s, TMP;\n", reg_coord, reg_coord);
-        }
+    shader_hw_sample(ins, reg_dest_code, dst_reg, "TA", 0, NULL, NULL);
 
 
-    } else {
-        DWORD tf;
-        if(reg_dest_code < MAX_TEXTURES) {
-            tf = ((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS];
-        } else {
-            tf = 0;
-        }
-        /* Without a bump matrix loaded, just sample with the unmodified coordinates */
-        shader_hw_sample(ins, reg_dest_code, reg_coord, reg_coord, tf & WINED3DTTFF_PROJECTED, FALSE);
+    if (ins->handler_idx == WINED3DSIH_TEXBEML)
+    {
+        /* No src swizzles are allowed, so this is ok */
+        shader_addline(buffer, "MAD TA, %s.z, luminance%d.x, luminance%d.y;\n",
+                       src_reg, reg_dest_code, reg_dest_code);
+        shader_addline(buffer, "MUL %s, %s, TA;\n", dst_reg, dst_reg);
     }
 }
 
 static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD reg = ins->dst[0].reg.idx;
     }
 }
 
 static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char src0_name[50];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src0_name[50], dst_name[50];
+    BOOL is_color;
+    struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
-    shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name);
+    /* The next instruction will be a texm3x2tex or texm3x2depth that writes to the uninitialized
+     * T<reg+1> register. Use this register to store the calculated vector
+     */
+    tmp_reg.idx = reg + 1;
+    shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
+    shader_addline(buffer, "DP3 %s.x, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
 }
 
 static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 }
 
 static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
@@ -1259,27 +1950,42 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_str[8];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_str[50];
     char src0_name[50];
     char src0_name[50];
+    char dst_reg[50];
+    BOOL is_color;
+
+    /* We know that we're writing to the uninitialized T<reg> register, so use it for temporary storage */
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
 
 
-    sprintf(dst_str, "T%u", reg);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
-    shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", reg, src0_name);
+    shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
+    shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
 }
 
 static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
 }
 
 static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    char src0_name[50];
+    char src0_name[50], dst_name[50];
+    struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
+    BOOL is_color;
+
+    /* There are always 2 texm3x3pad instructions followed by one texm3x3[tex,vspec, ...] instruction, with
+     * incrementing ins->dst[0].register_idx numbers. So the pad instruction already knows the final destination
+     * register, and this register is uninitialized(otherwise the assembler complains that it is 'redeclared')
+     */
+    tmp_reg.idx = reg + 2 - current_state->current_row;
+    shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
-    shader_addline(buffer, "DP3 TMP.%c, T%u, %s;\n", 'x' + current_state->current_row, reg, src0_name);
+    shader_addline(buffer, "DP3 %s.%c, fragment.texcoord[%u], %s;\n",
+                   dst_name, 'x' + current_state->current_row, reg, src0_name);
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
@@ -1289,18 +1995,20 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    char dst_str[8];
-    char src0_name[50];
+    char dst_str[50];
+    char src0_name[50], dst_name[50];
+    BOOL is_color;
 
 
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
+    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    sprintf(dst_str, "T%u", reg);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
+    shader_hw_sample(ins, reg, dst_str, dst_name, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
@@ -1310,33 +2018,39 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    char dst_str[8];
+    char dst_str[50];
     char src0_name[50];
     char src0_name[50];
+    char dst_reg[50];
+    BOOL is_color;
 
 
+    /* Get the dst reg without writemask strings. We know this register is uninitialized, so we can use all
+     * components for temporary data storage
+     */
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
+    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
 
     /* Construct the eye-ray vector from w coordinates */
 
     /* Construct the eye-ray vector from w coordinates */
-    shader_addline(buffer, "MOV TMP2.x, fragment.texcoord[%u].w;\n", current_state->texcoord_w[0]);
-    shader_addline(buffer, "MOV TMP2.y, fragment.texcoord[%u].w;\n", current_state->texcoord_w[1]);
-    shader_addline(buffer, "MOV TMP2.z, fragment.texcoord[%u].w;\n", reg);
+    shader_addline(buffer, "MOV TB.x, fragment.texcoord[%u].w;\n", current_state->texcoord_w[0]);
+    shader_addline(buffer, "MOV TB.y, fragment.texcoord[%u].w;\n", current_state->texcoord_w[1]);
+    shader_addline(buffer, "MOV TB.z, fragment.texcoord[%u].w;\n", reg);
 
     /* Calculate reflection vector
      */
 
     /* Calculate reflection vector
      */
-    shader_addline(buffer, "DP3 TMP.w, TMP, TMP2;\n");
-    /* The .w is ignored when sampling, so I can use TMP2.w to calculate dot(N, N) */
-    shader_addline(buffer, "DP3 TMP2.w, TMP, TMP;\n");
-    shader_addline(buffer, "RCP TMP2.w, TMP2.w;\n");
-    shader_addline(buffer, "MUL TMP.w, TMP.w, TMP2.w;\n");
-    shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n");
-    shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -TMP2;\n");
+    shader_addline(buffer, "DP3 %s.w, %s, TB;\n", dst_reg, dst_reg);
+    /* The .w is ignored when sampling, so I can use TB.w to calculate dot(N, N) */
+    shader_addline(buffer, "DP3 TB.w, %s, %s;\n", dst_reg, dst_reg);
+    shader_addline(buffer, "RCP TB.w, TB.w;\n");
+    shader_addline(buffer, "MUL %s.w, %s.w, TB.w;\n", dst_reg, dst_reg);
+    shader_addline(buffer, "MUL %s, %s.w, %s;\n", dst_reg, dst_reg, dst_reg);
+    shader_addline(buffer, "MAD %s, coefmul.x, %s, -TB;\n", dst_reg, dst_reg);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    sprintf(dst_str, "T%u", reg);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
+    shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
@@ -1347,51 +2061,53 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     DWORD flags;
     DWORD reg = ins->dst[0].reg.idx;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_str[8];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_str[50];
     char src0_name[50];
     char src1_name[50];
     char src0_name[50];
     char src1_name[50];
+    char dst_reg[50];
+    BOOL is_color;
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
+    /* Note: dst_reg.xy is input here, generated by two texm3x3pad instructions */
+    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
 
     /* Calculate reflection vector.
      *
 
     /* Calculate reflection vector.
      *
-     *               dot(N, E)
-     * TMP.xyz = 2 * --------- * N - E
-     *               dot(N, N)
+     *                   dot(N, E)
+     * dst_reg.xyz = 2 * --------- * N - E
+     *                   dot(N, N)
      *
      * Which normalizes the normal vector
      */
      *
      * Which normalizes the normal vector
      */
-    shader_addline(buffer, "DP3 TMP.w, TMP, %s;\n", src1_name);
-    shader_addline(buffer, "DP3 TMP2.w, TMP, TMP;\n");
-    shader_addline(buffer, "RCP TMP2.w, TMP2.w;\n");
-    shader_addline(buffer, "MUL TMP.w, TMP.w, TMP2.w;\n");
-    shader_addline(buffer, "MUL TMP, TMP.w, TMP;\n");
-    shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -%s;\n", src1_name);
+    shader_addline(buffer, "DP3 %s.w, %s, %s;\n", dst_reg, dst_reg, src1_name);
+    shader_addline(buffer, "DP3 TC.w, %s, %s;\n", dst_reg, dst_reg);
+    shader_addline(buffer, "RCP TC.w, TC.w;\n");
+    shader_addline(buffer, "MUL %s.w, %s.w, TC.w;\n", dst_reg, dst_reg);
+    shader_addline(buffer, "MUL %s, %s.w, %s;\n", dst_reg, dst_reg, dst_reg);
+    shader_addline(buffer, "MAD %s, coefmul.x, %s, -%s;\n", dst_reg, dst_reg, src1_name);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    sprintf(dst_str, "T%u", reg);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
+    shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
     current_state->current_row = 0;
 }
 
 static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     current_state->current_row = 0;
 }
 
 static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char dst_name[50];
-    BOOL is_color;
 
     /* texdepth has an implicit destination, the fragment depth value. It's only parameter,
      * which is essentially an input, is the destination register because it is the first
      * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
 
     /* texdepth has an implicit destination, the fragment depth value. It's only parameter,
      * which is essentially an input, is the destination register because it is the first
      * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
-     * here
+     * here(writemasks/swizzles are not valid on texdepth)
      */
      */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
+    shader_arb_get_dst_param(ins, dst, dst_name);
 
     /* According to the msdn, the source register(must be r5) is unusable after
      * the texdepth instruction, so we're free to modify it
 
     /* According to the msdn, the source register(must be r5) is unusable after
      * the texdepth instruction, so we're free to modify it
@@ -1403,9 +2119,9 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
     shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
     shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
-    shader_addline(buffer, "MUL TMP.x, %s.x, %s.y;\n", dst_name, dst_name);
-    shader_addline(buffer, "MIN TMP.x, TMP.x, one.x;\n");
-    shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
+    shader_addline(buffer, "MUL TA.x, %s.x, %s.y;\n", dst_name, dst_name);
+    shader_addline(buffer, "MIN TA.x, TA.x, one.x;\n");
+    shader_addline(buffer, "MAX result.depth, TA.x, 0.0;\n");
 }
 
 /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
@@ -1413,17 +2129,17 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     DWORD sampler_idx = ins->dst[0].reg.idx;
     char src0[50];
     DWORD sampler_idx = ins->dst[0].reg.idx;
     char src0[50];
-    char dst_str[8];
+    char dst_str[50];
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "MOV TMP, 0.0;\n");
-    shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0);
+    shader_addline(buffer, "MOV TB, 0.0;\n");
+    shader_addline(buffer, "DP3 TB.x, fragment.texcoord[%u], %s;\n", sampler_idx, src0);
 
 
-    sprintf(dst_str, "T%u", sampler_idx);
-    shader_hw_sample(ins, sampler_idx, dst_str, "TMP", FALSE /* Only one coord, can't be projected */, FALSE);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    shader_hw_sample(ins, sampler_idx, dst_str, "TB", 0 /* Only one coord, can't be projected */, NULL, NULL);
 }
 
 /** Process the WINED3DSIO_TEXDP3 instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXDP3 instruction in ARB:
@@ -1433,19 +2149,12 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     char src0[50];
     char dst_str[50];
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     char src0[50];
     char dst_str[50];
-    char dst_mask[6];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    BOOL is_color;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
 
     /* Handle output register */
 
     /* Handle output register */
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_mask);
-
+    shader_arb_get_dst_param(ins, dst, dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->reg.idx, src0);
-
-    /* TODO: Handle output modifiers */
+    shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx, src0);
 }
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
 }
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
@@ -1453,21 +2162,16 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    char dst_str[50];
-    char dst_mask[6];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_str[50], dst_name[50];
     char src0[50];
     BOOL is_color;
 
     char src0[50];
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_mask);
-
+    shader_arb_get_dst_param(ins, dst, dst_str);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->reg.idx, src0);
-    shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask);
-
-    /* TODO: Handle output modifiers */
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+    shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx, src0);
+    shader_addline(buffer, "MOV %s, %s;\n", dst_str, dst_name);
 }
 
 /** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB:
@@ -1477,21 +2181,23 @@ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
  */
 static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
  */
 static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    DWORD dst_reg = ins->dst[0].reg.idx;
-    char src0[50];
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+    char src0[50], dst_name[50];
+    BOOL is_color;
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, src0);
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+    shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx, src0);
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
      * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
      * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
      * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
      */
-    shader_addline(buffer, "RCP TMP.y, TMP.y;\n");
-    shader_addline(buffer, "MUL TMP.x, TMP.x, TMP.y;\n");
-    shader_addline(buffer, "MIN TMP.x, TMP.x, one.x;\n");
-    shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n");
+    shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
+    shader_addline(buffer, "MUL %s.x, %s.x, %s.y;\n", dst_name, dst_name, dst_name);
+    shader_addline(buffer, "MIN %s.x, %s.x, one.x;\n", dst_name, dst_name);
+    shader_addline(buffer, "MAX result.depth, %s.x, 0.0;\n", dst_name);
 }
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for
 }
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for
@@ -1550,26 +2256,25 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
+static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins)
 {
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
-    const char *instruction, *sat;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    const char *instruction;
 
     char dst[50];
     char src[50];
 
     switch(ins->handler_idx)
     {
 
     char dst[50];
     char src[50];
 
     switch(ins->handler_idx)
     {
-        case WINED3DSIH_RSQ: instruction = "RSQ"; break;
-        case WINED3DSIH_RCP: instruction = "RCP"; break;
+        case WINED3DSIH_RSQ:  instruction = "RSQ"; break;
+        case WINED3DSIH_RCP:  instruction = "RCP"; break;
+        case WINED3DSIH_EXP:  instruction = "EX2"; break;
+        case WINED3DSIH_EXPP: instruction = "EXP"; break;
         default: instruction = "";
             FIXME("Unhandled opcode %#x\n", ins->handler_idx);
             break;
     }
 
         default: instruction = "";
             FIXME("Unhandled opcode %#x\n", ins->handler_idx);
             break;
     }
 
-    if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) sat = "_SAT";
-    else sat = "";
-
     shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
     shader_arb_get_src_param(ins, &ins->src[0], 0, src);
     if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
     shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
     shader_arb_get_src_param(ins, &ins->src[0], 0, src);
     if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
@@ -1580,29 +2285,54 @@ static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
         strcat(src, ".w");
     }
 
         strcat(src, ".w");
     }
 
-    shader_addline(buffer, "%s%s %s, %s;\n", instruction, sat, dst, src);
+    shader_addline(buffer, "%s%s %s, %s;\n", instruction, shader_arb_get_modifier(ins), dst, src);
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
-    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_name[50];
     char src_name[50];
-    char dst_wmask[20];
-    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
-    BOOL is_color;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
 
 
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, src_name);
 
 
-    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
-    shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name);
-    shader_addline(buffer, "RSQ TMP, TMP.x;\n");
-    /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
-    shader_addline(buffer, "MUL%s %s%s, %s, TMP;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
-                   src_name);
+    if(pshader && priv->target_version >= NV3)
+    {
+        shader_addline(buffer, "NRM%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name);
+    }
+    else
+    {
+        shader_addline(buffer, "DP3 TA, %s, %s;\n", src_name, src_name);
+        shader_addline(buffer, "RSQ TA, TA.x;\n");
+        /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
+        shader_addline(buffer, "MUL%s %s, %s, TA;\n", shader_arb_get_modifier(ins), dst_name,
+                    src_name);
+    }
+}
+
+static void shader_hw_lrp(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_name[50];
+    char src_name[3][50];
+
+    /* ARB_fragment_program has a convenient LRP instruction */
+    if(shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) {
+        shader_hw_map2gl(ins);
+        return;
+    }
+
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+    shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+    shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+
+    shader_addline(buffer, "SUB TA, %s, %s;\n", src_name[1], src_name[2]);
+    shader_addline(buffer, "MAD%s %s, %s, TA, %s;\n", shader_arb_get_modifier(ins),
+                   dst_name, src_name[0], src_name[2]);
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
@@ -1611,129 +2341,1868 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
      * must contain fixed constants. So we need a separate function to filter those constants and
      * can't use map2gl
      */
      * must contain fixed constants. So we need a separate function to filter those constants and
      * can't use map2gl
      */
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     char dst_name[50];
-    char src_name[50];
-    char dst_wmask[20];
-    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    char src_name0[50], src_name1[50], src_name2[50];
     BOOL is_color;
 
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
-    shader_arb_get_write_mask(ins, dst, dst_wmask);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+    if(shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) {
+        shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+        /* No modifiers are supported on SCS */
+        shader_addline(buffer, "SCS %s, %s;\n", dst_name, src_name0);
 
 
-    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
-    shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
-                   src_name);
+        if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE)
+        {
+            shader_arb_get_register_name(ins, &dst->reg, src_name0, &is_color);
+            shader_addline(buffer, "MOV_SAT %s, %s;\n", dst_name, src_name0);
+        }
+    } else if(priv->target_version >= NV2) {
+        shader_arb_get_register_name(ins, &dst->reg, dst_name, &is_color);
+
+        /* Sincos writemask must be .x, .y or .xy */
+        if(dst->write_mask & WINED3DSP_WRITEMASK_0)
+            shader_addline(buffer, "COS%s %s.x, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name0);
+        if(dst->write_mask & WINED3DSP_WRITEMASK_1)
+            shader_addline(buffer, "SIN%s %s.y, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name0);
+    } else {
+        /* Approximate sine and cosine with a taylor series, as per math textbook. The application passes 8
+         * helper constants(D3DSINCOSCONST1 and D3DSINCOSCONST2) in src1 and src2.
+         *
+         * sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
+         * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ...
+         *
+         * The constants we get are:
+         *
+         *  +1   +1,     -1     -1     +1      +1      -1       -1
+         *      ---- ,  ---- , ---- , ----- , ----- , ----- , ------
+         *      1!*2    2!*4   3!*8   4!*16   5!*32   6!*64   7!*128
+         *
+         * If used with x^2, x^3, x^4 etc they calculate sin(x/2) and cos(x/2):
+         *
+         * (x/2)^2 = x^2 / 4
+         * (x/2)^3 = x^3 / 8
+         * (x/2)^4 = x^4 / 16
+         * (x/2)^5 = x^5 / 32
+         * etc
+         *
+         * To get the final result:
+         * sin(x) = 2 * sin(x/2) * cos(x/2)
+         * cos(x) = cos(x/2)^2 - sin(x/2)^2
+         * (from sin(x+y) and cos(x+y) rules)
+         *
+         * As per MSDN, dst.z is undefined after the operation, and so is
+         * dst.x and dst.y if they're masked out by the writemask. Ie
+         * sincos dst.y, src1, c0, c1
+         * returns the sine in dst.y. dst.x and dst.z are undefined, dst.w is not touched. The assembler
+         * vsa.exe also stops with an error if the dest register is the same register as the source
+         * register. This means we can use dest.xyz as temporary storage. The assembler vsa.exe output also
+         * indicates that sincos consumes 8 instruction slots in vs_2_0(and, strangely, in vs_3_0).
+         */
+        shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+        shader_arb_get_src_param(ins, &ins->src[2], 2, src_name2);
+        shader_arb_get_register_name(ins, &dst->reg, dst_name, &is_color);
+
+        shader_addline(buffer, "MUL %s.x, %s, %s;\n", dst_name, src_name0, src_name0);  /* x ^ 2 */
+        shader_addline(buffer, "MUL TA.y, %s.x, %s;\n", dst_name, src_name0);           /* x ^ 3 */
+        shader_addline(buffer, "MUL %s.y, TA.y, %s;\n", dst_name, src_name0);           /* x ^ 4 */
+        shader_addline(buffer, "MUL TA.z, %s.y, %s;\n", dst_name, src_name0);           /* x ^ 5 */
+        shader_addline(buffer, "MUL %s.z, TA.z, %s;\n", dst_name, src_name0);           /* x ^ 6 */
+        shader_addline(buffer, "MUL TA.w, %s.z, %s;\n", dst_name, src_name0);           /* x ^ 7 */
+
+        /* sin(x/2)
+         *
+         * Unfortunately we don't get the constants in a DP4-capable form. Is there a way to
+         * properly merge that with MULs in the code above?
+         * The swizzles .yz and xw however fit into the .yzxw swizzle added to ps_2_0. Maybe
+         * we can merge the sine and cosine MAD rows to calculate them together.
+         */
+        shader_addline(buffer, "MUL TA.x, %s, %s.w;\n", src_name0, src_name2); /* x^1, +1/(1!*2) */
+        shader_addline(buffer, "MAD TA.x, TA.y, %s.x, TA.x;\n", src_name2); /* -1/(3!*8) */
+        shader_addline(buffer, "MAD TA.x, TA.z, %s.w, TA.x;\n", src_name1); /* +1/(5!*32) */
+        shader_addline(buffer, "MAD TA.x, TA.w, %s.x, TA.x;\n", src_name1); /* -1/(7!*128) */
+
+        /* cos(x/2) */
+        shader_addline(buffer, "MAD TA.y, %s.x, %s.y, %s.z;\n", dst_name, src_name2, src_name2); /* -1/(2!*4), +1.0 */
+        shader_addline(buffer, "MAD TA.y, %s.y, %s.z, TA.y;\n", dst_name, src_name1); /* +1/(4!*16) */
+        shader_addline(buffer, "MAD TA.y, %s.z, %s.y, TA.y;\n", dst_name, src_name1); /* -1/(6!*64) */
+
+        if(dst->write_mask & WINED3DSP_WRITEMASK_0) {
+            /* cos x */
+            shader_addline(buffer, "MUL TA.z, TA.y, TA.y;\n");
+            shader_addline(buffer, "MAD %s.x, -TA.x, TA.x, TA.z;\n", dst_name);
+        }
+        if(dst->write_mask & WINED3DSP_WRITEMASK_1) {
+            /* sin x */
+            shader_addline(buffer, "MUL %s.y, TA.x, TA.y;\n", dst_name);
+            shader_addline(buffer, "ADD %s.y, %s.y, %s.y;\n", dst_name, dst_name, dst_name);
+        }
+    }
 }
 
 }
 
-static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
+static void shader_hw_sgn(const struct wined3d_shader_instruction *ins)
 {
 {
-    GLuint program_id = 0;
-    const char *blt_vprogram =
-        "!!ARBvp1.0\n"
-        "PARAM c[1] = { { 1, 0.5 } };\n"
-        "MOV result.position, vertex.position;\n"
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_name[50];
+    char src_name[50];
+    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+
+    /* SGN is only valid in vertex shaders */
+    if(ctx->target_version == NV2) {
+        shader_hw_map2gl(ins);
+        return;
+    }
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
+
+    /* If SRC > 0.0, -SRC < SRC = TRUE, otherwise false.
+     * if SRC < 0.0,  SRC < -SRC = TRUE. If neither is true, src = 0.0
+     */
+    if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) {
+        shader_addline(buffer, "SLT %s, -%s, %s;\n", dst_name, src_name, src_name);
+    } else {
+        /* src contains TA? Write to the dest first. This won't overwrite our destination.
+         * Then use TA, and calculate the final result
+         *
+         * Not reading from TA? Store the first result in TA to avoid overwriting the
+         * destination if src reg = dst reg
+         */
+        if(strstr(src_name, "TA"))
+        {
+            shader_addline(buffer, "SLT %s,  %s, -%s;\n", dst_name, src_name, src_name);
+            shader_addline(buffer, "SLT TA, -%s, %s;\n", src_name, src_name);
+            shader_addline(buffer, "ADD %s, %s, -TA;\n", dst_name, dst_name);
+        }
+        else
+        {
+            shader_addline(buffer, "SLT TA, -%s, %s;\n", src_name, src_name);
+            shader_addline(buffer, "SLT %s,  %s, -%s;\n", dst_name, src_name, src_name);
+            shader_addline(buffer, "ADD %s, TA, -%s;\n", dst_name, dst_name);
+        }
+    }
+}
+
+static void shader_hw_dsy(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src[50];
+    char dst[50];
+    char dst_name[50];
+    BOOL is_color;
+
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+    shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+
+    shader_addline(buffer, "DDY %s, %s;\n", dst, src);
+    shader_addline(buffer, "MUL%s %s, %s, ycorrection.y;\n", shader_arb_get_modifier(ins), dst, dst_name);
+}
+
+static DWORD abs_modifier(DWORD mod, BOOL *need_abs)
+{
+    *need_abs = FALSE;
+
+    switch(mod)
+    {
+        case WINED3DSPSM_NONE:      return WINED3DSPSM_ABS;
+        case WINED3DSPSM_NEG:       return WINED3DSPSM_ABS;
+        case WINED3DSPSM_BIAS:      *need_abs = TRUE; return WINED3DSPSM_BIAS;
+        case WINED3DSPSM_BIASNEG:   *need_abs = TRUE; return WINED3DSPSM_BIASNEG;
+        case WINED3DSPSM_SIGN:      *need_abs = TRUE; return WINED3DSPSM_SIGN;
+        case WINED3DSPSM_SIGNNEG:   *need_abs = TRUE; return WINED3DSPSM_SIGNNEG;
+        case WINED3DSPSM_COMP:      *need_abs = TRUE; return WINED3DSPSM_COMP;
+        case WINED3DSPSM_X2:        *need_abs = TRUE; return WINED3DSPSM_X2;
+        case WINED3DSPSM_X2NEG:     *need_abs = TRUE; return WINED3DSPSM_X2NEG;
+        case WINED3DSPSM_DZ:        *need_abs = TRUE; return WINED3DSPSM_DZ;
+        case WINED3DSPSM_DW:        *need_abs = TRUE; return WINED3DSPSM_DW;
+        case WINED3DSPSM_ABS:       return WINED3DSPSM_ABS;
+        case WINED3DSPSM_ABSNEG:    return WINED3DSPSM_ABS;
+    }
+    FIXME("Unknown modifier %u\n", mod);
+    return mod;
+}
+
+static void shader_hw_log_pow(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src0[50], src1[50], dst[50];
+    struct wined3d_shader_src_param src0_copy = ins->src[0];
+    BOOL need_abs = FALSE;
+    const char *instr;
+    BOOL arg2 = FALSE;
+
+    switch(ins->handler_idx)
+    {
+        case WINED3DSIH_LOG:  instr = "LG2"; break;
+        case WINED3DSIH_LOGP: instr = "LOG"; break;
+        case WINED3DSIH_POW:  instr = "POW"; arg2 = TRUE; break;
+        default:
+            ERR("Unexpected instruction %d\n", ins->handler_idx);
+            return;
+    }
+
+    /* LOG, LOGP and POW operate on the absolute value of the input */
+    src0_copy.modifiers = abs_modifier(src0_copy.modifiers, &need_abs);
+
+    shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+    shader_arb_get_src_param(ins, &src0_copy, 0, src0);
+    if(arg2) shader_arb_get_src_param(ins, &ins->src[1], 1, src1);
+
+    if(need_abs)
+    {
+        shader_addline(buffer, "ABS TA, %s;\n", src0);
+        if(arg2)
+        {
+            shader_addline(buffer, "%s%s %s, TA, %s;\n", instr, shader_arb_get_modifier(ins), dst, src1);
+        }
+        else
+        {
+            shader_addline(buffer, "%s%s %s, TA;\n", instr, shader_arb_get_modifier(ins), dst);
+        }
+    }
+    else if(arg2)
+    {
+        shader_addline(buffer, "%s%s %s, %s, %s;\n", instr, shader_arb_get_modifier(ins), dst, src0, src1);
+    }
+    else
+    {
+        shader_addline(buffer, "%s%s %s, %s;\n", instr, shader_arb_get_modifier(ins), dst, src0);
+    }
+}
+
+static void shader_hw_loop(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src_name[50];
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    /* src0 is aL */
+    shader_arb_get_src_param(ins, &ins->src[1], 0, src_name);
+
+    if(vshader)
+    {
+        struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+        struct list *e = list_head(&priv->control_frames);
+        struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n");
+        /* The constant loader makes sure to load -1 into iX.w */
+        shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name);
+        shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->loop_no);
+        shader_addline(buffer, "loop_%u_start:\n", control_frame->loop_no);
+    }
+    else
+    {
+        shader_addline(buffer, "LOOP %s;\n", src_name);
+    }
+}
+
+static void shader_hw_rep(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char src_name[50];
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
+
+    /* The constant loader makes sure to load -1 into iX.w */
+    if(vshader)
+    {
+        struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+        struct list *e = list_head(&priv->control_frames);
+        struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n");
+
+        shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name);
+        shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->loop_no);
+        shader_addline(buffer, "loop_%u_start:\n", control_frame->loop_no);
+    }
+    else
+    {
+        shader_addline(buffer, "REP %s;\n", src_name);
+    }
+}
+
+static void shader_hw_endloop(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(vshader)
+    {
+        struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+        struct list *e = list_head(&priv->control_frames);
+        struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        shader_addline(buffer, "ARAC aL.xy, aL;\n");
+        shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->loop_no);
+        shader_addline(buffer, "loop_%u_end:\n", control_frame->loop_no);
+
+        if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n");
+    }
+    else
+    {
+        shader_addline(buffer, "ENDLOOP;\n");
+    }
+}
+
+static void shader_hw_endrep(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(vshader)
+    {
+        struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+        struct list *e = list_head(&priv->control_frames);
+        struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        shader_addline(buffer, "ARAC aL.xy, aL;\n");
+        shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->loop_no);
+        shader_addline(buffer, "loop_%u_end:\n", control_frame->loop_no);
+
+        if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n");
+    }
+    else
+    {
+        shader_addline(buffer, "ENDREP;\n");
+    }
+}
+
+static const struct control_frame *find_last_loop(const struct shader_arb_ctx_priv *priv)
+{
+    struct control_frame *control_frame;
+
+    LIST_FOR_EACH_ENTRY(control_frame, &priv->control_frames, struct control_frame, entry)
+    {
+        if(control_frame->type == LOOP || control_frame->type == REP) return control_frame;
+    }
+    ERR("Could not find loop for break\n");
+    return NULL;
+}
+
+static void shader_hw_break(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    const struct control_frame *control_frame = find_last_loop(ins->ctx->backend_data);
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(vshader)
+    {
+        shader_addline(buffer, "BRA loop_%u_end;\n", control_frame->loop_no);
+    }
+    else
+    {
+        shader_addline(buffer, "BRK;\n");
+    }
+}
+
+static const char *get_compare(COMPARISON_TYPE flags)
+{
+    switch (flags)
+    {
+        case COMPARISON_GT: return "GT";
+        case COMPARISON_EQ: return "EQ";
+        case COMPARISON_GE: return "GE";
+        case COMPARISON_LT: return "LT";
+        case COMPARISON_NE: return "NE";
+        case COMPARISON_LE: return "LE";
+        default:
+            FIXME("Unrecognized comparison value: %u\n", flags);
+            return "(\?\?)";
+    }
+}
+
+static COMPARISON_TYPE invert_compare(COMPARISON_TYPE flags)
+{
+    switch (flags)
+    {
+        case COMPARISON_GT: return COMPARISON_LE;
+        case COMPARISON_EQ: return COMPARISON_NE;
+        case COMPARISON_GE: return COMPARISON_LT;
+        case COMPARISON_LT: return COMPARISON_GE;
+        case COMPARISON_NE: return COMPARISON_EQ;
+        case COMPARISON_LE: return COMPARISON_GT;
+        default:
+            FIXME("Unrecognized comparison value: %u\n", flags);
+            return -1;
+    }
+}
+
+static void shader_hw_breakc(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+    const struct control_frame *control_frame = find_last_loop(ins->ctx->backend_data);
+    char src_name0[50];
+    char src_name1[50];
+    const char *comp = get_compare(ins->flags);
+
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+    shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+
+    if(vshader)
+    {
+        /* SUBC CC, src0, src1" works only in pixel shaders, so use TA to throw
+         * away the subtraction result
+         */
+        shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+        shader_addline(buffer, "BRA loop_%u_end (%s.x);\n", control_frame->loop_no, comp);
+    }
+    else
+    {
+        shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+        shader_addline(buffer, "BRK (%s.x);\n", comp);
+    }
+}
+
+static void shader_hw_ifc(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    struct list *e = list_head(&priv->control_frames);
+    struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+    const char *comp;
+    char src_name0[50];
+    char src_name1[50];
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+    shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+
+    if(vshader)
+    {
+        /* Invert the flag. We jump to the else label if the condition is NOT true */
+        comp = get_compare(invert_compare(ins->flags));
+        shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+        shader_addline(buffer, "BRA ifc_%u_else (%s.x);\n", control_frame->ifc_no, comp);
+    }
+    else
+    {
+        comp = get_compare(ins->flags);
+        shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+        shader_addline(buffer, "IF %s.x;\n", comp);
+    }
+}
+
+static void shader_hw_else(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    struct list *e = list_head(&priv->control_frames);
+    struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(vshader)
+    {
+        shader_addline(buffer, "BRA ifc_%u_endif;\n", control_frame->ifc_no);
+        shader_addline(buffer, "ifc_%u_else:\n", control_frame->ifc_no);
+        control_frame->had_else = TRUE;
+    }
+    else
+    {
+        shader_addline(buffer, "ELSE;\n");
+    }
+}
+
+static void shader_hw_endif(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    struct list *e = list_head(&priv->control_frames);
+    struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(vshader)
+    {
+        if(control_frame->had_else)
+        {
+            shader_addline(buffer, "ifc_%u_endif:\n", control_frame->ifc_no);
+        }
+        else
+        {
+            shader_addline(buffer, "#No else branch. else is endif\n");
+            shader_addline(buffer, "ifc_%u_else:\n", control_frame->ifc_no);
+        }
+    }
+    else
+    {
+        shader_addline(buffer, "ENDIF;\n");
+    }
+}
+
+static void shader_hw_texldd(const struct wined3d_shader_instruction *ins)
+{
+    DWORD sampler_idx = ins->src[1].reg.idx;
+    char reg_dest[40];
+    char reg_src[3][40];
+    DWORD flags = TEX_DERIV;
+
+    shader_arb_get_dst_param(ins, &ins->dst[0], reg_dest);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src[0]);
+    shader_arb_get_src_param(ins, &ins->src[2], 1, reg_src[1]);
+    shader_arb_get_src_param(ins, &ins->src[3], 2, reg_src[2]);
+
+    if (ins->flags & WINED3DSI_TEXLD_PROJECT) flags |= TEX_PROJ;
+    if (ins->flags & WINED3DSI_TEXLD_BIAS) flags |= TEX_BIAS;
+
+    shader_hw_sample(ins, sampler_idx, reg_dest, reg_src[0], flags, reg_src[1], reg_src[2]);
+}
+
+static void shader_hw_texldl(const struct wined3d_shader_instruction *ins)
+{
+    DWORD sampler_idx = ins->src[1].reg.idx;
+    char reg_dest[40];
+    char reg_coord[40];
+    DWORD flags = TEX_LOD;
+
+    shader_arb_get_dst_param(ins, &ins->dst[0], reg_dest);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, reg_coord);
+
+    if (ins->flags & WINED3DSI_TEXLD_PROJECT) flags |= TEX_PROJ;
+    if (ins->flags & WINED3DSI_TEXLD_BIAS) flags |= TEX_BIAS;
+
+    shader_hw_sample(ins, sampler_idx, reg_dest, reg_coord, flags, NULL, NULL);
+}
+
+static void shader_hw_label(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+    priv->in_main_func = FALSE;
+    /* Call instructions activate the NV extensions, not labels and rets. If there is an uncalled
+     * subroutine, don't generate a label that will make GL complain
+     */
+    if(priv->target_version == ARB) return;
+
+    shader_addline(buffer, "l%u:\n", ins->src[0].reg.idx);
+}
+
+static void vshader_add_footer(IWineD3DVertexShaderImpl *This, struct wined3d_shader_buffer *buffer,
+        const struct arb_vs_compile_args *args, struct shader_arb_ctx_priv *priv_ctx)
+{
+    const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    unsigned int i;
+
+    /* 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->super.fog_src == VS_FOG_Z) {
+        shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
+    } else if (!reg_maps->fog) {
+        /* posFixup.x is always 1.0, so we can savely use it */
+        shader_addline(buffer, "ADD result.fogcoord, posFixup.x, -posFixup.x;\n");
+    }
+
+    /* Write the final position.
+     *
+     * OpenGL coordinates specify the center of the pixel while d3d coords specify
+     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+     * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
+     */
+    shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n");
+    shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n");
+    shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n");
+
+    if(use_nv_clip(gl_info) && priv_ctx->target_version >= NV2)
+    {
+        for(i = 0; i < priv_ctx->vs_clipplanes; i++)
+        {
+            shader_addline(buffer, "DP4 result.clip[%u].x, TMP_OUT, state.clip[%u].plane;\n", i, i);
+        }
+    }
+    else if(args->boolclip.clip_control[0])
+    {
+        unsigned int cur_clip = 0;
+        char component[4] = {'x', 'y', 'z', 'w'};
+
+        for(i = 0; i < GL_LIMITS(clipplanes); i++)
+        {
+            if(args->boolclip.clip_control[1] & (1 << i))
+            {
+                shader_addline(buffer, "DP4 TA.%c, TMP_OUT, state.clip[%u].plane;\n",
+                               component[cur_clip++], i);
+            }
+        }
+        switch(cur_clip)
+        {
+            case 0:
+                shader_addline(buffer, "MOV TA, -helper_const.w;\n");
+                break;
+            case 1:
+                shader_addline(buffer, "MOV TA.yzw, -helper_const.w;\n");
+                break;
+            case 2:
+                shader_addline(buffer, "MOV TA.zw, -helper_const.w;\n");
+                break;
+            case 3:
+                shader_addline(buffer, "MOV TA.w, -helper_const.w;\n");
+                break;
+        }
+        shader_addline(buffer, "MOV result.texcoord[%u], TA;\n",
+                       args->boolclip.clip_control[0] - 1);
+    }
+
+    /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
+     * and the glsl equivalent
+     */
+    if(need_helper_const(gl_info)) {
+        shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n");
+    } else {
+        shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n");
+        shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n");
+    }
+
+    shader_addline(buffer, "MOV result.position, TMP_OUT;\n");
+
+    priv_ctx->footer_written = TRUE;
+}
+
+static void shader_hw_ret(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *) ins->ctx->shader;
+    BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+    if(priv->target_version == ARB) return;
+
+    if(vshader)
+    {
+        if(priv->in_main_func) vshader_add_footer((IWineD3DVertexShaderImpl *) shader, buffer, priv->cur_vs_args, priv);
+    }
+
+    shader_addline(buffer, "RET;\n");
+}
+
+static void shader_hw_call(const struct wined3d_shader_instruction *ins)
+{
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    shader_addline(buffer, "CAL l%u;\n", ins->src[0].reg.idx);
+}
+
+/* GL locking is done by the caller */
+static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_info)
+{
+    GLuint program_id = 0;
+    const char *blt_vprogram =
+        "!!ARBvp1.0\n"
+        "PARAM c[1] = { { 1, 0.5 } };\n"
+        "MOV result.position, vertex.position;\n"
         "MOV result.color, c[0].x;\n"
         "MOV result.texcoord[0], vertex.texcoord[0];\n"
         "END\n";
 
         "MOV result.color, c[0].x;\n"
         "MOV result.texcoord[0], vertex.texcoord[0];\n"
         "END\n";
 
-    GL_EXTCALL(glGenProgramsARB(1, &program_id));
-    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, program_id));
-    GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(blt_vprogram), blt_vprogram));
+    GL_EXTCALL(glGenProgramsARB(1, &program_id));
+    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, program_id));
+    GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(blt_vprogram), blt_vprogram));
+
+    if (glGetError() == GL_INVALID_OPERATION) {
+        GLint pos;
+        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+        FIXME("Vertex program error at position %d: %s\n", pos,
+            debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+    }
+
+    return program_id;
+}
+
+/* GL locking is done by the caller */
+static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info, enum tex_types tex_type)
+{
+    GLuint program_id = 0;
+    static const char * const blt_fprograms[tex_type_count] =
+    {
+        /* tex_1d */
+        NULL,
+        /* tex_2d */
+        "!!ARBfp1.0\n"
+        "TEMP R0;\n"
+        "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
+        "MOV result.depth.z, R0.x;\n"
+        "END\n",
+        /* tex_3d */
+        NULL,
+        /* tex_cube */
+        "!!ARBfp1.0\n"
+        "TEMP R0;\n"
+        "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
+        "MOV result.depth.z, R0.x;\n"
+        "END\n",
+        /* tex_rect */
+        "!!ARBfp1.0\n"
+        "TEMP R0;\n"
+        "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
+        "MOV result.depth.z, R0.x;\n"
+        "END\n",
+    };
+
+    if (!blt_fprograms[tex_type])
+    {
+        FIXME("tex_type %#x not supported\n", tex_type);
+        tex_type = tex_2d;
+    }
+
+    GL_EXTCALL(glGenProgramsARB(1, &program_id));
+    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id));
+    GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type]));
+
+    if (glGetError() == GL_INVALID_OPERATION) {
+        GLint pos;
+        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+        FIXME("Fragment program error at position %d: %s\n", pos,
+            debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+    }
+
+    return program_id;
+}
+
+static void arbfp_add_sRGB_correction(struct wined3d_shader_buffer *buffer, const char *fragcolor,
+        const char *tmp1, const char *tmp2, const char *tmp3, const char *tmp4, BOOL condcode)
+{
+    /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
+
+    if(condcode)
+    {
+        /* Sigh. MOVC CC doesn't work, so use one of the temps as dummy dest */
+        shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.y;\n", tmp1, fragcolor);
+        /* Calculate the > 0.0031308 case */
+        shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts1.z;\n", fragcolor, fragcolor);
+        shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts1.z;\n", fragcolor, fragcolor);
+        shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts1.z;\n", fragcolor, fragcolor);
+        shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts1.w;\n", fragcolor, fragcolor);
+        shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts2.x;\n", fragcolor, fragcolor);
+        /* Calculate the < case */
+        shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts1.x, %s;\n", fragcolor, fragcolor);
+    }
+    else
+    {
+        /* Calculate the > 0.0031308 case */
+        shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor);
+        shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor);
+        shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor);
+        shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1);
+        shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1);
+        /* Calculate the < case */
+        shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
+        /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
+        shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor);
+        shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor);
+        /* Store the components > 0.0031308 in the destination */
+        shader_addline(buffer, "MUL %s.xyz, %s, %s;\n", fragcolor, tmp1, tmp3);
+        /* Add the components that are < 0.0031308 */
+        shader_addline(buffer, "MAD %s.xyz, %s, %s, %s;\n", fragcolor, tmp2, tmp4, fragcolor);
+        /* Move everything into result.color at once. Nvidia hardware cannot handle partial
+        * result.color writes(.rgb first, then .a), or handle overwriting already written
+        * components. The assembler uses a temporary register in this case, which is usually
+        * not allocated from one of our registers that were used earlier.
+        */
+    }
+    shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
+    /* [0.0;1.0] clamping. Not needed, this is done implicitly */
+}
+
+static const DWORD *find_loop_control_values(IWineD3DBaseShaderImpl *This, DWORD idx)
+{
+    const local_constant *constant;
+
+    LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsI, local_constant, entry)
+    {
+        if (constant->idx == idx)
+        {
+            return constant->value;
+        }
+    }
+    return NULL;
+}
+
+static void init_ps_input(const IWineD3DPixelShaderImpl *This, const struct arb_ps_compile_args *args,
+                          struct shader_arb_ctx_priv *priv)
+{
+    const char *texcoords[8] =
+    {
+        "fragment.texcoord[0]", "fragment.texcoord[1]", "fragment.texcoord[2]", "fragment.texcoord[3]",
+        "fragment.texcoord[4]", "fragment.texcoord[5]", "fragment.texcoord[6]", "fragment.texcoord[7]"
+    };
+    unsigned int i;
+    const struct wined3d_shader_signature_element *sig = This->input_signature;
+    const char *semantic_name;
+    DWORD semantic_idx;
+
+    switch(args->super.vp_mode)
+    {
+        case pretransformed:
+        case fixedfunction:
+            /* The pixelshader has to collect the varyings on its own. In any case properly load
+             * color0 and color1. In the case of pretransformed vertices also load texcoords. Set
+             * other attribs to 0.0.
+             *
+             * For fixedfunction this behavior is correct, according to the tests. For pretransformed
+             * we'd either need a replacement shader that can load other attribs like BINORMAL, or
+             * load the texcoord attrib pointers to match the pixel shader signature
+             */
+            for(i = 0; i < MAX_REG_INPUT; i++)
+            {
+                semantic_name = sig[i].semantic_name;
+                semantic_idx = sig[i].semantic_idx;
+                if(semantic_name == NULL) continue;
+
+                if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+                {
+                    if(semantic_idx == 0) priv->ps_input[i] = "fragment.color.primary";
+                    else if(semantic_idx == 1) priv->ps_input[i] = "fragment.color.secondary";
+                    else priv->ps_input[i] = "0.0";
+                }
+                else if(args->super.vp_mode == fixedfunction)
+                {
+                    priv->ps_input[i] = "0.0";
+                }
+                else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
+                {
+                    if(semantic_idx < 8) priv->ps_input[i] = texcoords[semantic_idx];
+                    else priv->ps_input[i] = "0.0";
+                }
+                else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
+                {
+                    if(semantic_idx == 0) priv->ps_input[i] = "fragment.fogcoord";
+                    else priv->ps_input[i] = "0.0";
+                }
+                else
+                {
+                    priv->ps_input[i] = "0.0";
+                }
+
+                TRACE("v%u, semantic %s%u is %s\n", i, semantic_name, semantic_idx, priv->ps_input[i]);
+            }
+            break;
+
+        case vertexshader:
+            /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in
+             * fragment.color
+             */
+            for(i = 0; i < 8; i++)
+            {
+                priv->ps_input[i] = texcoords[i];
+            }
+            priv->ps_input[8] = "fragment.color.primary";
+            priv->ps_input[9] = "fragment.color.secondary";
+            break;
+    }
+}
+
+/* GL locking is done by the caller */
+static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct wined3d_shader_buffer *buffer,
+        const struct arb_ps_compile_args *args, struct arb_ps_compiled_shader *compiled)
+{
+    const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
+    CONST DWORD *function = This->baseShader.function;
+    const struct wined3d_gl_info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
+    const local_constant *lconst;
+    GLuint retval;
+    char fragcolor[16];
+    DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This), next_local, cur;
+    struct shader_arb_ctx_priv priv_ctx;
+    BOOL dcl_tmp = args->super.srgb_correction, dcl_td = FALSE;
+    BOOL want_nv_prog = FALSE;
+    struct arb_pshader_private *shader_priv = This->backend_priv;
+    DWORD map;
+
+    char srgbtmp[4][4];
+    unsigned int i, found = 0;
+
+    for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+    {
+        if (!(map & 1)
+                || (This->color0_mov && i == This->color0_reg)
+                || (reg_maps->shader_version.major < 2 && i == 0))
+            continue;
+
+        sprintf(srgbtmp[found], "R%u", i);
+        ++found;
+        if (found == 4) break;
+    }
+
+    switch(found) {
+        case 4: dcl_tmp = FALSE; break;
+        case 0:
+            sprintf(srgbtmp[0], "TA");
+            sprintf(srgbtmp[1], "TB");
+            sprintf(srgbtmp[2], "TC");
+            sprintf(srgbtmp[3], "TD");
+            dcl_td = TRUE;
+            break;
+        case 1:
+            sprintf(srgbtmp[1], "TA");
+            sprintf(srgbtmp[2], "TB");
+            sprintf(srgbtmp[3], "TC");
+            break;
+        case 2:
+            sprintf(srgbtmp[2], "TA");
+            sprintf(srgbtmp[3], "TB");
+            break;
+        case 3:
+            sprintf(srgbtmp[3], "TA");
+            break;
+    }
+
+    /*  Create the hw ARB shader */
+    memset(&priv_ctx, 0, sizeof(priv_ctx));
+    priv_ctx.cur_ps_args = args;
+    priv_ctx.compiled_fprog = compiled;
+    priv_ctx.cur_np2fixup_info = &compiled->np2fixup_info;
+    init_ps_input(This, args, &priv_ctx);
+    list_init(&priv_ctx.control_frames);
+
+    /* Avoid enabling NV_fragment_program* if we do not need it.
+     *
+     * Enabling GL_NV_fragment_program_option causes the driver to occupy a temporary register,
+     * and it slows down the shader execution noticeably(about 5%). Usually our instruction emulation
+     * is faster than what we gain from using higher native instructions. There are some things though
+     * that cannot be emulated. In that case enable the extensions.
+     * If the extension is enabled, instruction handlers that support both ways will use it.
+     *
+     * Testing shows no performance difference between OPTION NV_fragment_program2 and NV_fragment_program.
+     * So enable the best we can get.
+     */
+    if(reg_maps->usesdsx || reg_maps->usesdsy || reg_maps->loop_depth > 0 || reg_maps->usestexldd ||
+       reg_maps->usestexldl || reg_maps->usesfacing || reg_maps->usesifc || reg_maps->usescall)
+    {
+        want_nv_prog = TRUE;
+    }
+
+    shader_addline(buffer, "!!ARBfp1.0\n");
+    if(want_nv_prog && GL_SUPPORT(NV_FRAGMENT_PROGRAM2)) {
+        shader_addline(buffer, "OPTION NV_fragment_program2;\n");
+        priv_ctx.target_version = NV3;
+    } else if(want_nv_prog && GL_SUPPORT(NV_FRAGMENT_PROGRAM_OPTION)) {
+        shader_addline(buffer, "OPTION NV_fragment_program;\n");
+        priv_ctx.target_version = NV2;
+    } else {
+        if(want_nv_prog)
+        {
+            /* This is an error - either we're advertising the wrong shader version, or aren't enforcing some
+             * limits properly
+             */
+            ERR("The shader requires instructions that are not available in plain GL_ARB_fragment_program\n");
+            ERR("Try GLSL\n");
+        }
+        priv_ctx.target_version = ARB;
+    }
+
+    if(This->baseShader.reg_maps.highest_render_target > 0)
+    {
+        shader_addline(buffer, "OPTION ARB_draw_buffers;\n");
+    }
+
+    if (reg_maps->shader_version.major < 3)
+    {
+        switch(args->super.fog) {
+            case FOG_OFF:
+                break;
+            case FOG_LINEAR:
+                shader_addline(buffer, "OPTION ARB_fog_linear;\n");
+                break;
+            case FOG_EXP:
+                shader_addline(buffer, "OPTION ARB_fog_exp;\n");
+                break;
+            case FOG_EXP2:
+                shader_addline(buffer, "OPTION ARB_fog_exp2;\n");
+                break;
+        }
+    }
+
+    /* For now always declare the temps. At least the Nvidia assembler optimizes completely
+     * unused temps away(but occupies them for the whole shader if they're used once). Always
+     * declaring them avoids tricky bookkeeping work
+     */
+    shader_addline(buffer, "TEMP TA;\n");      /* Used for modifiers */
+    shader_addline(buffer, "TEMP TB;\n");      /* Used for modifiers */
+    shader_addline(buffer, "TEMP TC;\n");      /* Used for modifiers */
+    if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */
+    shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
+    shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
+    shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
+
+    if (reg_maps->shader_version.major < 2)
+    {
+        strcpy(fragcolor, "R0");
+    } else {
+        if(args->super.srgb_correction) {
+            if(This->color0_mov) {
+                sprintf(fragcolor, "R%u", This->color0_reg);
+            } else {
+                shader_addline(buffer, "TEMP TMP_COLOR;\n");
+                strcpy(fragcolor, "TMP_COLOR");
+            }
+        } else {
+            strcpy(fragcolor, "result.color");
+        }
+    }
+
+    if(args->super.srgb_correction) {
+        shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
+                       srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
+        shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
+                       srgb_sub_high, 0.0, 0.0, 0.0);
+    }
+
+    /* Base Declarations */
+    next_local = shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION,
+            lconst_map, NULL, &priv_ctx);
+
+    for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
+    {
+        if (!(map & 1)) continue;
+
+        cur = compiled->numbumpenvmatconsts;
+        compiled->bumpenvmatconst[cur].const_num = WINED3D_CONST_NUM_UNUSED;
+        compiled->bumpenvmatconst[cur].texunit = i;
+        compiled->luminanceconst[cur].const_num = WINED3D_CONST_NUM_UNUSED;
+        compiled->luminanceconst[cur].texunit = i;
+
+        /* We can fit the constants into the constant limit for sure because texbem, texbeml, bem and beml are only supported
+         * in 1.x shaders, and GL_ARB_fragment_program has a constant limit of 24 constants. So in the worst case we're loading
+         * 8 shader constants, 8 bump matrices and 8 luminance parameters and are perfectly fine. (No NP2 fixup on bumpmapped
+         * textures due to conditional NP2 restrictions)
+         *
+         * Use local constants to load the bump env parameters, not program.env. This avoids collisions with d3d constants of
+         * shaders in newer shader models. Since the bump env parameters have to share their space with NP2 fixup constants,
+         * their location is shader dependent anyway and they cannot be loaded globally.
+         */
+        compiled->bumpenvmatconst[cur].const_num = next_local++;
+        shader_addline(buffer, "PARAM bumpenvmat%d = program.local[%d];\n",
+                       i, compiled->bumpenvmatconst[cur].const_num);
+        compiled->numbumpenvmatconsts = cur + 1;
+
+        if (!(reg_maps->luminanceparams & (1 << i))) continue;
+
+        compiled->luminanceconst[cur].const_num = next_local++;
+        shader_addline(buffer, "PARAM luminance%d = program.local[%d];\n",
+                       i, compiled->luminanceconst[cur].const_num);
+    }
+
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
+        if (reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+        {
+            const DWORD *control_values = find_loop_control_values((IWineD3DBaseShaderImpl *) This, i);
+
+            if(control_values)
+            {
+                shader_addline(buffer, "PARAM I%u = {%u, %u, %u, -1};\n", i,
+                                control_values[0], control_values[1], control_values[2]);
+            }
+            else
+            {
+                compiled->int_consts[i] = next_local;
+                compiled->num_int_consts++;
+                shader_addline(buffer, "PARAM I%u = program.local[%u];\n", i, next_local++);
+            }
+        }
+    }
+
+    if(reg_maps->vpos || reg_maps->usesdsy)
+    {
+        compiled->ycorrection = next_local;
+        shader_addline(buffer, "PARAM ycorrection = program.local[%u];\n", next_local++);
+
+        if(reg_maps->vpos)
+        {
+            shader_addline(buffer, "TEMP vpos;\n");
+            /* ycorrection.x: Backbuffer height(onscreen) or 0(offscreen).
+             * ycorrection.y: -1.0(onscreen), 1.0(offscreen)
+             * ycorrection.z: 1.0
+             * ycorrection.w: 0.0
+             */
+            shader_addline(buffer, "MAD vpos, fragment.position, ycorrection.zyww, ycorrection.wxww;\n");
+            shader_addline(buffer, "FLR vpos.xy, vpos;\n");
+        }
+    }
+    else
+    {
+        compiled->ycorrection = WINED3D_CONST_NUM_UNUSED;
+    }
+
+    /* Load constants to fixup NP2 texcoords if there are still free constants left:
+     * Constants (texture dimensions) for the NP2 fixup are loaded as local program parameters. This will consume
+     * at most 8 (MAX_FRAGMENT_SAMPLERS / 2) parameters, which is highly unlikely, since the application had to
+     * use 16 NP2 textures at the same time. In case that we run out of constants the fixup is simply not
+     * applied / activated. This will probably result in wrong rendering of the texture, but will save us from
+     * shader compilation errors and the subsequent errors when drawing with this shader. */
+    if (priv_ctx.cur_ps_args->super.np2_fixup) {
+
+        struct arb_ps_np2fixup_info* const fixup = priv_ctx.cur_np2fixup_info;
+        const WORD map = priv_ctx.cur_ps_args->super.np2_fixup;
+        const UINT max_lconsts = gl_info->ps_arb_max_local_constants;
+
+        fixup->offset = next_local;
+        fixup->super.active = 0;
+
+        cur = 0;
+        for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
+            if (!(map & (1 << i))) continue;
+
+            if (fixup->offset + (cur >> 1) < max_lconsts) {
+                fixup->super.active |= (1 << i);
+                fixup->super.idx[i] = cur++;
+            } else {
+                FIXME("No free constant found to load NP2 fixup data into shader. "
+                      "Sampling from this texture will probably look wrong.\n");
+                break;
+            }
+        }
+
+        fixup->super.num_consts = (cur + 1) >> 1;
+        if (fixup->super.num_consts) {
+            shader_addline(buffer, "PARAM np2fixup[%u] = { program.env[%u..%u] };\n",
+                           fixup->super.num_consts, fixup->offset, fixup->super.num_consts + fixup->offset - 1);
+        }
+
+        next_local += fixup->super.num_consts;
+    }
+
+    if (shader_priv->clipplane_emulation != ~0U)
+    {
+        shader_addline(buffer, "KIL fragment.texcoord[%u];\n", shader_priv->clipplane_emulation);
+    }
+
+    /* Base Shader Body */
+    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function, &priv_ctx);
+
+    if(args->super.srgb_correction) {
+        arbfp_add_sRGB_correction(buffer, fragcolor, srgbtmp[0], srgbtmp[1], srgbtmp[2], srgbtmp[3],
+                                  priv_ctx.target_version >= NV2);
+    } else if(reg_maps->shader_version.major < 2) {
+        shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
+    }
+    shader_addline(buffer, "END\n");
+
+    /* TODO: change to resource.glObjectHandle or something like that */
+    GL_EXTCALL(glGenProgramsARB(1, &retval));
+
+    TRACE("Creating a hw pixel shader, prg=%d\n", retval);
+    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, retval));
+
+    TRACE("Created hw pixel shader, prg=%d\n", retval);
+    /* Create the program and check for errors */
+    GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+               buffer->bsize, buffer->buffer));
+
+    if (glGetError() == GL_INVALID_OPERATION) {
+        GLint errPos;
+        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
+        FIXME("HW PixelShader Error at position %d: %s\n",
+              errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+        retval = 0;
+    }
+
+    /* Load immediate constants */
+    if(lconst_map) {
+        LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+            const float *value = (const float *)lconst->value;
+            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
+            checkGLcall("glProgramLocalParameter4fvARB");
+        }
+        HeapFree(GetProcessHeap(), 0, lconst_map);
+    }
+
+    return retval;
+}
+
+static int compare_sig(const struct wined3d_shader_signature_element *sig1, const struct wined3d_shader_signature_element *sig2)
+{
+    unsigned int i;
+    int ret;
+
+    for(i = 0; i < MAX_REG_INPUT; i++)
+    {
+        if(sig1[i].semantic_name == NULL || sig2[i].semantic_name == NULL)
+        {
+            /* Compare pointers, not contents. One string is NULL(element does not exist), the other one is not NULL */
+            if(sig1[i].semantic_name != sig2[i].semantic_name) return sig1[i].semantic_name < sig2[i].semantic_name ? -1 : 1;
+            continue;
+        }
+
+        ret = strcmp(sig1[i].semantic_name, sig2[i].semantic_name);
+        if(ret != 0) return ret;
+        if(sig1[i].semantic_idx    != sig2[i].semantic_idx)    return sig1[i].semantic_idx    < sig2[i].semantic_idx    ? -1 : 1;
+        if(sig1[i].sysval_semantic != sig2[i].sysval_semantic) return sig1[i].sysval_semantic < sig2[i].sysval_semantic ? -1 : 1;
+        if(sig1[i].component_type  != sig2[i].component_type)  return sig1[i].sysval_semantic < sig2[i].component_type  ? -1 : 1;
+        if(sig1[i].register_idx    != sig2[i].register_idx)    return sig1[i].register_idx    < sig2[i].register_idx    ? -1 : 1;
+        if(sig1[i].mask            != sig2->mask)              return sig1[i].mask            < sig2[i].mask            ? -1 : 1;
+    }
+    return 0;
+}
+
+static struct wined3d_shader_signature_element *clone_sig(const struct wined3d_shader_signature_element *sig)
+{
+    struct wined3d_shader_signature_element *new;
+    int i;
+    char *name;
+
+    new = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*new) * MAX_REG_INPUT);
+    for(i = 0; i < MAX_REG_INPUT; i++)
+    {
+        if(sig[i].semantic_name == NULL)
+        {
+            continue;
+        }
+
+        new[i] = sig[i];
+        /* Clone the semantic string */
+        name = HeapAlloc(GetProcessHeap(), 0, strlen(sig[i].semantic_name) + 1);
+        strcpy(name, sig[i].semantic_name);
+        new[i].semantic_name = name;
+    }
+    return new;
+}
+
+static DWORD find_input_signature(struct shader_arb_priv *priv, const struct wined3d_shader_signature_element *sig)
+{
+    struct wine_rb_entry *entry = wine_rb_get(&priv->signature_tree, sig);
+    struct ps_signature *found_sig;
+
+    if(entry != NULL)
+    {
+        found_sig = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+        TRACE("Found existing signature %u\n", found_sig->idx);
+        return found_sig->idx;
+    }
+    found_sig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sig));
+    found_sig->sig = clone_sig(sig);
+    found_sig->idx = priv->ps_sig_number++;
+    TRACE("New signature stored and assigned number %u\n", found_sig->idx);
+    if(wine_rb_put(&priv->signature_tree, sig, &found_sig->entry) == -1)
+    {
+        ERR("Failed to insert program entry.\n");
+    }
+    return found_sig->idx;
+}
+
+static void init_output_registers(IWineD3DVertexShaderImpl *shader, DWORD sig_num, struct shader_arb_ctx_priv *priv_ctx,
+                                  struct arb_vs_compiled_shader *compiled)
+{
+    unsigned int i, j;
+    static const char *texcoords[8] =
+    {
+        "result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
+        "result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
+    };
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) shader->baseShader.device;
+    const struct wined3d_shader_signature_element *sig;
+    const char *semantic_name;
+    DWORD semantic_idx, reg_idx;
+
+    /* Write generic input varyings 0 to 7 to result.texcoord[], varying 8 to result.color.primary
+     * and varying 9 to result.color.secondary
+     */
+    const char *decl_idx_to_string[MAX_REG_INPUT] =
+    {
+        texcoords[0], texcoords[1], texcoords[2], texcoords[3],
+        texcoords[4], texcoords[5], texcoords[6], texcoords[7],
+        "result.color.primary", "result.color.secondary"
+    };
+
+    if(sig_num == ~0)
+    {
+        TRACE("Pixel shader uses builtin varyings\n");
+        /* Map builtins to builtins */
+        for(i = 0; i < 8; i++)
+        {
+            priv_ctx->texcrd_output[i] = texcoords[i];
+        }
+        priv_ctx->color_output[0] = "result.color.primary";
+        priv_ctx->color_output[1] = "result.color.secondary";
+        priv_ctx->fog_output = "result.fogcoord";
+
+        /* Map declared regs to builtins. Use "TA" to /dev/null unread output */
+        for(i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); i++)
+        {
+            semantic_name = shader->output_signature[i].semantic_name;
+            if(semantic_name == NULL) continue;
+
+            if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
+            {
+                TRACE("o%u is TMP_OUT\n", i);
+                if(shader->output_signature[i].semantic_idx == 0) priv_ctx->vs_output[i] = "TMP_OUT";
+                else priv_ctx->vs_output[i] = "TA";
+            }
+            else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
+            {
+                TRACE("o%u is result.pointsize\n", i);
+                if(shader->output_signature[i].semantic_idx == 0) priv_ctx->vs_output[i] = "result.pointsize";
+                else priv_ctx->vs_output[i] = "TA";
+            }
+            else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+            {
+                TRACE("o%u is result.color.?, idx %u\n", i, shader->output_signature[i].semantic_idx);
+                if(shader->output_signature[i].semantic_idx == 0) priv_ctx->vs_output[i] = "result.color.primary";
+                else if(shader->output_signature[i].semantic_idx == 1) priv_ctx->vs_output[i] = "result.color.secondary";
+                else priv_ctx->vs_output[i] = "TA";
+            }
+            else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
+            {
+                TRACE("o%u is %s\n", i, texcoords[shader->output_signature[i].semantic_idx]);
+                if(shader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA";
+                else priv_ctx->vs_output[i] = texcoords[shader->output_signature[i].semantic_idx];
+            }
+            else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
+            {
+                TRACE("o%u is result.fogcoord\n", i);
+                if(shader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA";
+                else priv_ctx->vs_output[i] = "result.fogcoord";
+            }
+            else
+            {
+                priv_ctx->vs_output[i] = "TA";
+            }
+        }
+        return;
+    }
+
+    /* Instead of searching for the signature in the signature list, read the one from the current pixel shader.
+     * Its maybe not the shader where the signature came from, but it is the same signature and faster to find
+     */
+    sig = ((IWineD3DPixelShaderImpl *)device->stateBlock->pixelShader)->input_signature;
+    TRACE("Pixel shader uses declared varyings\n");
+
+    /* Map builtin to declared. /dev/null the results by default to the TA temp reg */
+    for(i = 0; i < 8; i++)
+    {
+        priv_ctx->texcrd_output[i] = "TA";
+    }
+    priv_ctx->color_output[0] = "TA";
+    priv_ctx->color_output[1] = "TA";
+    priv_ctx->fog_output = "TA";
+
+    for(i = 0; i < MAX_REG_INPUT; i++)
+    {
+        semantic_name = sig[i].semantic_name;
+        semantic_idx = sig[i].semantic_idx;
+        reg_idx = sig[i].register_idx;
+        if(semantic_name == NULL) continue;
+
+        /* If a declared input register is not written by builtin arguments, don't write to it.
+         * GL_NV_vertex_program makes sure the input defaults to 0.0, which is correct with D3D
+         *
+         * Don't care about POSITION and PSIZE here - this is a builtin vertex shader, position goes
+         * to TMP_OUT in any case
+         */
+        if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
+        {
+            if(semantic_idx < 8) priv_ctx->texcrd_output[semantic_idx] = decl_idx_to_string[reg_idx];
+        }
+        else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+        {
+            if(semantic_idx < 2) priv_ctx->color_output[semantic_idx] = decl_idx_to_string[reg_idx];
+        }
+        else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
+        {
+            if(semantic_idx == 0) priv_ctx->fog_output = decl_idx_to_string[reg_idx];
+        }
+        else
+        {
+            continue;
+        }
+
+        if(strcmp(decl_idx_to_string[reg_idx], "result.color.primary") == 0 ||
+           strcmp(decl_idx_to_string[reg_idx], "result.color.secondary") == 0)
+        {
+            compiled->need_color_unclamp = TRUE;
+        }
+    }
+
+    /* Map declared to declared */
+    for(i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); i++)
+    {
+        /* Write unread output to TA to throw them away */
+        priv_ctx->vs_output[i] = "TA";
+        semantic_name = shader->output_signature[i].semantic_name;
+        if(semantic_name == NULL)
+        {
+            continue;
+        }
+
+        if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION) &&
+           shader->output_signature[i].semantic_idx == 0)
+        {
+            priv_ctx->vs_output[i] = "TMP_OUT";
+            continue;
+        }
+        else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE) &&
+           shader->output_signature[i].semantic_idx == 0)
+        {
+            priv_ctx->vs_output[i] = "result.pointsize";
+            continue;
+        }
+
+        for(j = 0; j < MAX_REG_INPUT; j++)
+        {
+            if(sig[j].semantic_name == NULL)
+            {
+                continue;
+            }
+
+            if(strcmp(sig[j].semantic_name, semantic_name) == 0 &&
+               sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
+            {
+                priv_ctx->vs_output[i] = decl_idx_to_string[sig[j].register_idx];
+
+                if(strcmp(priv_ctx->vs_output[i], "result.color.primary") == 0 ||
+                   strcmp(priv_ctx->vs_output[i], "result.color.secondary") == 0)
+                {
+                    compiled->need_color_unclamp = TRUE;
+                }
+            }
+        }
+    }
+}
+
+/* GL locking is done by the caller */
+static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct wined3d_shader_buffer *buffer,
+        const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled)
+{
+    const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    CONST DWORD *function = This->baseShader.function;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const local_constant *lconst;
+    GLuint ret;
+    DWORD next_local, *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
+    struct shader_arb_ctx_priv priv_ctx;
+    unsigned int i;
+
+    memset(&priv_ctx, 0, sizeof(priv_ctx));
+    priv_ctx.cur_vs_args = args;
+    list_init(&priv_ctx.control_frames);
+    init_output_registers(This, args->ps_signature, &priv_ctx, compiled);
+
+    /*  Create the hw ARB shader */
+    shader_addline(buffer, "!!ARBvp1.0\n");
+
+    /* Always enable the NV extension if available. Unlike fragment shaders, there is no
+     * mesurable performance penalty, and we can always make use of it for clipplanes.
+     */
+    if(GL_SUPPORT(NV_VERTEX_PROGRAM3)) {
+        shader_addline(buffer, "OPTION NV_vertex_program3;\n");
+        priv_ctx.target_version = NV3;
+        shader_addline(buffer, "ADDRESS aL;\n");
+    } else if(GL_SUPPORT(NV_VERTEX_PROGRAM2_OPTION)) {
+        shader_addline(buffer, "OPTION NV_vertex_program2;\n");
+        priv_ctx.target_version = NV2;
+        shader_addline(buffer, "ADDRESS aL;\n");
+    } else {
+        priv_ctx.target_version = ARB;
+    }
+
+    shader_addline(buffer, "TEMP TMP_OUT;\n");
+    if(need_helper_const(gl_info)) {
+        shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset);
+    }
+    if(need_mova_const((IWineD3DBaseShader *) This, gl_info)) {
+        shader_addline(buffer, "PARAM mova_const = { 0.5, 0.0, 2.0, 1.0 };\n");
+        shader_addline(buffer, "TEMP A0_SHADOW;\n");
+    }
+
+    shader_addline(buffer, "TEMP TA;\n");
+
+    /* Base Declarations */
+    next_local = shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION,
+            lconst_map, &priv_ctx.vs_clipplanes, &priv_ctx);
+
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
+        if(reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+        {
+            const DWORD *control_values = find_loop_control_values((IWineD3DBaseShaderImpl *) This, i);
+
+            if(control_values)
+            {
+                shader_addline(buffer, "PARAM I%u = {%u, %u, %u, -1};\n", i,
+                                control_values[0], control_values[1], control_values[2]);
+            }
+            else
+            {
+                compiled->int_consts[i] = next_local;
+                compiled->num_int_consts++;
+                shader_addline(buffer, "PARAM I%u = program.local[%u];\n", i, next_local++);
+            }
+        }
+    }
+
+    /* We need a constant to fixup the final position */
+    shader_addline(buffer, "PARAM posFixup = program.local[%u];\n", next_local);
+    compiled->pos_fixup = next_local++;
+
+    /* Initialize output parameters. GL_ARB_vertex_program does not require special initialization values
+     * for output parameters. D3D in theory does not do that either, but some applications depend on a
+     * proper initialization of the secondary color, and programs using the fixed function pipeline without
+     * a replacement shader depend on the texcoord.w being set properly.
+     *
+     * GL_NV_vertex_program defines that all output values are initialized to {0.0, 0.0, 0.0, 1.0}. This
+     * assertion is in effect even when using GL_ARB_vertex_program without any NV specific additions. So
+     * skip this if NV_vertex_program is supported. Otherwise, initialize the secondary color. For the tex-
+     * coords, we have a flag in the opengl caps. Many cards do not require the texcoord being set, and
+     * this can eat a number of instructions, so skip it unless this cap is set as well
+     */
+    if(!GL_SUPPORT(NV_VERTEX_PROGRAM)) {
+        shader_addline(buffer, "MOV result.color.secondary, -helper_const.wwwy;\n");
+
+        if ((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W && !device->frag_pipe->ffp_proj_control)
+        {
+            int i;
+            for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
+                if(This->baseShader.reg_maps.texcoord_mask[i] != 0 &&
+                This->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
+                    shader_addline(buffer, "MOV result.texcoord[%u].w, -helper_const.y;\n", i);
+                }
+            }
+        }
+    }
+
+    /* The shader starts with the main function */
+    priv_ctx.in_main_func = TRUE;
+    /* Base Shader Body */
+    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function, &priv_ctx);
+
+    if(!priv_ctx.footer_written) vshader_add_footer(This, buffer, args, &priv_ctx);
+
+    shader_addline(buffer, "END\n");
+
+    /* TODO: change to resource.glObjectHandle or something like that */
+    GL_EXTCALL(glGenProgramsARB(1, &ret));
+
+    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", ret);
+    /* Create the program and check for errors */
+    GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+               buffer->bsize, buffer->buffer));
 
     if (glGetError() == GL_INVALID_OPERATION) {
 
     if (glGetError() == GL_INVALID_OPERATION) {
-        GLint pos;
-        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
-        FIXME("Vertex program error at position %d: %s\n", pos,
-            debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+        GLint errPos;
+        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)));
+        ret = -1;
+    } else {
+        /* Load immediate constants */
+        if(lconst_map) {
+            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_map[lconst->idx], value));
+            }
+        }
     }
     }
+    HeapFree(GetProcessHeap(), 0, lconst_map);
 
 
-    return program_id;
+    return ret;
 }
 
 }
 
-static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
+/* GL locking is done by the caller */
+static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DPixelShaderImpl *shader, const struct arb_ps_compile_args *args)
 {
 {
-    GLuint program_id = 0;
-    static const char * const blt_fprograms[tex_type_count] =
+    UINT i;
+    DWORD new_size;
+    struct arb_ps_compiled_shader *new_array;
+    struct wined3d_shader_buffer buffer;
+    struct arb_pshader_private *shader_data;
+    GLuint ret;
+
+    if(!shader->backend_priv) {
+        IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) shader->baseShader.device;
+        const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+        struct shader_arb_priv *priv = device->shader_priv;
+
+        shader->backend_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+        shader_data = shader->backend_priv;
+        shader_data->clamp_consts = shader->baseShader.reg_maps.shader_version.major == 1;
+
+        if(shader->baseShader.reg_maps.shader_version.major < 3) shader_data->input_signature_idx = ~0;
+        else shader_data->input_signature_idx = find_input_signature(priv, shader->input_signature);
+
+        shader_data->has_signature_idx = TRUE;
+        TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
+
+        if (!device->vs_clipping)
+            shader_data->clipplane_emulation = shader_find_free_input_register(&shader->baseShader.reg_maps,
+                    GL_LIMITS(texture_stages) - 1);
+        else
+            shader_data->clipplane_emulation = ~0U;
+    }
+    shader_data = shader->backend_priv;
+
+    /* 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_data->num_gl_shaders; i++) {
+        if(memcmp(&shader_data->gl_shaders[i].args, args, sizeof(*args)) == 0) {
+            return &shader_data->gl_shaders[i];
+        }
+    }
+
+    TRACE("No matching GL shader found, compiling a new shader\n");
+    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+        if (shader_data->num_gl_shaders)
+        {
+            new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
+                                    new_size * sizeof(*shader_data->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+            new_size = 1;
+        }
+
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader_data->gl_shaders = new_array;
+        shader_data->shader_array_size = new_size;
+    }
+
+    shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+    pixelshader_update_samplers(&shader->baseShader.reg_maps,
+            ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures);
+
+    if (!shader_buffer_init(&buffer))
     {
     {
-        /* tex_1d */
-        NULL,
-        /* tex_2d */
-        "!!ARBfp1.0\n"
-        "TEMP R0;\n"
-        "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
-        "MOV result.depth.z, R0.x;\n"
-        "END\n",
-        /* tex_3d */
-        NULL,
-        /* tex_cube */
-        "!!ARBfp1.0\n"
-        "TEMP R0;\n"
-        "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
-        "MOV result.depth.z, R0.x;\n"
-        "END\n",
-        /* tex_rect */
-        "!!ARBfp1.0\n"
-        "TEMP R0;\n"
-        "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
-        "MOV result.depth.z, R0.x;\n"
-        "END\n",
-    };
+        ERR("Failed to initialize shader buffer.\n");
+        return 0;
+    }
 
 
-    if (!blt_fprograms[tex_type])
+    ret = shader_arb_generate_pshader(shader, &buffer, args,
+                                      &shader_data->gl_shaders[shader_data->num_gl_shaders]);
+    shader_buffer_free(&buffer);
+    shader_data->gl_shaders[shader_data->num_gl_shaders].prgId = ret;
+
+    return &shader_data->gl_shaders[shader_data->num_gl_shaders++];
+}
+
+static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const struct arb_vs_compile_args *new,
+                                 const DWORD use_map, BOOL skip_int) {
+    if((stored->super.swizzle_map & use_map) != new->super.swizzle_map) return FALSE;
+    if(stored->super.fog_src != new->super.fog_src) return FALSE;
+    if(stored->boolclip_compare != new->boolclip_compare) return FALSE;
+    if(stored->ps_signature != new->ps_signature) return FALSE;
+    if(stored->vertex_samplers_compare != new->vertex_samplers_compare) return FALSE;
+    if(skip_int) return TRUE;
+
+    return memcmp(stored->loop_ctrl, new->loop_ctrl, sizeof(stored->loop_ctrl)) == 0;
+}
+
+static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DVertexShaderImpl *shader, const struct arb_vs_compile_args *args)
+{
+    UINT i;
+    DWORD new_size;
+    struct arb_vs_compiled_shader *new_array;
+    DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map;
+    struct wined3d_shader_buffer buffer;
+    struct arb_vshader_private *shader_data;
+    GLuint ret;
+    const struct wined3d_gl_info *gl_info = &((IWineD3DDeviceImpl *)shader->baseShader.device)->adapter->gl_info;
+
+    if(!shader->backend_priv) {
+        shader->backend_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+    }
+    shader_data = shader->backend_priv;
+
+    /* 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_data->num_gl_shaders; i++) {
+        if(vs_args_equal(&shader_data->gl_shaders[i].args, args, use_map, GL_SUPPORT(NV_VERTEX_PROGRAM2_OPTION))) {
+            return &shader_data->gl_shaders[i];
+        }
+    }
+
+    TRACE("No matching GL shader found, compiling a new shader\n");
+
+    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+        if (shader_data->num_gl_shaders)
+        {
+            new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
+                                    new_size * sizeof(*shader_data->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+            new_size = 1;
+        }
+
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader_data->gl_shaders = new_array;
+        shader_data->shader_array_size = new_size;
+    }
+
+    shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+    if (!shader_buffer_init(&buffer))
+    {
+        ERR("Failed to initialize shader buffer.\n");
+        return 0;
+    }
+
+    ret = shader_arb_generate_vshader(shader, &buffer, args,
+            &shader_data->gl_shaders[shader_data->num_gl_shaders]);
+    shader_buffer_free(&buffer);
+    shader_data->gl_shaders[shader_data->num_gl_shaders].prgId = ret;
+
+    return &shader_data->gl_shaders[shader_data->num_gl_shaders++];
+}
+
+static inline void find_arb_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock,
+        struct arb_ps_compile_args *args)
+{
+    int i;
+    WORD int_skip;
+    const struct wined3d_gl_info *gl_info = &((IWineD3DDeviceImpl *)shader->baseShader.device)->adapter->gl_info;
+    find_ps_compile_args(shader, stateblock, &args->super);
+
+    /* This forces all local boolean constants to 1 to make them stateblock independent */
+    args->bools = shader->baseShader.reg_maps.local_bool_consts;
+
+    for(i = 0; i < MAX_CONST_B; i++)
+    {
+        if(stateblock->pixelShaderConstantB[i]) args->bools |= ( 1 << i);
+    }
+
+    /* Skip if unused or local, or supported natively */
+    int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts;
+    if(int_skip == 0xffff || GL_SUPPORT(NV_FRAGMENT_PROGRAM_OPTION))
+    {
+        memset(&args->loop_ctrl, 0, sizeof(args->loop_ctrl));
+        return;
+    }
+
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        if(int_skip & (1 << i))
+        {
+            args->loop_ctrl[i][0] = 0;
+            args->loop_ctrl[i][1] = 0;
+            args->loop_ctrl[i][2] = 0;
+        }
+        else
+        {
+            args->loop_ctrl[i][0] = stateblock->pixelShaderConstantI[i * 4];
+            args->loop_ctrl[i][1] = stateblock->pixelShaderConstantI[i * 4 + 1];
+            args->loop_ctrl[i][2] = stateblock->pixelShaderConstantI[i * 4 + 2];
+        }
+    }
+}
+
+static inline void find_arb_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock,
+        struct arb_vs_compile_args *args)
+{
+    int i;
+    WORD int_skip;
+    IWineD3DDeviceImpl *dev = (IWineD3DDeviceImpl *)shader->baseShader.device;
+    const struct wined3d_gl_info *gl_info = &dev->adapter->gl_info;
+    find_vs_compile_args(shader, stateblock, &args->super);
+
+    args->boolclip_compare = 0;
+    if(use_ps(stateblock))
+    {
+        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) stateblock->pixelShader;
+        struct arb_pshader_private *shader_priv = ps->backend_priv;
+        args->ps_signature = shader_priv->input_signature_idx;
+
+        args->boolclip.clip_control[0] = shader_priv->clipplane_emulation + 1;
+    }
+    else
+    {
+        args->ps_signature = ~0;
+        if(!dev->vs_clipping)
+        {
+            args->boolclip.clip_control[0] = ffp_clip_emul(stateblock) ? GL_LIMITS(texture_stages) : 0;
+        }
+        /* Otherwise: Setting boolclip_compare set clip_control[0] to 0 */
+    }
+
+    if(args->boolclip.clip_control[0])
+    {
+        if(stateblock->renderState[WINED3DRS_CLIPPING])
+        {
+            args->boolclip.clip_control[1] = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
+        }
+        /* clip_control[1] was set to 0 by setting boolclip_compare to 0 */
+    }
+
+    /* This forces all local boolean constants to 1 to make them stateblock independent */
+    args->boolclip.bools = shader->baseShader.reg_maps.local_bool_consts;
+    /* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */
+    for(i = 0; i < MAX_CONST_B; i++)
     {
     {
-        FIXME("tex_type %#x not supported\n", tex_type);
-        tex_type = tex_2d;
+        if(stateblock->vertexShaderConstantB[i]) args->boolclip.bools |= ( 1 << i);
     }
 
     }
 
-    GL_EXTCALL(glGenProgramsARB(1, &program_id));
-    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id));
-    GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(blt_fprograms[tex_type]), blt_fprograms[tex_type]));
+    args->vertex_samplers[0] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0];
+    args->vertex_samplers[1] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1];
+    args->vertex_samplers[2] = dev->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2];
+    args->vertex_samplers[3] = 0;
 
 
-    if (glGetError() == GL_INVALID_OPERATION) {
-        GLint pos;
-        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
-        FIXME("Fragment program error at position %d: %s\n", pos,
-            debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+    /* Skip if unused or local */
+    int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts;
+    if(int_skip == 0xffff || GL_SUPPORT(NV_VERTEX_PROGRAM2_OPTION)) /* This is about flow control, not clipping */
+    {
+        memset(&args->loop_ctrl, 0, sizeof(args->loop_ctrl));
+        return;
     }
 
     }
 
-    return program_id;
+    for(i = 0; i < MAX_CONST_I; i++)
+    {
+        if(int_skip & (1 << i))
+        {
+            args->loop_ctrl[i][0] = 0;
+            args->loop_ctrl[i][1] = 0;
+            args->loop_ctrl[i][2] = 0;
+        }
+        else
+        {
+            args->loop_ctrl[i][0] = stateblock->vertexShaderConstantI[i * 4];
+            args->loop_ctrl[i][1] = stateblock->vertexShaderConstantI[i * 4 + 1];
+            args->loop_ctrl[i][2] = stateblock->vertexShaderConstantI[i * 4 + 2];
+        }
+    }
 }
 
 }
 
-static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+/* GL locking is done by the caller */
+static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
+{
+    IWineD3DDeviceImpl *This = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
     struct shader_arb_priv *priv = This->shader_priv;
     struct shader_arb_priv *priv = This->shader_priv;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
-
-    if (useVS) {
-        struct vs_compile_args compile_args;
-
-        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));
-        checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);");
-
-        /* Enable OpenGL vertex programs */
-        glEnable(GL_VERTEX_PROGRAM_ARB);
-        checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
-        TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", This, priv->current_vprogram_id);
-    } else if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
-        priv->current_vprogram_id = 0;
-        glDisable(GL_VERTEX_PROGRAM_ARB);
-        checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
-    }
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    int i;
 
 
+    /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
     if (usePS) {
     if (usePS) {
-        struct ps_compile_args compile_args;
-        TRACE("Using pixel shader\n");
-        find_ps_compile_args((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader, This->stateBlock, &compile_args);
-        priv->current_fprogram_id = find_gl_pshader((IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader,
-                                                    &compile_args);
+        struct arb_ps_compile_args compile_args;
+        struct arb_ps_compiled_shader *compiled;
+        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader;
+
+        TRACE("Using pixel shader %p\n", This->stateBlock->pixelShader);
+        find_arb_ps_compile_args(ps, This->stateBlock, &compile_args);
+        compiled = find_arb_pshader(ps, &compile_args);
+        priv->current_fprogram_id = compiled->prgId;
+        priv->compiled_fprog = compiled;
 
         /* 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));
@@ -1745,22 +4214,83 @@ static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
             checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
         }
         TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", This, priv->current_fprogram_id);
             checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
         }
         TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", This, priv->current_fprogram_id);
+
+        /* Pixel Shader 1.x constants are clamped to [-1;1], Pixel Shader 2.0 constants are not. If switching between
+         * a 1.x and newer shader, reload the first 8 constants
+         */
+        if(priv->last_ps_const_clamped != ((struct arb_pshader_private *) ps->backend_priv)->clamp_consts)
+        {
+            priv->last_ps_const_clamped = ((struct arb_pshader_private *) ps->backend_priv)->clamp_consts;
+            This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, 8);
+            for(i = 0; i < 8; i++)
+            {
+                context->pshader_const_dirty[i] = 1;
+            }
+            /* Also takes care of loading local constants */
+            shader_arb_load_constants(context, TRUE, FALSE);
+        }
+        else
+        {
+            shader_arb_ps_local_constants(This);
+        }
+
+        /* Force constant reloading for the NP2 fixup (see comment in shader_glsl_select for more info) */
+        if (compiled->np2fixup_info.super.active)
+            shader_arb_load_np2fixup_constants((IWineD3DDevice *)This, usePS, useVS);
     } else if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && !priv->use_arbfp_fixed_func) {
         /* Disable only if we're not using arbfp fixed function fragment processing. If this is used,
     } else if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && !priv->use_arbfp_fixed_func) {
         /* Disable only if we're not using arbfp fixed function fragment processing. If this is used,
-         * keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function pipeline will bind the fixed function
-         * replacement shader
-         */
+        * keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function pipeline will bind the fixed function
+        * replacement shader
+        */
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
         priv->current_fprogram_id = 0;
     }
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
         priv->current_fprogram_id = 0;
     }
+
+    if (useVS) {
+        struct arb_vs_compile_args compile_args;
+        struct arb_vs_compiled_shader *compiled;
+        IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) This->stateBlock->vertexShader;
+
+        TRACE("Using vertex shader %p\n", This->stateBlock->vertexShader);
+        find_arb_vs_compile_args(vs, This->stateBlock, &compile_args);
+        compiled = find_arb_vshader(vs, &compile_args);
+        priv->current_vprogram_id = compiled->prgId;
+        priv->compiled_vprog = compiled;
+
+        /* Bind the vertex program */
+        GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
+        checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);");
+
+        /* Enable OpenGL vertex programs */
+        glEnable(GL_VERTEX_PROGRAM_ARB);
+        checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
+        TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", This, priv->current_vprogram_id);
+        shader_arb_vs_local_constants(This);
+
+        if(priv->last_vs_color_unclamp != compiled->need_color_unclamp) {
+            priv->last_vs_color_unclamp = compiled->need_color_unclamp;
+
+            if (GL_SUPPORT(ARB_COLOR_BUFFER_FLOAT)) {
+                GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, !compiled->need_color_unclamp));
+                checkGLcall("glClampColorARB");
+            } else {
+                FIXME("vertex color clamp needs to be changed, but extension not supported.\n");
+            }
+        }
+    } else if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
+        priv->current_vprogram_id = 0;
+        glDisable(GL_VERTEX_PROGRAM_ARB);
+        checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
+    }
 }
 
 }
 
+/* GL locking is done by the caller */
 static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = This->shader_priv;
     GLuint *blt_fprogram = &priv->depth_blt_fprogram_id[tex_type];
 static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     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;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
 
     if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
 
     if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
@@ -1771,18 +4301,16 @@ static void shader_arb_select_depth_blt(IWineD3DDevice *iface, enum tex_types te
     glEnable(GL_FRAGMENT_PROGRAM_ARB);
 }
 
     glEnable(GL_FRAGMENT_PROGRAM_ARB);
 }
 
+/* GL locking is done by the caller */
 static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = This->shader_priv;
 static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = This->shader_priv;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
 
     if (priv->current_vprogram_id) {
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
         checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);");
 
 
     if (priv->current_vprogram_id) {
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
         checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);");
 
-        glEnable(GL_VERTEX_PROGRAM_ARB);
-        checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
-
         TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", This, priv->current_vprogram_id);
     } else {
         glDisable(GL_VERTEX_PROGRAM_ARB);
         TRACE("(%p) : Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", This, priv->current_vprogram_id);
     } else {
         glDisable(GL_VERTEX_PROGRAM_ARB);
@@ -1793,11 +4321,8 @@ static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
         checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);");
 
         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
         checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);");
 
-        glEnable(GL_FRAGMENT_PROGRAM_ARB);
-        checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
-
         TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", This, priv->current_fprogram_id);
         TRACE("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", This, priv->current_fprogram_id);
-    } else {
+    } else if(!priv->use_arbfp_fixed_func) {
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
@@ -1805,303 +4330,116 @@ static void shader_arb_deselect_depth_blt(IWineD3DDevice *iface) {
 
 static void shader_arb_destroy(IWineD3DBaseShader *iface) {
     IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
 
 static void shader_arb_destroy(IWineD3DBaseShader *iface) {
     IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
-    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)baseShader->baseShader.device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
 
     if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version.type))
     {
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
 
     if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version.type))
     {
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
+        struct arb_pshader_private *shader_data = This->backend_priv;
         UINT i;
 
         UINT i;
 
+        if(!shader_data) return; /* This can happen if a shader was never compiled */
         ENTER_GL();
         ENTER_GL();
-        for(i = 0; i < This->num_gl_shaders; i++) {
-            GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
-            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
+
+        if(shader_data->num_gl_shaders) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+
+        for(i = 0; i < shader_data->num_gl_shaders; i++) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
+            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->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;
+        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+        HeapFree(GetProcessHeap(), 0, shader_data);
+        This->backend_priv = NULL;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
+        struct arb_vshader_private *shader_data = This->backend_priv;
         UINT i;
 
         UINT i;
 
+        if(!shader_data) return; /* This can happen if a shader was never compiled */
         ENTER_GL();
         ENTER_GL();
-        for(i = 0; i < This->num_gl_shaders; i++) {
-            GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
-            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
-        }
-        LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, This->gl_shaders);
-        This->gl_shaders = NULL;
-        This->num_gl_shaders = 0;
-        This->shader_array_size = 0;
-    }
-}
-
-static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    This->shader_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_arb_priv));
-    return WINED3D_OK;
-}
-
-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 = This->shader_priv;
-    int i;
-
-    if(priv->depth_blt_vprogram_id) {
-        GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id));
-    }
-    for (i = 0; i < tex_type_count; ++i) {
-        if (priv->depth_blt_fprogram_id[i]) {
-            GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i]));
-        }
-    }
-
-    HeapFree(GetProcessHeap(), 0, This->shader_priv);
-}
-
-static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) {
-    return TRUE;
-}
-
-static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcolor, const char *tmp1,
-                                      const char *tmp2, const char *tmp3, const char *tmp4) {
-    /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
-
-    /* Calculate the > 0.0031308 case */
-    shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor);
-    shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor);
-    shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor);
-    shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1);
-    shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1);
-    /* Calculate the < case */
-    shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
-    /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
-    shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor);
-    shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor);
-    /* Store the components > 0.0031308 in the destination */
-    shader_addline(buffer, "MUL %s, %s, %s;\n", fragcolor, tmp1, tmp3);
-    /* Add the components that are < 0.0031308 */
-    shader_addline(buffer, "MAD result.color.xyz, %s, %s, %s;\n", tmp2, tmp4, fragcolor);
-    /* [0.0;1.0] clamping. Not needed, this is done implicitly */
-}
-
-static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface,
-        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
-{
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
-    CONST DWORD *function = This->baseShader.function;
-    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
-    const local_constant *lconst;
-    GLuint retval;
-    const char *fragcolor;
-    DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
-
-    /*  Create the hw ARB shader */
-    shader_addline(buffer, "!!ARBfp1.0\n");
-
-    if (reg_maps->shader_version.major < 3)
-    {
-        switch(args->fog) {
-            case FOG_OFF:
-                break;
-            case FOG_LINEAR:
-                shader_addline(buffer, "OPTION ARB_fog_linear;\n");
-                break;
-            case FOG_EXP:
-                shader_addline(buffer, "OPTION ARB_fog_exp;\n");
-                break;
-            case FOG_EXP2:
-                shader_addline(buffer, "OPTION ARB_fog_exp2;\n");
-                break;
-        }
-    }
-
-    shader_addline(buffer, "TEMP TMP;\n");     /* Used in matrix ops */
-    shader_addline(buffer, "TEMP TMP2;\n");    /* Used in matrix ops */
-    shader_addline(buffer, "TEMP TA;\n");      /* Used for modifiers */
-    shader_addline(buffer, "TEMP TB;\n");      /* Used for modifiers */
-    shader_addline(buffer, "TEMP TC;\n");      /* Used for modifiers */
-    shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
-    shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
-    shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
-
-    if (reg_maps->shader_version.major < 2)
-    {
-        fragcolor = "R0";
-    } else {
-        shader_addline(buffer, "TEMP TMP_COLOR;\n");
-        fragcolor = "TMP_COLOR";
-    }
-
-    /* Base Declarations */
-    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
-
-    /* Base Shader Body */
-    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
-
-    if(args->srgb_correction) {
-        arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
-    }
-    shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
-    shader_addline(buffer, "END\n");
-
-    /* TODO: change to resource.glObjectHandle or something like that */
-    GL_EXTCALL(glGenProgramsARB(1, &retval));
-
-    TRACE("Creating a hw pixel shader, prg=%d\n", retval);
-    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, retval));
-
-    TRACE("Created hw pixel shader, prg=%d\n", retval);
-    /* Create the program and check for errors */
-    GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
-               buffer->bsize, buffer->buffer));
-
-    if (glGetError() == GL_INVALID_OPERATION) {
-        GLint errPos;
-        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
-        FIXME("HW PixelShader Error at position %d: %s\n",
-              errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
-        retval = 0;
-    }
-
-    /* Load immediate constants */
-    if(lconst_map) {
-        LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
-            const float *value = (const float *)lconst->value;
-            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
-            checkGLcall("glProgramLocalParameter4fvARB");
-        }
-        HeapFree(GetProcessHeap(), 0, lconst_map);
-    }
-
-    return retval;
-}
-
-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;
-    GLuint ret;
-    DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This);
-
-    /*  Create the hw ARB shader */
-    shader_addline(buffer, "!!ARBvp1.0\n");
-    shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset);
-
-    /* Mesa supports only 95 constants */
-    if (GL_VEND(MESA) || GL_VEND(WINE))
-        This->baseShader.limits.constant_float =
-                min(95, This->baseShader.limits.constant_float);
-
-    shader_addline(buffer, "TEMP TMP;\n");
-
-    /* Base Declarations */
-    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
-
-    /* We need a constant to fixup the final position */
-    shader_addline(buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS);
-
-    /* Initialize output parameters. GL_ARB_vertex_program does not require special initialization values
-     * for output parameters. D3D in theory does not do that either, but some applications depend on a
-     * proper initialization of the secondary color, and programs using the fixed function pipeline without
-     * a replacement shader depend on the texcoord.w being set properly.
-     *
-     * GL_NV_vertex_program defines that all output values are initialized to {0.0, 0.0, 0.0, 1.0}. This
-     * assertion is in effect even when using GL_ARB_vertex_program without any NV specific additions. So
-     * skip this if NV_vertex_program is supported. Otherwise, initialize the secondary color. For the tex-
-     * coords, we have a flag in the opengl caps. Many cards do not require the texcoord being set, and
-     * this can eat a number of instructions, so skip it unless this cap is set as well
-     */
-    if(!GL_SUPPORT(NV_VERTEX_PROGRAM)) {
-        shader_addline(buffer, "MOV result.color.secondary, -helper_const.wwwy;\n");
 
 
-        if((GLINFO_LOCATION).set_texcoord_w && !device->frag_pipe->ffp_proj_control) {
-            int i;
-            for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
-                if(This->baseShader.reg_maps.texcoord_mask[i] != 0 &&
-                This->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
-                    shader_addline(buffer, "MOV result.texcoord[%u].w, -helper_const.y;\n", i);
-                }
-            }
-        }
-    }
-
-    /* Base Shader Body */
-    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
-
-    /* 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");
-    } else if (!reg_maps->fog) {
-        shader_addline(buffer, "MOV result.fogcoord, helper_const.w;\n");
-    }
-
-    /* Write the final position.
-     *
-     * OpenGL coordinates specify the center of the pixel while d3d coords specify
-     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
-     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
-     * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
-     */
-    shader_addline(buffer, "MUL TMP, posFixup, TMP_OUT.w;\n");
-    shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TMP.z;\n");
-    shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TMP.w;\n");
-
-    /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
-     * and the glsl equivalent
-     */
-    shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, helper_const.x, -TMP_OUT.w;\n");
+        if(shader_data->num_gl_shaders) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
 
 
-    shader_addline(buffer, "MOV result.position, TMP_OUT;\n");
+        for(i = 0; i < shader_data->num_gl_shaders; i++) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
+            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
+        }
+        LEAVE_GL();
+        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+        HeapFree(GetProcessHeap(), 0, shader_data);
+        This->backend_priv = NULL;
+    }
+}
 
 
-    shader_addline(buffer, "END\n");
+static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry)
+{
+    struct ps_signature *e = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+    return compare_sig(key, e->sig);
+}
 
 
-    /* TODO: change to resource.glObjectHandle or something like that */
-    GL_EXTCALL(glGenProgramsARB(1, &ret));
+struct wine_rb_functions sig_tree_functions =
+{
+    wined3d_rb_alloc,
+    wined3d_rb_realloc,
+    wined3d_rb_free,
+    sig_tree_compare
+};
 
 
-    TRACE("Creating a hw vertex shader, prg=%d\n", ret);
-    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ret));
+static HRESULT shader_arb_alloc(IWineD3DDevice *iface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
+    if(wine_rb_init(&priv->signature_tree, &sig_tree_functions) == -1)
+    {
+        ERR("RB tree init failed\n");
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
+    }
+    This->shader_priv = priv;
+    return WINED3D_OK;
+}
 
 
-    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));
+static void release_signature(struct wine_rb_entry *entry, void *context)
+{
+    struct ps_signature *sig = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+    int i;
+    for(i = 0; i < MAX_REG_INPUT; i++)
+    {
+        HeapFree(GetProcessHeap(), 0, (char *) sig->sig[i].semantic_name);
+    }
+    HeapFree(GetProcessHeap(), 0, sig->sig);
+    HeapFree(GetProcessHeap(), 0, sig);
+}
 
 
-    if (glGetError() == GL_INVALID_OPERATION) {
-        GLint errPos;
-        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)));
-        ret = -1;
-    } else {
-        /* Load immediate constants */
-        if(lconst_map) {
-            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_map[lconst->idx], value));
-            }
+/* Context activation is done by the caller. */
+static void shader_arb_free(IWineD3DDevice *iface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    struct shader_arb_priv *priv = This->shader_priv;
+    int i;
+
+    ENTER_GL();
+    if(priv->depth_blt_vprogram_id) {
+        GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id));
+    }
+    for (i = 0; i < tex_type_count; ++i) {
+        if (priv->depth_blt_fprogram_id[i]) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id[i]));
         }
     }
         }
     }
-    HeapFree(GetProcessHeap(), 0, lconst_map);
+    LEAVE_GL();
 
 
-    return ret;
+    wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
+    HeapFree(GetProcessHeap(), 0, This->shader_priv);
+}
+
+static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) {
+    return TRUE;
 }
 
 }
 
-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 struct wined3d_gl_info *gl_info,
+        struct shader_caps *pCaps)
 {
     /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
      * then overwrite the shader specific ones
 {
     /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
      * then overwrite the shader specific ones
@@ -2109,17 +4447,47 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *g
     none_shader_backend.shader_get_caps(devtype, gl_info, pCaps);
 
     if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
     none_shader_backend.shader_get_caps(devtype, gl_info, pCaps);
 
     if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
-        pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
-        TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
-        pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS;
+        if(GL_SUPPORT(NV_VERTEX_PROGRAM3))
+        {
+            pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
+            TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (NV_VERTEX_PROGRAM3)\n");
+        }
+        else if(GL_LIMITS(vshader_constantsF) >= 256)
+        {
+            /* Shader Model 2.0 requires at least 256 vertex shader constants */
+            pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
+            TRACE_(d3d_caps)("Hardware vertex shader version 2.0 enabled (ARB_PROGRAM)\n");
+        }
+        else
+        {
+            pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
+            TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
+        }
+        pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
     }
 
     if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
     }
 
     if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
-        pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
-        pCaps->PixelShader1xMaxValue = 8.0;
-        TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
-        pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS;
+        if(GL_SUPPORT(NV_FRAGMENT_PROGRAM2))
+        {
+            pCaps->PixelShaderVersion    = WINED3DPS_VERSION(3,0);
+            TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (NV_FRAGMENT_PROGRAM2)\n");
+        }
+        else if(GL_LIMITS(pshader_constantsF) >= 32)
+        {
+            /* Shader Model 2.0 requires at least 32 pixel shader constants */
+            pCaps->PixelShaderVersion    = WINED3DPS_VERSION(2,0);
+            TRACE_(d3d_caps)("Hardware pixel shader version 2.0 enabled (ARB_PROGRAM)\n");
+        }
+        else
+        {
+            pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
+            TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
+        }
+        pCaps->PixelShader1xMaxValue = 8.0f;
+        pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF);
     }
     }
+
+    pCaps->VSClipping = use_nv_clip(gl_info);
 }
 
 static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
@@ -2142,10 +4510,9 @@ static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {
 }
 
 static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {
-    BOOL saturate;
     DWORD shift;
     char write_mask[20], regstr[50];
     DWORD shift;
     char write_mask[20], regstr[50];
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     BOOL is_color = FALSE;
     const struct wined3d_shader_dst_param *dst;
 
     BOOL is_color = FALSE;
     const struct wined3d_shader_dst_param *dst;
 
@@ -2154,14 +4521,15 @@ static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_ins
     dst = &ins->dst[0];
     shift = dst->shift;
     if(shift == 0) return; /* Saturate alone is handled by the instructions */
     dst = &ins->dst[0];
     shift = dst->shift;
     if(shift == 0) return; /* Saturate alone is handled by the instructions */
-    saturate = dst->modifiers & WINED3DSPDM_SATURATE;
 
     shader_arb_get_write_mask(ins, dst, write_mask);
 
     shader_arb_get_write_mask(ins, dst, write_mask);
-    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
-                                 dst->reg.idx, !!dst->reg.rel_addr, regstr, &is_color);
+    shader_arb_get_register_name(ins, &dst->reg, regstr, &is_color);
 
 
-    /* Generate a line that does the output modifier computation */
-    shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
+    /* Generate a line that does the output modifier computation
+     * FIXME: _SAT vs shift? _SAT alone is already handled in the instructions, if this
+     * maps problems in e.g. _d4_sat modify shader_arb_get_modifier
+     */
+    shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", shader_arb_get_modifier(ins),
                    regstr, write_mask, regstr, shift_tab[shift]);
 }
 
                    regstr, write_mask, regstr, shift_tab[shift]);
 }
 
@@ -2170,10 +4538,10 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_ABS           */ shader_hw_map2gl,
     /* WINED3DSIH_ADD           */ shader_hw_map2gl,
     /* WINED3DSIH_BEM           */ pshader_hw_bem,
     /* WINED3DSIH_ABS           */ shader_hw_map2gl,
     /* WINED3DSIH_ADD           */ shader_hw_map2gl,
     /* WINED3DSIH_BEM           */ pshader_hw_bem,
-    /* WINED3DSIH_BREAK         */ NULL,
-    /* WINED3DSIH_BREAKC        */ NULL,
+    /* WINED3DSIH_BREAK         */ shader_hw_break,
+    /* WINED3DSIH_BREAKC        */ shader_hw_breakc,
     /* WINED3DSIH_BREAKP        */ NULL,
     /* WINED3DSIH_BREAKP        */ NULL,
-    /* WINED3DSIH_CALL          */ NULL,
+    /* WINED3DSIH_CALL          */ shader_hw_call,
     /* WINED3DSIH_CALLNZ        */ NULL,
     /* WINED3DSIH_CMP           */ pshader_hw_cmp,
     /* WINED3DSIH_CND           */ pshader_hw_cnd,
     /* WINED3DSIH_CALLNZ        */ NULL,
     /* WINED3DSIH_CMP           */ pshader_hw_cmp,
     /* WINED3DSIH_CND           */ pshader_hw_cnd,
@@ -2186,23 +4554,23 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_DP3           */ shader_hw_map2gl,
     /* WINED3DSIH_DP4           */ shader_hw_map2gl,
     /* WINED3DSIH_DST           */ shader_hw_map2gl,
     /* WINED3DSIH_DP3           */ shader_hw_map2gl,
     /* WINED3DSIH_DP4           */ shader_hw_map2gl,
     /* WINED3DSIH_DST           */ shader_hw_map2gl,
-    /* WINED3DSIH_DSX           */ NULL,
-    /* WINED3DSIH_DSY           */ NULL,
-    /* WINED3DSIH_ELSE          */ NULL,
-    /* WINED3DSIH_ENDIF         */ NULL,
-    /* WINED3DSIH_ENDLOOP       */ NULL,
-    /* WINED3DSIH_ENDREP        */ NULL,
-    /* WINED3DSIH_EXP           */ shader_hw_map2gl,
-    /* WINED3DSIH_EXPP          */ shader_hw_map2gl,
+    /* WINED3DSIH_DSX           */ shader_hw_map2gl,
+    /* WINED3DSIH_DSY           */ shader_hw_dsy,
+    /* WINED3DSIH_ELSE          */ shader_hw_else,
+    /* WINED3DSIH_ENDIF         */ shader_hw_endif,
+    /* WINED3DSIH_ENDLOOP       */ shader_hw_endloop,
+    /* WINED3DSIH_ENDREP        */ shader_hw_endrep,
+    /* WINED3DSIH_EXP           */ shader_hw_scalar_op,
+    /* WINED3DSIH_EXPP          */ shader_hw_scalar_op,
     /* WINED3DSIH_FRC           */ shader_hw_map2gl,
     /* WINED3DSIH_FRC           */ shader_hw_map2gl,
-    /* WINED3DSIH_IF            */ NULL,
-    /* WINED3DSIH_IFC           */ NULL,
-    /* WINED3DSIH_LABEL         */ NULL,
+    /* WINED3DSIH_IF            */ NULL /* Hardcoded into the shader */,
+    /* WINED3DSIH_IFC           */ shader_hw_ifc,
+    /* WINED3DSIH_LABEL         */ shader_hw_label,
     /* WINED3DSIH_LIT           */ shader_hw_map2gl,
     /* WINED3DSIH_LIT           */ shader_hw_map2gl,
-    /* WINED3DSIH_LOG           */ shader_hw_map2gl,
-    /* WINED3DSIH_LOGP          */ shader_hw_map2gl,
-    /* WINED3DSIH_LOOP          */ NULL,
-    /* WINED3DSIH_LRP           */ shader_hw_map2gl,
+    /* WINED3DSIH_LOG           */ shader_hw_log_pow,
+    /* WINED3DSIH_LOGP          */ shader_hw_log_pow,
+    /* WINED3DSIH_LOOP          */ shader_hw_loop,
+    /* WINED3DSIH_LRP           */ shader_hw_lrp,
     /* WINED3DSIH_M3x2          */ shader_hw_mnxn,
     /* WINED3DSIH_M3x3          */ shader_hw_mnxn,
     /* WINED3DSIH_M3x4          */ shader_hw_mnxn,
     /* WINED3DSIH_M3x2          */ shader_hw_mnxn,
     /* WINED3DSIH_M3x3          */ shader_hw_mnxn,
     /* WINED3DSIH_M3x4          */ shader_hw_mnxn,
@@ -2217,14 +4585,14 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_NOP           */ shader_hw_nop,
     /* WINED3DSIH_NRM           */ shader_hw_nrm,
     /* WINED3DSIH_PHASE         */ NULL,
     /* WINED3DSIH_NOP           */ shader_hw_nop,
     /* WINED3DSIH_NRM           */ shader_hw_nrm,
     /* WINED3DSIH_PHASE         */ NULL,
-    /* WINED3DSIH_POW           */ shader_hw_map2gl,
-    /* WINED3DSIH_RCP           */ shader_hw_rsq_rcp,
-    /* WINED3DSIH_REP           */ NULL,
-    /* WINED3DSIH_RET           */ NULL,
-    /* WINED3DSIH_RSQ           */ shader_hw_rsq_rcp,
+    /* WINED3DSIH_POW           */ shader_hw_log_pow,
+    /* WINED3DSIH_RCP           */ shader_hw_scalar_op,
+    /* WINED3DSIH_REP           */ shader_hw_rep,
+    /* WINED3DSIH_RET           */ shader_hw_ret,
+    /* WINED3DSIH_RSQ           */ shader_hw_scalar_op,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
-    /* WINED3DSIH_SGN           */ NULL,
+    /* WINED3DSIH_SGN           */ shader_hw_sgn,
     /* WINED3DSIH_SINCOS        */ shader_hw_sincos,
     /* WINED3DSIH_SLT           */ shader_hw_map2gl,
     /* WINED3DSIH_SUB           */ shader_hw_map2gl,
     /* WINED3DSIH_SINCOS        */ shader_hw_sincos,
     /* WINED3DSIH_SLT           */ shader_hw_map2gl,
     /* WINED3DSIH_SUB           */ shader_hw_map2gl,
@@ -2236,8 +4604,8 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_TEXDP3        */ pshader_hw_texdp3,
     /* WINED3DSIH_TEXDP3TEX     */ pshader_hw_texdp3tex,
     /* WINED3DSIH_TEXKILL       */ pshader_hw_texkill,
     /* WINED3DSIH_TEXDP3        */ pshader_hw_texdp3,
     /* WINED3DSIH_TEXDP3TEX     */ pshader_hw_texdp3tex,
     /* WINED3DSIH_TEXKILL       */ pshader_hw_texkill,
-    /* WINED3DSIH_TEXLDD        */ NULL,
-    /* WINED3DSIH_TEXLDL        */ NULL,
+    /* WINED3DSIH_TEXLDD        */ shader_hw_texldd,
+    /* WINED3DSIH_TEXLDL        */ shader_hw_texldl,
     /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_hw_texm3x2depth,
     /* WINED3DSIH_TEXM3x2PAD    */ pshader_hw_texm3x2pad,
     /* WINED3DSIH_TEXM3x2TEX    */ pshader_hw_texm3x2tex,
     /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_hw_texm3x2depth,
     /* WINED3DSIH_TEXM3x2PAD    */ pshader_hw_texm3x2pad,
     /* WINED3DSIH_TEXM3x2TEX    */ pshader_hw_texm3x2tex,
@@ -2252,8 +4620,391 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_TEXREG2RGB    */ pshader_hw_texreg2rgb,
 };
 
     /* WINED3DSIH_TEXREG2RGB    */ pshader_hw_texreg2rgb,
 };
 
+static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins, IWineD3DBaseShaderImpl *This, DWORD idx)
+{
+    BOOL vshader = shader_is_vshader_version(This->baseShader.reg_maps.shader_version.type);
+    WORD bools = 0;
+    WORD flag = (1 << idx);
+    const local_constant *constant;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+    if(This->baseShader.reg_maps.local_bool_consts & flag)
+    {
+        /* What good is a if(bool) with a hardcoded local constant? I don't know, but handle it */
+        LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsB, local_constant, entry)
+        {
+            if (constant->idx == idx)
+            {
+                return constant->value[0];
+            }
+        }
+        ERR("Local constant not found\n");
+        return FALSE;
+    }
+    else
+    {
+        if(vshader) bools = priv->cur_vs_args->boolclip.bools;
+        else bools = priv->cur_ps_args->bools;
+        return bools & flag;
+    }
+}
+
+static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
+        IWineD3DBaseShaderImpl *This, UINT idx, struct wined3d_shader_loop_control *loop_control)
+{
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+    /* Integer constants can either be a local constant, or they can be stored in the shader
+     * type specific compile args. */
+    if (This->baseShader.reg_maps.local_int_consts & (1 << idx))
+    {
+        const local_constant *constant;
+
+        LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsI, local_constant, entry)
+        {
+            if (constant->idx == idx)
+            {
+                loop_control->count = constant->value[0];
+                loop_control->start = constant->value[1];
+                /* Step is signed. */
+                loop_control->step = (int)constant->value[2];
+                return;
+            }
+        }
+        /* If this happens the flag was set incorrectly */
+        ERR("Local constant not found\n");
+        loop_control->count = 0;
+        loop_control->start = 0;
+        loop_control->step = 0;
+        return;
+    }
+
+    switch (This->baseShader.reg_maps.shader_version.type)
+    {
+        case WINED3D_SHADER_TYPE_VERTEX:
+            /* Count and aL start value are unsigned */
+            loop_control->count = priv->cur_vs_args->loop_ctrl[idx][0];
+            loop_control->start = priv->cur_vs_args->loop_ctrl[idx][1];
+            /* Step is signed. */
+            loop_control->step = ((char)priv->cur_vs_args->loop_ctrl[idx][2]);
+            break;
+
+        case WINED3D_SHADER_TYPE_PIXEL:
+            loop_control->count = priv->cur_ps_args->loop_ctrl[idx][0];
+            loop_control->start = priv->cur_ps_args->loop_ctrl[idx][1];
+            loop_control->step = ((char)priv->cur_ps_args->loop_ctrl[idx][2]);
+            break;
+
+        default:
+            FIXME("Unhandled shader type %#x.\n", This->baseShader.reg_maps.shader_version.type);
+            break;
+    }
+}
+
+static void record_instruction(struct list *list, const struct wined3d_shader_instruction *ins)
+{
+    unsigned int i;
+    struct wined3d_shader_dst_param *dst_param = NULL;
+    struct wined3d_shader_src_param *src_param = NULL, *rel_addr = NULL;
+    struct recorded_instruction *rec = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rec));
+    if(!rec)
+    {
+        ERR("Out of memory\n");
+        return;
+    }
+
+    rec->ins = *ins;
+    dst_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param));
+    if(!dst_param) goto free;
+    *dst_param = *ins->dst;
+    if(ins->dst->reg.rel_addr)
+    {
+        rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param->reg.rel_addr));
+        if(!rel_addr) goto free;
+        *rel_addr = *ins->dst->reg.rel_addr;
+        dst_param->reg.rel_addr = rel_addr;
+    }
+    rec->ins.dst = dst_param;
+
+    src_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*src_param) * ins->src_count);
+    if(!src_param) goto free;
+    for(i = 0; i < ins->src_count; i++)
+    {
+        src_param[i] = ins->src[i];
+        if(ins->src[i].reg.rel_addr)
+        {
+            rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
+            if(!rel_addr) goto free;
+            *rel_addr = *ins->src[i].reg.rel_addr;
+            src_param[i].reg.rel_addr = rel_addr;
+        }
+    }
+    rec->ins.src = src_param;
+    list_add_tail(list, &rec->entry);
+    return;
+
+free:
+    ERR("Out of memory\n");
+    if(dst_param)
+    {
+        HeapFree(GetProcessHeap(), 0, (void *) dst_param->reg.rel_addr);
+        HeapFree(GetProcessHeap(), 0, dst_param);
+    }
+    if(src_param)
+    {
+        for(i = 0; i < ins->src_count; i++)
+        {
+            HeapFree(GetProcessHeap(), 0, (void *) src_param[i].reg.rel_addr);
+        }
+        HeapFree(GetProcessHeap(), 0, src_param);
+    }
+    HeapFree(GetProcessHeap(), 0, rec);
+}
+
+static void free_recorded_instruction(struct list *list)
+{
+    struct recorded_instruction *rec_ins, *entry2;
+    unsigned int i;
+
+    LIST_FOR_EACH_ENTRY_SAFE(rec_ins, entry2, list, struct recorded_instruction, entry)
+    {
+        list_remove(&rec_ins->entry);
+        if(rec_ins->ins.dst)
+        {
+            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.dst->reg.rel_addr);
+            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.dst);
+        }
+        if(rec_ins->ins.src)
+        {
+            for(i = 0; i < rec_ins->ins.src_count; i++)
+            {
+                HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.src[i].reg.rel_addr);
+            }
+            HeapFree(GetProcessHeap(), 0, (void *) rec_ins->ins.src);
+        }
+        HeapFree(GetProcessHeap(), 0, rec_ins);
+    }
+}
+
+static void shader_arb_handle_instruction(const struct wined3d_shader_instruction *ins) {
+    SHADER_HANDLER hw_fct;
+    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
+    struct control_frame *control_frame;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    BOOL bool_const;
+
+    if(ins->handler_idx == WINED3DSIH_LOOP || ins->handler_idx == WINED3DSIH_REP)
+    {
+        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        list_add_head(&priv->control_frames, &control_frame->entry);
+
+        if(ins->handler_idx == WINED3DSIH_LOOP) control_frame->type = LOOP;
+        if(ins->handler_idx == WINED3DSIH_REP) control_frame->type = REP;
+
+        if(priv->target_version >= NV2)
+        {
+            control_frame->loop_no = priv->num_loops++;
+            priv->loop_depth++;
+        }
+        else
+        {
+            /* Don't bother recording when we're in a not used if branch */
+            if(priv->muted)
+            {
+                return;
+            }
+
+            if(!priv->recording)
+            {
+                list_init(&priv->record);
+                priv->recording = TRUE;
+                control_frame->outer_loop = TRUE;
+                get_loop_control_const(ins, This, ins->src[0].reg.idx, &control_frame->loop_control);
+                return; /* Instruction is handled */
+            }
+            /* Record this loop in the outer loop's recording */
+        }
+    }
+    else if(ins->handler_idx == WINED3DSIH_ENDLOOP || ins->handler_idx == WINED3DSIH_ENDREP)
+    {
+        if(priv->target_version >= NV2)
+        {
+            /* Nothing to do. The control frame is popped after the HW instr handler */
+        }
+        else
+        {
+            struct list *e = list_head(&priv->control_frames);
+            control_frame = LIST_ENTRY(e, struct control_frame, entry);
+            list_remove(&control_frame->entry);
+
+            if(control_frame->outer_loop)
+            {
+                int iteration, aL = 0;
+                struct list copy;
+
+                /* Turn off recording before playback */
+                priv->recording = FALSE;
+
+                /* Move the recorded instructions to a separate list and get them out of the private data
+                 * structure. If there are nested loops, the shader_arb_handle_instruction below will
+                 * be recorded again, thus priv->record might be overwritten
+                 */
+                list_init(&copy);
+                list_move_tail(&copy, &priv->record);
+                list_init(&priv->record);
+
+                if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+                {
+                    shader_addline(buffer, "#unrolling loop: %u iterations, aL=%u, inc %d\n",
+                                   control_frame->loop_control.count, control_frame->loop_control.start,
+                                   control_frame->loop_control.step);
+                    aL = control_frame->loop_control.start;
+                }
+                else
+                {
+                    shader_addline(buffer, "#unrolling rep: %u iterations\n", control_frame->loop_control.count);
+                }
+
+                for (iteration = 0; iteration < control_frame->loop_control.count; ++iteration)
+                {
+                    struct recorded_instruction *rec_ins;
+                    if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+                    {
+                        priv->aL = aL;
+                        shader_addline(buffer, "#Iteration %d, aL=%d\n", iteration, aL);
+                    }
+                    else
+                    {
+                        shader_addline(buffer, "#Iteration %d\n", iteration);
+                    }
+
+                    LIST_FOR_EACH_ENTRY(rec_ins, &copy, struct recorded_instruction, entry)
+                    {
+                        shader_arb_handle_instruction(&rec_ins->ins);
+                    }
+
+                    if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+                    {
+                        aL += control_frame->loop_control.step;
+                    }
+                }
+                shader_addline(buffer, "#end loop/rep\n");
+
+                free_recorded_instruction(&copy);
+                HeapFree(GetProcessHeap(), 0, control_frame);
+                return; /* Instruction is handled */
+            }
+            else
+            {
+                /* This is a nested loop. Proceed to the normal recording function */
+                HeapFree(GetProcessHeap(), 0, control_frame);
+            }
+        }
+    }
+
+    if(priv->recording)
+    {
+        record_instruction(&priv->record, ins);
+        return;
+    }
+
+    /* boolean if */
+    if(ins->handler_idx == WINED3DSIH_IF)
+    {
+        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        list_add_head(&priv->control_frames, &control_frame->entry);
+        control_frame->type = IF;
+
+        bool_const = get_bool_const(ins, This, ins->src[0].reg.idx);
+        if(ins->src[0].modifiers == WINED3DSPSM_NOT) bool_const = !bool_const;
+        if(!priv->muted && bool_const == FALSE)
+        {
+            shader_addline(buffer, "#if(FALSE){\n");
+            priv->muted = TRUE;
+            control_frame->muting = TRUE;
+        }
+        else shader_addline(buffer, "#if(TRUE) {\n");
+
+        return; /* Instruction is handled */
+    }
+    else if(ins->handler_idx == WINED3DSIH_IFC)
+    {
+        /* IF(bool) and if_cond(a, b) use the same ELSE and ENDIF tokens */
+        control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+        control_frame->type = IFC;
+        control_frame->ifc_no = priv->num_ifcs++;
+        list_add_head(&priv->control_frames, &control_frame->entry);
+    }
+    else if(ins->handler_idx == WINED3DSIH_ELSE)
+    {
+        struct list *e = list_head(&priv->control_frames);
+        control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        if(control_frame->type == IF)
+        {
+            shader_addline(buffer, "#} else {\n");
+            if(!priv->muted && !control_frame->muting)
+            {
+                priv->muted = TRUE;
+                control_frame->muting = TRUE;
+            }
+            else if(control_frame->muting) priv->muted = FALSE;
+            return; /* Instruction is handled. */
+        }
+        /* In case of an ifc, generate a HW shader instruction */
+    }
+    else if(ins->handler_idx == WINED3DSIH_ENDIF)
+    {
+        struct list *e = list_head(&priv->control_frames);
+        control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+        if(control_frame->type == IF)
+        {
+            shader_addline(buffer, "#} endif\n");
+            if(control_frame->muting) priv->muted = FALSE;
+            list_remove(&control_frame->entry);
+            HeapFree(GetProcessHeap(), 0, control_frame);
+            return; /* Instruction is handled */
+        }
+    }
+
+    if(priv->muted) return;
+
+    /* Select handler */
+    hw_fct = shader_arb_instruction_handler_table[ins->handler_idx];
+
+    /* Unhandled opcode */
+    if (!hw_fct)
+    {
+        FIXME("Backend can't handle opcode %#x\n", ins->handler_idx);
+        return;
+    }
+    hw_fct(ins);
+
+    if(ins->handler_idx == WINED3DSIH_ENDLOOP || ins->handler_idx == WINED3DSIH_ENDREP)
+    {
+        struct list *e = list_head(&priv->control_frames);
+        control_frame = LIST_ENTRY(e, struct control_frame, entry);
+        list_remove(&control_frame->entry);
+        HeapFree(GetProcessHeap(), 0, control_frame);
+        priv->loop_depth--;
+    }
+    else if(ins->handler_idx == WINED3DSIH_ENDIF)
+    {
+        /* Non-ifc ENDIFs don't reach that place because of the return in the if block above */
+        struct list *e = list_head(&priv->control_frames);
+        control_frame = LIST_ENTRY(e, struct control_frame, entry);
+        list_remove(&control_frame->entry);
+        HeapFree(GetProcessHeap(), 0, control_frame);
+    }
+
+
+    shader_arb_add_instruction_modifiers(ins);
+}
+
 const shader_backend_t arb_program_shader_backend = {
 const shader_backend_t arb_program_shader_backend = {
-    shader_arb_instruction_handler_table,
+    shader_arb_handle_instruction,
     shader_arb_select,
     shader_arb_select_depth_blt,
     shader_arb_deselect_depth_blt,
     shader_arb_select,
     shader_arb_select_depth_blt,
     shader_arb_deselect_depth_blt,
@@ -2265,11 +5016,8 @@ const shader_backend_t arb_program_shader_backend = {
     shader_arb_alloc,
     shader_arb_free,
     shader_arb_dirty_const,
     shader_arb_alloc,
     shader_arb_free,
     shader_arb_dirty_const,
-    shader_arb_generate_pshader,
-    shader_arb_generate_vshader,
     shader_arb_get_caps,
     shader_arb_color_fixup_supported,
     shader_arb_get_caps,
     shader_arb_color_fixup_supported,
-    shader_arb_add_instruction_modifiers,
 };
 
 /* ARB_fragment_program fixed function pipeline replacement definitions */
 };
 
 /* ARB_fragment_program fixed function pipeline replacement definitions */
@@ -2286,7 +5034,9 @@ struct arbfp_ffp_desc
     unsigned int num_textures_used;
 };
 
     unsigned int num_textures_used;
 };
 
+/* Context activation is done by the caller. */
 static void arbfp_enable(IWineD3DDevice *iface, BOOL enable) {
 static void arbfp_enable(IWineD3DDevice *iface, BOOL enable) {
+    ENTER_GL();
     if(enable) {
         glEnable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
     if(enable) {
         glEnable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
@@ -2294,6 +5044,7 @@ static void arbfp_enable(IWineD3DDevice *iface, BOOL enable) {
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
+    LEAVE_GL();
 }
 
 static HRESULT arbfp_alloc(IWineD3DDevice *iface) {
 }
 
 static HRESULT arbfp_alloc(IWineD3DDevice *iface) {
@@ -2310,14 +5061,21 @@ static HRESULT arbfp_alloc(IWineD3DDevice *iface) {
         if(!This->fragment_priv) return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
         if(!This->fragment_priv) return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
-    priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
+    if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1)
+    {
+        ERR("Failed to initialize rbtree.\n");
+        HeapFree(GetProcessHeap(), 0, This->fragment_priv);
+        return E_OUTOFMEMORY;
+    }
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
 }
 
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
 }
 
-static void arbfp_free_ffpshader(void *value, void *gli) {
-    const WineD3D_GL_Info *gl_info = gli;
-    struct arbfp_ffp_desc *entry_arb = value;
+/* Context activation is done by the caller. */
+static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *context)
+{
+    const struct wined3d_gl_info *gl_info = context;
+    struct arbfp_ffp_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_ffp_desc, parent.entry);
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
@@ -2326,11 +5084,12 @@ static void arbfp_free_ffpshader(void *value, void *gli) {
     LEAVE_GL();
 }
 
     LEAVE_GL();
 }
 
+/* Context activation is done by the caller. */
 static void arbfp_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     struct shader_arb_priv *priv = This->fragment_priv;
 
 static void arbfp_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     struct shader_arb_priv *priv = This->fragment_priv;
 
-    hash_table_destroy(priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
+    wine_rb_destroy(&priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
     priv->use_arbfp_fixed_func = FALSE;
 
     if(This->shader_backend != &arb_program_shader_backend) {
     priv->use_arbfp_fixed_func = FALSE;
 
     if(This->shader_backend != &arb_program_shader_backend) {
@@ -2338,7 +5097,7 @@ static void arbfp_free(IWineD3DDevice *iface) {
     }
 }
 
     }
 }
 
-static void arbfp_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
+static void arbfp_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
@@ -2376,7 +5135,8 @@ static void arbfp_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_inf
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
-static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
@@ -2387,7 +5147,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
         if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
         if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
-        device->activeContext->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
+        context->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
     }
 
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
     }
 
@@ -2397,7 +5157,8 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
 
 }
 
 
 }
 
-static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
@@ -2408,31 +5169,33 @@ static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateb
         if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
         if (use_ps(stateblock)) return;
 
         device = stateblock->wineD3DDevice;
-        device->activeContext->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
+        context->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
     }
 
     if(stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
         /* The specular color has no alpha */
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
     }
 
     if(stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
         /* The specular color has no alpha */
-        col[0] = 1.0; col[1] = 1.0;
-        col[2] = 1.0; col[3] = 0.0;
+        col[0] = 1.0f; col[1] = 1.0f;
+        col[2] = 1.0f; col[3] = 0.0f;
     } else {
     } else {
-        col[0] = 0.0; col[1] = 0.0;
-        col[2] = 0.0; col[3] = 0.0;
+        col[0] = 0.0f; col[1] = 0.0f;
+        col[2] = 0.0f; col[3] = 0.0f;
     }
     GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col));
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col)");
 }
 
     }
     GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col));
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col)");
 }
 
-static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float mat[2][2];
 
     if (use_ps(stateblock))
     {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float mat[2][2];
 
     if (use_ps(stateblock))
     {
-        if(stage != 0 &&
-           ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
+        if (stage != 0
+                && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.bumpmat & (1 << stage)))
+        {
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
              * anyway
              */
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
              * anyway
              */
@@ -2446,7 +5209,7 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, W
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
-        device->activeContext->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
+        context->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
     }
 
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
     }
 
@@ -2459,15 +5222,17 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_BUMPMAT(stage), &mat[0][0])");
 }
 
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_BUMPMAT(stage), &mat[0][0])");
 }
 
-static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float param[4];
 
     if (use_ps(stateblock))
     {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     float param[4];
 
     if (use_ps(stateblock))
     {
-        if(stage != 0 &&
-           ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
+        if (stage != 0
+                && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.luminanceparams & (1 << stage)))
+        {
             /* The pixel shader has to know the luminance offset. Do a constants update if it
              * isn't scheduled anyway
              */
             /* The pixel shader has to know the luminance offset. Do a constants update if it
              * isn't scheduled anyway
              */
@@ -2481,20 +5246,21 @@ static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
-        device->activeContext->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
+        context->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
     }
 
     param[0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE]);
     param[1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET]);
         device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
     }
 
     param[0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE]);
     param[1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET]);
-    param[2] = 0.0;
-    param[3] = 0.0;
+    param[2] = 0.0f;
+    param[3] = 0.0f;
 
     GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param));
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param)");
 }
 
 
     GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param));
     checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param)");
 }
 
-static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int stage, DWORD arg) {
+static const char *get_argreg(struct wined3d_shader_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg)
+{
     const char *ret;
 
     if(arg == ARG_UNUSED) return "unused"; /* This is the marker for unused registers */
     const char *ret;
 
     if(arg == ARG_UNUSED) return "unused"; /* This is the marker for unused registers */
@@ -2565,8 +5331,9 @@ static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int
     return ret;
 }
 
     return ret;
 }
 
-static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color, BOOL alpha,
-                          DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) {
+static void gen_ffp_instr(struct wined3d_shader_buffer *buffer, unsigned int stage, BOOL color,
+        BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+{
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
     unsigned int mul = 1;
     BOOL mul_final_dest = FALSE;
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
     unsigned int mul = 1;
     BOOL mul_final_dest = FALSE;
@@ -2707,7 +5474,7 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
 static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock)
 {
     unsigned int stage;
 static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWineD3DStateBlockImpl *stateblock)
 {
     unsigned int stage;
-    SHADER_BUFFER buffer;
+    struct wined3d_shader_buffer buffer;
     BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
     BOOL bump_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
     BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
     BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
     BOOL bump_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
     BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
@@ -2770,7 +5537,11 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
     }
 
     /* Shader header */
     }
 
     /* Shader header */
-    shader_buffer_init(&buffer);
+    if (!shader_buffer_init(&buffer))
+    {
+        ERR("Failed to initialize shader buffer.\n");
+        return 0;
+    }
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
@@ -2809,6 +5580,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
                        srgb_sub_high, 0.0, 0.0, 0.0);
     }
 
                        srgb_sub_high, 0.0, 0.0, 0.0);
     }
 
+    if(ffp_clip_emul(stateblock) && settings->emul_clipplanes) shader_addline(&buffer, "KIL fragment.texcoord[7];\n");
+
     /* Generate texture sampling instructions) */
     for(stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3DTOP_DISABLE; stage++) {
         if(!tex_read[stage]) continue;
     /* Generate texture sampling instructions) */
     for(stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3DTOP_DISABLE; stage++) {
         if(!tex_read[stage]) continue;
@@ -2935,8 +5708,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
 
     if(settings->sRGB_write) {
         shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
 
     if(settings->sRGB_write) {
         shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
-        arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
-        shader_addline(&buffer, "MOV result.color.w, ret.w;\n");
+        arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg", FALSE);
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
@@ -2959,7 +5731,8 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
     return ret;
 }
 
     return ret;
 }
 
-static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     struct shader_arb_priv *priv = device->fragment_priv;
     BOOL use_pshader = use_ps(stateblock);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     struct shader_arb_priv *priv = device->fragment_priv;
     BOOL use_pshader = use_ps(stateblock);
@@ -2979,7 +5752,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
             state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context);
             state_arb_specularenable(STATE_RENDER(WINED3DRS_SPECULARENABLE), stateblock, context);
         } else if(use_pshader && !isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
             state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context);
             state_arb_specularenable(STATE_RENDER(WINED3DRS_SPECULARENABLE), stateblock, context);
         } else if(use_pshader && !isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
-            device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
+            device->shader_backend->shader_select(context, use_pshader, use_vshader);
         }
         return;
     }
         }
         return;
     }
@@ -2987,7 +5760,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
     if(!use_pshader) {
         /* Find or create a shader implementing the fixed function pipeline settings, then activate it */
         gen_ffp_frag_op(stateblock, &settings, FALSE);
     if(!use_pshader) {
         /* Find or create a shader implementing the fixed function pipeline settings, then activate it */
         gen_ffp_frag_op(stateblock, &settings, FALSE);
-        desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(priv->fragment_shaders, &settings);
+        desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
         if(!desc) {
             struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
             if (!new_desc)
         if(!desc) {
             struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
             if (!new_desc)
@@ -3003,7 +5776,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
 
             memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
             new_desc->shader = gen_arbfp_ffp_shader(&settings, stateblock);
 
             memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
             new_desc->shader = gen_arbfp_ffp_shader(&settings, stateblock);
-            add_ffp_frag_shader(priv->fragment_shaders, &new_desc->parent);
+            add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent);
             TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
             desc = new_desc;
         }
             TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
             desc = new_desc;
         }
@@ -3039,7 +5812,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
      * shader handler
      */
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
      * shader handler
      */
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
-        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
+        device->shader_backend->shader_select(context, use_pshader, use_vshader);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
@@ -3056,7 +5829,8 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
  * is that changing the fog start and fog end(which links to FOGENABLE in vertex) results in the
  * fragment_prog_arbfp function being called because FOGENABLE is dirty, which calls this function here
  */
  * is that changing the fog start and fog end(which links to FOGENABLE in vertex) results in the
  * fragment_prog_arbfp function being called because FOGENABLE is dirty, which calls this function here
  */
-static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     enum fogsource new_source;
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
     enum fogsource new_source;
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
@@ -3086,7 +5860,8 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
@@ -3095,154 +5870,154 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
-    {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_arbfp   }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, 0                               },
-    {STATE_SAMPLER(0),                                    { STATE_SAMPLER(0),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(1),                                    { STATE_SAMPLER(1),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(2),                                    { STATE_SAMPLER(2),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(3),                                    { STATE_SAMPLER(3),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(4),                                    { STATE_SAMPLER(4),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(5),                                    { STATE_SAMPLER(5),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(6),                                    { STATE_SAMPLER(6),                                   sampler_texdim          }, 0                               },
-    {STATE_SAMPLER(7),                                    { STATE_SAMPLER(7),                                   sampler_texdim          }, 0                               },
-    {STATE_PIXELSHADER,                                   { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGSTART),                    { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGEND),                      { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
-    {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),             { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor          }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity        }, 0                               },
-    {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_RENDER(WINED3DRS_SPECULARENABLE),              { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_arb_specularenable}, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                       }, 0                               },
+    {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_arbfp   }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),           { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),         { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat_arbfp       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlum_arbfp    }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(0),                                    { STATE_SAMPLER(0),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(1),                                    { STATE_SAMPLER(1),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(2),                                    { STATE_SAMPLER(2),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(3),                                    { STATE_SAMPLER(3),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(4),                                    { STATE_SAMPLER(4),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(5),                                    { STATE_SAMPLER(5),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(6),                                    { STATE_SAMPLER(6),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_SAMPLER(7),                                    { STATE_SAMPLER(7),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_PIXELSHADER,                                   { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog         }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGSTART),                    { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGEND),                      { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),             { STATE_PIXELSHADER,                                  fragment_prog_arbfp     }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor          }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_SPECULARENABLE),              { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_arb_specularenable}, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                       }, WINED3D_GL_EXT_NONE             },
 };
 
 const struct fragment_pipeline arbfp_fragment_pipeline = {
 };
 
 const struct fragment_pipeline arbfp_fragment_pipeline = {
@@ -3272,6 +6047,8 @@ static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
     }
     return WINED3D_OK;
 }
     }
     return WINED3D_OK;
 }
+
+/* Context activation is done by the caller. */
 static void arbfp_blit_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
     struct arbfp_blit_priv *priv = device->blit_priv;
 static void arbfp_blit_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
     struct arbfp_blit_priv *priv = device->blit_priv;
@@ -3283,11 +6060,12 @@ static void arbfp_blit_free(IWineD3DDevice *iface) {
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader));
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader));
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader));
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader));
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader));
     GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader));
-    checkGLcall("Delete yuv programs\n");
+    checkGLcall("Delete yuv programs");
     LEAVE_GL();
 }
 
     LEAVE_GL();
 }
 
-static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup, GLenum textype, char *luminance)
+static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum yuv_fixup yuv_fixup,
+        GLenum textype, char *luminance)
 {
     char chroma;
     const char *tex, *texinstr;
 {
     char chroma;
     const char *tex, *texinstr;
@@ -3374,7 +6152,7 @@ static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup,
     return TRUE;
 }
 
     return TRUE;
 }
 
-static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance)
+static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance)
 {
     const char *tex;
 
 {
     const char *tex;
 
@@ -3425,7 +6203,7 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance
      * go from 0 to d3d_height, whereas the opengl texture height is 1.5 * d3d_height
      */
     shader_addline(buffer, "PARAM yv12_coef = {%f, %f, %f, %f};\n",
      * go from 0 to d3d_height, whereas the opengl texture height is 1.5 * d3d_height
      */
     shader_addline(buffer, "PARAM yv12_coef = {%f, %f, %f, %f};\n",
-                   2.0 / 3.0, 1.0 / 6.0, (2.0 / 3.0) + (1.0 / 6.0), 1.0 / 3.0);
+            2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f);
 
     shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
     /* the chroma planes have only half the width */
 
     shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
     /* the chroma planes have only half the width */
@@ -3520,15 +6298,20 @@ static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance
     return TRUE;
 }
 
     return TRUE;
 }
 
+/* Context activation is done by the caller. */
 static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixup, GLenum textype)
 {
     GLenum shader;
 static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixup, GLenum textype)
 {
     GLenum shader;
-    SHADER_BUFFER buffer;
+    struct wined3d_shader_buffer buffer;
     char luminance_component;
     struct arbfp_blit_priv *priv = device->blit_priv;
 
     /* Shader header */
     char luminance_component;
     struct arbfp_blit_priv *priv = device->blit_priv;
 
     /* Shader header */
-    shader_buffer_init(&buffer);
+    if (!shader_buffer_init(&buffer))
+    {
+        ERR("Failed to initialize shader buffer.\n");
+        return 0;
+    }
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
@@ -3656,6 +6439,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
     return shader;
 }
 
     return shader;
 }
 
+/* Context activation is done by the caller. */
 static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
         GLenum textype, UINT width, UINT height)
 {
 static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
         GLenum textype, UINT width, UINT height)
 {
@@ -3716,6 +6500,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+/* Context activation is done by the caller. */
 static void arbfp_blit_unset(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
 
 static void arbfp_blit_unset(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
 
index a8c137f..aea942c 100644 (file)
@@ -28,6 +28,8 @@
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
+/* GL locking for state handlers is done by the caller. */
+
 /* Some private defines, Constant associations, etc.
  * Env bump matrix and per stage constant should be independent,
  * a stage that bump maps can't read the per state constant
 /* Some private defines, Constant associations, etc.
  * Env bump matrix and per stage constant should be independent,
  * a stage that bump maps can't read the per state constant
@@ -51,8 +53,7 @@ struct atifs_ffp_desc
 
 struct atifs_private_data
 {
 
 struct atifs_private_data
 {
-    struct hash_table_t *fragment_shaders; /* A hashtable to track fragment pipeline replacement shaders */
-
+    struct wine_rb_tree fragment_shaders; /* A rb-tree to track fragment pipeline replacement shaders */
 };
 
 static const char *debug_dstmod(GLuint mod) {
 };
 
 static const char *debug_dstmod(GLuint mod) {
@@ -191,8 +192,9 @@ static const char *debug_mask(GLuint mask) {
 }
 #define GLINFO_LOCATION (*gl_info)
 
 }
 #define GLINFO_LOCATION (*gl_info)
 
-static void wrap_op1(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
-                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) {
+static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+        GLuint arg1, GLuint arg1Rep, GLuint arg1Mod)
+{
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp1ATI(%s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp1ATI(%s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
@@ -205,9 +207,9 @@ static void wrap_op1(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLui
     }
 }
 
     }
 }
 
-static void wrap_op2(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
-                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
-                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) {
+static void wrap_op2(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+        GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod)
+{
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
@@ -222,10 +224,10 @@ static void wrap_op2(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLui
     }
 }
 
     }
 }
 
-static void wrap_op3(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
-                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
-                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod,
-                     GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) {
+static void wrap_op3(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+        GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod,
+        GLuint arg3, GLuint arg3Rep, GLuint arg3Mod)
+{
     if(dstMask == GL_ALPHA) {
         /* Leave some free space to fit "GL_NONE, " in to align most alpha and color op lines */
         TRACE("glAlphaFragmentOp3ATI(%s, %s,          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
     if(dstMask == GL_ALPHA) {
         /* Leave some free space to fit "GL_NONE, " in to align most alpha and color op lines */
         TRACE("glAlphaFragmentOp3ATI(%s, %s,          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
@@ -249,7 +251,7 @@ static void wrap_op3(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLui
     }
 }
 
     }
 }
 
-static GLuint register_for_arg(DWORD arg, const WineD3D_GL_Info *gl_info,
+static GLuint register_for_arg(DWORD arg, const struct wined3d_gl_info *gl_info,
         unsigned int stage, GLuint *mod, GLuint *rep, GLuint tmparg)
 {
     GLenum ret;
         unsigned int stage, GLuint *mod, GLuint *rep, GLuint tmparg)
 {
     GLenum ret;
@@ -377,7 +379,7 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
     }
 }
 
     }
 }
 
-static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const WineD3D_GL_Info *gl_info)
+static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const struct wined3d_gl_info *gl_info)
 {
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
     unsigned int stage;
 {
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
     unsigned int stage;
@@ -422,13 +424,6 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
         GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1,
                    GL_TEXTURE0_ARB + stage + 1,
                    swizzle));
         GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1,
                    GL_TEXTURE0_ARB + stage + 1,
                    swizzle));
-
-        /* We need GL_REG_5_ATI as a temporary register to swizzle the bump matrix. So we run into
-         * issues if we're bump mapping on stage 4 or 5
-         */
-        if(stage >= 4) {
-            FIXME("Bump mapping in stage %d\n", stage);
-        }
     }
 
     /* Pass 2: Generate perturbation calculations */
     }
 
     /* Pass 2: Generate perturbation calculations */
@@ -459,22 +454,24 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
                  ATI_FFP_CONST_BUMPMAT(stage), GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
                  GL_REG_0_ATI + stage + 1, GL_RED, GL_NONE);
 
                  ATI_FFP_CONST_BUMPMAT(stage), GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
                  GL_REG_0_ATI + stage + 1, GL_RED, GL_NONE);
 
-        /* FIXME: How can I make GL_DOT2_ADD_ATI read the factors from blue and alpha? It defaults to red and green,
-         * and it is fairly easy to make it read GL_BLUE or BL_ALPHA, but I can't get an R * B + G * A. So we're wasting
-         * one register and two instructions in this pass for a simple swizzling operation.
-         * For starters it might be good enough to merge the two movs into one, but even that isn't possible :-(
+        /* Don't use GL_DOT2_ADD_ATI here because we cannot configure it to read the blue and alpha
+         * component of the bump matrix. Instead do this with two MADs:
          *
          *
-         * NOTE: GL_BLUE | GL_ALPHA is not possible. It doesn't throw a compilation error, but an OR operation on the
-         * constants doesn't make sense, considering their values.
+         * coord.a = tex.r * bump.b + coord.g
+         * coord.g = tex.g * bump.a + coord.a
+         *
+         * The first instruction writes to alpha so it can be coissued with the above DOT2_ADD.
+         * coord.a is unused. If the perturbed texture is projected, this was already handled
+         * in the glPassTexCoordATI above.
          */
          */
-        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_RED_BIT_ATI, GL_NONE,
-                 ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_NONE);
-        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE,
-                 ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE);
-        wrap_op3(gl_info, GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
-                 GL_REG_0_ATI + stage, GL_NONE, argmodextra_y,
-                 GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
+        wrap_op3(gl_info, GL_MAD_ATI, GL_REG_0_ATI + stage + 1, GL_ALPHA, GL_NONE,
+                 GL_REG_0_ATI + stage, GL_RED, argmodextra_y,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_NONE,
                  GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE);
                  GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE);
+        wrap_op3(gl_info, GL_MAD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
+                 GL_REG_0_ATI + stage, GL_GREEN, argmodextra_y,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE,
+                 GL_REG_0_ATI + stage + 1, GL_ALPHA, GL_NONE);
     }
 
     /* Pass 3: Generate sampling instructions for regular textures */
     }
 
     /* Pass 3: Generate sampling instructions for regular textures */
@@ -799,7 +796,8 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
-static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     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;
@@ -808,7 +806,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
     unsigned int i;
 
     gen_ffp_frag_op(stateblock, &settings, TRUE);
     unsigned int i;
 
     gen_ffp_frag_op(stateblock, &settings, TRUE);
-    desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(priv->fragment_shaders, &settings);
+    desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
     if(!desc) {
         struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
         if (!new_desc)
     if(!desc) {
         struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
         if (!new_desc)
@@ -824,7 +822,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
 
         memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
         new_desc->shader = gen_ati_shader(settings.op, &GLINFO_LOCATION);
 
         memcpy(&new_desc->parent.settings, &settings, sizeof(settings));
         new_desc->shader = gen_ati_shader(settings.op, &GLINFO_LOCATION);
-        add_ffp_frag_shader(priv->fragment_shaders, &new_desc->parent);
+        add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent);
         TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
         desc = new_desc;
     }
         TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
         desc = new_desc;
     }
@@ -845,7 +843,8 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
     GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
 }
 
     GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
 }
 
-static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
 
@@ -853,7 +852,8 @@ static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *statebloc
     checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col)");
 }
 
     checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col)");
 }
 
-static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     float mat[2][2];
 
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     float mat[2][2];
 
@@ -868,21 +868,23 @@ static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
      * shader(it is free). This might potentially reduce precision. However, if the hardware does
      * support proper floats it shouldn't, and if it doesn't we can't get anything better anyway
      */
      * shader(it is free). This might potentially reduce precision. However, if the hardware does
      * support proper floats it shouldn't, and if it doesn't we can't get anything better anyway
      */
-    mat[0][0] = (mat[0][0] + 1.0) * 0.5;
-    mat[1][0] = (mat[1][0] + 1.0) * 0.5;
-    mat[0][1] = (mat[0][1] + 1.0) * 0.5;
-    mat[1][1] = (mat[1][1] + 1.0) * 0.5;
+    mat[0][0] = (mat[0][0] + 1.0f) * 0.5f;
+    mat[1][0] = (mat[1][0] + 1.0f) * 0.5f;
+    mat[0][1] = (mat[0][1] + 1.0f) * 0.5f;
+    mat[1][1] = (mat[1][1] + 1.0f) * 0.5f;
     GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), (float *) mat));
     checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), mat)");
 }
 
     GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), (float *) mat));
     checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), mat)");
 }
 
-static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         set_tex_op_atifs(state, stateblock, context);
     }
 }
 
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         set_tex_op_atifs(state, stateblock, context);
     }
 }
 
-static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_vshader = use_vs(stateblock);
 
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_vshader = use_vs(stateblock);
 
@@ -899,7 +901,7 @@ static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *statebl
      * simpler.
      */
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
      * simpler.
      */
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
-        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, use_vshader);
+        device->shader_backend->shader_select(context, FALSE, use_vshader);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
@@ -910,139 +912,141 @@ static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *statebl
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
 #undef GLINFO_LOCATION
 
 static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
-    {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_atifs   }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor          }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity        }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGSTART),                    { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
-    {STATE_RENDER(WINED3DRS_FOGEND),                      { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, 0                               },
-    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim          }, 0                               },
-    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim          }, 0                               },
-    {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, 0                               },
-    {STATE_PIXELSHADER,                                   { STATE_PIXELSHADER,                                  atifs_apply_pixelshader }, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                       }, 0                               },
+    {STATE_RENDER(WINED3DRS_TEXTUREFACTOR),               { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor_atifs   }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGCOLOR),                    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor          }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGDENSITY),                  { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity        }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGENABLE),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGTABLEMODE),                { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGVERTEXMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart      }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGSTART),                    { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3DRS_FOGEND),                      { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend       }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),           { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),         { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          set_tex_op_atifs        }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),      { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     set_bumpmat             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim          }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform      }, WINED3D_GL_EXT_NONE             },
+    {STATE_PIXELSHADER,                                   { STATE_PIXELSHADER,                                  atifs_apply_pixelshader }, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                       }, WINED3D_GL_EXT_NONE             },
 };
 
 };
 
+/* Context activation is done by the caller. */
 static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
 static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
+    ENTER_GL();
     if(enable) {
         glEnable(GL_FRAGMENT_SHADER_ATI);
         checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
     if(enable) {
         glEnable(GL_FRAGMENT_SHADER_ATI);
         checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
@@ -1050,9 +1054,10 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
         glDisable(GL_FRAGMENT_SHADER_ATI);
         checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)");
     }
         glDisable(GL_FRAGMENT_SHADER_ATI);
         checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)");
     }
+    LEAVE_GL();
 }
 
 }
 
-static void atifs_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
+static void atifs_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
@@ -1110,14 +1115,21 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) {
         return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
         return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
-    priv->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
+    if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1)
+    {
+        ERR("Failed to initialize rbtree.\n");
+        HeapFree(GetProcessHeap(), 0, This->fragment_priv);
+        return E_OUTOFMEMORY;
+    }
     return WINED3D_OK;
 }
 
 #define GLINFO_LOCATION This->adapter->gl_info
     return WINED3D_OK;
 }
 
 #define GLINFO_LOCATION This->adapter->gl_info
-static void atifs_free_ffpshader(void *value, void *device) {
-    IWineD3DDeviceImpl *This = device;
-    struct atifs_ffp_desc *entry_ati = value;
+/* Context activation is done by the caller. */
+static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context)
+{
+    IWineD3DDeviceImpl *This = context;
+    struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry);
 
     ENTER_GL();
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
 
     ENTER_GL();
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
@@ -1126,11 +1138,12 @@ static void atifs_free_ffpshader(void *value, void *device) {
     LEAVE_GL();
 }
 
     LEAVE_GL();
 }
 
+/* Context activation is done by the caller. */
 static void atifs_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     struct atifs_private_data *priv = This->fragment_priv;
 
 static void atifs_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     struct atifs_private_data *priv = This->fragment_priv;
 
-    hash_table_destroy(priv->fragment_shaders, atifs_free_ffpshader, This);
+    wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, This);
 
     HeapFree(GetProcessHeap(), 0, priv);
     This->fragment_priv = NULL;
 
     HeapFree(GetProcessHeap(), 0, priv);
     This->fragment_priv = NULL;
index 8b8aef4..c983e80 100644 (file)
@@ -138,35 +138,41 @@ const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token
     }
 }
 
     }
 }
 
-static inline BOOL shader_is_version_token(DWORD token) {
-    return shader_is_pshader_version(token) ||
-           shader_is_vshader_version(token);
-}
-
-void shader_buffer_init(struct SHADER_BUFFER *buffer)
+void shader_buffer_clear(struct wined3d_shader_buffer *buffer)
 {
 {
-    buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
     buffer->buffer[0] = '\0';
     buffer->bsize = 0;
     buffer->lineNo = 0;
     buffer->newline = TRUE;
 }
 
     buffer->buffer[0] = '\0';
     buffer->bsize = 0;
     buffer->lineNo = 0;
     buffer->newline = TRUE;
 }
 
-void shader_buffer_free(struct SHADER_BUFFER *buffer)
+BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer)
+{
+    buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
+    if (!buffer->buffer)
+    {
+        ERR("Failed to allocate shader buffer memory.\n");
+        return FALSE;
+    }
+
+    shader_buffer_clear(buffer);
+    return TRUE;
+}
+
+void shader_buffer_free(struct wined3d_shader_buffer *buffer)
 {
     HeapFree(GetProcessHeap(), 0, buffer->buffer);
 }
 
 {
     HeapFree(GetProcessHeap(), 0, buffer->buffer);
 }
 
-int shader_vaddline(SHADER_BUFFER* buffer, const char *format, va_list args)
+int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va_list args)
 {
     char* base = buffer->buffer + buffer->bsize;
     int rc;
 
     rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
 
 {
     char* base = buffer->buffer + buffer->bsize;
     int rc;
 
     rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
 
-    if (rc < 0 ||                                   /* C89 */ 
-        rc > SHADER_PGMSIZE - 1 - buffer->bsize) {  /* C99 */
-
+    if (rc < 0 /* C89 */ || (unsigned int)rc > SHADER_PGMSIZE - 1 - buffer->bsize /* C99 */)
+    {
         ERR("The buffer allocated for the shader program string "
             "is too small at %d bytes.\n", SHADER_PGMSIZE);
         buffer->bsize = SHADER_PGMSIZE - 1;
         ERR("The buffer allocated for the shader program string "
             "is too small at %d bytes.\n", SHADER_PGMSIZE);
         buffer->bsize = SHADER_PGMSIZE - 1;
@@ -188,7 +194,7 @@ int shader_vaddline(SHADER_BUFFER* buffer, const char *format, va_list args)
     return 0;
 }
 
     return 0;
 }
 
-int shader_addline(SHADER_BUFFER* buffer, const char *format, ...)
+int shader_addline(struct wined3d_shader_buffer *buffer, const char *format, ...)
 {
     int ret;
     va_list args;
 {
     int ret;
     va_list args;
@@ -246,24 +252,23 @@ static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
 }
 
 static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
 }
 
 static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
-        DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
+        const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
 {
 {
-    switch (register_type)
+    switch (reg->type)
     {
         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
     {
         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
-            if (pshader) reg_maps->texcoord[register_idx] = 1;
-            else reg_maps->address[register_idx] = 1;
+            if (shader_type == WINED3D_SHADER_TYPE_PIXEL) reg_maps->texcoord |= 1 << reg->idx;
+            else reg_maps->address |= 1 << reg->idx;
             break;
 
         case WINED3DSPR_TEMP:
             break;
 
         case WINED3DSPR_TEMP:
-            reg_maps->temporary[register_idx] = 1;
+            reg_maps->temporary |= 1 << reg->idx;
             break;
 
         case WINED3DSPR_INPUT:
             break;
 
         case WINED3DSPR_INPUT:
-            if (!pshader) reg_maps->attributes[register_idx] = 1;
-            else
+            if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
             {
             {
-                if (has_rel_addr)
+                if (reg->rel_addr)
                 {
                     /* If relative addressing is used, we must assume that all registers
                      * are used. Even if it is a construct like v3[aL], we can't assume
                 {
                     /* If relative addressing is used, we must assume that all registers
                      * are used. Even if it is a construct like v3[aL], we can't assume
@@ -276,84 +281,142 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
                 }
                 else
                 {
                 }
                 else
                 {
-                    ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE;
+                    ((IWineD3DPixelShaderImpl *)This)->input_reg_used[reg->idx] = TRUE;
                 }
             }
                 }
             }
+            else reg_maps->input_registers |= 1 << reg->idx;
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
-            if (register_idx == 1) reg_maps->fog = 1;
+            if (reg->idx == 1) reg_maps->fog = 1;
             break;
 
         case WINED3DSPR_MISCTYPE:
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (pshader && register_idx == 0) reg_maps->vpos = 1;
+            if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+            {
+                if (reg->idx == 0) reg_maps->vpos = 1;
+                else if (reg->idx == 1) reg_maps->usesfacing = 1;
+            }
             break;
 
         case WINED3DSPR_CONST:
             break;
 
         case WINED3DSPR_CONST:
-            if (has_rel_addr)
+            if (reg->rel_addr)
             {
             {
-                if (!pshader)
+                if (shader_type != WINED3D_SHADER_TYPE_PIXEL)
                 {
                 {
-                    if (register_idx <= ((IWineD3DVertexShaderImpl *)This)->min_rel_offset)
-                        ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = register_idx;
-                    else if (register_idx >= ((IWineD3DVertexShaderImpl *)This)->max_rel_offset)
-                        ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = register_idx;
+                    if (reg->idx < ((IWineD3DVertexShaderImpl *)This)->min_rel_offset)
+                    {
+                        ((IWineD3DVertexShaderImpl *)This)->min_rel_offset = reg->idx;
+                    }
+                    if (reg->idx > ((IWineD3DVertexShaderImpl *)This)->max_rel_offset)
+                    {
+                        ((IWineD3DVertexShaderImpl *)This)->max_rel_offset = reg->idx;
+                    }
                 }
                 reg_maps->usesrelconstF = TRUE;
             }
             else
             {
                 }
                 reg_maps->usesrelconstF = TRUE;
             }
             else
             {
-                set_bitmap_bit(reg_maps->constf, register_idx);
+                set_bitmap_bit(reg_maps->constf, reg->idx);
             }
             break;
 
         case WINED3DSPR_CONSTINT:
             }
             break;
 
         case WINED3DSPR_CONSTINT:
-            reg_maps->integer_constants |= (1 << register_idx);
+            reg_maps->integer_constants |= (1 << reg->idx);
             break;
 
         case WINED3DSPR_CONSTBOOL:
             break;
 
         case WINED3DSPR_CONSTBOOL:
-            reg_maps->boolean_constants |= (1 << register_idx);
+            reg_maps->boolean_constants |= (1 << reg->idx);
+            break;
+
+        case WINED3DSPR_COLOROUT:
+            reg_maps->highest_render_target = max(reg_maps->highest_render_target, reg->idx);
             break;
 
         default:
             break;
 
         default:
-            TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx);
+            TRACE("Not recording register of type %#x and idx %u\n", reg->type, reg->idx);
             break;
     }
 }
 
             break;
     }
 }
 
-static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
+static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
 {
     switch(instr)
     {
         case WINED3DSIH_M4x4:
         case WINED3DSIH_M3x4:
 {
     switch(instr)
     {
         case WINED3DSIH_M4x4:
         case WINED3DSIH_M3x4:
-            return param == 1 ? 4 : 1;
+            return param == 1 ? 3 : 0;
 
         case WINED3DSIH_M4x3:
         case WINED3DSIH_M3x3:
 
         case WINED3DSIH_M4x3:
         case WINED3DSIH_M3x3:
-            return param == 1 ? 3 : 1;
+            return param == 1 ? 2 : 0;
 
         case WINED3DSIH_M3x2:
 
         case WINED3DSIH_M3x2:
-            return param == 1 ? 2 : 1;
+            return param == 1 ? 1 : 0;
 
         default:
 
         default:
-            return 1;
+            return 0;
     }
 }
 
     }
 }
 
+static const char *shader_semantic_name_from_usage(WINED3DDECLUSAGE usage)
+{
+    static const char *semantic_names[] =
+    {
+        /* WINED3DDECLUSAGE_POSITION        */ "SV_POSITION",
+        /* WINED3DDECLUSAGE_BLENDWEIGHT     */ "BLENDWEIGHT",
+        /* WINED3DDECLUSAGE_BLENDINDICES    */ "BLENDINDICES",
+        /* WINED3DDECLUSAGE_NORMAL          */ "NORMAL",
+        /* WINED3DDECLUSAGE_PSIZE           */ "PSIZE",
+        /* WINED3DDECLUSAGE_TEXCOORD        */ "TEXCOORD",
+        /* WINED3DDECLUSAGE_TANGENT         */ "TANGENT",
+        /* WINED3DDECLUSAGE_BINORMAL        */ "BINORMAL",
+        /* WINED3DDECLUSAGE_TESSFACTOR      */ "TESSFACTOR",
+        /* WINED3DDECLUSAGE_POSITIONT       */ "POSITIONT",
+        /* WINED3DDECLUSAGE_COLOR           */ "COLOR",
+        /* WINED3DDECLUSAGE_FOG             */ "FOG",
+        /* WINED3DDECLUSAGE_DEPTH           */ "DEPTH",
+        /* WINED3DDECLUSAGE_SAMPLE          */ "SAMPLE",
+    };
+
+    if (usage >= sizeof(semantic_names) / sizeof(*semantic_names))
+    {
+        FIXME("Unrecognized usage %#x\n", usage);
+        return "UNRECOGNIZED";
+    }
+
+    return semantic_names[usage];
+}
+
+BOOL shader_match_semantic(const char *semantic_name, WINED3DDECLUSAGE usage)
+{
+    return !strcmp(semantic_name, shader_semantic_name_from_usage(usage));
+}
+
+static void shader_signature_from_semantic(struct wined3d_shader_signature_element *e,
+        const struct wined3d_shader_semantic *s)
+{
+    e->semantic_name = shader_semantic_name_from_usage(s->usage);
+    e->semantic_idx = s->usage_idx;
+    e->sysval_semantic = 0;
+    e->component_type = 0;
+    e->register_idx = s->reg.reg.idx;
+    e->mask = s->reg.write_mask;
+}
+
 /* Note that this does not count the loop register
  * as an address register. */
 
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
 /* Note that this does not count the loop register
  * as an address register. */
 
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
-        struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
-        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size)
+        struct shader_reg_maps *reg_maps, struct wined3d_shader_attribute *attributes,
+        struct wined3d_shader_signature_element *input_signature,
+        struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     void *fe_data = This->baseShader.frontend_data;
     struct wined3d_shader_version shader_version;
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
     const DWORD* pToken = byte_code;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     void *fe_data = This->baseShader.frontend_data;
     struct wined3d_shader_version shader_version;
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
     const DWORD* pToken = byte_code;
-    char pshader;
 
     /* There are some minor differences between pixel and vertex shaders */
 
 
     /* There are some minor differences between pixel and vertex shaders */
 
@@ -368,7 +431,6 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
 
     fe->shader_read_header(fe_data, &pToken, &shader_version);
     reg_maps->shader_version = shader_version;
 
     fe->shader_read_header(fe_data, &pToken, &shader_version);
     reg_maps->shader_version = shader_version;
-    pshader = shader_is_pshader_version(shader_version.type);
 
     reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                  sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
 
     reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                  sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
@@ -410,15 +472,22 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
                 /* Vshader: mark attributes used
                  * Pshader: mark 3.0 input registers used, save token */
                 case WINED3DSPR_INPUT:
                 /* Vshader: mark attributes used
                  * Pshader: mark 3.0 input registers used, save token */
                 case WINED3DSPR_INPUT:
-                    if (!pshader) reg_maps->attributes[semantic.reg.reg.idx] = 1;
-                    else reg_maps->packed_input[semantic.reg.reg.idx] = 1;
-                    semantics_in[semantic.reg.reg.idx] = semantic;
+                    reg_maps->input_registers |= 1 << semantic.reg.reg.idx;
+                    if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX)
+                    {
+                        attributes[semantic.reg.reg.idx].usage = semantic.usage;
+                        attributes[semantic.reg.reg.idx].usage_idx = semantic.usage_idx;
+                    }
+                    else
+                    {
+                        shader_signature_from_semantic(&input_signature[semantic.reg.reg.idx], &semantic);
+                    }
                     break;
 
                 /* Vshader: mark 3.0 output registers used, save token */
                 case WINED3DSPR_OUTPUT:
                     break;
 
                 /* Vshader: mark 3.0 output registers used, save token */
                 case WINED3DSPR_OUTPUT:
-                    reg_maps->packed_output[semantic.reg.reg.idx] = 1;
-                    semantics_out[semantic.reg.reg.idx] = semantic;
+                    reg_maps->output_registers |= 1 << semantic.reg.reg.idx;
+                    shader_signature_from_semantic(&output_signature[semantic.reg.reg.idx], &semantic);
                     if (semantic.usage == WINED3DDECLUSAGE_FOG) reg_maps->fog = 1;
                     break;
 
                     if (semantic.usage == WINED3DDECLUSAGE_FOG) reg_maps->fog = 1;
                     break;
 
@@ -447,17 +516,17 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             pToken += 4;
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
             pToken += 4;
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
-            if (shader_version.major == 1 && pshader)
+            if (shader_version.major == 1 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
             {
                 float *value = (float *) lconst->value;
             {
                 float *value = (float *) lconst->value;
-                if(value[0] < -1.0) value[0] = -1.0;
-                else if(value[0] >  1.0) value[0] =  1.0;
-                if(value[1] < -1.0) value[1] = -1.0;
-                else if(value[1] >  1.0) value[1] =  1.0;
-                if(value[2] < -1.0) value[2] = -1.0;
-                else if(value[2] >  1.0) value[2] =  1.0;
-                if(value[3] < -1.0) value[3] = -1.0;
-                else if(value[3] >  1.0) value[3] =  1.0;
+                if (value[0] < -1.0f) value[0] = -1.0f;
+                else if (value[0] > 1.0f) value[0] = 1.0f;
+                if (value[1] < -1.0f) value[1] = -1.0f;
+                else if (value[1] > 1.0f) value[1] = 1.0f;
+                if (value[2] < -1.0f) value[2] = -1.0f;
+                else if (value[2] > 1.0f) value[2] = 1.0f;
+                if (value[3] < -1.0f) value[3] = -1.0f;
+                else if (value[3] > 1.0f) value[3] = 1.0f;
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
@@ -477,6 +546,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             pToken += 4;
 
             list_add_head(&This->baseShader.constantsI, &lconst->entry);
             pToken += 4;
 
             list_add_head(&This->baseShader.constantsI, &lconst->entry);
+            reg_maps->local_int_consts |= (1 << dst.reg.idx);
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
@@ -493,6 +563,7 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             ++pToken;
 
             list_add_head(&This->baseShader.constantsB, &lconst->entry);
             ++pToken;
 
             list_add_head(&This->baseShader.constantsB, &lconst->entry);
+            reg_maps->local_bool_consts |= (1 << dst.reg.idx);
         }
         /* If there's a loop in the shader */
         else if (ins.handler_idx == WINED3DSIH_LOOP
         }
         /* If there's a loop in the shader */
         else if (ins.handler_idx == WINED3DSIH_LOOP
@@ -528,12 +599,13 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             struct wined3d_shader_src_param src, rel_addr;
 
             fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
             struct wined3d_shader_src_param src, rel_addr;
 
             fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
-            reg_maps->labels[src.reg.idx] = 1;
+            reg_maps->labels |= 1 << src.reg.idx;
         }
         /* Set texture, address, temporary registers */
         else
         {
             int i, limit;
         }
         /* Set texture, address, temporary registers */
         else
         {
             int i, limit;
+            BOOL color0_mov = FALSE;
 
             /* This will loop over all the registers and try to
              * make a bitmask of the ones we're interested in.
 
             /* This will loop over all the registers and try to
              * make a bitmask of the ones we're interested in.
@@ -549,22 +621,49 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
 
                 fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
 
                 fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
+                shader_record_register_usage(This, reg_maps, &dst_param.reg, shader_version.type);
+
                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
                  * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
                  * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
                  * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
                  * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
-                if (!pshader && shader_version.major < 3 && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
+                if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3
+                        && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
                 {
                 {
-                    reg_maps->texcoord_mask[dst_param.reg.type] |= dst_param.write_mask;
+                    reg_maps->texcoord_mask[dst_param.reg.idx] |= dst_param.write_mask;
                 }
                 }
-                else
+
+                if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
                 {
                 {
-                    shader_record_register_usage(This, reg_maps, dst_param.reg.type,
-                            dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader);
+                    IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)This;
+
+                    if(dst_param.reg.type == WINED3DSPR_COLOROUT && dst_param.reg.idx == 0)
+                    {
+                    /* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
+                     * COLOROUT 0. If we know this in advance, the ARB shader backend can skip
+                     * the mov and perform the sRGB write correction from the source register.
+                     *
+                     * However, if the mov is only partial, we can't do this, and if the write
+                     * comes from an instruction other than MOV it is hard to do as well. If
+                     * COLOROUT 0 is overwritten partially later, the marker is dropped again. */
+
+                        ps->color0_mov = FALSE;
+                        if (ins.handler_idx == WINED3DSIH_MOV)
+                        {
+                            /* Used later when the source register is read. */
+                            color0_mov = TRUE;
+                        }
+                    }
+                    /* Also drop the MOV marker if the source register is overwritten prior to the shader
+                     * end
+                     */
+                    else if(dst_param.reg.type == WINED3DSPR_TEMP && dst_param.reg.idx == ps->color0_reg)
+                    {
+                        ps->color0_mov = FALSE;
+                    }
                 }
 
                 /* Declare 1.X samplers implicitly, based on the destination reg. number */
                 if (shader_version.major == 1
                 }
 
                 /* Declare 1.X samplers implicitly, based on the destination reg. number */
                 if (shader_version.major == 1
-                        && pshader /* Filter different instructions with the same enum values in VS */
                         && (ins.handler_idx == WINED3DSIH_TEX
                             || ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML
                         && (ins.handler_idx == WINED3DSIH_TEX
                             || ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML
@@ -587,16 +686,16 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
                     if (ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML)
                     {
                     if (ins.handler_idx == WINED3DSIH_TEXBEM
                             || ins.handler_idx == WINED3DSIH_TEXBEML)
                     {
-                        reg_maps->bumpmat[sampler_code] = TRUE;
+                        reg_maps->bumpmat |= 1 << dst_param.reg.idx;
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
-                            reg_maps->luminanceparams[sampler_code] = TRUE;
+                            reg_maps->luminanceparams |= 1 << dst_param.reg.idx;
                         }
                     }
                 }
                         }
                     }
                 }
-                else if (pshader && ins.handler_idx == WINED3DSIH_BEM)
+                else if (ins.handler_idx == WINED3DSIH_BEM)
                 {
                 {
-                    reg_maps->bumpmat[dst_param.reg.idx] = TRUE;
+                    reg_maps->bumpmat |= 1 << dst_param.reg.idx;
                 }
             }
 
                 }
             }
 
@@ -608,45 +707,77 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             {
                 reg_maps->usesdsy = 1;
             }
             {
                 reg_maps->usesdsy = 1;
             }
+            else if (ins.handler_idx == WINED3DSIH_DSX)
+            {
+                reg_maps->usesdsx = 1;
+            }
             else if(ins.handler_idx == WINED3DSIH_TEXLDD)
             {
                 reg_maps->usestexldd = 1;
             }
             else if(ins.handler_idx == WINED3DSIH_TEXLDD)
             {
                 reg_maps->usestexldd = 1;
             }
+            else if(ins.handler_idx == WINED3DSIH_TEXLDL)
+            {
+                reg_maps->usestexldl = 1;
+            }
+            else if(ins.handler_idx == WINED3DSIH_MOVA)
+            {
+                reg_maps->usesmova = 1;
+            }
+            else if(ins.handler_idx == WINED3DSIH_IFC)
+            {
+                reg_maps->usesifc = 1;
+            }
+            else if(ins.handler_idx == WINED3DSIH_CALL)
+            {
+                reg_maps->usescall = 1;
+            }
 
             limit = ins.src_count + (ins.predicate ? 1 : 0);
             for (i = 0; i < limit; ++i)
             {
                 struct wined3d_shader_src_param src_param, src_rel_addr;
 
             limit = ins.src_count + (ins.predicate ? 1 : 0);
             for (i = 0; i < limit; ++i)
             {
                 struct wined3d_shader_src_param src_param, src_rel_addr;
+                unsigned int count;
 
                 fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
 
                 fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
-                switch(get_instr_regcount(ins.handler_idx, i))
+                count = get_instr_extra_regcount(ins.handler_idx, i);
+
+                shader_record_register_usage(This, reg_maps, &src_param.reg, shader_version.type);
+                while (count)
+                {
+                    ++src_param.reg.idx;
+                    shader_record_register_usage(This, reg_maps, &src_param.reg, shader_version.type);
+                    --count;
+                }
+
+                if(color0_mov)
                 {
                 {
-                    case 4:
-                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
-                                src_param.reg.idx + 3, !!src_param.reg.rel_addr, pshader);
-                        /* drop through */
-                    case 3:
-                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
-                                src_param.reg.idx + 2, !!src_param.reg.rel_addr, pshader);
-                        /* drop through */
-                    case 2:
-                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
-                                src_param.reg.idx + 1, !!src_param.reg.rel_addr, pshader);
-                        /* drop through */
-                    case 1:
-                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
-                                src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
+                    IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This;
+                    if(src_param.reg.type == WINED3DSPR_TEMP &&
+                       src_param.swizzle == WINED3DSP_NOSWIZZLE)
+                    {
+                        ps->color0_mov = TRUE;
+                        ps->color0_reg = src_param.reg.idx;
+                    }
                 }
             }
         }
     }
     reg_maps->loop_depth = max_loop_depth;
 
                 }
             }
         }
     }
     reg_maps->loop_depth = max_loop_depth;
 
-    This->baseShader.functionLength = ((char *)pToken - (char *)byte_code);
+    This->baseShader.functionLength = ((const char *)pToken - (const char *)byte_code);
 
     return WINED3D_OK;
 }
 
 
     return WINED3D_OK;
 }
 
+unsigned int shader_find_free_input_register(const struct shader_reg_maps *reg_maps, unsigned int max)
+{
+    DWORD map = 1 << max;
+    map |= map - 1;
+    map &= reg_maps->shader_version.major < 3 ? ~reg_maps->texcoord : ~reg_maps->input_registers;
+
+    return wined3d_log2i(map);
+}
+
 static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
         const struct wined3d_shader_version *shader_version)
 {
 static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
         const struct wined3d_shader_version *shader_version)
 {
@@ -665,7 +796,7 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
     else
     {
         /* Pixel shaders 3.0 don't have usage semantics */
     else
     {
         /* Pixel shaders 3.0 don't have usage semantics */
-        if (shader_is_pshader_version(shader_version->type) && shader_version->major < 3)
+        if (shader_version->major < 3 && shader_version->type == WINED3D_SHADER_TYPE_PIXEL)
             return;
         else
             TRACE("_");
             return;
         else
             TRACE("_");
@@ -721,15 +852,14 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
     }
 }
 
     }
 }
 
-static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx,
-        enum wined3d_immconst_type immconst_type, const DWORD *immconst_data,
-        const struct wined3d_shader_src_param *rel_addr, const struct wined3d_shader_version *shader_version)
+static void shader_dump_register(const struct wined3d_shader_register *reg,
+        const struct wined3d_shader_version *shader_version)
 {
     static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
     static const char * const misctype_reg_names[] = {"vPos", "vFace"};
 {
     static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
     static const char * const misctype_reg_names[] = {"vPos", "vFace"};
-    UINT offset = register_idx;
+    UINT offset = reg->idx;
 
 
-    switch (register_type)
+    switch (reg->type)
     {
         case WINED3DSPR_TEMP:
             TRACE("r");
     {
         case WINED3DSPR_TEMP:
             TRACE("r");
@@ -744,15 +874,15 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
-            offset = shader_get_float_offset(register_type, register_idx);
+            offset = shader_get_float_offset(reg->type, reg->idx);
             break;
 
         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
             break;
 
         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
-            TRACE("%c", shader_is_pshader_version(shader_version->type) ? 't' : 'a');
+            TRACE("%c", shader_version->type == WINED3D_SHADER_TYPE_PIXEL ? 't' : 'a');
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
-            TRACE("%s", rastout_reg_names[register_idx]);
+            TRACE("%s", rastout_reg_names[reg->idx]);
             break;
 
         case WINED3DSPR_COLOROUT:
             break;
 
         case WINED3DSPR_COLOROUT:
@@ -795,8 +925,8 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type
             break;
 
         case WINED3DSPR_MISCTYPE:
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx);
-            else TRACE("%s", misctype_reg_names[register_idx]);
+            if (reg->idx > 1) FIXME("Unhandled misctype register %d\n", reg->idx);
+            else TRACE("%s", misctype_reg_names[reg->idx]);
             break;
 
         case WINED3DSPR_PREDICATE:
             break;
 
         case WINED3DSPR_PREDICATE:
@@ -807,42 +937,59 @@ static void shader_dump_register(WINED3DSHADER_PARAM_REGISTER_TYPE register_type
             TRACE("l");
             break;
 
             TRACE("l");
             break;
 
+        case WINED3DSPR_CONSTBUFFER:
+            TRACE("cb");
+            break;
+
         default:
         default:
-            TRACE("unhandled_rtype(%#x)", register_type);
+            TRACE("unhandled_rtype(%#x)", reg->type);
             break;
     }
 
             break;
     }
 
-    if (register_type == WINED3DSPR_IMMCONST)
+    if (reg->type == WINED3DSPR_IMMCONST)
     {
         TRACE("(");
     {
         TRACE("(");
-        switch (immconst_type)
+        switch (reg->immconst_type)
         {
             case WINED3D_IMMCONST_FLOAT:
         {
             case WINED3D_IMMCONST_FLOAT:
-                TRACE("%.8e", *(float *)immconst_data);
+                TRACE("%.8e", *(const float *)reg->immconst_data);
                 break;
 
             case WINED3D_IMMCONST_FLOAT4:
                 TRACE("%.8e, %.8e, %.8e, %.8e",
                 break;
 
             case WINED3D_IMMCONST_FLOAT4:
                 TRACE("%.8e, %.8e, %.8e, %.8e",
-                        *(float *)&immconst_data[0], *(float *)&immconst_data[1],
-                        *(float *)&immconst_data[2], *(float *)&immconst_data[3]);
+                        *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
+                        *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
                 break;
 
             default:
                 break;
 
             default:
-                TRACE("<unhandled immconst_type %#x>", immconst_type);
+                TRACE("<unhandled immconst_type %#x>", reg->immconst_type);
                 break;
         }
         TRACE(")");
     }
                 break;
         }
         TRACE(")");
     }
-    else if (register_type != WINED3DSPR_RASTOUT && register_type != WINED3DSPR_MISCTYPE)
+    else if (reg->type != WINED3DSPR_RASTOUT && reg->type != WINED3DSPR_MISCTYPE)
     {
     {
-        if (rel_addr)
+        if (reg->array_idx != ~0U)
+        {
+            TRACE("%u[%u", offset, reg->array_idx);
+            if (reg->rel_addr)
+            {
+                TRACE(" + ");
+                shader_dump_src_param(reg->rel_addr, shader_version);
+            }
+            TRACE("]");
+        }
+        else
         {
         {
-            TRACE("[");
-            shader_dump_src_param(rel_addr, shader_version);
-            TRACE(" + ");
+            if (reg->rel_addr)
+            {
+                TRACE("[");
+                shader_dump_src_param(reg->rel_addr, shader_version);
+                TRACE(" + ");
+            }
+            TRACE("%u", offset);
+            if (reg->rel_addr) TRACE("]");
         }
         }
-        TRACE("%u", offset);
-        if (rel_addr) TRACE("]");
     }
 }
 
     }
 }
 
@@ -851,7 +998,7 @@ void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
 {
     DWORD write_mask = param->write_mask;
 
 {
     DWORD write_mask = param->write_mask;
 
-    shader_dump_register(param->reg.type, param->reg.idx, 0, NULL, param->reg.rel_addr, shader_version);
+    shader_dump_register(&param->reg, shader_version);
 
     if (write_mask != WINED3DSP_WRITEMASK_ALL)
     {
 
     if (write_mask != WINED3DSP_WRITEMASK_ALL)
     {
@@ -885,8 +1032,7 @@ void shader_dump_src_param(const struct wined3d_shader_src_param *param,
     if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
         TRACE("abs(");
 
     if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
         TRACE("abs(");
 
-    shader_dump_register(param->reg.type, param->reg.idx, param->reg.immconst_type,
-            param->reg.immconst_data, param->reg.rel_addr, shader_version);
+    shader_dump_register(&param->reg, shader_version);
 
     if (src_modifier)
     {
 
     if (src_modifier)
     {
@@ -935,12 +1081,11 @@ void shader_dump_src_param(const struct wined3d_shader_src_param *param,
 
 /* Shared code in order to generate the bulk of the shader string.
  * NOTE: A description of how to parse tokens can be found on msdn */
 
 /* Shared code in order to generate the bulk of the shader string.
  * NOTE: A description of how to parse tokens can be found on msdn */
-void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
-        const shader_reg_maps *reg_maps, const DWORD *pFunction)
+void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffer *buffer,
+        const shader_reg_maps *reg_maps, const DWORD *pFunction, void *backend_ctx)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
-    const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
     const struct wined3d_shader_frontend *fe = This->baseShader.frontend;
     void *fe_data = This->baseShader.frontend_data;
     struct wined3d_shader_src_param src_rel_addr[4];
     const struct wined3d_shader_frontend *fe = This->baseShader.frontend;
     void *fe_data = This->baseShader.frontend_data;
     struct wined3d_shader_src_param src_rel_addr[4];
@@ -951,13 +1096,13 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
     struct wined3d_shader_instruction ins;
     struct wined3d_shader_context ctx;
     const DWORD *pToken = pFunction;
     struct wined3d_shader_instruction ins;
     struct wined3d_shader_context ctx;
     const DWORD *pToken = pFunction;
-    SHADER_HANDLER hw_fct;
     DWORD i;
 
     /* Initialize current parsing state */
     ctx.shader = iface;
     ctx.reg_maps = reg_maps;
     ctx.buffer = buffer;
     DWORD i;
 
     /* Initialize current parsing state */
     ctx.shader = iface;
     ctx.reg_maps = reg_maps;
     ctx.buffer = buffer;
+    ctx.backend_data = backend_ctx;
 
     ins.ctx = &ctx;
     ins.dst = &dst_param;
 
     ins.ctx = &ctx;
     ins.dst = &dst_param;
@@ -992,24 +1137,12 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
                 || ins.handler_idx == WINED3DSIH_DEF
                 || ins.handler_idx == WINED3DSIH_DEFI
                 || ins.handler_idx == WINED3DSIH_DEFB
                 || ins.handler_idx == WINED3DSIH_DEF
                 || ins.handler_idx == WINED3DSIH_DEFI
                 || ins.handler_idx == WINED3DSIH_DEFB
-                || ins.handler_idx == WINED3DSIH_PHASE
-                || ins.handler_idx == WINED3DSIH_RET)
+                || ins.handler_idx == WINED3DSIH_PHASE)
         {
             pToken += param_size;
             continue;
         }
 
         {
             pToken += param_size;
             continue;
         }
 
-        /* Select handler */
-        hw_fct = handler_table[ins.handler_idx];
-
-        /* Unhandled opcode */
-        if (!hw_fct)
-        {
-            FIXME("Backend can't handle opcode %#x\n", ins.handler_idx);
-            pToken += param_size;
-            continue;
-        }
-
         /* Destination token */
         if (ins.dst_count) fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
         /* Destination token */
         if (ins.dst_count) fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
@@ -1023,10 +1156,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         }
 
         /* Call appropriate function for output target */
         }
 
         /* Call appropriate function for output target */
-        hw_fct(&ins);
-
-        /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
-        device->shader_backend->shader_add_instruction_modifiers(&ins);
+        device->shader_backend->shader_handle_instruction(&ins);
     }
 }
 
     }
 }
 
@@ -1059,14 +1189,34 @@ void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data,
 {
     struct wined3d_shader_version shader_version;
     const DWORD* pToken = pFunction;
 {
     struct wined3d_shader_version shader_version;
     const DWORD* pToken = pFunction;
+    const char *type_prefix;
     DWORD i;
 
     TRACE("Parsing %p\n", pFunction);
 
     fe->shader_read_header(fe_data, &pToken, &shader_version);
 
     DWORD i;
 
     TRACE("Parsing %p\n", pFunction);
 
     fe->shader_read_header(fe_data, &pToken, &shader_version);
 
-    TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version.type) ? "ps": "vs",
-            shader_version.major, shader_version.minor);
+    switch (shader_version.type)
+    {
+        case WINED3D_SHADER_TYPE_VERTEX:
+            type_prefix = "vs";
+            break;
+
+        case WINED3D_SHADER_TYPE_GEOMETRY:
+            type_prefix = "gs";
+            break;
+
+        case WINED3D_SHADER_TYPE_PIXEL:
+            type_prefix = "ps";
+            break;
+
+        default:
+            FIXME("Unhandled shader type %#x.\n", shader_version.type);
+            type_prefix = "unknown";
+            break;
+    }
+
+    TRACE("%s_%u_%u\n", type_prefix, shader_version.major, shader_version.minor);
 
     while (!fe->shader_is_end(fe_data, &pToken))
     {
 
     while (!fe->shader_is_end(fe_data, &pToken))
     {
@@ -1224,39 +1374,27 @@ void shader_cleanup(IWineD3DBaseShader *iface)
     }
 }
 
     }
 }
 
-static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
-static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
+static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
+static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
-static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
+static void shader_none_load_constants(const struct wined3d_context *context, char usePS, char useVS) {}
 static void shader_none_load_np2fixup_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 static void shader_none_destroy(IWineD3DBaseShader *iface) {}
 static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
 static void shader_none_free(IWineD3DDevice *iface) {}
 static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;}
 static void shader_none_load_np2fixup_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 static void shader_none_destroy(IWineD3DBaseShader *iface) {}
 static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
 static void shader_none_free(IWineD3DDevice *iface) {}
 static BOOL shader_none_dirty_const(IWineD3DDevice *iface) {return FALSE;}
-static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface,
-        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
-{
-    FIXME("NONE shader backend asked to generate a pixel shader\n");
-    return 0;
-}
-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");
-    return 0;
-}
-static void shader_none_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {}
 
 #define GLINFO_LOCATION      (*gl_info)
 
 #define GLINFO_LOCATION      (*gl_info)
-static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
+static void shader_none_get_caps(WINED3DDEVTYPE devtype,
+        const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
 {
     /* Set the shader caps to 0 for the none shader backend */
     pCaps->VertexShaderVersion  = 0;
     pCaps->PixelShaderVersion    = 0;
 {
     /* Set the shader caps to 0 for the none shader backend */
     pCaps->VertexShaderVersion  = 0;
     pCaps->PixelShaderVersion    = 0;
-    pCaps->PixelShader1xMaxValue = 0.0;
+    pCaps->PixelShader1xMaxValue = 0.0f;
 }
 #undef GLINFO_LOCATION
 static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
 }
 #undef GLINFO_LOCATION
 static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
@@ -1279,7 +1417,7 @@ static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 const shader_backend_t none_shader_backend = {
 }
 
 const shader_backend_t none_shader_backend = {
-    shader_none_instruction_handler_table,
+    shader_none_handle_instruction,
     shader_none_select,
     shader_none_select_depth_blt,
     shader_none_deselect_depth_blt,
     shader_none_select,
     shader_none_select_depth_blt,
     shader_none_deselect_depth_blt,
@@ -1291,9 +1429,6 @@ const shader_backend_t none_shader_backend = {
     shader_none_alloc,
     shader_none_free,
     shader_none_dirty_const,
     shader_none_alloc,
     shader_none_free,
     shader_none_dirty_const,
-    shader_none_generate_pshader,
-    shader_none_generate_vshader,
     shader_none_get_caps,
     shader_none_color_fixup_supported,
     shader_none_get_caps,
     shader_none_color_fixup_supported,
-    shader_none_add_instruction_modifiers,
 };
 };
index caf2148..ab38b62 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
-void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage)
+HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type,
+        IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
+        WINED3DPOOL pool, IUnknown *parent)
 {
 {
-    texture->levels = levels;
-    texture->filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
-    texture->LOD = 0;
-    texture->dirty = TRUE;
-    texture->srgbDirty = TRUE;
-    texture->is_srgb = FALSE;
-    texture->pow2Matrix_identity = TRUE;
-}
+    HRESULT hr;
 
 
-void basetexture_cleanup(IWineD3DBaseTexture *iface)
-{
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    hr = resource_init((IWineD3DResource *)texture, resource_type, device, size, usage, format_desc, pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x\n", hr);
+        return hr;
+    }
 
 
-    TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
-    if (This->baseTexture.textureName != 0) {
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        ENTER_GL();
-        TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
-        glDeleteTextures(1, &This->baseTexture.textureName);
-        glDeleteTextures(1, &This->baseTexture.srgbTextureName);
-        LEAVE_GL();
+    texture->baseTexture.levels = levels;
+    texture->baseTexture.filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
+    texture->baseTexture.LOD = 0;
+    texture->baseTexture.dirty = TRUE;
+    texture->baseTexture.srgbDirty = TRUE;
+    texture->baseTexture.is_srgb = FALSE;
+    texture->baseTexture.pow2Matrix_identity = TRUE;
+
+    if (texture->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
+    {
+        texture->baseTexture.minMipLookup = minMipLookup;
+        texture->baseTexture.magLookup = magLookup;
     }
     }
+    else
+    {
+        texture->baseTexture.minMipLookup = minMipLookup_noFilter;
+        texture->baseTexture.magLookup = magLookup_noFilter;
+    }
+
+    return WINED3D_OK;
+}
 
 
+void basetexture_cleanup(IWineD3DBaseTexture *iface)
+{
+    basetexture_unload(iface);
     resource_cleanup((IWineD3DResource *)iface);
 }
 
     resource_cleanup((IWineD3DResource *)iface);
 }
 
@@ -62,11 +74,17 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     if(This->baseTexture.textureName) {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     if(This->baseTexture.textureName) {
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         glDeleteTextures(1, &This->baseTexture.textureName);
         ENTER_GL();
         glDeleteTextures(1, &This->baseTexture.textureName);
-        glDeleteTextures(1, &This->baseTexture.srgbTextureName);
         This->baseTexture.textureName = 0;
         This->baseTexture.textureName = 0;
+        LEAVE_GL();
+    }
+
+    if(This->baseTexture.srgbTextureName) {
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+        ENTER_GL();
+        glDeleteTextures(1, &This->baseTexture.srgbTextureName);
         This->baseTexture.srgbTextureName = 0;
         LEAVE_GL();
     }
         This->baseTexture.srgbTextureName = 0;
         LEAVE_GL();
     }
@@ -74,33 +92,41 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
     This->baseTexture.srgbDirty = TRUE;
 }
 
     This->baseTexture.srgbDirty = TRUE;
 }
 
-/* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading
- * so just pretend that they work unless something really needs a failure. */
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+    DWORD old = This->baseTexture.LOD;
 
 
+    /* The d3d9:texture test shows that SetLOD is ignored on non-managed
+     * textures. The call always returns 0, and GetLOD always returns 0
+     */
     if (This->resource.pool != WINED3DPOOL_MANAGED) {
     if (This->resource.pool != WINED3DPOOL_MANAGED) {
-        return  WINED3DERR_INVALIDCALL;
+        TRACE("Ignoring SetLOD on %s texture, returning 0\n", debug_d3dpool(This->resource.pool));
+        return 0;
     }
 
     if(LODNew >= This->baseTexture.levels)
         LODNew = This->baseTexture.levels - 1;
     }
 
     if(LODNew >= This->baseTexture.levels)
         LODNew = This->baseTexture.levels - 1;
-     This->baseTexture.LOD = LODNew;
 
 
-    TRACE("(%p) : set bogus LOD to %d\n", This, This->baseTexture.LOD);
+    if(This->baseTexture.LOD != LODNew) {
+        This->baseTexture.LOD = LODNew;
 
 
-    return This->baseTexture.LOD;
+        This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+        This->baseTexture.srgbstates[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+        if(This->baseTexture.bindCount) {
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(This->baseTexture.sampler));
+        }
+    }
+
+    TRACE("(%p) : set LOD to %d\n", This, This->baseTexture.LOD);
+
+    return old;
 }
 
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 
 }
 
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 
-    if (This->resource.pool != WINED3DPOOL_MANAGED) {
-        return  WINED3DERR_INVALIDCALL;
-    }
-
     TRACE("(%p) : returning %d\n", This, This->baseTexture.LOD);
 
     return This->baseTexture.LOD;
     TRACE("(%p) : returning %d\n", This, This->baseTexture.LOD);
 
     return This->baseTexture.LOD;
@@ -128,7 +154,7 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT
        * Or should we delay the applying until the texture is used for drawing? For now, apply
        * immediately.
        */
        * Or should we delay the applying until the texture is used for drawing? For now, apply
        * immediately.
        */
-      ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+      ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
       ENTER_GL();
       glBindTexture(textureDimensions, This->baseTexture.textureName);
       checkGLcall("glBindTexture");
       ENTER_GL();
       glBindTexture(textureDimensions, This->baseTexture.textureName);
       checkGLcall("glBindTexture");
@@ -158,12 +184,11 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT
 
 WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture *iface)
 {
 
 WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture *iface)
 {
-  IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-  FIXME("(%p) : stub\n", This);
-  if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
-     return WINED3DTEXF_NONE;
-  }
-  return This->baseTexture.filterType;
+    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+
+    FIXME("(%p) : stub\n", This);
+
+    return This->baseTexture.filterType;
 }
 
 void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface)
 }
 
 void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface)
@@ -190,6 +215,7 @@ BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface)
     return This->baseTexture.dirty || This->baseTexture.srgbDirty;
 }
 
     return This->baseTexture.dirty || This->baseTexture.srgbDirty;
 }
 
+/* Context activation is done by the caller. */
 HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surface_desc)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
 HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surface_desc)
 {
     IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
@@ -234,7 +260,7 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac
         states[WINED3DTEXSTA_MINFILTER]     = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
         states[WINED3DTEXSTA_MIPFILTER]     = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
         states[WINED3DTEXSTA_MAXMIPLEVEL]   = 0;
         states[WINED3DTEXSTA_MINFILTER]     = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
         states[WINED3DTEXSTA_MIPFILTER]     = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
         states[WINED3DTEXSTA_MAXMIPLEVEL]   = 0;
-        states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
+        states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
         states[WINED3DTEXSTA_SRGBTEXTURE]   = 0;
         states[WINED3DTEXSTA_ELEMENTINDEX]  = 0;
         states[WINED3DTEXSTA_DMAPOFFSET]    = 0;
         states[WINED3DTEXSTA_SRGBTEXTURE]   = 0;
         states[WINED3DTEXSTA_ELEMENTINDEX]  = 0;
         states[WINED3DTEXSTA_DMAPOFFSET]    = 0;
@@ -288,6 +314,7 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surfac
     return hr;
 }
 
     return hr;
 }
 
+/* GL locking is done by the caller */
 static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type,
                               BOOL cond_np2) {
     GLint wrapParm;
 static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type,
                               BOOL cond_np2) {
     GLint wrapParm;
@@ -313,6 +340,7 @@ static inline void apply_wrap(const GLint textureDimensions, const DWORD state,
     }
 }
 
     }
 }
 
+/* GL locking is done by the caller (state handler) */
 void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
         const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1])
 void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
         const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1])
@@ -321,6 +349,9 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
     DWORD state, *states;
     GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
     BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2(iface);
     DWORD state, *states;
     GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
     BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2(iface);
+    DWORD aniso;
+
+    TRACE("iface %p, textureStates %p, samplerStates %p\n", iface, textureStates, samplerStates);
 
     if(This->baseTexture.is_srgb) {
         states = This->baseTexture.srgbstates;
 
     if(This->baseTexture.is_srgb) {
         states = This->baseTexture.srgbstates;
@@ -328,7 +359,7 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         states = This->baseTexture.states;
     }
 
         states = This->baseTexture.states;
     }
 
-    /* ApplyStateChanges relies on the correct texture being bound and loaded. */
+    /* This function relies on the correct texture being bound and loaded. */
 
     if(samplerStates[WINED3DSAMP_ADDRESSU]      != states[WINED3DTEXSTA_ADDRESSU]) {
         state = samplerStates[WINED3DSAMP_ADDRESSU];
 
     if(samplerStates[WINED3DSAMP_ADDRESSU]      != states[WINED3DTEXSTA_ADDRESSU]) {
         state = samplerStates[WINED3DSAMP_ADDRESSU];
@@ -364,17 +395,14 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         state = samplerStates[WINED3DSAMP_MAGFILTER];
         if (state > WINED3DTEXF_ANISOTROPIC) {
             FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
         state = samplerStates[WINED3DSAMP_MAGFILTER];
         if (state > WINED3DTEXF_ANISOTROPIC) {
             FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
-        } else {
-            glValue = This->baseTexture.magLookup[state - WINED3DTEXF_NONE];
-            TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
-            glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
-            /* We need to reset the Anisotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentation to see how it should be switched off. */
-            if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state &&
-                !cond_np2) {
-                glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
-            }
-            states[WINED3DTEXSTA_MAGFILTER] = state;
         }
         }
+
+        glValue = wined3d_gl_mag_filter(This->baseTexture.magLookup,
+                min(max(state, WINED3DTEXF_POINT), WINED3DTEXF_LINEAR));
+        TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
+        glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
+
+        states[WINED3DTEXSTA_MAGFILTER] = state;
     }
 
     if((samplerStates[WINED3DSAMP_MINFILTER]     != states[WINED3DTEXSTA_MINFILTER] ||
     }
 
     if((samplerStates[WINED3DSAMP_MINFILTER]     != states[WINED3DTEXSTA_MINFILTER] ||
@@ -386,17 +414,17 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
         states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
 
         states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
         states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
 
-        if (states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
-            states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
+        if (states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC
+                || states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_ANISOTROPIC)
         {
 
             FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
                   states[WINED3DTEXSTA_MINFILTER],
                   states[WINED3DTEXSTA_MIPFILTER]);
         }
         {
 
             FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
                   states[WINED3DTEXSTA_MINFILTER],
                   states[WINED3DTEXSTA_MIPFILTER]);
         }
-        glValue = This->baseTexture.minMipLookup
-                [min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
-                .mip[min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
+        glValue = wined3d_gl_min_mip_filter(This->baseTexture.minMipLookup,
+                min(max(samplerStates[WINED3DSAMP_MINFILTER], WINED3DTEXF_POINT), WINED3DTEXF_LINEAR),
+                min(max(samplerStates[WINED3DSAMP_MIPFILTER], WINED3DTEXF_NONE), WINED3DTEXF_LINEAR));
 
         TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
               samplerStates[WINED3DSAMP_MINFILTER],
 
         TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
               samplerStates[WINED3DSAMP_MINFILTER],
@@ -406,23 +434,46 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
 
         if(!cond_np2) {
             if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
 
         if(!cond_np2) {
             if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
-                glValue = 0;
+                glValue = This->baseTexture.LOD;
             } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
                 glValue = This->baseTexture.levels - 1;
             } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
                 glValue = This->baseTexture.levels - 1;
+            } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) {
+                /* baseTexture.LOD is already clamped in the setter */
+                glValue = This->baseTexture.LOD;
             } else {
                 glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
             }
             } else {
                 glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
             }
+            /* Note that D3DSAMP_MAXMIPLEVEL specifies the biggest mipmap(default 0), while
+             * GL_TEXTURE_MAX_LEVEL specifies the smallest mimap used(default 1000).
+             * So D3DSAMP_MAXMIPLEVEL is the same as GL_TEXTURE_BASE_LEVEL.
+             */
             glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
         }
     }
 
             glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
         }
     }
 
-    if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != states[WINED3DTEXSTA_MAXANISOTROPY]) {
-        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && !cond_np2) {
-            glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
-            checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
-        } else {
-            WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
+    if ((states[WINED3DSAMP_MAGFILTER] != WINED3DTEXF_ANISOTROPIC
+            && states[WINED3DSAMP_MINFILTER] != WINED3DTEXF_ANISOTROPIC
+            && states[WINED3DSAMP_MIPFILTER] != WINED3DTEXF_ANISOTROPIC)
+            || cond_np2)
+    {
+        aniso = 1;
+    }
+    else
+    {
+        aniso = samplerStates[WINED3DSAMP_MAXANISOTROPY];
+    }
+
+    if (states[WINED3DTEXSTA_MAXANISOTROPY] != aniso)
+    {
+        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC))
+        {
+            glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
+            checkGLcall("glTexParameteri(GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso)");
+        }
+        else
+        {
+            WARN("Anisotropic filtering not supported.\n");
         }
         }
-        states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
+        states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
     }
 }
     }
 }
index 666de8e..104f572 100644 (file)
@@ -34,16 +34,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #define VB_MAXDECLCHANGES     100     /* After that number we stop converting */
 #define VB_RESETDECLCHANGE    1000    /* Reset the changecount after that number of draws */
 
 #define VB_MAXDECLCHANGES     100     /* After that number we stop converting */
 #define VB_RESETDECLCHANGE    1000    /* Reset the changecount after that number of draws */
 
+/* Context activation is done by the caller. */
 static void buffer_create_buffer_object(struct wined3d_buffer *This)
 {
     GLenum error, gl_usage;
 static void buffer_create_buffer_object(struct wined3d_buffer *This)
 {
     GLenum error, gl_usage;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n",
             This, debug_d3dusage(This->resource.usage));
 
 
     TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n",
             This, debug_d3dusage(This->resource.usage));
 
-    /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
-    ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
     ENTER_GL();
 
     /* Make sure that the gl error is cleared. Do not use checkGLcall
     ENTER_GL();
 
     /* Make sure that the gl error is cleared. Do not use checkGLcall
@@ -200,17 +198,20 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
     return ret;
 }
 
     return ret;
 }
 
-static BOOL buffer_check_attribute(struct wined3d_buffer *This,
-        const struct wined3d_stream_info_element *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position,
-        const BOOL is_ffp_color, DWORD *stride_this_run, BOOL *float16_used)
+static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
+        UINT attrib_idx, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color,
+        DWORD *stride_this_run, BOOL *float16_used)
 {
 {
+    const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
     BOOL ret = FALSE;
     WINED3DFORMAT format;
 
     /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
      * there, on nonexistent attribs the vbo is 0.
      */
     BOOL ret = FALSE;
     WINED3DFORMAT format;
 
     /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
      * there, on nonexistent attribs the vbo is 0.
      */
-    if (attrib->buffer_object != This->buffer_object) return FALSE;
+    if (!(si->use_map & (1 << attrib_idx))
+            || attrib->buffer_object != This->buffer_object)
+        return FALSE;
 
     format = attrib->format_desc->format;
     /* Look for newly appeared conversion */
 
     format = attrib->format_desc->format;
     /* Look for newly appeared conversion */
@@ -257,7 +258,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This,
     {
         WINED3DFORMAT format;
 
     {
         WINED3DFORMAT format;
 
-        if (strided->elements[i].buffer_object != This->buffer_object) continue;
+        if (!(strided->use_map & (1 << i)) || strided->elements[i].buffer_object != This->buffer_object) continue;
 
         format = strided->elements[i].format_desc->format;
         if (format == WINED3DFMT_R16G16_FLOAT)
 
         format = strided->elements[i].format_desc->format;
         if (format == WINED3DFMT_R16G16_FLOAT)
@@ -308,6 +309,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This,
 static BOOL buffer_find_decl(struct wined3d_buffer *This)
 {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 static BOOL buffer_find_decl(struct wined3d_buffer *This)
 {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    const struct wined3d_stream_info *si = &device->strided_streams;
     UINT stride_this_run = 0;
     BOOL float16_used = FALSE;
     BOOL ret = FALSE;
     UINT stride_this_run = 0;
     BOOL float16_used = FALSE;
     BOOL ret = FALSE;
@@ -395,8 +397,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
         }
         for (i = 0; i < MAX_ATTRIBS; ++i)
         {
         }
         for (i = 0; i < MAX_ATTRIBS; ++i)
         {
-            ret = buffer_check_attribute(This, &device->strided_streams.elements[i],
-                    FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
+            ret = buffer_check_attribute(This, si, i, FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         }
 
         /* Recalculate the conversion shift map if the declaration has changed,
         }
 
         /* Recalculate the conversion shift map if the declaration has changed,
@@ -405,7 +406,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
         if (ret && (float16_used || This->conversion_map))
         {
             HeapFree(GetProcessHeap(), 0, This->conversion_shift);
         if (ret && (float16_used || This->conversion_map))
         {
             HeapFree(GetProcessHeap(), 0, This->conversion_shift);
-            This->conversion_shift = find_conversion_shift(This, &device->strided_streams, This->stride);
+            This->conversion_shift = find_conversion_shift(This, si, This->stride);
         }
     }
     else
         }
     }
     else
@@ -415,29 +416,29 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
          * the attributes that our current fixed function pipeline implementation cares for.
          */
         BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA);
          * the attributes that our current fixed function pipeline implementation cares for.
          */
         BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA);
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_POSITION],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
                 TRUE, TRUE,  FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, TRUE,  FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_NORMAL],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_DIFFUSE],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_SPECULAR],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD0],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD1],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD2],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD3],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD4],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD5],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD6],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD7],
+        ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
 
         if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n");
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
 
         if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n");
@@ -457,6 +458,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
     return ret;
 }
 
     return ret;
 }
 
+/* Context activation is done by the caller. */
 static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
 {
     UINT size = This->conversion_stride ?
 static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
 {
     UINT size = This->conversion_stride ?
@@ -506,29 +508,18 @@ static inline void fixup_d3dcolor(DWORD *dst_color)
 
 static inline void fixup_transformed_pos(float *p)
 {
 
 static inline void fixup_transformed_pos(float *p)
 {
-    float x, y, z, w;
-
-    /* rhw conversion like in drawStridedSlow */
-    if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps)))
-    {
-        x = p[0];
-        y = p[1];
-        z = p[2];
-        w = 1.0;
-    }
-    else
+    /* rhw conversion like in position_float4(). */
+    if (p[3] != 1.0f && p[3] != 0.0f)
     {
     {
-        w = 1.0 / p[3];
-        x = p[0] * w;
-        y = p[1] * w;
-        z = p[2] * w;
+        float w = 1.0f / p[3];
+        p[0] *= w;
+        p[1] *= w;
+        p[2] *= w;
+        p[3] = w;
     }
     }
-    p[0] = x;
-    p[1] = y;
-    p[2] = z;
-    p[3] = w;
 }
 
 }
 
+/* Context activation is done by the caller. */
 const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
@@ -588,7 +579,8 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface)
     return refcount;
 }
 
     return refcount;
 }
 
-const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
+/* Context activation is done by the caller. */
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
 {
     /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
     if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
 {
     /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
     if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
@@ -614,7 +606,7 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
     {
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     {
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
 
         /* Download the buffer, but don't permanently enable double buffering */
         if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
 
         /* Download the buffer, but don't permanently enable double buffering */
         if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
@@ -701,6 +693,8 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
 
     TRACE("iface %p\n", iface);
 
 
     TRACE("iface %p\n", iface);
 
+    ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+
     if (!This->buffer_object)
     {
         /* TODO: Make converting independent from VBOs */
     if (!This->buffer_object)
     {
         /* TODO: Make converting independent from VBOs */
@@ -736,7 +730,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
         if (This->conversion_count > VB_MAXDECLCHANGES)
         {
             FIXME("Too many declaration changes, stopping converting\n");
         if (This->conversion_count > VB_MAXDECLCHANGES)
         {
             FIXME("Too many declaration changes, stopping converting\n");
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+
             ENTER_GL();
             GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
             checkGLcall("glDeleteBuffersARB");
             ENTER_GL();
             GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
             checkGLcall("glDeleteBuffersARB");
@@ -809,7 +803,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
 
         if (!device->isInDraw)
         {
 
         if (!device->isInDraw)
         {
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         }
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         }
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
@@ -959,7 +953,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
                 IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
             }
 
                 IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
             }
 
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
             ENTER_GL();
             GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
             This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
             ENTER_GL();
             GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
             This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
@@ -985,6 +979,16 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
 
     TRACE("(%p)\n", This);
 
 
     TRACE("(%p)\n", This);
 
+    /* In the case that the number of Unmap calls > the
+     * number of Map calls, d3d returns always D3D_OK.
+     * This is also needed to prevent Map from returning garbage on
+     * the next call (this will happen if the lock_count is < 0). */
+    if(This->lock_count == 0)
+    {
+        TRACE("Unmap called without a previous Map call!\n");
+        return WINED3D_OK;
+    }
+
     if (InterlockedDecrement(&This->lock_count))
     {
         /* Delay loading the buffer until everything is unlocked */
     if (InterlockedDecrement(&This->lock_count))
     {
         /* Delay loading the buffer until everything is unlocked */
@@ -1001,7 +1005,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
 
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
 
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
index 2c6703f..c4cd436 100644 (file)
@@ -2,6 +2,7 @@
  * Context and render target management in wined3d
  *
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Context and render target management in wined3d
  *
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
-#define GLINFO_LOCATION This->adapter->gl_info
+#define GLINFO_LOCATION (*gl_info)
 
 
-/* The last used device.
- *
- * If the application creates multiple devices and switches between them, ActivateContext has to
- * change the opengl context. This flag allows to keep track which device is active
- */
-static IWineD3DDeviceImpl *last_device;
+static DWORD wined3d_context_tls_idx;
 
 /* FBO helper functions */
 
 
 /* FBO helper functions */
 
-void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo)
+/* GL locking is done by the caller */
+void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo)
 {
 {
-    const IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    GLuint f;
+
+    if (!fbo)
+    {
+        f = 0;
+    }
+    else
+    {
+        if (!*fbo)
+        {
+            GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
+            checkGLcall("glGenFramebuffersEXT()");
+            TRACE("Created FBO %u.\n", *fbo);
+        }
+        f = *fbo;
+    }
 
 
-    if (!*fbo)
+    switch (target)
     {
     {
-        GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
-        checkGLcall("glGenFramebuffersEXT()");
-        TRACE("Created FBO %d\n", *fbo);
+        case GL_READ_FRAMEBUFFER_EXT:
+            if (context->fbo_read_binding == f) return;
+            context->fbo_read_binding = f;
+            break;
+
+        case GL_DRAW_FRAMEBUFFER_EXT:
+            if (context->fbo_draw_binding == f) return;
+            context->fbo_draw_binding = f;
+            break;
+
+        case GL_FRAMEBUFFER_EXT:
+            if (context->fbo_read_binding == f
+                    && context->fbo_draw_binding == f) return;
+            context->fbo_read_binding = f;
+            context->fbo_draw_binding = f;
+            break;
+
+        default:
+            FIXME("Unhandled target %#x.\n", target);
+            break;
     }
 
     }
 
-    GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
+    GL_EXTCALL(glBindFramebufferEXT(target, f));
     checkGLcall("glBindFramebuffer()");
 }
 
     checkGLcall("glBindFramebuffer()");
 }
 
-static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
+/* GL locking is done by the caller */
+static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info)
 {
     unsigned int i;
 
 {
     unsigned int i;
 
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
-    checkGLcall("glBindFramebuffer()");
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
         GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
         GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
@@ -66,16 +95,29 @@ static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
     }
     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
     checkGLcall("glFramebufferTexture2D()");
     }
     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
     checkGLcall("glFramebufferTexture2D()");
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-    checkGLcall("glBindFramebuffer()");
+
+    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+    checkGLcall("glFramebufferTexture2D()");
+}
+
+/* GL locking is done by the caller */
+static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, fbo);
+    context_clean_fbo_attachments(gl_info);
+    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+
     GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
     checkGLcall("glDeleteFramebuffers()");
 }
 
     GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
     checkGLcall("glDeleteFramebuffers()");
 }
 
-static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD3DSurface *surface, BOOL force_preload)
+/* GL locking is done by the caller */
+static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOOL force_preload)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
     const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
+    IWineD3DDeviceImpl *device = surface_impl->resource.wineD3DDevice;
     IWineD3DBaseTextureImpl *texture_impl;
     BOOL update_minfilter = FALSE;
     BOOL update_magfilter = FALSE;
     IWineD3DBaseTextureImpl *texture_impl;
     BOOL update_minfilter = FALSE;
     BOOL update_magfilter = FALSE;
@@ -100,7 +142,7 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD
         if (texture_impl->baseTexture.bindCount)
         {
             WARN("Render targets should not be bound to a sampler\n");
         if (texture_impl->baseTexture.bindCount)
         {
             WARN("Render targets should not be bound to a sampler\n");
-            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
+            IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(texture_impl->baseTexture.sampler));
         }
 
         IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
         }
 
         IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
@@ -111,7 +153,7 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD
         GLenum target, bind_target;
         GLint old_binding;
 
         GLenum target, bind_target;
         GLint old_binding;
 
-        target = surface_impl->glDescription.target;
+        target = surface_impl->texture_target;
         if (target == GL_TEXTURE_2D)
         {
             bind_target = GL_TEXTURE_2D;
         if (target == GL_TEXTURE_2D)
         {
             bind_target = GL_TEXTURE_2D;
@@ -126,7 +168,7 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD
 
         surface_internal_preload(surface, SRGB_RGB);
 
 
         surface_internal_preload(surface, SRGB_RGB);
 
-        glBindTexture(bind_target, surface_impl->glDescription.textureName);
+        glBindTexture(bind_target, surface_impl->texture_name);
         if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glBindTexture(bind_target, old_binding);
         if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glBindTexture(bind_target, old_binding);
@@ -135,44 +177,93 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD
     checkGLcall("apply_attachment_filter_states()");
 }
 
     checkGLcall("apply_attachment_filter_states()");
 }
 
-/* TODO: Handle stencil attachments */
-void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer)
+/* GL locking is done by the caller */
+void context_attach_depth_stencil_fbo(struct wined3d_context *context,
+        GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer)
 {
     IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
 {
     IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("Attach depth stencil %p\n", depth_stencil);
 
     if (depth_stencil)
     {
 
     TRACE("Attach depth stencil %p\n", depth_stencil);
 
     if (depth_stencil)
     {
+        DWORD format_flags = depth_stencil_impl->resource.format_desc->Flags;
+
         if (use_render_buffer && depth_stencil_impl->current_renderbuffer)
         {
         if (use_render_buffer && depth_stencil_impl->current_renderbuffer)
         {
-            GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
-            checkGLcall("glFramebufferRenderbufferEXT()");
-        } else {
-            context_apply_attachment_filter_states((IWineD3DDevice *)This, depth_stencil, TRUE);
+            if (format_flags & WINED3DFMT_FLAG_DEPTH)
+            {
+                GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT,
+                        GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
+                checkGLcall("glFramebufferRenderbufferEXT()");
+            }
+
+            if (format_flags & WINED3DFMT_FLAG_STENCIL)
+            {
+                GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT,
+                        GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
+                checkGLcall("glFramebufferRenderbufferEXT()");
+            }
+        }
+        else
+        {
+            context_apply_attachment_filter_states(depth_stencil, TRUE);
+
+            if (format_flags & WINED3DFMT_FLAG_DEPTH)
+            {
+                GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT,
+                        depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
+                        depth_stencil_impl->texture_level));
+                checkGLcall("glFramebufferTexture2DEXT()");
+            }
+
+            if (format_flags & WINED3DFMT_FLAG_STENCIL)
+            {
+                GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT,
+                        depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
+                        depth_stencil_impl->texture_level));
+                checkGLcall("glFramebufferTexture2DEXT()");
+            }
+        }
 
 
-            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, depth_stencil_impl->glDescription.target,
-                        depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
+        if (!(format_flags & WINED3DFMT_FLAG_DEPTH))
+        {
+            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
             checkGLcall("glFramebufferTexture2DEXT()");
         }
             checkGLcall("glFramebufferTexture2DEXT()");
         }
-    } else {
+
+        if (!(format_flags & WINED3DFMT_FLAG_STENCIL))
+        {
+            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+            checkGLcall("glFramebufferTexture2DEXT()");
+        }
+    }
+    else
+    {
         GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
         checkGLcall("glFramebufferTexture2DEXT()");
         GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
         checkGLcall("glFramebufferTexture2DEXT()");
+
+        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2DEXT()");
     }
 }
 
     }
 }
 
-void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
+/* GL locking is done by the caller */
+void context_attach_surface_fbo(const struct wined3d_context *context,
+        GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
 {
     const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
 {
     const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("Attach surface %p to %u\n", surface, idx);
 
     if (surface)
     {
 
     TRACE("Attach surface %p to %u\n", surface, idx);
 
     if (surface)
     {
-        context_apply_attachment_filter_states((IWineD3DDevice *)This, surface, TRUE);
+        context_apply_attachment_filter_states(surface, TRUE);
 
 
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->glDescription.target,
-                surface_impl->glDescription.textureName, surface_impl->glDescription.level));
+        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->texture_target,
+                surface_impl->texture_name, surface_impl->texture_level));
         checkGLcall("glFramebufferTexture2DEXT()");
     } else {
         GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
         checkGLcall("glFramebufferTexture2DEXT()");
     } else {
         GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
@@ -180,9 +271,10 @@ void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWO
     }
 }
 
     }
 }
 
-static void context_check_fbo_status(IWineD3DDevice *iface)
+/* GL locking is done by the caller */
+static void context_check_fbo_status(struct wined3d_context *context)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     GLenum status;
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
     GLenum status;
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
@@ -197,7 +289,7 @@ static void context_check_fbo_status(IWineD3DDevice *iface)
         /* Dump the FBO attachments */
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
         /* Dump the FBO attachments */
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
-            attachment = (IWineD3DSurfaceImpl *)This->activeContext->current_fbo->render_targets[i];
+            attachment = (IWineD3DSurfaceImpl *)context->current_fbo->render_targets[i];
             if (attachment)
             {
                 FIXME("\tColor attachment %d: (%p) %s %ux%u\n",
             if (attachment)
             {
                 FIXME("\tColor attachment %d: (%p) %s %ux%u\n",
@@ -205,7 +297,7 @@ static void context_check_fbo_status(IWineD3DDevice *iface)
                         attachment->pow2Width, attachment->pow2Height);
             }
         }
                         attachment->pow2Width, attachment->pow2Height);
             }
         }
-        attachment = (IWineD3DSurfaceImpl *)This->activeContext->current_fbo->depth_stencil;
+        attachment = (IWineD3DSurfaceImpl *)context->current_fbo->depth_stencil;
         if (attachment)
         {
             FIXME("\tDepth attachment: (%p) %s %ux%u\n",
         if (attachment)
         {
             FIXME("\tDepth attachment: (%p) %s %ux%u\n",
@@ -215,113 +307,270 @@ static void context_check_fbo_status(IWineD3DDevice *iface)
     }
 }
 
     }
 }
 
-static struct fbo_entry *context_create_fbo_entry(IWineD3DDevice *iface)
+static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     struct fbo_entry *entry;
 
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
     entry->render_targets = HeapAlloc(GetProcessHeap(), 0, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
     struct fbo_entry *entry;
 
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
     entry->render_targets = HeapAlloc(GetProcessHeap(), 0, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
-    memcpy(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
-    entry->depth_stencil = This->stencilBufferTarget;
+    memcpy(entry->render_targets, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
+    entry->depth_stencil = device->stencilBufferTarget;
     entry->attached = FALSE;
     entry->id = 0;
 
     return entry;
 }
 
     entry->attached = FALSE;
     entry->id = 0;
 
     return entry;
 }
 
-static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, struct fbo_entry *entry)
+/* GL locking is done by the caller */
+static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+{
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id);
+    context_clean_fbo_attachments(gl_info);
+
+    memcpy(entry->render_targets, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
+    entry->depth_stencil = device->stencilBufferTarget;
+    entry->attached = FALSE;
+}
+
+/* GL locking is done by the caller */
+static void context_destroy_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
 {
     if (entry->id)
     {
         TRACE("Destroy FBO %d\n", entry->id);
 {
     if (entry->id)
     {
         TRACE("Destroy FBO %d\n", entry->id);
-        context_destroy_fbo(This, &entry->id);
+        context_destroy_fbo(context, &entry->id);
     }
     }
+    --context->fbo_entry_count;
     list_remove(&entry->entry);
     HeapFree(GetProcessHeap(), 0, entry->render_targets);
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
 
     list_remove(&entry->entry);
     HeapFree(GetProcessHeap(), 0, entry->render_targets);
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
 
-static struct fbo_entry *context_find_fbo_entry(IWineD3DDevice *iface, WineD3DContext *context)
+/* GL locking is done by the caller */
+static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     struct fbo_entry *entry;
 
     LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
     {
     struct fbo_entry *entry;
 
     LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
     {
-        if (!memcmp(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets))
-                && entry->depth_stencil == This->stencilBufferTarget)
+        if (!memcmp(entry->render_targets, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets))
+                && entry->depth_stencil == device->stencilBufferTarget)
         {
         {
+            list_remove(&entry->entry);
+            list_add_head(&context->fbo_list, &entry->entry);
             return entry;
         }
     }
 
             return entry;
         }
     }
 
-    entry = context_create_fbo_entry(iface);
-    list_add_head(&context->fbo_list, &entry->entry);
+    if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
+    {
+        entry = context_create_fbo_entry(context);
+        list_add_head(&context->fbo_list, &entry->entry);
+        ++context->fbo_entry_count;
+    }
+    else
+    {
+        entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry);
+        context_reuse_fbo_entry(context, entry);
+        list_remove(&entry->entry);
+        list_add_head(&context->fbo_list, &entry->entry);
+    }
+
     return entry;
 }
 
     return entry;
 }
 
-static void context_apply_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *entry)
+/* GL locking is done by the caller */
+static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i;
 
     unsigned int i;
 
-    context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &entry->id);
+    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id);
 
     if (!entry->attached)
     {
         /* Apply render targets */
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
 
     if (!entry->attached)
     {
         /* Apply render targets */
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
-            IWineD3DSurface *render_target = This->render_targets[i];
-            context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, i, render_target);
+            IWineD3DSurface *render_target = device->render_targets[i];
+            context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, i, render_target);
         }
 
         /* Apply depth targets */
         }
 
         /* Apply depth targets */
-        if (This->stencilBufferTarget) {
-            unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
-            unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
+        if (device->stencilBufferTarget)
+        {
+            unsigned int w = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Width;
+            unsigned int h = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Height;
 
 
-            surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
+            surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h);
         }
         }
-        context_attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, This->stencilBufferTarget, TRUE);
+        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, device->stencilBufferTarget, TRUE);
 
         entry->attached = TRUE;
     } else {
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
 
         entry->attached = TRUE;
     } else {
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
-            if (This->render_targets[i])
-                context_apply_attachment_filter_states(iface, This->render_targets[i], FALSE);
+            if (device->render_targets[i])
+                context_apply_attachment_filter_states(device->render_targets[i], FALSE);
         }
         }
-        if (This->stencilBufferTarget)
-            context_apply_attachment_filter_states(iface, This->stencilBufferTarget, FALSE);
+        if (device->stencilBufferTarget)
+            context_apply_attachment_filter_states(device->stencilBufferTarget, FALSE);
     }
 
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
     }
 
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
-        if (This->render_targets[i])
-            This->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
+        if (device->render_targets[i])
+            device->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
         else
         else
-            This->draw_buffers[i] = GL_NONE;
+            device->draw_buffers[i] = GL_NONE;
     }
 }
 
     }
 }
 
-static void context_apply_fbo_state(IWineD3DDevice *iface)
+/* GL locking is done by the caller */
+static void context_apply_fbo_state(struct wined3d_context *context)
 {
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3DContext *context = This->activeContext;
-
-    if (This->render_offscreen)
+    if (context->render_offscreen)
     {
     {
-        context->current_fbo = context_find_fbo_entry(iface, context);
-        context_apply_fbo_entry(iface, context->current_fbo);
+        context->current_fbo = context_find_fbo_entry(context);
+        context_apply_fbo_entry(context, context->current_fbo);
     } else {
         context->current_fbo = NULL;
     } else {
         context->current_fbo = NULL;
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
     }
 
     }
 
-    context_check_fbo_status(iface);
+    context_check_fbo_status(context);
+}
+
+/* Context activation is done by the caller. */
+void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (context->free_occlusion_query_count)
+    {
+        query->id = context->free_occlusion_queries[--context->free_occlusion_query_count];
+    }
+    else
+    {
+        if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
+        {
+            ENTER_GL();
+            GL_EXTCALL(glGenQueriesARB(1, &query->id));
+            checkGLcall("glGenQueriesARB");
+            LEAVE_GL();
+
+            TRACE("Allocated occlusion query %u in context %p.\n", query->id, context);
+        }
+        else
+        {
+            WARN("Occlusion queries not supported, not allocating query id.\n");
+            query->id = 0;
+        }
+    }
+
+    query->context = context;
+    list_add_head(&context->occlusion_queries, &query->entry);
+}
+
+void context_free_occlusion_query(struct wined3d_occlusion_query *query)
+{
+    struct wined3d_context *context = query->context;
+
+    list_remove(&query->entry);
+    query->context = NULL;
+
+    if (context->free_occlusion_query_count >= context->free_occlusion_query_size - 1)
+    {
+        UINT new_size = context->free_occlusion_query_size << 1;
+        GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_occlusion_queries,
+                new_size * sizeof(*context->free_occlusion_queries));
+
+        if (!new_data)
+        {
+            ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
+            return;
+        }
+
+        context->free_occlusion_query_size = new_size;
+        context->free_occlusion_queries = new_data;
+    }
+
+    context->free_occlusion_queries[context->free_occlusion_query_count++] = query->id;
+}
+
+/* Context activation is done by the caller. */
+void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (context->free_event_query_count)
+    {
+        query->id = context->free_event_queries[--context->free_event_query_count];
+    }
+    else
+    {
+        if (GL_SUPPORT(APPLE_FENCE))
+        {
+            ENTER_GL();
+            GL_EXTCALL(glGenFencesAPPLE(1, &query->id));
+            checkGLcall("glGenFencesAPPLE");
+            LEAVE_GL();
+
+            TRACE("Allocated event query %u in context %p.\n", query->id, context);
+        }
+        else if(GL_SUPPORT(NV_FENCE))
+        {
+            ENTER_GL();
+            GL_EXTCALL(glGenFencesNV(1, &query->id));
+            checkGLcall("glGenFencesNV");
+            LEAVE_GL();
+
+            TRACE("Allocated event query %u in context %p.\n", query->id, context);
+        }
+        else
+        {
+            WARN("Event queries not supported, not allocating query id.\n");
+            query->id = 0;
+        }
+    }
+
+    query->context = context;
+    list_add_head(&context->event_queries, &query->entry);
+}
+
+void context_free_event_query(struct wined3d_event_query *query)
+{
+    struct wined3d_context *context = query->context;
+
+    list_remove(&query->entry);
+    query->context = NULL;
+
+    if (context->free_event_query_count >= context->free_event_query_size - 1)
+    {
+        UINT new_size = context->free_event_query_size << 1;
+        GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
+                new_size * sizeof(*context->free_event_queries));
+
+        if (!new_data)
+        {
+            ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
+            return;
+        }
+
+        context->free_event_query_size = new_size;
+        context->free_event_queries = new_data;
+    }
+
+    context->free_event_queries[context->free_event_query_count++] = query->id;
 }
 
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
 }
 
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
@@ -329,15 +578,25 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     UINT i;
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     UINT i;
 
+    if (!This->d3d_initialized) return;
+
     switch(type)
     {
         case WINED3DRTYPE_SURFACE:
         {
     switch(type)
     {
         case WINED3DRTYPE_SURFACE:
         {
+            ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
             for (i = 0; i < This->numContexts; ++i)
             {
             for (i = 0; i < This->numContexts; ++i)
             {
+                struct wined3d_context *context = This->contexts[i];
+                const struct wined3d_gl_info *gl_info = context->gl_info;
                 struct fbo_entry *entry, *entry2;
 
                 struct fbo_entry *entry, *entry2;
 
-                LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->contexts[i]->fbo_list, struct fbo_entry, entry)
+                if (context->current_rt == (IWineD3DSurface *)resource) context->current_rt = NULL;
+
+                ENTER_GL();
+
+                LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
                 {
                     BOOL destroyed = FALSE;
                     UINT j;
                 {
                     BOOL destroyed = FALSE;
                     UINT j;
@@ -346,14 +605,16 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
                     {
                         if (entry->render_targets[j] == (IWineD3DSurface *)resource)
                         {
                     {
                         if (entry->render_targets[j] == (IWineD3DSurface *)resource)
                         {
-                            context_destroy_fbo_entry(This, entry);
+                            context_destroy_fbo_entry(context, entry);
                             destroyed = TRUE;
                         }
                     }
 
                     if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource)
                             destroyed = TRUE;
                         }
                     }
 
                     if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource)
-                        context_destroy_fbo_entry(This, entry);
+                        context_destroy_fbo_entry(context, entry);
                 }
                 }
+
+                LEAVE_GL();
             }
 
             break;
             }
 
             break;
@@ -364,6 +625,156 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
     }
 }
 
     }
 }
 
+static void context_destroy_gl_resources(struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_occlusion_query *occlusion_query;
+    struct wined3d_event_query *event_query;
+    struct fbo_entry *entry, *entry2;
+    BOOL has_glctx;
+
+    has_glctx = pwglMakeCurrent(context->hdc, context->glCtx);
+    if (!has_glctx) WARN("Failed to activate context. Window already destroyed?\n");
+
+    ENTER_GL();
+
+    LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry)
+    {
+        if (has_glctx && GL_SUPPORT(ARB_OCCLUSION_QUERY)) GL_EXTCALL(glDeleteQueriesARB(1, &occlusion_query->id));
+        occlusion_query->context = NULL;
+    }
+
+    LIST_FOR_EACH_ENTRY(event_query, &context->event_queries, struct wined3d_event_query, entry)
+    {
+        if (has_glctx)
+        {
+            if (GL_SUPPORT(APPLE_FENCE)) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->id));
+            else if (GL_SUPPORT(NV_FENCE)) GL_EXTCALL(glDeleteFencesNV(1, &event_query->id));
+        }
+        event_query->context = NULL;
+    }
+
+    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) {
+        if (!has_glctx) entry->id = 0;
+        context_destroy_fbo_entry(context, entry);
+    }
+    if (has_glctx)
+    {
+        if (context->src_fbo)
+        {
+            TRACE("Destroy src FBO %d\n", context->src_fbo);
+            context_destroy_fbo(context, &context->src_fbo);
+        }
+        if (context->dst_fbo)
+        {
+            TRACE("Destroy dst FBO %d\n", context->dst_fbo);
+            context_destroy_fbo(context, &context->dst_fbo);
+        }
+        if (context->dummy_arbfp_prog)
+        {
+            GL_EXTCALL(glDeleteProgramsARB(1, &context->dummy_arbfp_prog));
+        }
+
+        if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
+            GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
+
+        if (GL_SUPPORT(APPLE_FENCE))
+            GL_EXTCALL(glDeleteFencesAPPLE(context->free_event_query_count, context->free_event_queries));
+        else if (GL_SUPPORT(NV_FENCE))
+            GL_EXTCALL(glDeleteFencesNV(context->free_event_query_count, context->free_event_queries));
+
+        checkGLcall("context cleanup");
+    }
+
+    LEAVE_GL();
+
+    HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
+    HeapFree(GetProcessHeap(), 0, context->free_event_queries);
+
+    if (!pwglMakeCurrent(NULL, NULL))
+    {
+        ERR("Failed to disable GL context.\n");
+    }
+
+    if (context->isPBuffer)
+    {
+        GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc));
+        GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer));
+    }
+    else
+    {
+        ReleaseDC(context->win_handle, context->hdc);
+    }
+
+    if (!pwglDeleteContext(context->glCtx))
+    {
+        DWORD err = GetLastError();
+        ERR("wglDeleteContext(%p) failed, last error %#x.\n", context->glCtx, err);
+    }
+}
+
+DWORD context_get_tls_idx(void)
+{
+    return wined3d_context_tls_idx;
+}
+
+void context_set_tls_idx(DWORD idx)
+{
+    wined3d_context_tls_idx = idx;
+}
+
+struct wined3d_context *context_get_current(void)
+{
+    return TlsGetValue(wined3d_context_tls_idx);
+}
+
+BOOL context_set_current(struct wined3d_context *ctx)
+{
+    struct wined3d_context *old = context_get_current();
+
+    if (old == ctx)
+    {
+        TRACE("Already using D3D context %p.\n", ctx);
+        return TRUE;
+    }
+
+    if (old)
+    {
+        if (old->destroyed)
+        {
+            TRACE("Switching away from destroyed context %p.\n", old);
+            context_destroy_gl_resources(old);
+            HeapFree(GetProcessHeap(), 0, old);
+        }
+        else
+        {
+            old->current = 0;
+        }
+    }
+
+    if (ctx)
+    {
+        TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->hdc);
+        if (!pwglMakeCurrent(ctx->hdc, ctx->glCtx))
+        {
+            ERR("Failed to make GL context %p current on device context %p.\n", ctx->glCtx, ctx->hdc);
+            return FALSE;
+        }
+        ctx->current = 1;
+    }
+    else
+    {
+        TRACE("Clearing current D3D context.\n");
+        if (!pwglMakeCurrent(NULL, NULL))
+        {
+            ERR("Failed to clear current GL context.\n");
+            return FALSE;
+        }
+    }
+
+    return TlsSetValue(wined3d_context_tls_idx, ctx);
+}
+
 /*****************************************************************************
  * Context_MarkStateDirty
  *
 /*****************************************************************************
  * Context_MarkStateDirty
  *
@@ -377,12 +788,13 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
  *  StateTable: Pointer to the state table in use(for state grouping)
  *
  *****************************************************************************/
  *  StateTable: Pointer to the state table in use(for state grouping)
  *
  *****************************************************************************/
-static void Context_MarkStateDirty(WineD3DContext *context, DWORD state, const struct StateEntry *StateTable) {
+static void Context_MarkStateDirty(struct wined3d_context *context, DWORD state, const struct StateEntry *StateTable)
+{
     DWORD rep = StateTable[state].representative;
     DWORD idx;
     BYTE shift;
 
     DWORD rep = StateTable[state].representative;
     DWORD idx;
     BYTE shift;
 
-    if(!rep || isStateDirty(context, rep)) return;
+    if (isStateDirty(context, rep)) return;
 
     context->dirtyArray[context->numDirtyEntries++] = rep;
     idx = rep >> 5;
 
     context->dirtyArray[context->numDirtyEntries++] = rep;
     idx = rep >> 5;
@@ -406,8 +818,10 @@ static void Context_MarkStateDirty(WineD3DContext *context, DWORD state, const s
  *  pbuffer: optional pbuffer used with this context
  *
  *****************************************************************************/
  *  pbuffer: optional pbuffer used with this context
  *
  *****************************************************************************/
-static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) {
-    WineD3DContext **oldArray = This->contexts;
+static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This,
+        HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer)
+{
+    struct wined3d_context **oldArray = This->contexts;
     DWORD state;
 
     This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1));
     DWORD state;
 
     This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1));
@@ -420,7 +834,7 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand
         memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts);
     }
 
         memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts);
     }
 
-    This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineD3DContext));
+    This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This->contexts));
     if(This->contexts[This->numContexts] == NULL) {
         ERR("Unable to allocate a new context\n");
         HeapFree(GetProcessHeap(), 0, This->contexts);
     if(This->contexts[This->numContexts] == NULL) {
         ERR("Unable to allocate a new context\n");
         HeapFree(GetProcessHeap(), 0, This->contexts);
@@ -437,7 +851,8 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand
     /* Mark all states dirty to force a proper initialization of the states on the first use of the context
      */
     for(state = 0; state <= STATE_HIGHEST; state++) {
     /* Mark all states dirty to force a proper initialization of the states on the first use of the context
      */
     for(state = 0; state <= STATE_HIGHEST; state++) {
-        Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
+        if (This->StateTable[state].representative)
+            Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
     }
 
     This->numContexts++;
     }
 
     This->numContexts++;
@@ -636,12 +1051,15 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc,
  *  pPresentParameters: contains the pixelformats to use for onscreen rendering
  *
  *****************************************************************************/
  *  pPresentParameters: contains the pixelformats to use for onscreen rendering
  *
  *****************************************************************************/
-WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) {
-    HDC oldDrawable, hdc;
+struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target,
+        HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms)
+{
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    struct wined3d_context *ret = NULL;
     HPBUFFERARB pbuffer = NULL;
     HPBUFFERARB pbuffer = NULL;
-    HGLRC ctx = NULL, oldCtx;
-    WineD3DContext *ret = NULL;
     unsigned int s;
     unsigned int s;
+    HGLRC ctx;
+    HDC hdc;
 
     TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
 
 
     TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
 
@@ -757,7 +1175,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
         /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
         if(!iPixelFormat) {
             ERR("Can't find a suitable iPixelFormat\n");
         /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
         if(!iPixelFormat) {
             ERR("Can't find a suitable iPixelFormat\n");
-            return FALSE;
+            return NULL;
         }
 
         DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
         }
 
         DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
@@ -776,7 +1194,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
 
                 if(!res) {
                     ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
 
                 if(!res) {
                     ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
-                    return FALSE;
+                    return NULL;
                 }
             } else if(oldPixelFormat) {
                 /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
                 }
             } else if(oldPixelFormat) {
                 /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
@@ -784,13 +1202,21 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
                 ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
             } else {
                 ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
                 ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
             } else {
                 ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
-                return FALSE;
+                return NULL;
             }
         }
     }
 
     ctx = pwglCreateContext(hdc);
             }
         }
     }
 
     ctx = pwglCreateContext(hdc);
-    if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
+    if (This->numContexts)
+    {
+        if (!pwglShareLists(This->contexts[0]->glCtx, ctx))
+        {
+            DWORD err = GetLastError();
+            ERR("wglShareLists(%p, %p) failed, last error %#x.\n",
+                    This->contexts[0]->glCtx, ctx, err);
+        }
+    }
 
     if(!ctx) {
         ERR("Failed to create a WGL context\n");
 
     if(!ctx) {
         ERR("Failed to create a WGL context\n");
@@ -803,14 +1229,20 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
     ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer);
     if(!ret) {
         ERR("Failed to add the newly created context to the context list\n");
     ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer);
     if(!ret) {
         ERR("Failed to add the newly created context to the context list\n");
-        pwglDeleteContext(ctx);
+        if (!pwglDeleteContext(ctx))
+        {
+            DWORD err = GetLastError();
+            ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err);
+        }
         if(create_pbuffer) {
             GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
             GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
         }
         goto out;
     }
         if(create_pbuffer) {
             GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
             GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
         }
         goto out;
     }
+    ret->gl_info = &This->adapter->gl_info;
     ret->surface = (IWineD3DSurface *) target;
     ret->surface = (IWineD3DSurface *) target;
+    ret->current_rt = (IWineD3DSurface *)target;
     ret->isPBuffer = create_pbuffer;
     ret->tid = GetCurrentThreadId();
     if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) {
     ret->isPBuffer = create_pbuffer;
     ret->tid = GetCurrentThreadId();
     if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) {
@@ -825,18 +1257,27 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
                 sizeof(*ret->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
     }
 
                 sizeof(*ret->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
     }
 
+    ret->free_occlusion_query_size = 4;
+    ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0,
+            ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries));
+    if (!ret->free_occlusion_queries) goto out;
+
+    list_init(&ret->occlusion_queries);
+
+    ret->free_event_query_size = 4;
+    ret->free_event_queries = HeapAlloc(GetProcessHeap(), 0,
+            ret->free_event_query_size * sizeof(*ret->free_event_queries));
+    if (!ret->free_event_queries) goto out;
+
+    list_init(&ret->event_queries);
+
     TRACE("Successfully created new context %p\n", ret);
 
     list_init(&ret->fbo_list);
 
     /* Set up the context defaults */
     TRACE("Successfully created new context %p\n", ret);
 
     list_init(&ret->fbo_list);
 
     /* Set up the context defaults */
-    oldCtx  = pwglGetCurrentContext();
-    oldDrawable = pwglGetCurrentDC();
-    if(oldCtx && oldDrawable) {
-        /* See comment in ActivateContext context switching */
-        This->frag_pipe->enable_extension((IWineD3DDevice *) This, FALSE);
-    }
-    if(pwglMakeCurrent(hdc, ctx) == FALSE) {
+    if (!context_set_current(ret))
+    {
         ERR("Cannot activate context to set up defaults\n");
         goto out;
     }
         ERR("Cannot activate context to set up defaults\n");
         goto out;
     }
@@ -847,7 +1288,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
 
     TRACE("Setting up the screen\n");
     /* Clear the screen */
 
     TRACE("Setting up the screen\n");
     /* Clear the screen */
-    glClearColor(1.0, 0.0, 0.0, 0.0);
+    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
     checkGLcall("glClearColor");
     glClearIndex(0);
     glClearDepth(1);
     checkGLcall("glClearColor");
     glClearIndex(0);
     glClearDepth(1);
@@ -891,30 +1332,54 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
         for(s = 1; s < GL_LIMITS(textures); s++) {
             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
         for(s = 1; s < GL_LIMITS(textures); s++) {
             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
-            checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...\n");
+            checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...");
         }
     }
         }
     }
+    if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
+        /* MacOS(radeon X1600 at least, but most likely others too) refuses to draw if GLSL and ARBFP are
+         * enabled, but the currently bound arbfp program is 0. Enabling ARBFP with prog 0 is invalid, but
+         * GLSL should bypass this. This causes problems in programs that never use the fixed function pipeline,
+         * because the ARBFP extension is enabled by the ARBFP pipeline at context creation, but no program
+         * is ever assigned.
+         *
+         * So make sure a program is assigned to each context. The first real ARBFP use will set a different
+         * program and the dummy program is destroyed when the context is destroyed.
+         */
+        const char *dummy_program =
+                "!!ARBfp1.0\n"
+                "MOV result.color, fragment.color.primary;\n"
+                "END\n";
+        GL_EXTCALL(glGenProgramsARB(1, &ret->dummy_arbfp_prog));
+        GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ret->dummy_arbfp_prog));
+        GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(dummy_program), dummy_program));
+    }
 
     for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
         glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
 
     for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
         glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
-        checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
+        checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)");
     }
     }
-    LEAVE_GL();
 
 
-    /* Never keep GL_FRAGMENT_SHADER_ATI enabled on a context that we switch away from,
-     * but enable it for the first context we create, and reenable it on the old context
-     */
-    if(oldDrawable && oldCtx) {
-        pwglMakeCurrent(oldDrawable, oldCtx);
-    } else {
-        last_device = This;
+    if (GL_SUPPORT(EXT_PROVOKING_VERTEX))
+    {
+        GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
     }
     }
+
+    LEAVE_GL();
+
     This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE);
 
     return ret;
 
 out:
     This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE);
 
     return ret;
 
 out:
+    if (ret)
+    {
+        HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
+        HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
+        HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
+        HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty);
+        HeapFree(GetProcessHeap(), 0, ret);
+    }
     return NULL;
 }
 
     return NULL;
 }
 
@@ -932,8 +1397,9 @@ out:
  *  context: Context to remove
  *
  *****************************************************************************/
  *  context: Context to remove
  *
  *****************************************************************************/
-static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *context) {
-    WineD3DContext **new_array;
+static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_context *context)
+{
+    struct wined3d_context **new_array;
     BOOL found = FALSE;
     UINT i;
 
     BOOL found = FALSE;
     UINT i;
 
@@ -943,7 +1409,6 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *con
     {
         if (This->contexts[i] == context)
         {
     {
         if (This->contexts[i] == context)
         {
-            HeapFree(GetProcessHeap(), 0, context);
             found = TRUE;
             break;
         }
             found = TRUE;
             break;
         }
@@ -989,52 +1454,35 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *con
  *  context: Context to destroy
  *
  *****************************************************************************/
  *  context: Context to destroy
  *
  *****************************************************************************/
-void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
-    struct fbo_entry *entry, *entry2;
+void DestroyContext(IWineD3DDeviceImpl *This, struct wined3d_context *context)
+{
+    BOOL destroy;
 
     TRACE("Destroying ctx %p\n", context);
 
 
     TRACE("Destroying ctx %p\n", context);
 
-    /* The correct GL context needs to be active to cleanup the GL resources below */
-    if(pwglGetCurrentContext() != context->glCtx){
-        pwglMakeCurrent(context->hdc, context->glCtx);
-        last_device = NULL;
-    }
-
-    ENTER_GL();
+    if (context->tid == GetCurrentThreadId() || !context->current)
+    {
+        context_destroy_gl_resources(context);
+        destroy = TRUE;
 
 
-    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) {
-        context_destroy_fbo_entry(This, entry);
-    }
-    if (context->src_fbo) {
-        TRACE("Destroy src FBO %d\n", context->src_fbo);
-        context_destroy_fbo(This, &context->src_fbo);
-    }
-    if (context->dst_fbo) {
-        TRACE("Destroy dst FBO %d\n", context->dst_fbo);
-        context_destroy_fbo(This, &context->dst_fbo);
+        if (!context_set_current(NULL))
+        {
+            ERR("Failed to clear current D3D context.\n");
+        }
     }
     }
-
-    LEAVE_GL();
-
-    if (This->activeContext == context)
+    else
     {
     {
-        This->activeContext = NULL;
-        TRACE("Destroying the active context.\n");
+        context->destroyed = 1;
+        destroy = FALSE;
     }
 
     }
 
-    /* Cleanup the GL context */
-    pwglMakeCurrent(NULL, NULL);
-    if(context->isPBuffer) {
-        GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc));
-        GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer));
-    } else ReleaseDC(context->win_handle, context->hdc);
-    pwglDeleteContext(context->glCtx);
-
     HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
     HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
     RemoveContextFromArray(This, context);
     HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
     HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
     RemoveContextFromArray(This, context);
+    if (destroy) HeapFree(GetProcessHeap(), 0, context);
 }
 
 }
 
+/* GL locking is done by the caller */
 static inline void set_blit_dimension(UINT width, UINT height) {
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
 static inline void set_blit_dimension(UINT width, UINT height) {
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
@@ -1064,14 +1512,20 @@ static inline void set_blit_dimension(UINT width, UINT height) {
  *  height: render target height
  *
  *****************************************************************************/
  *  height: render target height
  *
  *****************************************************************************/
-static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
-    int i, sampler;
+/* Context activation is done by the caller. */
+static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *context, UINT width, UINT height)
+{
+    int i;
     const struct StateEntry *StateTable = This->StateTable;
     const struct StateEntry *StateTable = This->StateTable;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    DWORD sampler;
 
     TRACE("Setting up context %p for blitting\n", context);
     if(context->last_was_blit) {
         if(context->blit_w != width || context->blit_h != height) {
 
     TRACE("Setting up context %p for blitting\n", context);
     if(context->last_was_blit) {
         if(context->blit_w != width || context->blit_h != height) {
+            ENTER_GL();
             set_blit_dimension(width, height);
             set_blit_dimension(width, height);
+            LEAVE_GL();
             context->blit_w = width; context->blit_h = height;
             /* No need to dirtify here, the states are still dirtified because they weren't
              * applied since the last SetupForBlit call. Otherwise last_was_blit would not
             context->blit_w = width; context->blit_h = height;
             /* No need to dirtify here, the states are still dirtified because they weren't
              * applied since the last SetupForBlit call. Otherwise last_was_blit would not
@@ -1086,7 +1540,10 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     /* TODO: Use a display list */
 
     /* Disable shaders */
     /* TODO: Use a display list */
 
     /* Disable shaders */
-    This->shader_backend->shader_select((IWineD3DDevice *)This, FALSE, FALSE);
+    ENTER_GL();
+    This->shader_backend->shader_select(context, FALSE, FALSE);
+    LEAVE_GL();
+
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
@@ -1124,7 +1581,8 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
 
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
 
-        if (sampler != -1) {
+        if (sampler != WINED3D_UNMAPPED_STAGE)
+        {
             if (sampler < MAX_TEXTURES) {
                 Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
             }
             if (sampler < MAX_TEXTURES) {
                 Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
             }
@@ -1159,11 +1617,12 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
         glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
                   GL_TEXTURE_LOD_BIAS_EXT,
     if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
         glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
                   GL_TEXTURE_LOD_BIAS_EXT,
-                  0.0);
+                  0.0f);
         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
     }
 
         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
     }
 
-    if (sampler != -1) {
+    if (sampler != WINED3D_UNMAPPED_STAGE)
+    {
         if (sampler < MAX_TEXTURES) {
             Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + sampler), StateTable);
             Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
         if (sampler < MAX_TEXTURES) {
             Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + sampler), StateTable);
             Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
@@ -1203,7 +1662,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     }
     glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
     checkGLcall("glColorMask");
     }
     glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
     checkGLcall("glColorMask");
-    Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
+    Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE), StateTable);
     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
         glDisable(GL_COLOR_SUM_EXT);
         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable);
     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
         glDisable(GL_COLOR_SUM_EXT);
         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable);
@@ -1227,9 +1686,11 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
     glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
     glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
     glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
     glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
-    LEAVE_GL();
 
     set_blit_dimension(width, height);
 
     set_blit_dimension(width, height);
+
+    LEAVE_GL();
+
     context->blit_w = width; context->blit_h = height;
     Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
     context->blit_w = width; context->blit_h = height;
     Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
@@ -1245,7 +1706,8 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
  * If none can be found the swapchain is requested to create a new context
  *
  *****************************************************************************/
  * If none can be found the swapchain is requested to create a new context
  *
  *****************************************************************************/
-static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid) {
+static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid)
+{
     unsigned int i;
 
     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
     unsigned int i;
 
     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
@@ -1271,34 +1733,44 @@ static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchai
  * Returns: The needed context
  *
  *****************************************************************************/
  * Returns: The needed context
  *
  *****************************************************************************/
-static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid) {
+static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid)
+{
     IWineD3DSwapChain *swapchain = NULL;
     IWineD3DSwapChain *swapchain = NULL;
-    BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
-    WineD3DContext *context = This->activeContext;
-    BOOL oldRenderOffscreen = This->render_offscreen;
-    const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)This->lastActiveRenderTarget)->resource.format_desc;
-    const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc;
+    struct wined3d_context *current_context = context_get_current();
     const struct StateEntry *StateTable = This->StateTable;
     const struct StateEntry *StateTable = This->StateTable;
+    struct wined3d_context *context;
+    BOOL old_render_offscreen;
 
 
-    /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
-     * the alpha blend state changes with different render target formats
-     */
-    if (old->format != new->format)
+    if (current_context && current_context->destroyed) current_context = NULL;
+
+    if (!target)
     {
     {
-        /* Disable blending when the alpha mask has changed and when a format doesn't support blending */
-        if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
-                || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+        if (current_context
+                && current_context->current_rt
+                && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.wineD3DDevice == This)
         {
         {
-            Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
+            target = current_context->current_rt;
+        }
+        else
+        {
+            IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
+            if (swapchain->backBuffer) target = swapchain->backBuffer[0];
+            else target = swapchain->frontBuffer;
         }
     }
 
         }
     }
 
+    if (current_context && current_context->current_rt == target)
+    {
+        return current_context;
+    }
+
     if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
         TRACE("Rendering onscreen\n");
 
         context = findThreadContextForSwapChain(swapchain, tid);
 
     if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
         TRACE("Rendering onscreen\n");
 
         context = findThreadContextForSwapChain(swapchain, tid);
 
-        This->render_offscreen = FALSE;
+        old_render_offscreen = context->render_offscreen;
+        context->render_offscreen = FALSE;
         /* The context != This->activeContext will catch a NOP context change. This can occur
          * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
          * rendering. No context change is needed in that case
         /* The context != This->activeContext will catch a NOP context change. This can occur
          * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
          * rendering. No context change is needed in that case
@@ -1310,157 +1782,161 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
             }
         }
         IWineD3DSwapChain_Release(swapchain);
             }
         }
         IWineD3DSwapChain_Release(swapchain);
-
-        if(oldRenderOffscreen) {
-            Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable);
-            Context_MarkStateDirty(context, STATE_VDECL, StateTable);
-            Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
-            Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
-            Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
-        }
-
-    } else {
+    }
+    else
+    {
         TRACE("Rendering offscreen\n");
         TRACE("Rendering offscreen\n");
-        This->render_offscreen = TRUE;
 
 
-        switch(wined3d_settings.offscreen_rendering_mode) {
-            case ORM_FBO:
-                /* FBOs do not need a different context. Stay with whatever context is active at the moment */
-                if(This->activeContext && tid == This->lastThread) {
-                    context = This->activeContext;
-                } else {
-                    /* This may happen if the app jumps straight into offscreen rendering
-                     * Start using the context of the primary swapchain. tid == 0 is no problem
-                     * for findThreadContextForSwapChain.
-                     *
-                     * Can also happen on thread switches - in that case findThreadContextForSwapChain
-                     * is perfect to call.
-                     */
-                    context = findThreadContextForSwapChain(This->swapchains[0], tid);
-                }
-                break;
-
-            case ORM_PBUFFER:
+retry:
+        if (wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER)
+        {
+            IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *)target;
+            if (!This->pbufferContext
+                    || This->pbufferWidth < targetimpl->currentDesc.Width
+                    || This->pbufferHeight < targetimpl->currentDesc.Height)
             {
             {
-                IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *) target;
-                if(This->pbufferContext == NULL ||
-                   This->pbufferWidth < targetimpl->currentDesc.Width ||
-                   This->pbufferHeight < targetimpl->currentDesc.Height) {
-                    if(This->pbufferContext) {
-                        DestroyContext(This, This->pbufferContext);
-                    }
-
-                    /* The display is irrelevant here, the window is 0. But CreateContext needs a valid X connection.
-                     * Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
-                     */
-                    This->pbufferContext = CreateContext(This, targetimpl,
-                            ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0]->win_handle,
-                            TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms);
-                    This->pbufferWidth = targetimpl->currentDesc.Width;
-                    This->pbufferHeight = targetimpl->currentDesc.Height;
-                   }
-
-                   if(This->pbufferContext) {
-                       if(This->pbufferContext->tid != 0 && This->pbufferContext->tid != tid) {
-                           FIXME("The PBuffr context is only supported for one thread for now!\n");
-                       }
-                       This->pbufferContext->tid = tid;
-                       context = This->pbufferContext;
-                       break;
-                   } else {
-                       ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering\n");
-                       wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
-                   }
+                if (This->pbufferContext) DestroyContext(This, This->pbufferContext);
+
+                /* The display is irrelevant here, the window is 0. But
+                 * CreateContext needs a valid X connection. Create the context
+                 * on the same server as the primary swapchain. The primary
+                 * swapchain is exists at this point. */
+                This->pbufferContext = CreateContext(This, targetimpl,
+                        ((IWineD3DSwapChainImpl *)This->swapchains[0])->context[0]->win_handle,
+                        TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms);
+                This->pbufferWidth = targetimpl->currentDesc.Width;
+                This->pbufferHeight = targetimpl->currentDesc.Height;
             }
 
             }
 
-            case ORM_BACKBUFFER:
-                /* Stay with the currently active context for back buffer rendering */
-                if(This->activeContext && tid == This->lastThread) {
-                    context = This->activeContext;
-                } else {
-                    /* This may happen if the app jumps straight into offscreen rendering
-                     * Start using the context of the primary swapchain. tid == 0 is no problem
-                     * for findThreadContextForSwapChain.
-                     *
-                     * Can also happen on thread switches - in that case findThreadContextForSwapChain
-                     * is perfect to call.
-                     */
-                    context = findThreadContextForSwapChain(This->swapchains[0], tid);
+            if (This->pbufferContext)
+            {
+                if (This->pbufferContext->tid && This->pbufferContext->tid != tid)
+                {
+                    FIXME("The PBuffer context is only supported for one thread for now!\n");
                 }
                 }
-                break;
+                This->pbufferContext->tid = tid;
+                context = This->pbufferContext;
+            }
+            else
+            {
+                ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering.\n");
+                wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+                goto retry;
+            }
         }
         }
-
-        if(!oldRenderOffscreen) {
-            Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable);
-            Context_MarkStateDirty(context, STATE_VDECL, StateTable);
-            Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
-            Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
-            Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
+        else
+        {
+            /* Stay with the currently active context. */
+            if (current_context
+                    && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.wineD3DDevice == This)
+            {
+                context = current_context;
+            }
+            else
+            {
+                /* This may happen if the app jumps straight into offscreen rendering
+                 * Start using the context of the primary swapchain. tid == 0 is no problem
+                 * for findThreadContextForSwapChain.
+                 *
+                 * Can also happen on thread switches - in that case findThreadContextForSwapChain
+                 * is perfect to call. */
+                context = findThreadContextForSwapChain(This->swapchains[0], tid);
+            }
         }
         }
+
+        old_render_offscreen = context->render_offscreen;
+        context->render_offscreen = TRUE;
     }
 
     }
 
-    /* When switching away from an offscreen render target, and we're not using FBOs,
-     * we have to read the drawable into the texture. This is done via PreLoad(and
-     * SFLAG_INDRAWABLE set on the surface). There are some things that need care though.
-     * PreLoad needs a GL context, and FindContext is called before the context is activated.
-     * It also has to be called with the old rendertarget active, otherwise a wrong drawable
-     * is read. This leads to these possible situations:
-     *
-     * 0) lastActiveRenderTarget == target && oldTid == newTid:
-     *    Nothing to do, we don't even reach this code in this case...
-     *
-     * 1) lastActiveRenderTarget != target && oldTid == newTid:
-     *    The currently active context is OK for readback. Call PreLoad, and it
-     *    performs the read
-     *
-     * 2) lastActiveRenderTarget == target && oldTid != newTid:
-     *    Nothing to do - the drawable is unchanged
-     *
-     * 3) lastActiveRenderTarget != target && oldTid != newTid:
-     *    This is tricky. We have to get a context with the old drawable from somewhere
-     *    before we can switch to the new context. In this case, PreLoad calls
-     *    ActivateContext(lastActiveRenderTarget) from the new(current) thread. This
-     *    is case (2) then. The old drawable is activated for the new thread, and the
-     *    readback can be done. The recursed ActivateContext does *not* call PreLoad again.
-     *    After that, the outer ActivateContext(which calls PreLoad) can activate the new
-     *    target for the new thread
-     */
-    if (readTexture && This->lastActiveRenderTarget != target) {
-        BOOL oldInDraw = This->isInDraw;
+    if (context->render_offscreen != old_render_offscreen)
+    {
+        Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
+        Context_MarkStateDirty(context, STATE_VDECL, StateTable);
+        Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
+        Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
+        Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
+    }
 
 
-        /* PreLoad requires a context to load the texture, thus it will call ActivateContext.
-         * Set the isInDraw to true to signal PreLoad that it has a context. Will be tricky
-         * when using offscreen rendering with multithreading
-         */
-        This->isInDraw = TRUE;
+    /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
+     * the alpha blend state changes with different render target formats. */
+    if (!context->current_rt)
+    {
+        Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
+    }
+    else
+    {
+        const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.format_desc;
+        const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc;
 
 
-        /* Do that before switching the context:
-         * Read the back buffer of the old drawable into the destination texture
-         */
-        if(((IWineD3DSurfaceImpl *)This->lastActiveRenderTarget)->glDescription.srgbTextureName) {
-            surface_internal_preload(This->lastActiveRenderTarget, SRGB_BOTH);
-        } else {
-            surface_internal_preload(This->lastActiveRenderTarget, SRGB_RGB);
+        if (old->format != new->format)
+        {
+            /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
+            if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
+                    || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+            {
+                Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
+            }
         }
 
         }
 
-        /* Assume that the drawable will be modified by some other things now */
-        IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE);
+        /* When switching away from an offscreen render target, and we're not
+         * using FBOs, we have to read the drawable into the texture. This is
+         * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There
+         * are some things that need care though. PreLoad needs a GL context,
+         * and FindContext is called before the context is activated. It also
+         * has to be called with the old rendertarget active, otherwise a
+         * wrong drawable is read. */
+        if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+                && old_render_offscreen && context->current_rt != target)
+        {
+            BOOL oldInDraw = This->isInDraw;
+
+            /* surface_internal_preload() requires a context to load the
+             * texture, so it will call ActivateContext. Set isInDraw to true
+             * to signal surface_internal_preload() that it has a context. */
+
+            /* FIXME: This is just broken. There's no guarantee whatsoever
+             * that the currently active context, if any, is appropriate for
+             * reading back the render target. We should probably call
+             * context_set_current(context) here and then rely on
+             * ActivateContext() doing the right thing. */
+            This->isInDraw = TRUE;
+
+            /* Read the back buffer of the old drawable into the destination texture. */
+            if (((IWineD3DSurfaceImpl *)context->current_rt)->texture_name_srgb)
+            {
+                surface_internal_preload(context->current_rt, SRGB_BOTH);
+            }
+            else
+            {
+                surface_internal_preload(context->current_rt, SRGB_RGB);
+            }
 
 
-        This->isInDraw = oldInDraw;
+            IWineD3DSurface_ModifyLocation(context->current_rt, SFLAG_INDRAWABLE, FALSE);
+
+            This->isInDraw = oldInDraw;
+        }
     }
 
     }
 
+    context->draw_buffer_dirty = TRUE;
+    context->current_rt = target;
+
     return context;
 }
 
     return context;
 }
 
-static void apply_draw_buffer(IWineD3DDeviceImpl *This, IWineD3DSurface *target, BOOL blit)
+/* Context activation is done by the caller. */
+static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit)
 {
 {
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DSurface *rt = context->current_rt;
     IWineD3DSwapChain *swapchain;
     IWineD3DSwapChain *swapchain;
+    IWineD3DDeviceImpl *device;
 
 
-    if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    device = ((IWineD3DSurfaceImpl *)rt)->resource.wineD3DDevice;
+    if (SUCCEEDED(IWineD3DSurface_GetContainer(rt, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
         IWineD3DSwapChain_Release((IUnknown *)swapchain);
         ENTER_GL();
     {
         IWineD3DSwapChain_Release((IUnknown *)swapchain);
         ENTER_GL();
-        glDrawBuffer(surface_get_gl_buffer(target, swapchain));
+        glDrawBuffer(surface_get_gl_buffer(rt, swapchain));
         checkGLcall("glDrawBuffers()");
         LEAVE_GL();
     }
         checkGLcall("glDrawBuffers()");
         LEAVE_GL();
     }
@@ -1473,12 +1949,12 @@ static void apply_draw_buffer(IWineD3DDeviceImpl *This, IWineD3DSurface *target,
             {
                 if (GL_SUPPORT(ARB_DRAW_BUFFERS))
                 {
             {
                 if (GL_SUPPORT(ARB_DRAW_BUFFERS))
                 {
-                    GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), This->draw_buffers));
+                    GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), device->draw_buffers));
                     checkGLcall("glDrawBuffers()");
                 }
                 else
                 {
                     checkGLcall("glDrawBuffers()");
                 }
                 else
                 {
-                    glDrawBuffer(This->draw_buffers[0]);
+                    glDrawBuffer(device->draw_buffers[0]);
                     checkGLcall("glDrawBuffer()");
                 }
             } else {
                     checkGLcall("glDrawBuffer()");
                 }
             } else {
@@ -1488,7 +1964,7 @@ static void apply_draw_buffer(IWineD3DDeviceImpl *This, IWineD3DSurface *target,
         }
         else
         {
         }
         else
         {
-            glDrawBuffer(This->offscreenBuffer);
+            glDrawBuffer(device->offscreenBuffer);
             checkGLcall("glDrawBuffer()");
         }
         LEAVE_GL();
             checkGLcall("glDrawBuffer()");
         }
         LEAVE_GL();
@@ -1508,89 +1984,75 @@ static void apply_draw_buffer(IWineD3DDeviceImpl *This, IWineD3DSurface *target,
  *  usage: Prepares the context for blitting, drawing or other actions
  *
  *****************************************************************************/
  *  usage: Prepares the context for blitting, drawing or other actions
  *
  *****************************************************************************/
-void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
+struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
+{
+    struct wined3d_context *current_context = context_get_current();
     DWORD                         tid = GetCurrentThreadId();
     DWORD                         i, dirtyState, idx;
     BYTE                          shift;
     DWORD                         tid = GetCurrentThreadId();
     DWORD                         i, dirtyState, idx;
     BYTE                          shift;
-    WineD3DContext                *context;
     const struct StateEntry       *StateTable = This->StateTable;
     const struct StateEntry       *StateTable = This->StateTable;
+    const struct wined3d_gl_info *gl_info;
+    struct wined3d_context *context;
 
     TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
 
     TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
-    if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
-        context = FindContext(This, target, tid);
-        context->draw_buffer_dirty = TRUE;
-        This->lastActiveRenderTarget = target;
-        This->lastThread = tid;
-    } else {
-        /* Stick to the old context */
-        context = This->activeContext;
-    }
 
 
-    /* Activate the opengl context */
-    if(last_device != This || context != This->activeContext) {
-        BOOL ret;
+    context = FindContext(This, target, tid);
 
 
-        /* Prevent an unneeded context switch as those are expensive */
-        if(context->glCtx && (context->glCtx == pwglGetCurrentContext())) {
-            TRACE("Already using gl context %p\n", context->glCtx);
-        }
-        else {
-            TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
+    gl_info = context->gl_info;
 
 
-            ret = pwglMakeCurrent(context->hdc, context->glCtx);
-            if(ret == FALSE) {
-                ERR("Failed to activate the new context\n");
-            } else if(!context->last_was_blit) {
-                This->frag_pipe->enable_extension((IWineD3DDevice *) This, TRUE);
-            } else {
-                This->frag_pipe->enable_extension((IWineD3DDevice *) This, FALSE);
-            }
-        }
-        if(This->activeContext->vshader_const_dirty) {
-            memset(This->activeContext->vshader_const_dirty, 1,
-                   sizeof(*This->activeContext->vshader_const_dirty) * GL_LIMITS(vshader_constantsF));
+    /* Activate the opengl context */
+    if (context != current_context)
+    {
+        if (!context_set_current(context)) ERR("Failed to activate the new context.\n");
+        else This->frag_pipe->enable_extension((IWineD3DDevice *)This, !context->last_was_blit);
+
+        if (context->vshader_const_dirty)
+        {
+            memset(context->vshader_const_dirty, 1,
+                    sizeof(*context->vshader_const_dirty) * GL_LIMITS(vshader_constantsF));
+            This->highest_dirty_vs_const = GL_LIMITS(vshader_constantsF);
         }
         }
-        if(This->activeContext->pshader_const_dirty) {
-            memset(This->activeContext->pshader_const_dirty, 1,
-                   sizeof(*This->activeContext->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
+        if (context->pshader_const_dirty)
+        {
+            memset(context->pshader_const_dirty, 1,
+                   sizeof(*context->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
+            This->highest_dirty_ps_const = GL_LIMITS(pshader_constantsF);
         }
         }
-        This->activeContext = context;
-        last_device = This;
     }
 
     switch (usage) {
         case CTXUSAGE_CLEAR:
         case CTXUSAGE_DRAWPRIM:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
     }
 
     switch (usage) {
         case CTXUSAGE_CLEAR:
         case CTXUSAGE_DRAWPRIM:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-                context_apply_fbo_state((IWineD3DDevice *)This);
+                ENTER_GL();
+                context_apply_fbo_state(context);
+                LEAVE_GL();
             }
             if (context->draw_buffer_dirty) {
             }
             if (context->draw_buffer_dirty) {
-                apply_draw_buffer(This, target, FALSE);
+                context_apply_draw_buffer(context, FALSE);
                 context->draw_buffer_dirty = FALSE;
             }
             break;
 
         case CTXUSAGE_BLIT:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
                 context->draw_buffer_dirty = FALSE;
             }
             break;
 
         case CTXUSAGE_BLIT:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-                if (This->render_offscreen) {
+                if (context->render_offscreen)
+                {
                     FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
                     FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
-                    context_bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
-                    context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target);
-
                     ENTER_GL();
                     ENTER_GL();
-                    GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
-                    checkGLcall("glFramebufferRenderbufferEXT");
+                    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
+                    context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, target);
+                    context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE);
                     LEAVE_GL();
                 } else {
                     ENTER_GL();
                     LEAVE_GL();
                 } else {
                     ENTER_GL();
-                    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-                    checkGLcall("glFramebufferRenderbufferEXT");
+                    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
                     LEAVE_GL();
                 }
                 context->draw_buffer_dirty = TRUE;
             }
             if (context->draw_buffer_dirty) {
                     LEAVE_GL();
                 }
                 context->draw_buffer_dirty = TRUE;
             }
             if (context->draw_buffer_dirty) {
-                apply_draw_buffer(This, target, TRUE);
+                context_apply_draw_buffer(context, TRUE);
                 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
                     context->draw_buffer_dirty = FALSE;
                 }
                 if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
                     context->draw_buffer_dirty = FALSE;
                 }
@@ -1636,6 +2098,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
 
             IWineD3DDeviceImpl_FindTexUnitMap(This);
 
 
             IWineD3DDeviceImpl_FindTexUnitMap(This);
 
+            ENTER_GL();
             for(i=0; i < context->numDirtyEntries; i++) {
                 dirtyState = context->dirtyArray[i];
                 idx = dirtyState >> 5;
             for(i=0; i < context->numDirtyEntries; i++) {
                 dirtyState = context->dirtyArray[i];
                 idx = dirtyState >> 5;
@@ -1643,6 +2106,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                 context->isStateDirty[idx] &= ~(1 << shift);
                 StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
             }
                 context->isStateDirty[idx] &= ~(1 << shift);
                 StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
             }
+            LEAVE_GL();
             context->numDirtyEntries = 0; /* This makes the whole list clean */
             context->last_was_blit = FALSE;
             break;
             context->numDirtyEntries = 0; /* This makes the whole list clean */
             context->last_was_blit = FALSE;
             break;
@@ -1656,8 +2120,6 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
         default:
             FIXME("Unexpected context usage requested\n");
     }
         default:
             FIXME("Unexpected context usage requested\n");
     }
-}
 
 
-WineD3DContext *getActiveContext(void) {
-    return last_device->activeContext;
+    return context;
 }
 }
index ce5f6b6..4b6900a 100644 (file)
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
+#define GLINFO_LOCATION (*gl_info)
+
+static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb)
+{
+    /* Override the IWineD3DResource Preload method. */
+    IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    unsigned int i, j;
+    BOOL srgb_mode;
+    BOOL *dirty;
+
+    switch (srgb)
+    {
+        case SRGB_RGB:
+            srgb_mode = FALSE;
+            break;
+
+        case SRGB_BOTH:
+            cubetexture_internal_preload(iface, SRGB_RGB);
+            /* Fallthrough */
+
+        case SRGB_SRGB:
+            srgb_mode = TRUE;
+            break;
+
+        default:
+            srgb_mode = This->baseTexture.is_srgb;
+            break;
+    }
+    dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
+
+    TRACE("(%p) : About to load texture: dirtified(%u).\n", This, *dirty);
+
+    /* We only have to activate a context for gl when we're not drawing.
+     * In most cases PreLoad will be called during draw and a context was
+     * activated at the beginning of drawPrimitive. */
+    if (!device->isInDraw)
+    {
+        /* No danger of recursive calls, ActivateContext sets isInDraw to true
+         * when loading offscreen render targets into their texture. */
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    }
+
+    if (This->resource.format_desc->format == WINED3DFMT_P8
+            || This->resource.format_desc->format == WINED3DFMT_A8P8)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j)
+            {
+                if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[j][i]))
+                {
+                    TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
+                    /* TODO: This is not necessarily needed with hw palettized texture support. */
+                    IWineD3DSurface_LoadLocation(This->surfaces[j][i], SFLAG_INSYSMEM, NULL);
+                    /* Make sure the texture is reloaded because of the palette change,
+                     * this kills performance though :( */
+                    IWineD3DSurface_ModifyLocation(This->surfaces[j][i], SFLAG_INTEXTURE, FALSE);
+                }
+            }
+        }
+    }
+
+    /* If the texture is marked dirty or the srgb sampler setting has changed
+     * since the last load then reload the surfaces. */
+    if (*dirty)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j)
+            {
+                IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
+            }
+        }
+    }
+    else
+    {
+        TRACE("(%p) Texture not dirty, nothing to do.\n" , iface);
+    }
+
+    /* No longer dirty. */
+    *dirty = FALSE;
+}
+
+static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This, D3DCB_DESTROYSURFACEFN surface_destroy_cb)
+{
+    unsigned int i, j;
+
+    TRACE("(%p) : Cleaning up.\n", This);
+
+    for (i = 0; i < This->baseTexture.levels; ++i)
+    {
+        for (j = 0; j < 6; ++j)
+        {
+            IWineD3DSurface *surface = This->surfaces[j][i];
+
+            if (surface)
+            {
+                /* Clean out the texture name we gave to the surface so that the
+                 * surface doesn't try and release it. */
+                surface_set_texture_name(surface, 0, TRUE);
+                surface_set_texture_name(surface, 0, FALSE);
+                surface_set_texture_target(surface, 0);
+                IWineD3DSurface_SetContainer(surface, NULL);
+                surface_destroy_cb(surface);
+            }
+        }
+    }
+    basetexture_cleanup((IWineD3DBaseTexture *)This);
+}
+
+HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+    UINT pow2_edge_length;
+    unsigned int i, j;
+    UINT tmp_w;
+    HRESULT hr;
+
+    /* TODO: It should only be possible to create textures for formats
+     * that are reported as supported. */
+    if (WINED3DFMT_UNKNOWN >= format)
+    {
+        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (!GL_SUPPORT(ARB_TEXTURE_CUBE_MAP) && pool != WINED3DPOOL_SCRATCH)
+    {
+        WARN("(%p) : Tried to create not supported cube texture.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    /* Calculate levels for mip mapping */
+    if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        levels = 1;
+    }
+    else if (!levels)
+    {
+        levels = wined3d_log2i(edge_length) + 1;
+        TRACE("Calculated levels = %u.\n", levels);
+    }
+
+    hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels,
+            WINED3DRTYPE_CUBETEXTURE, device, 0, usage, format_desc, pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize basetexture, returning %#x\n", hr);
+        return hr;
+    }
+
+    /* Find the nearest pow2 match. */
+    pow2_edge_length = 1;
+    while (pow2_edge_length < edge_length) pow2_edge_length <<= 1;
+
+    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || (edge_length == pow2_edge_length))
+    {
+        /* Precalculated scaling for 'faked' non power of two texture coords. */
+        texture->baseTexture.pow2Matrix[0] = 1.0f;
+        texture->baseTexture.pow2Matrix[5] = 1.0f;
+        texture->baseTexture.pow2Matrix[10] = 1.0f;
+        texture->baseTexture.pow2Matrix[15] = 1.0f;
+    }
+    else
+    {
+        /* Precalculated scaling for 'faked' non power of two texture coords. */
+        texture->baseTexture.pow2Matrix[0] = ((float)edge_length) / ((float)pow2_edge_length);
+        texture->baseTexture.pow2Matrix[5] = ((float)edge_length) / ((float)pow2_edge_length);
+        texture->baseTexture.pow2Matrix[10] = ((float)edge_length) / ((float)pow2_edge_length);
+        texture->baseTexture.pow2Matrix[15] = 1.0f;
+        texture->baseTexture.pow2Matrix_identity = FALSE;
+    }
+
+    /* Generate all the surfaces. */
+    tmp_w = edge_length;
+    for (i = 0; i < texture->baseTexture.levels; ++i)
+    {
+        /* Create the 6 faces. */
+        for (j = 0; j < 6; ++j)
+        {
+            static const GLenum cube_targets[6] =
+            {
+                GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
+                GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
+                GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
+                GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
+                GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
+                GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
+            };
+
+            hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_w,
+                    format, usage, pool, i /* Level */, j, &texture->surfaces[j][i]);
+            if (FAILED(hr))
+            {
+                FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr);
+                texture->surfaces[j][i] = NULL;
+                cubetexture_cleanup(texture, D3DCB_DefaultDestroySurface);
+                return hr;
+            }
+
+            IWineD3DSurface_SetContainer(texture->surfaces[j][i], (IWineD3DBase *)texture);
+            TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[j][i]);
+            surface_set_texture_target(texture->surfaces[j][i], cube_targets[j]);
+        }
+        tmp_w = max(1, tmp_w >> 1);
+    }
+    texture->baseTexture.internal_preload = cubetexture_internal_preload;
+
+    return WINED3D_OK;
+}
+
+#undef GLINFO_LOCATION
 
 /* *******************************************
    IWineD3DCubeTexture IUnknown parts follow
    ******************************************* */
 
 /* *******************************************
    IWineD3DCubeTexture IUnknown parts follow
    ******************************************* */
+
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
 static HRESULT WINAPI IWineD3DCubeTextureImpl_QueryInterface(IWineD3DCubeTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
 static HRESULT WINAPI IWineD3DCubeTextureImpl_QueryInterface(IWineD3DCubeTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
@@ -91,65 +321,6 @@ static DWORD WINAPI IWineD3DCubeTextureImpl_GetPriority(IWineD3DCubeTexture *ifa
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
-void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
-    /* Override the IWineD3DResource Preload method */
-    unsigned int i,j;
-    IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BOOL srgb_mode;
-    BOOL *dirty;
-
-    switch(srgb) {
-        case SRGB_RGB:      srgb_mode = FALSE; break;
-        case SRGB_BOTH:     cubetexture_internal_preload(iface, SRGB_RGB);
-        case SRGB_SRGB:     srgb_mode = TRUE; break;
-        /* DONTKNOW, and shut up the compiler */
-        default:            srgb_mode = This->baseTexture.is_srgb; break;
-    }
-    dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
-
-    TRACE("(%p) : About to load texture: dirtified(%d)\n", This, *dirty);
-
-    /* We only have to activate a context for gl when we're not drawing. In most cases PreLoad will be called during draw
-     * and a context was activated at the beginning of drawPrimitive
-     */
-    if(!device->isInDraw) {
-        /* No danger of recursive calls, ActivateContext sets isInDraw to true when loading
-         * offscreen render targets into their texture
-         */
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-    }
-
-    if (This->resource.format_desc->format == WINED3DFMT_P8 || This->resource.format_desc->format == WINED3DFMT_A8P8)
-    {
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
-                if(palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[j][i])) {
-                    TRACE("Reloading surface because the d3d8/9 palette was changed\n");
-                    /* TODO: This is not necessarily needed with hw palettized texture support */
-                    IWineD3DSurface_LoadLocation(This->surfaces[j][i], SFLAG_INSYSMEM, NULL);
-                    /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
-                    IWineD3DSurface_ModifyLocation(This->surfaces[j][i], SFLAG_INTEXTURE, FALSE);
-                }
-            }
-        }
-    }
-    /* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
-    if (*dirty) {
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
-                IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
-            }
-        }
-    } else {
-        TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
-    }
-
-    /* No longer dirty */
-    *dirty = FALSE;
-    return;
-}
-
 static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
     cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
 static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
     cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
@@ -219,6 +390,7 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface)
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
+/* Context activation is done by the caller. */
 static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface, BOOL srgb) {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
     BOOL set_gl_texture_desc;
 static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface, BOOL srgb) {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
     BOOL set_gl_texture_desc;
@@ -257,36 +429,13 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface)
     return FALSE;
 }
 
     return FALSE;
 }
 
-static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface, 
-                                                        const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], 
-                                                        const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
-    TRACE("(%p) : relay to BaseTexture\n", iface);
-    basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
-}
-
-
 /* *******************************************
    IWineD3DCubeTexture IWineD3DCubeTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
 /* *******************************************
    IWineD3DCubeTexture IWineD3DCubeTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
     IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
-    unsigned int i,j;
-    TRACE("(%p) : Cleaning up\n",This);
-    for (i = 0; i < This->baseTexture.levels; i++) {
-        for (j = 0; j < 6; j++) {
-            if (This->surfaces[j][i] != NULL) {
-                IWineD3DSurface *surface = This->surfaces[j][i];
-                /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
-                surface_set_texture_name(surface, 0, TRUE);
-                surface_set_texture_name(surface, 0, FALSE);
-                surface_set_texture_target(surface, 0);
-                /* Cleanup the container */
-                IWineD3DSurface_SetContainer(This->surfaces[j][i], 0);
-                D3DCB_DestroySurface(This->surfaces[j][i]);
-            }
-        }
-    }
-    basetexture_cleanup((IWineD3DBaseTexture *)iface);
+
+    cubetexture_cleanup(This, D3DCB_DestroySurface);
     /* finally delete the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
     /* finally delete the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -399,7 +548,6 @@ const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl =
     IWineD3DCubeTextureImpl_BindTexture,
     IWineD3DCubeTextureImpl_GetTextureDimensions,
     IWineD3DCubeTextureImpl_IsCondNP2,
     IWineD3DCubeTextureImpl_BindTexture,
     IWineD3DCubeTextureImpl_GetTextureDimensions,
     IWineD3DCubeTextureImpl_IsCondNP2,
-    IWineD3DCubeTextureImpl_ApplyStateChanges,
     /* IWineD3DCubeTexture */
     IWineD3DCubeTextureImpl_Destroy,
     IWineD3DCubeTextureImpl_GetLevelDesc,
     /* IWineD3DCubeTexture */
     IWineD3DCubeTextureImpl_Destroy,
     IWineD3DCubeTextureImpl_GetLevelDesc,
index ec6d3f0..58e3b69 100644 (file)
@@ -38,26 +38,29 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 /* Define the default light parameters as specified by MSDN */
 const WINED3DLIGHT WINED3D_default_light = {
 
 /* Define the default light parameters as specified by MSDN */
 const WINED3DLIGHT WINED3D_default_light = {
 
-    WINED3DLIGHT_DIRECTIONAL, /* Type */
-    { 1.0, 1.0, 1.0, 0.0 },   /* Diffuse r,g,b,a */
-    { 0.0, 0.0, 0.0, 0.0 },   /* Specular r,g,b,a */
-    { 0.0, 0.0, 0.0, 0.0 },   /* Ambient r,g,b,a, */
-    { 0.0, 0.0, 0.0 },        /* Position x,y,z */
-    { 0.0, 0.0, 1.0 },        /* Direction x,y,z */
-    0.0,                      /* Range */
-    0.0,                      /* Falloff */
-    0.0, 0.0, 0.0,            /* Attenuation 0,1,2 */
-    0.0,                      /* Theta */
-    0.0                       /* Phi */
+    WINED3DLIGHT_DIRECTIONAL,   /* Type */
+    { 1.0f, 1.0f, 1.0f, 0.0f }, /* Diffuse r,g,b,a */
+    { 0.0f, 0.0f, 0.0f, 0.0f }, /* Specular r,g,b,a */
+    { 0.0f, 0.0f, 0.0f, 0.0f }, /* Ambient r,g,b,a, */
+    { 0.0f, 0.0f, 0.0f },       /* Position x,y,z */
+    { 0.0f, 0.0f, 1.0f },       /* Direction x,y,z */
+    0.0f,                       /* Range */
+    0.0f,                       /* Falloff */
+    0.0f, 0.0f, 0.0f,           /* Attenuation 0,1,2 */
+    0.0f,                       /* Theta */
+    0.0                       /* Phi */
 };
 
 };
 
-/* static function declarations */
-static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
-
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
-const float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};  /* When needed for comparisons */
+const float identity[] =
+{
+    1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 1.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 1.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f,
+};  /* When needed for comparisons */
 
 /* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
  * actually have the same values in GL and D3D. */
 
 /* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
  * actually have the same values in GL and D3D. */
@@ -169,6 +172,7 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
     return TRUE;
 }
 
     return TRUE;
 }
 
+/* Context activation is done by the caller. */
 void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
         BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup)
 {
 void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
         BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup)
 {
@@ -178,7 +182,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
     const DWORD *streams = declaration->streams;
     unsigned int i;
 
     const DWORD *streams = declaration->streams;
     unsigned int i;
 
-    memset(stream_info, 0, sizeof(*stream_info));
+    stream_info->use_map = 0;
+    stream_info->swizzle_map = 0;
 
     /* Check for transformed vertices, disable vertex shader if present. */
     stream_info->position_transformed = declaration->position_transformed;
 
     /* Check for transformed vertices, disable vertex shader if present. */
     stream_info->position_transformed = declaration->position_transformed;
@@ -440,6 +445,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
         struct wined3d_buffer_desc *desc, const void *data, IUnknown *parent, IWineD3DBuffer **buffer)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
         struct wined3d_buffer_desc *desc, const void *data, IUnknown *parent, IWineD3DBuffer **buffer)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
     struct wined3d_buffer *object;
     HRESULT hr;
 
     struct wined3d_buffer *object;
     HRESULT hr;
 
@@ -457,8 +463,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
 
     FIXME("Ignoring access flags (pool)\n");
 
 
     FIXME("Ignoring access flags (pool)\n");
 
-    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, desc->byte_width,
-            desc->usage, WINED3DFMT_UNKNOWN, WINED3DPOOL_MANAGED, parent);
+    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, desc->byte_width,
+            desc->usage, format_desc, WINED3DPOOL_MANAGED, parent);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -469,8 +475,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
 
     TRACE("Created resource %p\n", object);
 
 
     TRACE("Created resource %p\n", object);
 
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
     TRACE("size %#x, usage=%#x, format %s, memory @ %p, iface @ %p\n", object->resource.size, object->resource.usage,
             debug_d3dformat(object->resource.format_desc->format), object->resource.allocatedMemory, object);
 
     TRACE("size %#x, usage=%#x, format %s, memory @ %p, iface @ %p\n", object->resource.size, object->resource.usage,
             debug_d3dformat(object->resource.format_desc->format), object->resource.allocatedMemory, object);
 
@@ -535,7 +539,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
+    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -547,8 +551,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
     TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
     *ppVertexBuffer = (IWineD3DBuffer *)object;
 
     TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
     *ppVertexBuffer = (IWineD3DBuffer *)object;
 
@@ -602,7 +604,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
+    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -614,8 +616,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
     if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
         object->flags |= WINED3D_BUFFER_CREATEBO;
     }
     if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
         object->flags |= WINED3D_BUFFER_CREATEBO;
     }
@@ -897,171 +897,45 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface,
-        UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
-        IWineD3DSurface **ppSurface, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool,
-        WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, WINED3DSURFTYPE Impl, IUnknown *parent)
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height,
+        WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,
+        DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
+        WINED3DSURFTYPE Impl, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
-    unsigned int Size       = 1;
-    const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
-    UINT mul_4w, mul_4h;
+    IWineD3DSurfaceImpl *object;
     HRESULT hr;
 
     TRACE("(%p) Create surface\n",This);
 
     HRESULT hr;
 
     TRACE("(%p) Create surface\n",This);
 
-    if(MultisampleQuality > 0) {
-        FIXME("MultisampleQuality set to %d, substituting 0\n", MultisampleQuality);
-        MultisampleQuality=0;
-    }
-
-    /** FIXME: Check that the format is supported
-    *    by the device.
-      *******************************/
-
-    /** DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
-     *  it is based around 4x4 pixel blocks it requires padding, so allocate enough
-     *  space!
-      *********************************/
-    mul_4w = (Width + 3) & ~3;
-    mul_4h = (Height + 3) & ~3;
-    if (WINED3DFMT_UNKNOWN == Format) {
-        Size = 0;
-    } else if (Format == WINED3DFMT_DXT1) {
-        /* DXT1 is half byte per pixel */
-        Size = (mul_4w * glDesc->byte_count * mul_4h) >> 1;
-
-    } else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
-               Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 ||
-               Format == WINED3DFMT_ATI2N) {
-        Size = (mul_4w * glDesc->byte_count * mul_4h);
-    } else {
-       /* The pitch is a multiple of 4 bytes */
-        Size = ((Width * glDesc->byte_count) + This->surface_alignment - 1) & ~(This->surface_alignment - 1);
-        Size *= Height;
+    if (Impl == SURFACE_OPENGL && !This->adapter)
+    {
+        ERR("OpenGL surfaces are not available without OpenGL.\n");
+        return WINED3DERR_NOTAVAILABLE;
     }
 
     }
 
-    if(glDesc->heightscale != 0.0) Size *= glDesc->heightscale;
-
-    /** Create and initialise the surface resource **/
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
     {
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
     {
-        ERR("Out of memory\n");
+        ERR("Failed to allocate surface memory.\n");
         *ppSurface = NULL;
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
         *ppSurface = NULL;
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
-    /* Look at the implementation and set the correct Vtable */
-    switch(Impl)
-    {
-        case SURFACE_OPENGL:
-            /* Check if a 3D adapter is available when creating gl surfaces */
-            if (!This->adapter)
-            {
-                ERR("OpenGL surfaces are not available without opengl\n");
-                HeapFree(GetProcessHeap(), 0, object);
-                return WINED3DERR_NOTAVAILABLE;
-            }
-            object->lpVtbl = &IWineD3DSurface_Vtbl;
-            break;
-
-        case SURFACE_GDI:
-            object->lpVtbl = &IWineGDISurface_Vtbl;
-            break;
-
-        default:
-            /* To be sure to catch this */
-            ERR("Unknown requested surface implementation %d!\n", Impl);
-            HeapFree(GetProcessHeap(), 0, object);
-            return WINED3DERR_INVALIDCALL;
-    }
-
-    hr = resource_init(&object->resource, WINED3DRTYPE_SURFACE, This, Size, Usage, glDesc, Pool, parent);
+    hr = surface_init(object, Impl, This->surface_alignment, Width, Height, Level, Lockable,
+            Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize resource, returning %#x\n", hr);
+        WARN("Failed to initialize surface, returning %#x.\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppSurface = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppSurface = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created resource %p\n", This, object);
-
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
+    TRACE("(%p) : Created surface %p\n", This, object);
 
     *ppSurface = (IWineD3DSurface *)object;
 
 
     *ppSurface = (IWineD3DSurface *)object;
 
-    /* "Standalone" surface */
-    IWineD3DSurface_SetContainer((IWineD3DSurface *)object, NULL);
-
-    object->currentDesc.Width      = Width;
-    object->currentDesc.Height     = Height;
-    object->currentDesc.MultiSampleType    = MultiSample;
-    object->currentDesc.MultiSampleQuality = MultisampleQuality;
-    object->glDescription.level            = Level;
-    list_init(&object->overlays);
-
-    /* Flags */
-    object->Flags      = SFLAG_NORMCOORD; /* Default to normalized coords */
-    object->Flags     |= Discard ? SFLAG_DISCARD : 0;
-    object->Flags     |= (WINED3DFMT_D16_LOCKABLE == Format) ? SFLAG_LOCKABLE : 0;
-    object->Flags     |= Lockable ? SFLAG_LOCKABLE : 0;
-
-    TRACE("Pool %d %d %d %d\n",Pool, WINED3DPOOL_DEFAULT, WINED3DPOOL_MANAGED, WINED3DPOOL_SYSTEMMEM);
-
-    /** Quick lockable sanity check TODO: remove this after surfaces, usage and lockability have been debugged properly
-    * this function is too deep to need to care about things like this.
-    * Levels need to be checked too, and possibly Type since they all affect what can be done.
-    * ****************************************/
-    switch(Pool) {
-    case WINED3DPOOL_SCRATCH:
-        if(!Lockable)
-            FIXME("Create surface called with a pool of SCRATCH and a Lockable of FALSE "
-                "which are mutually exclusive, setting lockable to TRUE\n");
-                Lockable = TRUE;
-    break;
-    case WINED3DPOOL_SYSTEMMEM:
-        if(!Lockable) FIXME("Create surface called with a pool of SYSTEMMEM and a Lockable of FALSE, "
-                                    "this is acceptable but unexpected (I can't know how the surface can be usable!)\n");
-    case WINED3DPOOL_MANAGED:
-        if(Usage == WINED3DUSAGE_DYNAMIC) FIXME("Create surface called with a pool of MANAGED and a "
-                                                "Usage of DYNAMIC which are mutually exclusive, not doing "
-                                                "anything just telling you.\n");
-    break;
-    case WINED3DPOOL_DEFAULT: /*TODO: Create offscreen plain can cause this check to fail..., find out if it should */
-        if(!(Usage & WINED3DUSAGE_DYNAMIC) && !(Usage & WINED3DUSAGE_RENDERTARGET)
-           && !(Usage && WINED3DUSAGE_DEPTHSTENCIL ) && Lockable)
-            WARN("Creating a surface with a POOL of DEFAULT with Lockable true, that doesn't specify DYNAMIC usage.\n");
-    break;
-    default:
-        FIXME("(%p) Unknown pool %d\n", This, Pool);
-    break;
-    };
-
-    if (Usage & WINED3DUSAGE_RENDERTARGET && Pool != WINED3DPOOL_DEFAULT) {
-        FIXME("Trying to create a render target that isn't in the default pool\n");
-    }
-
-    /* mark the texture as dirty so that it gets loaded first time around*/
-    surface_add_dirty_rect(*ppSurface, NULL);
-    TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n",
-           This, Width, Height, Format, debug_d3dformat(Format),
-           (WINED3DFMT_D16_LOCKABLE == Format), *ppSurface, object->resource.allocatedMemory, object->resource.size);
-
-    list_init(&object->renderbuffers);
-
-    /* Call the private setup routine */
-    hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)object);
-    if (FAILED(hr))
-    {
-        ERR("Private setup failed, returning %#x\n", hr);
-        IWineD3DSurface_Release(*ppSurface);
-        *ppSurface = NULL;
-        return hr;
-    }
-
     return hr;
 }
 
     return hr;
 }
 
@@ -1093,73 +967,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
         WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
         WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
     IWineD3DTextureImpl *object;
     IWineD3DTextureImpl *object;
-    unsigned int i;
-    UINT tmpW;
-    UINT tmpH;
     HRESULT hr;
     HRESULT hr;
-    unsigned int pow2Width;
-    unsigned int pow2Height;
 
     TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
     TRACE("Format %#x (%s), Pool %#x, ppTexture %p, parent %p\n",
             Format, debug_d3dformat(Format), Pool, ppTexture, parent);
 
 
     TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
     TRACE("Format %#x (%s), Pool %#x, ppTexture %p, parent %p\n",
             Format, debug_d3dformat(Format), Pool, ppTexture, parent);
 
-    /* TODO: It should only be possible to create textures for formats
-             that are reported as supported */
-    if (WINED3DFMT_UNKNOWN >= Format) {
-        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    /* Non-power2 support */
-    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO))
-    {
-        pow2Width = Width;
-        pow2Height = Height;
-    }
-    else
-    {
-        /* Find the nearest pow2 match */
-        pow2Width = pow2Height = 1;
-        while (pow2Width < Width) pow2Width <<= 1;
-        while (pow2Height < Height) pow2Height <<= 1;
-
-        if (pow2Width != Width || pow2Height != Height)
-        {
-            if (Levels > 1)
-            {
-                WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support\n");
-                return WINED3DERR_INVALIDCALL;
-            }
-            Levels = 1;
-        }
-    }
-
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
-    {
-        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
-        {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        if (Levels > 1)
-        {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        Levels = 1;
-    }
-    else if (!Levels)
-    {
-        Levels = wined3d_log2i(max(Width, Height)) + 1;
-        TRACE("Calculated levels = %d\n", Levels);
-    }
-
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
     {
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
     {
@@ -1169,106 +983,20 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
     }
 
     object->lpVtbl = &IWineD3DTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DTexture_Vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_TEXTURE, This, 0, Usage, format_desc, Pool, parent);
+
+    hr = texture_init(object, Width, Height, Levels, This, Usage, Format, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize resource, returning %#x\n", hr);
+        WARN("Failed to initialize texture, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppTexture = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppTexture = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created resource %p\n", This, object);
-
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
     *ppTexture = (IWineD3DTexture *)object;
 
     *ppTexture = (IWineD3DTexture *)object;
 
-    basetexture_init(&object->baseTexture, Levels, Usage);
-
-    if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
-    {
-        object->baseTexture.minMipLookup = minMipLookup;
-        object->baseTexture.magLookup    = magLookup;
-    } else {
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-        object->baseTexture.magLookup    = magLookup_noFilter;
-    }
-
-    /** FIXME: add support for real non-power-two if it's provided by the video card **/
-    /* Precalculated scaling for 'faked' non power of two texture coords.
-       Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
-       is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
-       doesn't work in combination with ARB_TEXTURE_RECTANGLE.
-    */
-    if(GL_SUPPORT(WINE_NORMALIZED_TEXRECT) && (Width != pow2Width || Height != pow2Height)) {
-        object->baseTexture.pow2Matrix[0] =  1.0;
-        object->baseTexture.pow2Matrix[5] =  1.0;
-        object->baseTexture.pow2Matrix[10] = 1.0;
-        object->baseTexture.pow2Matrix[15] = 1.0;
-        object->target = GL_TEXTURE_2D;
-        object->cond_np2 = TRUE;
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-    } else if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE) &&
-       (Width != pow2Width || Height != pow2Height) &&
-       !((Format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE) && (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
-    {
-        if ((Width != 1) || (Height != 1)) {
-            object->baseTexture.pow2Matrix_identity = FALSE;
-        }
-
-        object->baseTexture.pow2Matrix[0] =  (float)Width;
-        object->baseTexture.pow2Matrix[5] =  (float)Height;
-        object->baseTexture.pow2Matrix[10] = 1.0;
-        object->baseTexture.pow2Matrix[15] = 1.0;
-        object->target = GL_TEXTURE_RECTANGLE_ARB;
-        object->cond_np2 = TRUE;
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-    } else {
-        if ((Width != pow2Width) || (Height != pow2Height)) {
-            object->baseTexture.pow2Matrix_identity = FALSE;
-            object->baseTexture.pow2Matrix[0] =  (((float)Width)  / ((float)pow2Width));
-            object->baseTexture.pow2Matrix[5] =  (((float)Height) / ((float)pow2Height));
-        } else {
-            object->baseTexture.pow2Matrix[0] =  1.0;
-            object->baseTexture.pow2Matrix[5] =  1.0;
-        }
+    TRACE("(%p) : Created texture %p\n", This, object);
 
 
-        object->baseTexture.pow2Matrix[10] = 1.0;
-        object->baseTexture.pow2Matrix[15] = 1.0;
-        object->target = GL_TEXTURE_2D;
-        object->cond_np2 = FALSE;
-    }
-    TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], object->baseTexture.pow2Matrix[5]);
-
-    /* Generate all the surfaces */
-    tmpW = Width;
-    tmpH = Height;
-    for (i = 0; i < object->baseTexture.levels; i++)
-    {
-        /* use the callback to create the texture surface */
-        hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpH, Format,
-                Usage, Pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &object->surfaces[i]);
-        if (hr!= WINED3D_OK || ( (IWineD3DSurfaceImpl *) object->surfaces[i])->Flags & SFLAG_OVERSIZE) {
-            FIXME("Failed to create surface  %p\n", object);
-            /* clean up */
-            object->surfaces[i] = NULL;
-            IWineD3DTexture_Release((IWineD3DTexture *)object);
-
-            *ppTexture = NULL;
-            return hr;
-        }
-
-        IWineD3DSurface_SetContainer(object->surfaces[i], (IWineD3DBase *)object);
-        TRACE("Created surface level %d @ %p\n", i, object->surfaces[i]);
-        surface_set_texture_target(object->surfaces[i], object->target);
-        /* calculate the next mipmap level */
-        tmpW = max(1, tmpW >> 1);
-        tmpH = max(1, tmpH >> 1);
-    }
-    object->baseTexture.internal_preload = texture_internal_preload;
-
-    TRACE("(%p) : Created  texture %p\n", This, object);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -1277,47 +1005,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
         WINED3DPOOL Pool, IWineD3DVolumeTexture **ppVolumeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
         WINED3DPOOL Pool, IWineD3DVolumeTexture **ppVolumeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
-    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
     IWineD3DVolumeTextureImpl *object;
     IWineD3DVolumeTextureImpl *object;
-    unsigned int               i;
-    UINT                       tmpW;
-    UINT                       tmpH;
-    UINT                       tmpD;
     HRESULT hr;
 
     HRESULT hr;
 
-    /* TODO: It should only be possible to create textures for formats 
-             that are reported as supported */
-    if (WINED3DFMT_UNKNOWN >= Format) {
-        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
-        return WINED3DERR_INVALIDCALL;
-    }
-    if(!GL_SUPPORT(EXT_TEXTURE3D)) {
-        WARN("(%p) : Texture cannot be created - no volume texture support\n", This);
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
-    {
-        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
-        {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        if (Levels > 1)
-        {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        Levels = 1;
-    }
-    else if (!Levels)
-    {
-        Levels = wined3d_log2i(max(max(Width, Height), Depth)) + 1;
-        TRACE("Calculated levels = %d\n", Levels);
-    }
+    TRACE("(%p) : W(%u) H(%u) D(%u), Lvl(%u) Usage(%#x), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
+          Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
@@ -1328,69 +1020,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     }
 
     object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_VOLUMETEXTURE, This, 0, Usage, format_desc, Pool, parent);
+    hr = volumetexture_init(object, Width, Height, Depth, Levels, This, Usage, Format, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize resource, returning %#x\n", hr);
+        WARN("Failed to initialize volumetexture, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppVolumeTexture = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppVolumeTexture = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created resource %p\n", This, object);
-
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
-    basetexture_init(&object->baseTexture, Levels, Usage);
-
-    TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
-          Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
-
-    /* Is NP2 support for volumes needed? */
-    object->baseTexture.pow2Matrix[ 0] = 1.0;
-    object->baseTexture.pow2Matrix[ 5] = 1.0;
-    object->baseTexture.pow2Matrix[10] = 1.0;
-    object->baseTexture.pow2Matrix[15] = 1.0;
-
-    if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
-    {
-        object->baseTexture.minMipLookup = minMipLookup;
-        object->baseTexture.magLookup    = magLookup;
-    } else {
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-        object->baseTexture.magLookup    = magLookup_noFilter;
-    }
-
-    /* Generate all the surfaces */
-    tmpW = Width;
-    tmpH = Height;
-    tmpD = Depth;
+    TRACE("(%p) : Created volume texture %p.\n", This, object);
+    *ppVolumeTexture = (IWineD3DVolumeTexture *)object;
 
 
-    for (i = 0; i < object->baseTexture.levels; i++)
-    {
-        HRESULT hr;
-        /* Create the volume */
-        hr = IWineD3DDeviceParent_CreateVolume(This->device_parent, parent,
-                tmpW, tmpH, tmpD, Format, Pool, Usage, &object->volumes[i]);
-        if(FAILED(hr)) {
-            ERR("Creating a volume for the volume texture failed(%08x)\n", hr);
-            IWineD3DVolumeTexture_Release((IWineD3DVolumeTexture *) object);
-            *ppVolumeTexture = NULL;
-            return hr;
-        }
-
-        /* Set its container to this object */
-        IWineD3DVolume_SetContainer(object->volumes[i], (IWineD3DBase *)object);
-
-        /* calculate the next mipmap level */
-        tmpW = max(1, tmpW >> 1);
-        tmpH = max(1, tmpH >> 1);
-        tmpD = max(1, tmpD >> 1);
-    }
-    object->baseTexture.internal_preload = volumetexture_internal_preload;
-
-    *ppVolumeTexture = (IWineD3DVolumeTexture *) object;
-    TRACE("(%p) : Created volume texture %p\n", This, object);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -1417,7 +1058,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
     }
 
     object->lpVtbl = &IWineD3DVolume_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DVolume_Vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_VOLUME, This,
+    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_VOLUME, This,
             Width * Height * Depth * format_desc->byte_count, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
             Width * Height * Depth * format_desc->byte_count, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
@@ -1429,8 +1070,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
     *ppVolume = (IWineD3DVolume *)object;
 
     TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
     *ppVolume = (IWineD3DVolume *)object;
 
     TRACE("(%p) : W(%d) H(%d) D(%d), Usage(%d), Fmt(%u,%s), Pool(%s)\n", This, Width, Height,
@@ -1456,47 +1095,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
         WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
         WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
-    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
     IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
     IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/
-    unsigned int             i, j;
-    UINT                     tmpW;
     HRESULT                  hr;
     HRESULT                  hr;
-    unsigned int pow2EdgeLength;
-
-    /* TODO: It should only be possible to create textures for formats 
-             that are reported as supported */
-    if (WINED3DFMT_UNKNOWN >= Format) {
-        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN\n", This);
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    if (!GL_SUPPORT(ARB_TEXTURE_CUBE_MAP) && Pool != WINED3DPOOL_SCRATCH) {
-        WARN("(%p) : Tried to create not supported cube texture\n", This);
-        return WINED3DERR_INVALIDCALL;
-    }
-
-    /* Calculate levels for mip mapping */
-    if (Usage & WINED3DUSAGE_AUTOGENMIPMAP)
-    {
-        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
-        {
-            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        if (Levels > 1)
-        {
-            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL\n");
-            return WINED3DERR_INVALIDCALL;
-        }
-
-        Levels = 1;
-    }
-    else if (!Levels)
-    {
-        Levels = wined3d_log2i(EdgeLength) + 1;
-        TRACE("Calculated levels = %d\n", Levels);
-    }
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
@@ -1507,85 +1107,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
     }
 
     object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_CUBETEXTURE, This, 0, Usage, format_desc, Pool, parent);
+    hr = cubetexture_init(object, EdgeLength, Levels, This, Usage, Format, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize resource, returning %#x\n", hr);
+        WARN("Failed to initialize cubetexture, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppCubeTexture = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppCubeTexture = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created resource %p\n", This, object);
-
-    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
-
-    basetexture_init(&object->baseTexture, Levels, Usage);
-
-    TRACE("(%p) Create Cube Texture\n", This);
-
-    /* Find the nearest pow2 match */
-    pow2EdgeLength = 1;
-    while (pow2EdgeLength < EdgeLength) pow2EdgeLength <<= 1;
-
-    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || (EdgeLength == pow2EdgeLength)) {
-        /* Precalculated scaling for 'faked' non power of two texture coords */
-        object->baseTexture.pow2Matrix[ 0] = 1.0;
-        object->baseTexture.pow2Matrix[ 5] = 1.0;
-        object->baseTexture.pow2Matrix[10] = 1.0;
-        object->baseTexture.pow2Matrix[15] = 1.0;
-    } else {
-        /* Precalculated scaling for 'faked' non power of two texture coords */
-        object->baseTexture.pow2Matrix[ 0] = ((float)EdgeLength) / ((float)pow2EdgeLength);
-        object->baseTexture.pow2Matrix[ 5] = ((float)EdgeLength) / ((float)pow2EdgeLength);
-        object->baseTexture.pow2Matrix[10] = ((float)EdgeLength) / ((float)pow2EdgeLength);
-        object->baseTexture.pow2Matrix[15] = 1.0;
-        object->baseTexture.pow2Matrix_identity = FALSE;
-    }
-
-    if (object->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
-    {
-        object->baseTexture.minMipLookup = minMipLookup;
-        object->baseTexture.magLookup    = magLookup;
-    } else {
-        object->baseTexture.minMipLookup = minMipLookup_noFilter;
-        object->baseTexture.magLookup    = magLookup_noFilter;
-    }
-
-    /* Generate all the surfaces */
-    tmpW = EdgeLength;
-    for (i = 0; i < object->baseTexture.levels; i++) {
-
-        /* Create the 6 faces */
-        for (j = 0; j < 6; j++) {
-            static const GLenum cube_targets[6] = {
-                GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
-                GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
-                GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
-                GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
-            };
-
-            hr = IWineD3DDeviceParent_CreateSurface(This->device_parent, parent, tmpW, tmpW,
-                    Format, Usage, Pool, i /* Level */, j, &object->surfaces[j][i]);
-            if (FAILED(hr))
-            {
-                FIXME("(%p) Failed to create surface\n",object);
-                IWineD3DCubeTexture_Release((IWineD3DCubeTexture *)object);
-                *ppCubeTexture = NULL;
-                return hr;
-            }
-            IWineD3DSurface_SetContainer(object->surfaces[j][i], (IWineD3DBase *)object);
-            TRACE("Created surface level %d @ %p,\n", i, object->surfaces[j][i]);
-            surface_set_texture_target(object->surfaces[j][i], cube_targets[j]);
-        }
-        tmpW = max(1, tmpW >> 1);
-    }
-    object->baseTexture.internal_preload = cubetexture_internal_preload;
-
     TRACE("(%p) : Created Cube Texture %p\n", This, object);
     TRACE("(%p) : Created Cube Texture %p\n", This, object);
-    *ppCubeTexture = (IWineD3DCubeTexture *) object;
+    *ppCubeTexture = (IWineD3DCubeTexture *)object;
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -1659,32 +1192,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
     /* allocated the 'extended' data based on the type of query requested */
     switch(Type){
     case WINED3DQUERYTYPE_OCCLUSION:
     /* allocated the 'extended' data based on the type of query requested */
     switch(Type){
     case WINED3DQUERYTYPE_OCCLUSION:
-        object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryOcclusionData));
-        ((WineQueryOcclusionData *)(object->extendedData))->ctx = This->activeContext;
-
-        if(GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
-            TRACE("(%p) Allocating data for an occlusion query\n", This);
+        object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
+        ((struct wined3d_occlusion_query *)object->extendedData)->context = NULL;
+        break;
 
 
-            ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-            ENTER_GL();
-            GL_EXTCALL(glGenQueriesARB(1, &((WineQueryOcclusionData *)(object->extendedData))->queryId));
-            LEAVE_GL();
-            break;
-        }
     case WINED3DQUERYTYPE_EVENT:
     case WINED3DQUERYTYPE_EVENT:
-        object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
-        ((WineQueryEventData *)(object->extendedData))->ctx = This->activeContext;
-
-        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        ENTER_GL();
-        if(GL_SUPPORT(APPLE_FENCE)) {
-            GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
-            checkGLcall("glGenFencesAPPLE");
-        } else if(GL_SUPPORT(NV_FENCE)) {
-            GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
-            checkGLcall("glGenFencesNV");
-        }
-        LEAVE_GL();
+        object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_event_query));
+        ((struct wined3d_event_query *)object->extendedData)->context = NULL;
         break;
 
     case WINED3DQUERYTYPE_VCACHE:
         break;
 
     case WINED3DQUERYTYPE_VCACHE:
@@ -2327,7 +1841,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3D
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD *pFunction, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
+        const DWORD *pFunction, const struct wined3d_shader_signature *output_signature,
+        IWineD3DVertexShader **ppVertexShader, IUnknown *parent)
+{
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
@@ -2350,11 +1867,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
 
     TRACE("(%p) : Created vertex shader %p\n", This, *ppVertexShader);
 
 
     TRACE("(%p) : Created vertex shader %p\n", This, *ppVertexShader);
 
-    if (vertex_declaration) {
-        IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
-    }
-
-    hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, NULL);
+    hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, output_signature);
     if (FAILED(hr))
     {
         WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
@@ -2468,9 +1981,8 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
         bm.bmHeight = 32;
     }
 
         bm.bmHeight = 32;
     }
 
-    hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5,
-                                      TRUE, FALSE, 0, &This->logo_surface, WINED3DRTYPE_SURFACE, 0,
-                                      WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
+    hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5, TRUE,
+            FALSE, 0, &This->logo_surface, 0, WINED3DPOOL_DEFAULT, WINED3DMULTISAMPLE_NONE, 0, SURFACE_OPENGL, NULL);
     if(FAILED(hr)) {
         ERR("Wine logo requested, but failed to create surface\n");
         goto out;
     if(FAILED(hr)) {
         ERR("Wine logo requested, but failed to create surface\n");
         goto out;
@@ -2500,6 +2012,7 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
     return;
 }
 
     return;
 }
 
+/* Context activation is done by the caller. */
 static void create_dummy_textures(IWineD3DDeviceImpl *This) {
     unsigned int i;
     /* Under DirectX you can have texture stage operations even if no texture is
 static void create_dummy_textures(IWineD3DDeviceImpl *This) {
     unsigned int i;
     /* Under DirectX you can have texture stage operations even if no texture is
@@ -2601,12 +2114,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
             This->texUnitMap[state] = state;
             This->rev_tex_unit_map[state] = state;
         } else {
             This->texUnitMap[state] = state;
             This->rev_tex_unit_map[state] = state;
         } else {
-            This->texUnitMap[state] = -1;
-            This->rev_tex_unit_map[state] = -1;
+            This->texUnitMap[state] = WINED3D_UNMAPPED_STAGE;
+            This->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE;
         }
     }
 
         }
     }
 
-    /* Setup the implicit swapchain */
+    /* Setup the implicit swapchain. This also initializes a context. */
     TRACE("Creating implicit swapchain\n");
     hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
             pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
     TRACE("Creating implicit swapchain\n");
     hr = IWineD3DDeviceParent_CreateSwapChain(This->device_parent,
             pPresentationParameters, (IWineD3DSwapChain **)&swapchain);
@@ -2627,16 +2140,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
     if(swapchain->backBuffer && swapchain->backBuffer[0]) {
         TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
         This->render_targets[0] = swapchain->backBuffer[0];
     if(swapchain->backBuffer && swapchain->backBuffer[0]) {
         TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
         This->render_targets[0] = swapchain->backBuffer[0];
-        This->lastActiveRenderTarget = swapchain->backBuffer[0];
     }
     else {
         TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
         This->render_targets[0] = swapchain->frontBuffer;
     }
     else {
         TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
         This->render_targets[0] = swapchain->frontBuffer;
-        This->lastActiveRenderTarget = swapchain->frontBuffer;
     }
     IWineD3DSurface_AddRef(This->render_targets[0]);
     }
     IWineD3DSurface_AddRef(This->render_targets[0]);
-    This->activeContext = swapchain->context[0];
-    This->lastThread = GetCurrentThreadId();
 
     /* Depth Stencil support */
     This->stencilBufferTarget = This->auto_depth_stencil_buffer;
 
     /* Depth Stencil support */
     This->stencilBufferTarget = This->auto_depth_stencil_buffer;
@@ -2682,7 +2191,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
 
         case ORM_BACKBUFFER:
         {
 
         case ORM_BACKBUFFER:
         {
-            if(This->activeContext->aux_buffers > 0) {
+            if (context_get_current()->aux_buffers > 0)
+            {
                 TRACE("Using auxilliary buffer for offscreen rendering\n");
                 This->offscreenBuffer = GL_AUX0;
             } else {
                 TRACE("Using auxilliary buffer for offscreen rendering\n");
                 This->offscreenBuffer = GL_AUX0;
             } else {
@@ -2698,7 +2208,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
     /* Clear the screen */
     IWineD3DDevice_Clear((IWineD3DDevice *) This, 0, NULL,
                           WINED3DCLEAR_TARGET | pPresentationParameters->EnableAutoDepthStencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0,
     /* Clear the screen */
     IWineD3DDevice_Clear((IWineD3DDevice *) This, 0, NULL,
                           WINED3DCLEAR_TARGET | pPresentationParameters->EnableAutoDepthStencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0,
-                          0x00, 1.0, 0);
+                          0x00, 1.0f, 0);
 
     This->d3d_initialized = TRUE;
 
 
     This->d3d_initialized = TRUE;
 
@@ -2787,7 +2297,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
     /* I don't think that the interface guarantees that the device is destroyed from the same thread
      * it was created. Thus make sure a context is active for the glDelete* calls
      */
     /* I don't think that the interface guarantees that the device is destroyed from the same thread
      * it was created. Thus make sure a context is active for the glDelete* calls
      */
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
 
     if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
 
 
     if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
 
@@ -2834,11 +2344,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
      * private data, it might contain opengl pointers
      */
     if(This->depth_blt_texture) {
      * private data, it might contain opengl pointers
      */
     if(This->depth_blt_texture) {
+        ENTER_GL();
         glDeleteTextures(1, &This->depth_blt_texture);
         glDeleteTextures(1, &This->depth_blt_texture);
+        LEAVE_GL();
         This->depth_blt_texture = 0;
     }
     if (This->depth_blt_rb) {
         This->depth_blt_texture = 0;
     }
     if (This->depth_blt_rb) {
+        ENTER_GL();
         GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
         GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        LEAVE_GL();
         This->depth_blt_rb = 0;
         This->depth_blt_rb_w = 0;
         This->depth_blt_rb_h = 0;
         This->depth_blt_rb = 0;
         This->depth_blt_rb_w = 0;
         This->depth_blt_rb_h = 0;
@@ -3269,7 +2783,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
             /* Incorrect attenuation values can cause the gl driver to crash. Happens with Need for speed
              * most wanted
              */
             /* Incorrect attenuation values can cause the gl driver to crash. Happens with Need for speed
              * most wanted
              */
-            if(pLight->Attenuation0 < 0.0 || pLight->Attenuation1 < 0.0 || pLight->Attenuation2 < 0.0) {
+            if (pLight->Attenuation0 < 0.0f || pLight->Attenuation1 < 0.0f || pLight->Attenuation2 < 0.0f)
+            {
                 WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
                 return WINED3DERR_INVALIDCALL;
             }
                 WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
                 return WINED3DERR_INVALIDCALL;
             }
@@ -3331,7 +2846,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
         object->lightPosn[0] = -pLight->Direction.x;
         object->lightPosn[1] = -pLight->Direction.y;
         object->lightPosn[2] = -pLight->Direction.z;
         object->lightPosn[0] = -pLight->Direction.x;
         object->lightPosn[1] = -pLight->Direction.y;
         object->lightPosn[2] = -pLight->Direction.z;
-        object->lightPosn[3] = 0.0;
+        object->lightPosn[3] = 0.0f;
         object->exponent     = 0.0f;
         object->cutoff       = 180.0f;
         break;
         object->exponent     = 0.0f;
         object->cutoff       = 180.0f;
         break;
@@ -3341,13 +2856,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
         object->lightPosn[0] = pLight->Position.x;
         object->lightPosn[1] = pLight->Position.y;
         object->lightPosn[2] = pLight->Position.z;
         object->lightPosn[0] = pLight->Position.x;
         object->lightPosn[1] = pLight->Position.y;
         object->lightPosn[2] = pLight->Position.z;
-        object->lightPosn[3] = 1.0;
+        object->lightPosn[3] = 1.0f;
 
         /* Direction */
         object->lightDirn[0] = pLight->Direction.x;
         object->lightDirn[1] = pLight->Direction.y;
         object->lightDirn[2] = pLight->Direction.z;
 
         /* Direction */
         object->lightDirn[0] = pLight->Direction.x;
         object->lightDirn[1] = pLight->Direction.y;
         object->lightDirn[2] = pLight->Direction.z;
-        object->lightDirn[3] = 1.0;
+        object->lightDirn[3] = 1.0f;
 
         /*
          * opengl-ish and d3d-ish spot lights use too different models for the
 
         /*
          * opengl-ish and d3d-ish spot lights use too different models for the
@@ -3362,14 +2877,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLight(IWineD3DDevice *iface, DWORD I
              * will always be 1.0 for both of them, and we don't have to care for the
              * rest of the rather complex calculation
              */
              * will always be 1.0 for both of them, and we don't have to care for the
              * rest of the rather complex calculation
              */
-            object->exponent = 0;
+            object->exponent = 0.0f;
         } else {
             rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
         } else {
             rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
-            if (rho < 0.0001) rho = 0.0001f;
-            object->exponent = -0.3/log(cos(rho/2));
+            if (rho < 0.0001f) rho = 0.0001f;
+            object->exponent = -0.3f/logf(cosf(rho/2));
         }
         }
-        if (object->exponent > 128.0) {
-            object->exponent = 128.0;
+        if (object->exponent > 128.0f)
+        {
+            object->exponent = 128.0f;
         }
         object->cutoff = pLight->Phi*90/M_PI;
 
         }
         object->cutoff = pLight->Phi*90/M_PI;
 
@@ -3420,9 +2936,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetLightEnable(IWineD3DDevice *iface, D
     struct list *e;
     TRACE("(%p) : Idx(%d), enable? %d\n", This, Index, Enable);
 
     struct list *e;
     TRACE("(%p) : Idx(%d), enable? %d\n", This, Index, Enable);
 
-    /* Tests show true = 128...not clear why */
-    Enable = Enable? 128: 0;
-
     LIST_FOR_EACH(e, &This->updateStateBlock->lightMap[Hi]) {
         lightInfo = LIST_ENTRY(e, PLIGHTINFOEL, entry);
         if(lightInfo->OriginalIndex == Index) break;
     LIST_FOR_EACH(e, &This->updateStateBlock->lightMap[Hi]) {
         lightInfo = LIST_ENTRY(e, PLIGHTINFOEL, entry);
         if(lightInfo->OriginalIndex == Index) break;
@@ -4123,18 +3636,21 @@ static inline void markTextureStagesDirty(IWineD3DDeviceImpl *This, DWORD stage)
     }
 }
 
     }
 }
 
-static void device_map_stage(IWineD3DDeviceImpl *This, int stage, int unit) {
-    int i = This->rev_tex_unit_map[unit];
-    int j = This->texUnitMap[stage];
+static void device_map_stage(IWineD3DDeviceImpl *This, DWORD stage, DWORD unit)
+{
+    DWORD i = This->rev_tex_unit_map[unit];
+    DWORD j = This->texUnitMap[stage];
 
     This->texUnitMap[stage] = unit;
 
     This->texUnitMap[stage] = unit;
-    if (i != -1 && i != stage) {
-        This->texUnitMap[i] = -1;
+    if (i != WINED3D_UNMAPPED_STAGE && i != stage)
+    {
+        This->texUnitMap[i] = WINED3D_UNMAPPED_STAGE;
     }
 
     This->rev_tex_unit_map[unit] = stage;
     }
 
     This->rev_tex_unit_map[unit] = stage;
-    if (j != -1 && j != unit) {
-        This->rev_tex_unit_map[j] = -1;
+    if (j != WINED3D_UNMAPPED_STAGE && j != unit)
+    {
+        This->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
     }
 }
 
     }
 }
 
@@ -4228,14 +3744,12 @@ static void device_map_psamplers(IWineD3DDeviceImpl *This) {
 }
 
 static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshader_sampler_tokens,
 }
 
 static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshader_sampler_tokens,
-        const DWORD *vshader_sampler_tokens, int unit)
+        const DWORD *vshader_sampler_tokens, DWORD unit)
 {
 {
-    int current_mapping = This->rev_tex_unit_map[unit];
+    DWORD current_mapping = This->rev_tex_unit_map[unit];
 
 
-    if (current_mapping == -1) {
-        /* Not currently used */
-        return TRUE;
-    }
+    /* Not currently used */
+    if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE;
 
     if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
         /* Used by a fragment sampler */
 
     if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
         /* Used by a fragment sampler */
@@ -4250,14 +3764,14 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshad
     }
 
     /* Used by a vertex sampler */
     }
 
     /* Used by a vertex sampler */
-    return !vshader_sampler_tokens[current_mapping];
+    return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
 }
 
 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
     const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
             ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
     const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
 }
 
 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
     const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
             ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
     const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
-    int start = GL_LIMITS(combined_samplers) - 1;
+    int start = min(MAX_COMBINED_SAMPLERS, GL_LIMITS(combined_samplers)) - 1;
     int i;
 
     if (ps) {
     int i;
 
     if (ps) {
@@ -4269,7 +3783,7 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
     }
 
     for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
     }
 
     for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
-        int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
+        DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
         if (vshader_sampler_type[i])
         {
             if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
         if (vshader_sampler_type[i])
         {
             if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
@@ -4510,6 +4024,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+/* Context activation is done by the caller. */
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
 static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount,
         const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags,
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
 static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount,
         const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags,
@@ -4522,12 +4037,12 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
     BOOL doClip;
     DWORD numTextures;
 
     BOOL doClip;
     DWORD numTextures;
 
-    if (stream_info->elements[WINED3D_FFP_NORMAL].data)
+    if (stream_info->use_map & (1 << WINED3D_FFP_NORMAL))
     {
         WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
     }
 
     {
         WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
     }
 
-    if (!stream_info->elements[WINED3D_FFP_POSITION].data)
+    if (!(stream_info->use_map & (1 << WINED3D_FFP_POSITION)))
     {
         ERR("Source has no position mask\n");
         return WINED3DERR_INVALIDCALL;
     {
         ERR("Source has no position mask\n");
         return WINED3DERR_INVALIDCALL;
@@ -4637,10 +4152,10 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
             TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
 
             /* Multiplication with world, view and projection matrix */
             TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
 
             /* Multiplication with world, view and projection matrix */
-            x =   (p[0] * mat.u.s._11) + (p[1] * mat.u.s._21) + (p[2] * mat.u.s._31) + (1.0 * mat.u.s._41);
-            y =   (p[0] * mat.u.s._12) + (p[1] * mat.u.s._22) + (p[2] * mat.u.s._32) + (1.0 * mat.u.s._42);
-            z =   (p[0] * mat.u.s._13) + (p[1] * mat.u.s._23) + (p[2] * mat.u.s._33) + (1.0 * mat.u.s._43);
-            rhw = (p[0] * mat.u.s._14) + (p[1] * mat.u.s._24) + (p[2] * mat.u.s._34) + (1.0 * mat.u.s._44);
+            x =   (p[0] * mat.u.s._11) + (p[1] * mat.u.s._21) + (p[2] * mat.u.s._31) + (1.0f * mat.u.s._41);
+            y =   (p[0] * mat.u.s._12) + (p[1] * mat.u.s._22) + (p[2] * mat.u.s._32) + (1.0f * mat.u.s._42);
+            z =   (p[0] * mat.u.s._13) + (p[1] * mat.u.s._23) + (p[2] * mat.u.s._33) + (1.0f * mat.u.s._43);
+            rhw = (p[0] * mat.u.s._14) + (p[1] * mat.u.s._24) + (p[2] * mat.u.s._34) + (1.0f * mat.u.s._44);
 
             TRACE("x=%f y=%f z=%f rhw=%f\n", x, y, z, rhw);
 
 
             TRACE("x=%f y=%f z=%f rhw=%f\n", x, y, z, rhw);
 
@@ -4663,7 +4178,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
 
             if( !doClip ||
                 ( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) &&
 
             if( !doClip ||
                 ( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) &&
-                  (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) && 
+                  (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) &&
                   ( rhw > eps ) ) ) {
 
                 /* "Normal" viewport transformation (not clipped)
                   ( rhw > eps ) ) ) {
 
                 /* "Normal" viewport transformation (not clipped)
@@ -4760,7 +4275,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
         if (DestFVF & WINED3DFVF_DIFFUSE) {
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE];
             const DWORD *color_d = (const DWORD *)(element->data + i * element->stride);
         if (DestFVF & WINED3DFVF_DIFFUSE) {
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE];
             const DWORD *color_d = (const DWORD *)(element->data + i * element->stride);
-            if(!color_d) {
+            if (!(stream_info->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+            {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
@@ -4787,11 +4303,13 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
             }
         }
 
             }
         }
 
-        if (DestFVF & WINED3DFVF_SPECULAR) { 
+        if (DestFVF & WINED3DFVF_SPECULAR)
+        {
             /* What's the color value in the feedback buffer? */
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR];
             const DWORD *color_s = (const DWORD *)(element->data + i * element->stride);
             /* What's the color value in the feedback buffer? */
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR];
             const DWORD *color_s = (const DWORD *)(element->data + i * element->stride);
-            if(!color_s) {
+            if (!(stream_info->use_map & (1 << WINED3D_FFP_SPECULAR)))
+            {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
@@ -4821,7 +4339,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
         for (tex_index = 0; tex_index < numTextures; tex_index++) {
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
             const float *tex_coord = (const float *)(element->data + i * element->stride);
         for (tex_index = 0; tex_index < numTextures; tex_index++) {
             const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
             const float *tex_coord = (const float *)(element->data + i * element->stride);
-            if(!tex_coord) {
+            if (!(stream_info->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + tex_index))))
+            {
                 ERR("No source texture, but destination requests one\n");
                 dest_ptr+=GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
                 if(dest_conv) dest_conv += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
                 ERR("No source texture, but destination requests one\n");
                 dest_ptr+=GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
                 if(dest_conv) dest_conv += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
@@ -4865,7 +4384,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
     }
 
     /* Need any context to write to the vbo. */
     }
 
     /* Need any context to write to the vbo. */
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
 
     /* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP
      * control the streamIsUP flag, thus restore it afterwards.
 
     /* ProcessVertices reads from vertex buffers, which have to be assigned. DrawPrimitive and DrawPrimitiveUP
      * control the streamIsUP flag, thus restore it afterwards.
@@ -4883,7 +4402,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
          */
         for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i)
         {
          */
         for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i)
         {
-            struct wined3d_stream_info_element *e = &stream_info.elements[i];
+            struct wined3d_stream_info_element *e;
+
+            if (!(stream_info.use_map & (1 << i))) continue;
+
+            e = &stream_info.elements[i];
             if (e->buffer_object)
             {
                 struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
             if (e->buffer_object)
             {
                 struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
@@ -5331,9 +4854,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) {
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
     /* We only have to do this if we need to read the, swapbuffers performs a flush for us */
     /* We only have to do this if we need to read the, swapbuffers performs a flush for us */
-    glFlush();
+    wglFlush();
     /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
      * fails
      */
     /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
      * fails
      */
@@ -5375,6 +4898,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
     UINT drawable_width, drawable_height;
     IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
     IWineD3DSwapChainImpl *swapchain = NULL;
     UINT drawable_width, drawable_height;
     IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
     IWineD3DSwapChainImpl *swapchain = NULL;
+    struct wined3d_context *context;
 
     /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
      * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
 
     /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
      * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
@@ -5410,9 +4934,10 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
         }
     }
 
         }
     }
 
-    target->get_drawable_size(target, &drawable_width, &drawable_height);
+    context = ActivateContext(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR);
+
+    target->get_drawable_size(context, &drawable_width, &drawable_height);
 
 
-    ActivateContext(This, (IWineD3DSurface *) target, CTXUSAGE_CLEAR);
     ENTER_GL();
 
     /* Only set the values up once, as they are not changing */
     ENTER_GL();
 
     /* Only set the values up once, as they are not changing */
@@ -5424,7 +4949,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
     }
 
     if (Flags & WINED3DCLEAR_ZBUFFER) {
     }
 
     if (Flags & WINED3DCLEAR_ZBUFFER) {
-        DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
         glDepthMask(GL_TRUE);
         glClearDepth(Z);
         checkGLcall("glClearDepth");
         glDepthMask(GL_TRUE);
         glClearDepth(Z);
         checkGLcall("glClearDepth");
@@ -5433,19 +4958,19 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
 
         if (vp->X != 0 || vp->Y != 0 ||
                 vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) {
 
         if (vp->X != 0 || vp->Y != 0 ||
                 vp->Width < depth_stencil->currentDesc.Width || vp->Height < depth_stencil->currentDesc.Height) {
-            surface_load_ds_location(This->stencilBufferTarget, location);
+            surface_load_ds_location(This->stencilBufferTarget, context, location);
         }
         else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
                 This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
                 This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width ||
                 This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) {
         }
         else if (This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && (
                 This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 ||
                 This->stateBlock->scissorRect.right < depth_stencil->currentDesc.Width ||
                 This->stateBlock->scissorRect.bottom < depth_stencil->currentDesc.Height)) {
-            surface_load_ds_location(This->stencilBufferTarget, location);
+            surface_load_ds_location(This->stencilBufferTarget, context, location);
         }
         else if (Count > 0 && pRects && (
                 pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
                 pRects[0].x2 < depth_stencil->currentDesc.Width ||
                 pRects[0].y2 < depth_stencil->currentDesc.Height)) {
         }
         else if (Count > 0 && pRects && (
                 pRects[0].x1 > 0 || pRects[0].y1 > 0 ||
                 pRects[0].x2 < depth_stencil->currentDesc.Width ||
                 pRects[0].y2 < depth_stencil->currentDesc.Height)) {
-            surface_load_ds_location(This->stencilBufferTarget, location);
+            surface_load_ds_location(This->stencilBufferTarget, context, location);
         }
     }
 
         }
     }
 
@@ -5470,7 +4995,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
         if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
             IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect);
         }
         if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
             IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect);
         }
-        if(This->render_offscreen) {
+        if (context->render_offscreen)
+        {
             glScissor(vp_rect.left, vp_rect.top,
                         vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
         } else {
             glScissor(vp_rect.left, vp_rect.top,
                         vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top);
         } else {
@@ -5502,7 +5028,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
                 continue;
             }
 
                 continue;
             }
 
-            if(This->render_offscreen) {
+            if (context->render_offscreen)
+            {
                 glScissor(curRect.x1, curRect.y1,
                           curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
             } else {
                 glScissor(curRect.x1, curRect.y1,
                           curRect.x2 - curRect.x1, curRect.y2 - curRect.y1);
             } else {
@@ -5530,11 +5057,11 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
         /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists,
          * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it
          */
         /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists,
          * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it
          */
-        IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, TRUE);
+        IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
     }
     if (Flags & WINED3DCLEAR_ZBUFFER) {
         /* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */
     }
     if (Flags & WINED3DCLEAR_ZBUFFER) {
         /* Note that WINED3DCLEAR_ZBUFFER implies a depth stencil exists on the device */
-        DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
         surface_modify_ds_location(This->stencilBufferTarget, location);
     }
 
         surface_modify_ds_location(This->stencilBufferTarget, location);
     }
 
@@ -5542,7 +5069,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
 
     if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
         if (target == (IWineD3DSurfaceImpl*) swapchain->frontBuffer) {
 
     if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
         if (target == (IWineD3DSurfaceImpl*) swapchain->frontBuffer) {
-            glFlush();
+            wglFlush();
         }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
         }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
@@ -6203,6 +5730,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
      *       NOTE: move code to surface to accomplish this
       ****************************************/
     IWineD3DSurfaceImpl *pSrcSurface  = (IWineD3DSurfaceImpl *)pSourceSurface;
      *       NOTE: move code to surface to accomplish this
       ****************************************/
     IWineD3DSurfaceImpl *pSrcSurface  = (IWineD3DSurfaceImpl *)pSourceSurface;
+    IWineD3DSurfaceImpl *dst_impl = (IWineD3DSurfaceImpl *)pDestinationSurface;
     int srcWidth, srcHeight;
     unsigned int  srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight;
     WINED3DFORMAT destFormat, srcFormat;
     int srcWidth, srcHeight;
     unsigned int  srcSurfaceWidth, srcSurfaceHeight, destSurfaceWidth, destSurfaceHeight;
     WINED3DFORMAT destFormat, srcFormat;
@@ -6211,31 +5739,28 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
     WINED3DPOOL       srcPool, destPool;
     int offset    = 0;
     int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */
     WINED3DPOOL       srcPool, destPool;
     int offset    = 0;
     int rowoffset = 0; /* how many bytes to add onto the end of a row to wraparound to the beginning of the next */
-    glDescriptor *glDescription = NULL;
     const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc;
     GLenum dummy;
     const struct GlPixelFormatDesc *src_format_desc, *dst_format_desc;
     GLenum dummy;
-    int sampler;
+    DWORD sampler;
     int bpp;
     CONVERT_TYPES convert = NO_CONVERSION;
 
     WINED3DSURFACE_DESC  winedesc;
 
     TRACE("(%p) : Source (%p)  Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
     int bpp;
     CONVERT_TYPES convert = NO_CONVERSION;
 
     WINED3DSURFACE_DESC  winedesc;
 
     TRACE("(%p) : Source (%p)  Rect (%p) Destination (%p) Point(%p)\n", This, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
-    memset(&winedesc, 0, sizeof(winedesc));
-    winedesc.Width  = &srcSurfaceWidth;
-    winedesc.Height = &srcSurfaceHeight;
-    winedesc.Pool   = &srcPool;
-    winedesc.Format = &srcFormat;
 
     IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
 
     IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
-
-    winedesc.Width  = &destSurfaceWidth;
-    winedesc.Height = &destSurfaceHeight;
-    winedesc.Pool   = &destPool;
-    winedesc.Format = &destFormat;
-    winedesc.Size   = &destSize;
+    srcSurfaceWidth = winedesc.width;
+    srcSurfaceHeight = winedesc.height;
+    srcPool = winedesc.pool;
+    srcFormat = winedesc.format;
 
     IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
 
     IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
+    destSurfaceWidth = winedesc.width;
+    destSurfaceHeight = winedesc.height;
+    destPool = winedesc.pool;
+    destFormat = winedesc.format;
+    destSize = winedesc.size;
 
     if(srcPool != WINED3DPOOL_SYSTEMMEM  || destPool != WINED3DPOOL_DEFAULT){
         WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface);
 
     if(srcPool != WINED3DPOOL_SYSTEMMEM  || destPool != WINED3DPOOL_DEFAULT){
         WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n", pSourceSurface, pDestinationSurface);
@@ -6246,8 +5771,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
      * destination's sysmem copy. If surface conversion is needed, use BltFast instead to
      * copy in sysmem and use regular surface loading.
      */
      * destination's sysmem copy. If surface conversion is needed, use BltFast instead to
      * copy in sysmem and use regular surface loading.
      */
-    d3dfmt_get_conv((IWineD3DSurfaceImpl *) pDestinationSurface, FALSE, TRUE,
-                    &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
+    d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
     if(convert != NO_CONVERSION) {
         return IWineD3DSurface_BltFast(pDestinationSurface,
                                         pDestPoint  ? pDestPoint->x : 0,
     if(convert != NO_CONVERSION) {
         return IWineD3DSurface_BltFast(pDestinationSurface,
                                         pDestPoint  ? pDestPoint->x : 0,
@@ -6263,7 +5787,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
     }
 
         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
     }
 
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
 
     ENTER_GL();
     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
 
     ENTER_GL();
     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
@@ -6274,10 +5798,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
     surface_internal_preload(pDestinationSurface, SRGB_RGB);
     IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
 
     surface_internal_preload(pDestinationSurface, SRGB_RGB);
     IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
 
-    IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription);
-
     src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc;
     src_format_desc = ((IWineD3DSurfaceImpl *)pSrcSurface)->resource.format_desc;
-    dst_format_desc = ((IWineD3DSurfaceImpl *)pDestinationSurface)->resource.format_desc;
+    dst_format_desc = dst_impl->resource.format_desc;
 
     /* this needs to be done in lines if the sourceRect != the sourceWidth */
     srcWidth   = pSourceRect ? pSourceRect->right - pSourceRect->left   : srcSurfaceWidth;
 
     /* this needs to be done in lines if the sourceRect != the sourceWidth */
     srcWidth   = pSourceRect ? pSourceRect->right - pSourceRect->left   : srcSurfaceWidth;
@@ -6300,7 +5822,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
        offset +=  pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count;
     }
     TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n",
        offset +=  pSourceRect->top * srcSurfaceWidth * src_format_desc->byte_count;
     }
     TRACE("(%p) glTexSubImage2D, level %d, left %d, top %d, width %d, height %d, fmt %#x, type %#x, memory %p+%#x\n",
-            This, glDescription->level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
+            This, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
             dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset);
 
     /* Sanity check */
             dst_format_desc->glType, IWineD3DSurface_GetData(pSourceSurface), offset);
 
     /* Sanity check */
@@ -6322,7 +5844,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
 
         for (j = destTop; j < (srcHeight + destTop); ++j)
         {
 
         for (j = destTop; j < (srcHeight + destTop); ++j)
         {
-            glTexSubImage2D(glDescription->target, glDescription->level, destLeft, j,
+            glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j,
                     srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data);
             data += rowoffset;
         }
                     srcWidth, 1, dst_format_desc->glFormat, dst_format_desc->glType,data);
             data += rowoffset;
         }
@@ -6330,28 +5852,26 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
     } else { /* Full width, so just write out the whole texture */
         const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
 
     } else { /* Full width, so just write out the whole texture */
         const unsigned char* data = ((const unsigned char *)IWineD3DSurface_GetData(pSourceSurface)) + offset;
 
-        if (WINED3DFMT_DXT1 == destFormat ||
-            WINED3DFMT_DXT2 == destFormat ||
-            WINED3DFMT_DXT3 == destFormat ||
-            WINED3DFMT_DXT4 == destFormat ||
-            WINED3DFMT_DXT5 == destFormat) {
-            if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
-                if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth) {
-                    /* FIXME: The easy way to do this is to lock the destination, and copy the bits across */
-                    FIXME("Updating part of a compressed texture is not supported at the moment\n");
-                } if (destFormat != srcFormat) {
-                    FIXME("Updating mixed format compressed texture is not curretly support\n");
-                } else {
-                    GL_EXTCALL(glCompressedTexImage2DARB(glDescription->target, glDescription->level,
-                            dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
-                }
-            } else {
-                FIXME("Attempting to update a DXT compressed texture without hardware support\n");
+        if (dst_format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+        {
+            if (destSurfaceHeight != srcHeight || destSurfaceWidth != srcWidth)
+            {
+                /* FIXME: The easy way to do this is to lock the destination, and copy the bits across. */
+                FIXME("Updating part of a compressed texture is not supported.\n");
             }
             }
-
-
-        } else {
-            glTexSubImage2D(glDescription->target, glDescription->level, destLeft, destTop,
+            if (destFormat != srcFormat)
+            {
+                FIXME("Updating mixed format compressed textures is not supported.\n");
+            }
+            else
+            {
+                GL_EXTCALL(glCompressedTexImage2DARB(dst_impl->texture_target, dst_impl->texture_level,
+                        dst_format_desc->glInternal, srcWidth, srcHeight, 0, destSize, data));
+            }
+        }
+        else
+        {
+            glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop,
                     srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data);
         }
      }
                     srcWidth, srcHeight, dst_format_desc->glFormat, dst_format_desc->glType, data);
         }
      }
@@ -6361,7 +5881,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
 
     IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE);
     sampler = This->rev_tex_unit_map[0];
 
     IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE);
     sampler = This->rev_tex_unit_map[0];
-    if (sampler != -1) {
+    if (sampler != WINED3D_UNMAPPED_STAGE)
+    {
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
     }
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
     }
 
@@ -6503,6 +6024,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
         const WINED3DRECT *rect, const float color[4])
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
         const WINED3DRECT *rect, const float color[4])
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    struct wined3d_context *context;
     IWineD3DSwapChain *swapchain;
 
     swapchain = get_swapchain(surface);
     IWineD3DSwapChain *swapchain;
 
     swapchain = get_swapchain(surface);
@@ -6511,21 +6033,20 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
         TRACE("Surface %p is onscreen\n", surface);
 
 
         TRACE("Surface %p is onscreen\n", surface);
 
-        ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
+        context = ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
         buffer = surface_get_gl_buffer(surface, swapchain);
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
     } else {
         TRACE("Surface %p is offscreen\n", surface);
 
         buffer = surface_get_gl_buffer(surface, swapchain);
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
     } else {
         TRACE("Surface %p is offscreen\n", surface);
 
-        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
-        context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
-        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
-        checkGLcall("glFramebufferRenderbufferEXT");
+        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
+        context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, surface);
+        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE);
     }
 
     if (rect) {
     }
 
     if (rect) {
@@ -6553,13 +6074,6 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
     glClear(GL_COLOR_BUFFER_BIT);
     checkGLcall("glClear");
 
     glClear(GL_COLOR_BUFFER_BIT);
     checkGLcall("glClear");
 
-    if (This->activeContext->current_fbo) {
-        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->current_fbo->id);
-    } else {
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-        checkGLcall("glBindFramebuffer()");
-    }
-
     if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer
             && ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) {
         glDrawBuffer(GL_BACK);
     if (swapchain && surface == ((IWineD3DSwapChainImpl *)swapchain)->frontBuffer
             && ((IWineD3DSwapChainImpl *)swapchain)->backBuffer) {
         glDrawBuffer(GL_BACK);
@@ -6697,7 +6211,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD
         BltFx.dwSize = sizeof(BltFx);
         BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format);
         return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
         BltFx.dwSize = sizeof(BltFx);
         BltFx.u5.dwFillColor = argb_to_fmt(color, surface->resource.format_desc->format);
         return IWineD3DSurface_Blt(pSurface, (const RECT *)pRect, NULL, NULL,
-                WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+                WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
     }
 }
 
     }
 }
 
@@ -6735,16 +6249,16 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac
 
         WARN("Converting to WINED3DCOLOR, this might give incorrect results\n");
 
 
         WARN("Converting to WINED3DCOLOR, this might give incorrect results\n");
 
-        c = ((DWORD)(color[2] * 255.0));
-        c |= ((DWORD)(color[1] * 255.0)) << 8;
-        c |= ((DWORD)(color[0] * 255.0)) << 16;
-        c |= ((DWORD)(color[3] * 255.0)) << 24;
+        c = ((DWORD)(color[2] * 255.0f));
+        c |= ((DWORD)(color[1] * 255.0f)) << 8;
+        c |= ((DWORD)(color[0] * 255.0f)) << 16;
+        c |= ((DWORD)(color[3] * 255.0f)) << 24;
 
         /* Just forward this to the DirectDraw blitting engine */
         memset(&BltFx, 0, sizeof(BltFx));
         BltFx.dwSize = sizeof(BltFx);
         BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format);
 
         /* Just forward this to the DirectDraw blitting engine */
         memset(&BltFx, 0, sizeof(BltFx));
         BltFx.dwSize = sizeof(BltFx);
         BltFx.u5.dwFillColor = argb_to_fmt(c, ((IWineD3DSurfaceImpl *)surface)->resource.format_desc->format);
-        hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
+        hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_POINT);
         if (FAILED(hr))
         {
             ERR("Blt failed, hr %#x\n", hr);
         if (FAILED(hr))
         {
             ERR("Blt failed, hr %#x\n", hr);
@@ -6829,6 +6343,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
         /* What to do about the context here in the case of multithreading? Not sure.
          * This function is called by IDirect3D7::CreateDevice so in theory its initialization code
          */
         /* What to do about the context here in the case of multithreading? Not sure.
          * This function is called by IDirect3D7::CreateDevice so in theory its initialization code
          */
+        WARN("No active context?\n");
+
         ENTER_GL();
         if(!Swapchain->backBuffer[0]) {
             /* GL was told to draw to the front buffer at creation,
         ENTER_GL();
         if(!Swapchain->backBuffer[0]) {
             /* GL was told to draw to the front buffer at creation,
@@ -6887,6 +6403,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
     IWineD3DSwapChain *src_swapchain, *dst_swapchain;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
     IWineD3DSwapChain *src_swapchain, *dst_swapchain;
+    struct wined3d_context *context;
     GLenum gl_filter;
     POINT offset = {0, 0};
 
     GLenum gl_filter;
     POINT offset = {0, 0};
 
@@ -6910,11 +6427,16 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
 
     /* Attach src surface to src fbo */
     src_swapchain = get_swapchain(src_surface);
 
     /* Attach src surface to src fbo */
     src_swapchain = get_swapchain(src_surface);
+    dst_swapchain = get_swapchain(dst_surface);
+
+    if (src_swapchain) context = ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);
+    else if (dst_swapchain) context = ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
+    else context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
     if (src_swapchain) {
         GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
 
         TRACE("Source surface %p is onscreen\n", src_surface);
     if (src_swapchain) {
         GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
 
         TRACE("Source surface %p is onscreen\n", src_surface);
-        ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);
         /* Make sure the drawable is up to date. In the offscreen case
          * attach_surface_fbo() implicitly takes care of this. */
         IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
         /* Make sure the drawable is up to date. In the offscreen case
          * attach_surface_fbo() implicitly takes care of this. */
         IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
@@ -6934,28 +6456,25 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
+        context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL);
         glReadBuffer(buffer);
         checkGLcall("glReadBuffer()");
     } else {
         TRACE("Source surface %p is offscreen\n", src_surface);
         ENTER_GL();
         glReadBuffer(buffer);
         checkGLcall("glReadBuffer()");
     } else {
         TRACE("Source surface %p is offscreen\n", src_surface);
         ENTER_GL();
-        context_bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
-        context_attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
+        context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, &context->src_fbo);
+        context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glReadBuffer()");
         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glReadBuffer()");
-        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
-        checkGLcall("glFramebufferRenderbufferEXT");
+        context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL, FALSE);
     }
     LEAVE_GL();
 
     /* Attach dst surface to dst fbo */
     }
     LEAVE_GL();
 
     /* Attach dst surface to dst fbo */
-    dst_swapchain = get_swapchain(dst_surface);
     if (dst_swapchain) {
         GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
 
         TRACE("Destination surface %p is onscreen\n", dst_surface);
     if (dst_swapchain) {
         GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
 
         TRACE("Destination surface %p is onscreen\n", dst_surface);
-        ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
         /* Make sure the drawable is up to date. In the offscreen case
          * attach_surface_fbo() implicitly takes care of this. */
         IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
         /* Make sure the drawable is up to date. In the offscreen case
          * attach_surface_fbo() implicitly takes care of this. */
         IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
@@ -6976,24 +6495,18 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
+        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL);
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
     } else {
         TRACE("Destination surface %p is offscreen\n", dst_surface);
 
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
     } else {
         TRACE("Destination surface %p is offscreen\n", dst_surface);
 
-        /* No src or dst swapchain? Make sure some context is active(multithreading) */
-        if(!src_swapchain) {
-            ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        }
-
         ENTER_GL();
         ENTER_GL();
-        context_bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
-        context_attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
+        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, &context->dst_fbo);
+        context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glDrawBuffer()");
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glDrawBuffer()");
-        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
-        checkGLcall("glFramebufferRenderbufferEXT");
+        context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL, FALSE);
     }
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
     }
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
@@ -7010,13 +6523,6 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
 
     IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
 
 
     IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
 
-    if (This->activeContext->current_fbo) {
-        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->current_fbo->id);
-    } else {
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-        checkGLcall("glBindFramebuffer()");
-    }
-
     /* If we switched from GL_BACK to GL_FRONT above, we need to switch back here */
     if (dst_swapchain && dst_surface == ((IWineD3DSwapChainImpl *)dst_swapchain)->frontBuffer
             && ((IWineD3DSwapChainImpl *)dst_swapchain)->backBuffer) {
     /* If we switched from GL_BACK to GL_FRONT above, we need to switch back here */
     if (dst_swapchain && dst_surface == ((IWineD3DSwapChainImpl *)dst_swapchain)->frontBuffer
             && ((IWineD3DSwapChainImpl *)dst_swapchain)->backBuffer) {
@@ -7070,10 +6576,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface,
         viewport.MaxZ   = 1.0f;
         viewport.MinZ   = 0.0f;
         IWineD3DDeviceImpl_SetViewport(iface, &viewport);
         viewport.MaxZ   = 1.0f;
         viewport.MinZ   = 0.0f;
         IWineD3DDeviceImpl_SetViewport(iface, &viewport);
-        /* Make sure the viewport state is dirty, because the render_offscreen thing affects it.
-         * SetViewport may catch NOP viewport changes, which would occur when switching between equally sized targets
-         */
-        IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VIEWPORT);
     }
     return WINED3D_OK;
 }
     }
     return WINED3D_OK;
 }
@@ -7100,8 +6602,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *
                     || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) {
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED);
             } else {
                     || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) {
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_DISCARDED);
             } else {
-                ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
-                surface_load_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
+                struct wined3d_context *context = ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
+                surface_load_ds_location(This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN);
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
             }
         }
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
             }
         }
@@ -7135,7 +6637,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
 
     /* some basic validation checks */
     if(This->cursorTexture) {
 
     /* some basic validation checks */
     if(This->cursorTexture) {
-        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         glDeleteTextures(1, &This->cursorTexture);
         LEAVE_GL();
         ENTER_GL();
         glDeleteTextures(1, &This->cursorTexture);
         LEAVE_GL();
@@ -7185,7 +6687,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
                 INT height = This->cursorHeight;
                 INT width = This->cursorWidth;
                 INT bpp = glDesc->byte_count;
                 INT height = This->cursorHeight;
                 INT width = This->cursorWidth;
                 INT bpp = glDesc->byte_count;
-                INT i, sampler;
+                DWORD sampler;
+                INT i;
 
                 /* Reformat the texture memory (pitch and width can be
                  * different) */
 
                 /* Reformat the texture memory (pitch and width can be
                  * different) */
@@ -7193,6 +6696,9 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
                 for(i = 0; i < height; i++)
                     memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp);
                 IWineD3DSurface_UnlockRect(pCursorBitmap);
                 for(i = 0; i < height; i++)
                     memcpy(&mem[width * bpp * i], &bits[rect.Pitch * i], width * bpp);
                 IWineD3DSurface_UnlockRect(pCursorBitmap);
+
+                ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
                 ENTER_GL();
 
                 if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
                 ENTER_GL();
 
                 if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
@@ -7204,7 +6710,8 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
                 checkGLcall("glActiveTextureARB");
                 sampler = This->rev_tex_unit_map[0];
                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
                 checkGLcall("glActiveTextureARB");
                 sampler = This->rev_tex_unit_map[0];
-                if (sampler != -1) {
+                if (sampler != WINED3D_UNMAPPED_STAGE)
+                {
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
                 }
                 /* Create a new cursor texture */
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
                 }
                 /* Create a new cursor texture */
@@ -7341,14 +6848,21 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_TestCooperativeLevel(IWineD3DDevice*
     return WINED3DERR_DRIVERINTERNALERROR;
 }
 
     return WINED3DERR_DRIVERINTERNALERROR;
 }
 
+static HRESULT WINAPI evict_managed_resource(IWineD3DResource *resource, void *data) {
+    TRACE("checking resource %p for eviction\n", resource);
+    if(((IWineD3DResourceImpl *) resource)->resource.pool == WINED3DPOOL_MANAGED) {
+        TRACE("Evicting %p\n", resource);
+        IWineD3DResource_UnLoad(resource);
+    }
+    IWineD3DResource_Release(resource);
+    return S_OK;
+}
 
 static HRESULT  WINAPI  IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice* iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
 
 static HRESULT  WINAPI  IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice* iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    /** FIXME: Resource tracking needs to be done,
-    * The closes we can do to this is set the priorities of all managed textures low
-    * and then reset them.
-     ***********************************************************/
-    FIXME("(%p) : stub\n", This);
+    TRACE("(%p)\n", This);
+
+    IWineD3DDevice_EnumResources(iface, evict_managed_resource, NULL);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -7383,12 +6897,13 @@ static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, const WINED3DPRESENT
     surface->glRect.right = surface->pow2Width;
     surface->glRect.bottom = surface->pow2Height;
 
     surface->glRect.right = surface->pow2Width;
     surface->glRect.bottom = surface->pow2Height;
 
-    if(surface->glDescription.textureName) {
-        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    if (surface->texture_name)
+    {
+        ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        glDeleteTextures(1, &surface->glDescription.textureName);
+        glDeleteTextures(1, &surface->texture_name);
         LEAVE_GL();
         LEAVE_GL();
-        surface->glDescription.textureName = 0;
+        surface->texture_name = 0;
         surface->Flags &= ~SFLAG_CLIENT;
     }
     if(surface->pow2Width != pPresentationParameters->BackBufferWidth ||
         surface->Flags &= ~SFLAG_CLIENT;
     }
     if(surface->pow2Width != pPresentationParameters->BackBufferWidth ||
@@ -7449,6 +6964,8 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_
     UINT i;
     IWineD3DBaseShaderImpl *shader;
 
     UINT i;
     IWineD3DBaseShaderImpl *shader;
 
+    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+
     IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
     LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
         This->shader_backend->shader_destroy((IWineD3DBaseShader *) shader);
     IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
     LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
         This->shader_backend->shader_destroy((IWineD3DBaseShader *) shader);
@@ -7483,7 +7000,6 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_
     while(This->numContexts) {
         DestroyContext(This, This->contexts[0]);
     }
     while(This->numContexts) {
         DestroyContext(This, This->contexts[0]);
     }
-    This->activeContext = NULL;
     HeapFree(GetProcessHeap(), 0, swapchain->context);
     swapchain->context = NULL;
     swapchain->num_contexts = 0;
     HeapFree(GetProcessHeap(), 0, swapchain->context);
     swapchain->context = NULL;
     swapchain->num_contexts = 0;
@@ -7505,7 +7021,6 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
     swapchain->context[0] = CreateContext(This, target, swapchain->win_handle, FALSE,
                                           &swapchain->presentParms);
     swapchain->num_contexts = 1;
     swapchain->context[0] = CreateContext(This, target, swapchain->win_handle, FALSE,
                                           &swapchain->presentParms);
     swapchain->num_contexts = 1;
-    This->activeContext = swapchain->context[0];
 
     create_dummy_textures(This);
 
 
     create_dummy_textures(This);
 
@@ -7775,69 +7290,36 @@ static void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT i
 * any handles to other resource held by the caller must be closed
 * (e.g. a texture should release all held surfaces because telling the device that it's been released.)
  *****************************************************/
 * any handles to other resource held by the caller must be closed
 * (e.g. a texture should release all held surfaces because telling the device that it's been released.)
  *****************************************************/
-static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
+    TRACE("(%p) : Adding resource %p\n", This, resource);
 
 
-    TRACE("(%p) : Adding Resource %p\n", This, resource);
     list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
     list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
-static void IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
+static void device_resource_remove(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
     TRACE("(%p) : Removing resource %p\n", This, resource);
 
     list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
     TRACE("(%p) : Removing resource %p\n", This, resource);
 
     list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
-
-static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DResource *resource){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
+{
     WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource);
     int counter;
 
     TRACE("(%p) : resource %p\n", This, resource);
 
     WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource);
     int counter;
 
     TRACE("(%p) : resource %p\n", This, resource);
 
-    context_resource_released(iface, resource, type);
+    context_resource_released((IWineD3DDevice *)This, resource, type);
 
     switch (type) {
         /* TODO: check front and back buffers, rendertargets etc..  possibly swapchains? */
         case WINED3DRTYPE_SURFACE: {
             unsigned int i;
 
 
     switch (type) {
         /* TODO: check front and back buffers, rendertargets etc..  possibly swapchains? */
         case WINED3DRTYPE_SURFACE: {
             unsigned int i;
 
-            /* Cleanup any FBO attachments if d3d is enabled */
-            if(This->d3d_initialized) {
-                if((IWineD3DSurface *)resource == This->lastActiveRenderTarget) {
-                    IWineD3DSwapChainImpl *swapchain = This->swapchains ? (IWineD3DSwapChainImpl *) This->swapchains[0] : NULL;
-
-                    TRACE("Last active render target destroyed\n");
-                    /* Find a replacement surface for the currently active back buffer. The context manager does not do NULL
-                     * checks, so switch to a valid target as long as the currently set surface is still valid. Use the
-                     * surface of the implicit swpchain. If that is the same as the destroyed surface the device is destroyed
-                     * and the lastActiveRenderTarget member shouldn't matter
-                     */
-                    if(swapchain) {
-                        if(swapchain->backBuffer && swapchain->backBuffer[0] != (IWineD3DSurface *)resource) {
-                            TRACE("Activating primary back buffer\n");
-                            ActivateContext(This, swapchain->backBuffer[0], CTXUSAGE_RESOURCELOAD);
-                        } else if(!swapchain->backBuffer && swapchain->frontBuffer != (IWineD3DSurface *)resource) {
-                            /* Single buffering environment */
-                            TRACE("Activating primary front buffer\n");
-                            ActivateContext(This, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD);
-                        } else {
-                            TRACE("Device is being destroyed, setting lastActiveRenderTarget = 0xdeadbabe\n");
-                            /* Implicit render target destroyed, that means the device is being destroyed
-                             * whatever we set here, it shouldn't matter
-                             */
-                            This->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadbabe;
-                        }
-                    } else {
-                        /* May happen during ddraw uninitialization */
-                        TRACE("Render target set, but swapchain does not exist!\n");
-                        This->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadcafe;
-                    }
-                }
-
+            if (This->d3d_initialized)
+            {
                 for (i = 0; i < GL_LIMITS(buffers); ++i) {
                     if (This->render_targets[i] == (IWineD3DSurface *)resource) {
                         This->render_targets[i] = NULL;
                 for (i = 0; i < GL_LIMITS(buffers); ++i) {
                     if (This->render_targets[i] == (IWineD3DSurface *)resource) {
                         This->render_targets[i] = NULL;
@@ -7913,7 +7395,7 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
 
 
     /* Remove the resource from the resourceStore */
 
 
     /* Remove the resource from the resourceStore */
-    IWineD3DDeviceImpl_RemoveResource(iface, resource);
+    device_resource_remove(This, resource);
 
     TRACE("Resource released\n");
 
 
     TRACE("Resource released\n");
 
@@ -8085,7 +7567,6 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_UpdateSurface,
     IWineD3DDeviceImpl_GetFrontBufferData,
     /*** object tracking ***/
     IWineD3DDeviceImpl_UpdateSurface,
     IWineD3DDeviceImpl_GetFrontBufferData,
     /*** object tracking ***/
-    IWineD3DDeviceImpl_ResourceReleased,
     IWineD3DDeviceImpl_EnumResources
 };
 
     IWineD3DDeviceImpl_EnumResources
 };
 
@@ -8209,12 +7690,11 @@ const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S] = {
 
 void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
     DWORD rep = This->StateTable[state].representative;
 
 void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
     DWORD rep = This->StateTable[state].representative;
+    struct wined3d_context *context;
     DWORD idx;
     BYTE shift;
     UINT i;
     DWORD idx;
     BYTE shift;
     UINT i;
-    WineD3DContext *context;
 
 
-    if(!rep) return;
     for(i = 0; i < This->numContexts; i++) {
         context = This->contexts[i];
         if(isStateDirty(context, rep)) continue;
     for(i = 0; i < This->numContexts; i++) {
         context = This->contexts[i];
         if(isStateDirty(context, rep)) continue;
@@ -8226,28 +7706,29 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
     }
 }
 
     }
 }
 
-void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
-    IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice;
-    /* The drawable size of a pbuffer render target is the current pbuffer size
-     */
-    *width = dev->pbufferWidth;
-    *height = dev->pbufferHeight;
+void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height)
+{
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.wineD3DDevice;
+    /* The drawable size of a pbuffer render target is the current pbuffer size. */
+    *width = device->pbufferWidth;
+    *height = device->pbufferHeight;
 }
 
 }
 
-void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
-    /* The drawable size of a fbo target is the opengl texture size, which is the power of two size
-     */
-    *width = This->pow2Width;
-    *height = This->pow2Height;
+void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height)
+{
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt;
+    /* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */
+    *width = surface->pow2Width;
+    *height = surface->pow2Height;
 }
 
 }
 
-void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
-    IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice;
+void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height)
+{
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;
     /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
      * current context's drawable, which is the size of the back buffer of the swapchain
      * the active context belongs to. The back buffer of the swapchain is stored as the
     /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
      * current context's drawable, which is the size of the back buffer of the swapchain
      * the active context belongs to. The back buffer of the swapchain is stored as the
-     * surface the context belongs to.
-     */
-    *width = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Width;
-    *height = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Height;
+     * surface the context belongs to. */
+    *width = surface->currentDesc.Width;
+    *height = surface->currentDesc.Height;
 }
 }
index 9a064bb..d9608f5 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-/* Compile time diagnostics: */
-
-#ifndef DEBUG_SINGLE_MODE
-/* Set to 1 to force only a single display mode to be exposed: */
-#define DEBUG_SINGLE_MODE 0
-#endif
-
 #include "config.h"
 #include "config.h"
-#include <assert.h>
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -63,6 +55,9 @@ static const struct {
 
     /* ARB */
     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT,         0                           },
 
     /* ARB */
     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT,         0                           },
+    {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT,         0                           },
+    {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP,                0                           },
+    {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE,              0                           },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
@@ -103,8 +98,10 @@ static const struct {
     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
     {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE,    0                           },
     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
     {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE,    0                           },
     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
+    {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL,       0                           },
     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
+    {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX,           0                           },
     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
@@ -140,7 +137,9 @@ static const struct {
     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
+    {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION,      0                           },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
+    {"GL_NV_fragment_program_option",       NV_FRAGMENT_PROGRAM_OPTION,     0                           },
     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
     {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT,          0                           },
 
     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
     {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT,          0                           },
 
@@ -171,19 +170,40 @@ const int maxLookup[MAX_LOOKUPS] =
 
 DWORD *stateLookup[MAX_LOOKUPS];
 
 
 DWORD *stateLookup[MAX_LOOKUPS];
 
-struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
-const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+const struct min_lookup minMipLookup[] =
+{
+    /* NONE         POINT                       LINEAR */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
+    {{GL_NEAREST,   GL_NEAREST_MIPMAP_NEAREST,  GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
+    {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
+};
+
+const struct min_lookup minMipLookup_noFilter[] =
+{
+    /* NONE         POINT                       LINEAR */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* LINEAR */
+};
+
+const struct min_lookup minMipLookup_noMip[] =
+{
+    /* NONE         POINT                       LINEAR */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
+    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
+    {{GL_LINEAR,    GL_LINEAR,                  GL_LINEAR }},               /* LINEAR */
+};
+
+const GLenum magLookup[] =
 {
 {
-    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
-    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
-    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
-    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    /* NONE     POINT       LINEAR */
+    GL_NEAREST, GL_NEAREST, GL_LINEAR,
 };
 
 };
 
-GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
-const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+const GLenum magLookup_noFilter[] =
 {
 {
-    GL_NEAREST, GL_NEAREST, GL_NEAREST, GL_NEAREST
+    /* NONE     POINT       LINEAR */
+    GL_NEAREST, GL_NEAREST, GL_NEAREST,
 };
 
 /* drawStridedSlow attributes */
 };
 
 /* drawStridedSlow attributes */
@@ -200,132 +220,104 @@ glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
  * function query some info from GL.
  */
 
  * function query some info from GL.
  */
 
-static int             wined3d_fake_gl_context_ref = 0;
-static BOOL            wined3d_fake_gl_context_foreign;
-static BOOL            wined3d_fake_gl_context_available = FALSE;
-static HDC             wined3d_fake_gl_context_hdc = NULL;
-static HWND            wined3d_fake_gl_context_hwnd = NULL;
-
-static CRITICAL_SECTION wined3d_fake_gl_context_cs;
-static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
+struct wined3d_fake_gl_ctx
 {
 {
-    0, 0, &wined3d_fake_gl_context_cs,
-    { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
-      &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
-    0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
+    HDC dc;
+    HWND wnd;
+    HGLRC gl_ctx;
 };
 };
-static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
-
-static void WineD3D_ReleaseFakeGLContext(void) {
-    HGLRC glCtx;
 
 
-    EnterCriticalSection(&wined3d_fake_gl_context_cs);
+static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
+{
+    TRACE_(d3d_caps)("Destroying fake GL context.\n");
 
 
-    if(!wined3d_fake_gl_context_available) {
-        TRACE_(d3d_caps)("context not available\n");
-        LeaveCriticalSection(&wined3d_fake_gl_context_cs);
-        return;
+    if (!pwglMakeCurrent(NULL, NULL))
+    {
+        ERR_(d3d_caps)("Failed to disable fake GL context.\n");
     }
 
     }
 
-    glCtx = pwglGetCurrentContext();
-
-    TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
-    if (0 == (--wined3d_fake_gl_context_ref) ) {
-        if(!wined3d_fake_gl_context_foreign && glCtx) {
-            TRACE_(d3d_caps)("destroying fake GL context\n");
-            pwglMakeCurrent(NULL, NULL);
-            //pwglDeleteContext(glCtx);
-        }
-        if(wined3d_fake_gl_context_hdc)
-            ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
-        wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
-        if(wined3d_fake_gl_context_hwnd)
-            DestroyWindow(wined3d_fake_gl_context_hwnd);
-        wined3d_fake_gl_context_hwnd = NULL;
-        wined3d_fake_gl_context_available = FALSE;
+    if (!pwglDeleteContext(ctx->gl_ctx))
+    {
+        DWORD err = GetLastError();
+        ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
     }
     }
-    assert(wined3d_fake_gl_context_ref >= 0);
 
 
-    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
+    ReleaseDC(ctx->wnd, ctx->dc);
+    DestroyWindow(ctx->wnd);
 }
 
 }
 
-static BOOL WineD3D_CreateFakeGLContext(void) {
-    HGLRC glCtx = NULL;
-
-    EnterCriticalSection(&wined3d_fake_gl_context_cs);
+static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
+{
+    PIXELFORMATDESCRIPTOR pfd;
+    int iPixelFormat;
 
     TRACE("getting context...\n");
 
     TRACE("getting context...\n");
-    if(wined3d_fake_gl_context_ref > 0) goto ret;
-    assert(0 == wined3d_fake_gl_context_ref);
 
 
-    wined3d_fake_gl_context_foreign = TRUE;
+    /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
+    ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
+            WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
+    if (!ctx->wnd)
+    {
+        ERR_(d3d_caps)("Failed to create a window.\n");
+        goto fail;
+    }
 
 
-    glCtx = pwglGetCurrentContext();
-    if (!glCtx) {
-        PIXELFORMATDESCRIPTOR pfd;
-        int iPixelFormat;
+    ctx->dc = GetDC(ctx->wnd);
+    if (!ctx->dc)
+    {
+        ERR_(d3d_caps)("Failed to get a DC.\n");
+        goto fail;
+    }
 
 
-        wined3d_fake_gl_context_foreign = FALSE;
+    /* PixelFormat selection */
+    ZeroMemory(&pfd, sizeof(pfd));
+    pfd.nSize = sizeof(pfd);
+    pfd.nVersion = 1;
+    pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
+    pfd.iPixelType = PFD_TYPE_RGBA;
+    pfd.cColorBits = 32;
+    pfd.iLayerType = PFD_MAIN_PLANE;
+
+    iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
+    if (!iPixelFormat)
+    {
+        /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
+        ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
+        goto fail;
+    }
+    DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
+    SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
 
 
-        /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
-        wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW,        10, 10, 10, 10, NULL, NULL, NULL, NULL);
-        if(!wined3d_fake_gl_context_hwnd) {
-            ERR("HWND creation failed!\n");
-            goto fail;
-        }
-        wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
-        if(!wined3d_fake_gl_context_hdc) {
-            ERR("GetDC failed!\n");
-            goto fail;
-        }
+    /* Create a GL context. */
+    ctx->gl_ctx = pwglCreateContext(ctx->dc);
+    if (!ctx->gl_ctx)
+    {
+        WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
+        goto fail;
+    }
 
 
-        /* PixelFormat selection */
-        ZeroMemory(&pfd, sizeof(pfd));
-        pfd.nSize      = sizeof(pfd);
-        pfd.nVersion   = 1;
-        pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
-        pfd.iPixelType = PFD_TYPE_RGBA;
-        pfd.cColorBits = 32;
-        pfd.iLayerType = PFD_MAIN_PLANE;
-
-        iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
-        if(!iPixelFormat) {
-            /* If this happens something is very wrong as ChoosePixelFormat barely fails */
-            ERR("Can't find a suitable iPixelFormat\n");
-            goto fail;
-        }
-        DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
-        SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);
-
-        /* Create a GL context */
-        glCtx = pwglCreateContext(wined3d_fake_gl_context_hdc);
-        if (!glCtx) {
-            WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
-            goto fail;
-        }
+    /* Make it the current GL context. */
+    if (!context_set_current(NULL))
+    {
+        ERR_(d3d_caps)("Failed to clear current D3D context.\n");
+    }
 
 
-        /* Make it the current GL context */
-        if (!pwglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
-            WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
-            goto fail;
-        }
+    if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
+    {
+        ERR_(d3d_caps)("Failed to make fake GL context current.\n");
+        goto fail;
     }
 
     }
 
-  ret:
-    TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
-    wined3d_fake_gl_context_ref++;
-    wined3d_fake_gl_context_available = TRUE;
-    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
     return TRUE;
     return TRUE;
-  fail:
-    if(wined3d_fake_gl_context_hdc)
-        ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
-    wined3d_fake_gl_context_hdc = NULL;
-    if(wined3d_fake_gl_context_hwnd)
-        DestroyWindow(wined3d_fake_gl_context_hwnd);
-    wined3d_fake_gl_context_hwnd = NULL;
-    if(glCtx) pwglDeleteContext(glCtx);
-    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
+
+fail:
+    if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
+    ctx->gl_ctx = NULL;
+    if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
+    ctx->dc = NULL;
+    if (ctx->wnd) DestroyWindow(ctx->wnd);
+    ctx->wnd = NULL;
+
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -387,7 +379,8 @@ static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
 /* Set the shader type for this device, depending on the given capabilities,
  * the device type, and the user preferences in wined3d_settings */
 
 /* Set the shader type for this device, depending on the given capabilities,
  * the device type, and the user preferences in wined3d_settings */
 
-static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
+static void select_shader_mode(const struct wined3d_gl_info *gl_info,
+        WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
 {
     if (wined3d_settings.vs_mode == VS_NONE) {
         *vs_selected = SHADER_NONE;
 {
     if (wined3d_settings.vs_mode == VS_NONE) {
         *vs_selected = SHADER_NONE;
@@ -395,7 +388,7 @@ static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE De
         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
          * shaders only on this card. */
         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
          * shaders only on this card. */
-        if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
+        if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2])
             *vs_selected = SHADER_ARB;
         else
             *vs_selected = SHADER_GLSL;
             *vs_selected = SHADER_ARB;
         else
             *vs_selected = SHADER_GLSL;
@@ -419,11 +412,8 @@ static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE De
 }
 
 /** Select the number of report maximum shader constants based on the selected shader modes */
 }
 
 /** Select the number of report maximum shader constants based on the selected shader modes */
-static void select_shader_max_constants(
-    int ps_selected_mode,
-    int vs_selected_mode,
-    WineD3D_GL_Info *gl_info) {
-
+static void select_shader_max_constants(int ps_selected_mode, int vs_selected_mode, struct wined3d_gl_info *gl_info)
+{
     switch (vs_selected_mode) {
         case SHADER_GLSL:
             gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF;
     switch (vs_selected_mode) {
         case SHADER_GLSL:
             gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF;
@@ -453,7 +443,8 @@ static void select_shader_max_constants(
  * IWineD3D parts follows
  **********************************************************/
 
  * IWineD3D parts follows
  **********************************************************/
 
-static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
+/* GL locking is done by the caller */
+static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
 {
     GLuint prog;
     BOOL ret = FALSE;
 {
     GLuint prog;
     BOOL ret = FALSE;
@@ -482,7 +473,7 @@ static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
 
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
 
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
-    checkGLcall("ARB vp offset limit test cleanup\n");
+    checkGLcall("ARB vp offset limit test cleanup");
 
     return ret;
 }
 
     return ret;
 }
@@ -498,529 +489,1378 @@ static DWORD ver_for_ext(GL_SupportedExt ext)
     return 0;
 }
 
     return 0;
 }
 
-static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
-    const char *GL_Extensions    = NULL;
-    const char *WGL_Extensions   = NULL;
-    const char *gl_string        = NULL;
-    const char *gl_string_cursor = NULL;
-    GLint       gl_max;
-    GLfloat     gl_floatv[2];
-    int         major = 1, minor = 0;
-    BOOL        return_value = TRUE;
-    unsigned    i;
-    HDC         hdc;
-    unsigned int vidmem=0;
-
-    TRACE_(d3d_caps)("(%p)\n", gl_info);
-
-    ENTER_GL();
+static BOOL match_ati_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    if (gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+    if (gl_info->gl_card == CARD_ATI_RADEON_9500) return TRUE;
+    if (gl_info->gl_card == CARD_ATI_RADEON_X700) return TRUE;
+    if (gl_info->gl_card == CARD_ATI_RADEON_X1600) return TRUE;
+    return FALSE;
+}
 
 
-    gl_string = (const char *) glGetString(GL_RENDERER);
-    if (!gl_string) gl_string = "None";
-    strcpy(gl_info->gl_renderer, gl_string);
-
-    gl_string = (const char *) glGetString(GL_VENDOR);
-    TRACE_(d3d_caps)("Filling vendor string %s\n", gl_string);
-    if (gl_string != NULL) {
-        /* Fill in the GL vendor */
-        if (strstr(gl_string, "NVIDIA")) {
-            gl_info->gl_vendor = VENDOR_NVIDIA;
-        } else if (strstr(gl_string, "ATI")) {
-            gl_info->gl_vendor = VENDOR_ATI;
-        } else if (strstr(gl_string, "Intel(R)") ||
-                   strstr(gl_info->gl_renderer, "Intel(R)") ||
-                   strstr(gl_string, "Intel Inc.")) {
-            gl_info->gl_vendor = VENDOR_INTEL;
-        } else if (strstr(gl_string, "Mesa")) {
-            gl_info->gl_vendor = VENDOR_MESA;
-        } else {
-            gl_info->gl_vendor = VENDOR_WINE;
+static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    if (gl_info->gl_vendor == VENDOR_NVIDIA)
+    {
+        if (gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600)
+        {
+            return TRUE;
         }
         }
-    } else {
-        gl_info->gl_vendor = VENDOR_WINE;
     }
     }
+    return FALSE;
+}
 
 
+static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
+     * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
+     * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
+     *
+     * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
+     * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
+     * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
+     * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
+     * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
+     * the chance that other implementations support them is rather small since Win32 QuickTime uses
+     * DirectDraw, not OpenGL. */
+    if (gl_info->supported[APPLE_FENCE]
+            && gl_info->supported[APPLE_CLIENT_STORAGE]
+            && gl_info->supported[APPLE_FLUSH_RENDER]
+            && gl_info->supported[APPLE_YCBCR_422])
+    {
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
 
 
-    TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
+/* Context activation is done by the caller. */
+static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
+{
+    /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
+     * but glTexSubImage from a PBO fails miserably, with the first line repeated over
+     * all the texture. This function detects this bug by its symptom and disables PBOs
+     * if the test fails.
+     *
+     * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
+     * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
+     * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
+     * read back is compared to the original. If they are equal PBOs are assumed to work,
+     * otherwise the PBO extension is disabled. */
+    GLuint texture, pbo;
+    static const unsigned int pattern[] =
+    {
+        0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
+        0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
+        0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
+        0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
+    };
+    unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
 
 
-    /* Parse the GL_VERSION field into major and minor information */
-    gl_string = (const char *) glGetString(GL_VERSION);
-    if (gl_string != NULL) {
+    /* No PBO -> No point in testing them. */
+    if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
 
 
-        /* First, parse the generic opengl version. This is supposed not to be convoluted with
-         * driver specific information
-         */
-        gl_string_cursor = gl_string;
-        major = atoi(gl_string_cursor);
-        if(major <= 0) {
-            ERR("Invalid opengl major version: %d\n", major);
-        }
-        while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
-            ++gl_string_cursor;
-        }
-        if (*gl_string_cursor++ != '.') {
-            ERR_(d3d_caps)("Invalid opengl version string: %s\n", debugstr_a(gl_string));
-        }
-        minor = atoi(gl_string_cursor);
-        TRACE_(d3d_caps)("Found OpenGL version: %d.%d\n", major, minor);
-        gl_info->gl_version = MAKEDWORD_VERSION(major, minor);
+    ENTER_GL();
 
 
-        /* Now parse the driver specific string which we'll report to the app */
-        switch (gl_info->gl_vendor) {
-        case VENDOR_NVIDIA:
-            gl_string_cursor = strstr(gl_string, "NVIDIA");
-            if (!gl_string_cursor) {
-                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
-                break;
-            }
+    while (glGetError());
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
 
 
-            gl_string_cursor = strstr(gl_string_cursor, " ");
-            if (!gl_string_cursor) {
-                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
-                break;
-            }
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
+    checkGLcall("Specifying the PBO test texture");
 
 
-            while (*gl_string_cursor == ' ') {
-                ++gl_string_cursor;
-            }
+    GL_EXTCALL(glGenBuffersARB(1, &pbo));
+    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
+    GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
+    checkGLcall("Specifying the PBO test pbo");
 
 
-            if (!*gl_string_cursor) {
-                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
-                break;
-            }
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+    checkGLcall("Loading the PBO test texture");
 
 
-            major = atoi(gl_string_cursor);
-            while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
-                ++gl_string_cursor;
-            }
+    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+    wglFinish(); /* just to be sure */
 
 
-            if (*gl_string_cursor++ != '.') {
-                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
-                break;
-            }
+    memset(check, 0, sizeof(check));
+    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
+    checkGLcall("Reading back the PBO test texture");
 
 
-            minor = atoi(gl_string_cursor);
-            minor = major*100+minor;
-            major = 10;
+    glDeleteTextures(1, &texture);
+    GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
+    checkGLcall("PBO test cleanup");
 
 
-            break;
+    LEAVE_GL();
 
 
-        case VENDOR_ATI:
-            major = minor = 0;
-            gl_string_cursor = strchr(gl_string, '-');
-            if (gl_string_cursor) {
-                int error = 0;
-                gl_string_cursor++;
-
-                /* Check if version number is of the form x.y.z */
-                if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
-                    error = 1;
-                if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
-                    error = 1;
-                if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
-                    error = 1;
-                if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
-                    error = 1;
-
-                /* Mark version number as malformed */
-                if (error)
-                    gl_string_cursor = 0;
-            }
+    if (memcmp(check, pattern, sizeof(check)))
+    {
+        WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
+        WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
+        gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
+    }
+    else
+    {
+        TRACE_(d3d_caps)("PBO test successful.\n");
+    }
+}
 
 
-            if (!gl_string_cursor)
-                WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
-            else {
-                major = *gl_string_cursor - '0';
-                minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
-            }
-            break;
+static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    return gl_info->gl_vendor == VENDOR_INTEL && match_apple(gl_info, gl_renderer);
+}
 
 
-        case VENDOR_INTEL:
-            /* Apple and Mesa version strings look differently, but both provide intel drivers */
-            if(strstr(gl_string, "APPLE")) {
-                /* [0-9]+.[0-9]+ APPLE-[0-9]+.[0.9]+.[0.9]+
-                 * We only need the first part, and use the APPLE as identification
-                 * "1.2 APPLE-1.4.56"
-                 */
-                gl_string_cursor = gl_string;
-                major = atoi(gl_string_cursor);
-                while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
-                    ++gl_string_cursor;
-                }
+static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    if (!match_apple(gl_info, gl_renderer)) return FALSE;
+    if (gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+    if (gl_info->gl_card == CARD_ATI_RADEON_X1600) return FALSE;
+    return TRUE;
+}
 
 
-                if (*gl_string_cursor++ != '.') {
-                    ERR_(d3d_caps)("Invalid MacOS-Intel version string: %s\n", debugstr_a(gl_string));
-                    break;
-                }
+static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    if (gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+    if (match_apple(gl_info, gl_renderer)) return FALSE;
+    if (strstr(gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers. */
+    return TRUE;
+}
 
 
-                minor = atoi(gl_string_cursor);
-                break;
-            }
+static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
+     * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
+     * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
+     * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
+     * hardcoded
+     *
+     * dx10 cards usually have 64 varyings */
+    return gl_info->max_glsl_varyings > 44;
+}
 
 
-        case VENDOR_MESA:
-            gl_string_cursor = strstr(gl_string, "Mesa");
-            gl_string_cursor = strstr(gl_string_cursor, " ");
-            while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
-            if (*gl_string_cursor) {
-                char tmp[16];
-                int cursor = 0;
-
-                while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
-                    tmp[cursor++] = *gl_string_cursor;
-                    ++gl_string_cursor;
-                }
-                tmp[cursor] = 0;
-                major = atoi(tmp);
+/* A GL context is provided by the caller */
+static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    GLenum error;
+    DWORD data[16];
 
 
-                if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
-                ++gl_string_cursor;
+    if(!GL_SUPPORT(EXT_SECONDARY_COLOR)) return FALSE;
 
 
-                cursor = 0;
-                while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
-                    tmp[cursor++] = *gl_string_cursor;
-                    ++gl_string_cursor;
-                }
-                tmp[cursor] = 0;
-                minor = atoi(tmp);
-            }
-            break;
+    ENTER_GL();
+    while(glGetError());
+    GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
+    error = glGetError();
+    LEAVE_GL();
 
 
-        default:
-            major = 0;
-            minor = 9;
-        }
-        gl_info->driver_version = MAKEDWORD_VERSION(major, minor);
-        TRACE_(d3d_caps)("found driver version (%s)->%i.%i->(0x%08x)\n", debugstr_a(gl_string), major, minor, gl_info->driver_version);
-        /* Current Windows drivers have versions like 6.14.... (some older have an earlier version) */
-        gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
-    } else {
-        FIXME("OpenGL driver did not return version information\n");
-        gl_info->driver_version = MAKEDWORD_VERSION(0, 0);
-        gl_info->driver_version_hipart = MAKEDWORD_VERSION(6, 14);
+    if(error == GL_NO_ERROR)
+    {
+        TRACE("GL Implementation accepts 4 component specular color pointers\n");
+        return TRUE;
+    }
+    else
+    {
+        TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
+              debug_glerror(error));
+        return FALSE;
     }
     }
+}
 
 
-    TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
+static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
+{
+    TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->vs_arb_constantsF);
+    gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+    TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->ps_arb_constantsF);
+    gl_info->ps_glsl_constantsF = gl_info->ps_arb_constantsF;
+}
 
 
-    /*
-     * Initialize openGL extension related variables
-     *  with Default values
-     */
-    memset(gl_info->supported, 0, sizeof(gl_info->supported));
-    gl_info->max_buffers        = 1;
-    gl_info->max_textures       = 1;
-    gl_info->max_texture_stages = 1;
-    gl_info->max_fragment_samplers = 1;
-    gl_info->max_vertex_samplers = 0;
-    gl_info->max_combined_samplers = gl_info->max_fragment_samplers + gl_info->max_vertex_samplers;
-    gl_info->max_sampler_stages = 1;
-    gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
-    gl_info->ps_arb_max_temps = 0;
-    gl_info->ps_arb_max_instructions = 0;
-    gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
-    gl_info->vs_arb_max_temps = 0;
-    gl_info->vs_arb_max_instructions = 0;
-    gl_info->vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
-    gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
-    gl_info->vs_glsl_constantsF = 0;
-    gl_info->ps_glsl_constantsF = 0;
-    gl_info->vs_arb_constantsF = 0;
-    gl_info->ps_arb_constantsF = 0;
+static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
+{
+    quirk_arb_constants(gl_info);
+    /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
+     * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
+     * allow 48 different offsets or other helper immediate values. */
+    TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
+    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
+}
 
 
-    /* Retrieve opengl defaults */
-    glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
-    gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
-    TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
+/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
+ * on more than one texture unit. This means that the d3d9 visual point size test will cause a
+ * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
+ * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
+ * most games, but avoids the crash
+ *
+ * A more sophisticated way would be to find all units that need texture coordinates and enable
+ * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
+ * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
+ *
+ * Note that disabling the extension entirely does not gain predictability because there is no point
+ * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. */
+static void quirk_one_point_sprite(struct wined3d_gl_info *gl_info)
+{
+    if (gl_info->supported[ARB_POINT_SPRITE])
+    {
+        TRACE("Limiting point sprites to one texture unit.\n");
+        gl_info->max_point_sprite_units = 1;
+    }
+}
 
 
-    glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
-    gl_info->max_lights = gl_max;
-    TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
+static void quirk_ati_dx9(struct wined3d_gl_info *gl_info)
+{
+    quirk_arb_constants(gl_info);
 
 
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
-    gl_info->max_texture_size = gl_max;
-    TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
+    /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
+     * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
+     * If real NP2 textures are used, the driver falls back to software. We could just remove the
+     * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
+     * due to the non-normalized texture coordinates. Thus set an internal extension flag,
+     * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
+     * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
+     *
+     * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
+     * has this extension promoted to core. The extension loading code sets this extension supported
+     * due to that, so this code works on fglrx as well. */
+    if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+    {
+        TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
+        gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+        gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
+    }
 
 
-    glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
-    gl_info->max_pointsizemin = gl_floatv[0];
-    gl_info->max_pointsize = gl_floatv[1];
-    TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
+    /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
+     * it is generally more efficient. Reserve just 8 constants. */
+    TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use.\n");
+    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
+}
 
 
-    /* Parse the gl supported features, in theory enabling parts of our code appropriately */
-    GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
-    TRACE_(d3d_caps)("GL_Extensions reported:\n");
+static void quirk_no_np2(struct wined3d_gl_info *gl_info)
+{
+    /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
+     *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
+     *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
+     *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
+     *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
+     *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
+     *
+     *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
+     *  triggering the software fallback. There is not much we can do here apart from disabling the
+     *  software-emulated extension and reenable ARB_tex_rect (which was previously disabled
+     *  in IWineD3DImpl_FillGLCaps).
+     *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
+     *  post-processing effects in the game "Max Payne 2").
+     *  The behaviour can be verified through a simple test app attached in bugreport #14724. */
+    TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
+    gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+    gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
+}
 
 
-    if (NULL == GL_Extensions) {
-        ERR("   GL_Extensions returns NULL\n");
-    } else {
-        while (*GL_Extensions != 0x00) {
-            const char *Start;
-            char        ThisExtn[256];
-            size_t      len;
-
-            while (isspace(*GL_Extensions)) GL_Extensions++;
-            Start = GL_Extensions;
-            while (!isspace(*GL_Extensions) && *GL_Extensions != 0x00) {
-                GL_Extensions++;
+static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
+{
+    /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
+     * with fixed function fragment processing. Ideally this flag should be detected with a test shader
+     * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
+     * do not like vertex shaders in feedback mode and return an error, even though it should be valid
+     * according to the spec.
+     *
+     * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
+     * makes the shader slower and eats instruction slots which should be available to the d3d app.
+     *
+     * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
+     * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
+     * this workaround is activated on cards that do not need it, it won't break things, just affect
+     * performance negatively. */
+    TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
+    gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
+}
+
+static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
+{
+    gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
+}
+
+static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
+{
+    gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
+}
+
+struct driver_quirk
+{
+    BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer);
+    void (*apply)(struct wined3d_gl_info *gl_info);
+    const char *description;
+};
+
+struct driver_quirk quirk_table[] =
+{
+    {
+        match_ati_r300_to_500,
+        quirk_ati_dx9,
+        "ATI GLSL constant and normalized texrect quirk"
+    },
+    /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
+     * used it falls back to software. While the compiler can detect if the shader uses all declared
+     * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
+     * using relative addressing falls back to software.
+     *
+     * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
+    {
+        match_apple,
+        quirk_apple_glsl_constants,
+        "Apple GLSL uniform override"
+    },
+    {
+        match_geforce5,
+        quirk_no_np2,
+        "Geforce 5 NP2 disable"
+    },
+    {
+        match_apple_intel,
+        quirk_texcoord_w,
+        "Init texcoord .w for Apple Intel GPU driver"
+    },
+    {
+        match_apple_nonr500ati,
+        quirk_texcoord_w,
+        "Init texcoord .w for Apple ATI >= r600 GPU driver"
+    },
+    {
+        match_fglrx,
+        quirk_one_point_sprite,
+        "Fglrx point sprite crash workaround"
+    },
+    {
+        match_dx10_capable,
+        quirk_clip_varying,
+        "Reserved varying for gl_ClipPos"
+    },
+    {
+        /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
+         * GL implementations accept it. The Mac GL is the only implementation known to
+         * reject it.
+         *
+         * If we can pass 4 component specular colors, do it, because (a) we don't have
+         * to screw around with the data, and (b) the D3D fixed function vertex pipeline
+         * passes specular alpha to the pixel shader if any is used. Otherwise the
+         * specular alpha is used to pass the fog coordinate, which we pass to opengl
+         * via GL_EXT_fog_coord.
+         */
+        match_allows_spec_alpha,
+        quirk_allows_specular_alpha,
+        "Allow specular alpha quirk"
+    }
+};
+
+/* Certain applications (Steam) complain if we report an outdated driver version. In general,
+ * reporting a driver version is moot because we are not the Windows driver, and we have different
+ * bugs, features, etc.
+ *
+ * If a card is not found in this table, the GL driver version is reported. */
+struct driver_version_information
+{
+    WORD vendor;                    /* reported PCI card vendor ID  */
+    WORD card;                      /* reported PCI card device ID  */
+    const char *description;        /* Description of the card e.g. NVIDIA RIVA TNT */
+    WORD hipart_hi, hipart_lo;      /* driver hiword to report      */
+    WORD lopart_hi, lopart_lo;      /* driver loword to report      */
+};
+
+static const struct driver_version_information driver_version_table[] =
+{
+    /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
+     * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
+     * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
+     * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
+     *
+     * All version numbers used below are from the Linux nvidia drivers. */
+    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        9,  6,  4,  3      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", 7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  9,  6,  10, 9371   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           9,  6,  10, 9371   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          9,  6,  10, 9371   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           7,  15, 11, 7516   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           7,  15, 11, 7516   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           7,  15, 11, 7516   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           7,  15, 11, 8585   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           7,  15, 11, 8585   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          7,  15, 11, 8585   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           7,  15, 11, 8618   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           7,  15, 11, 8618   },
+
+    /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
+    {VENDOR_ATI,        CARD_ATI_RADEON_9500,           "ATI Radeon 9500",                  6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_X700,           "ATI Radeon X700 SE",               6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          "ATI Radeon X1600 Series",          6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         "ATI Mobility Radeon HD 2300",      6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD4350,         "ATI Radeon HD 4350",               6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD4600,         "ATI Radeon HD 4600 Series",        6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD4700,         "ATI Radeon HD 4700 Series",        6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD4800,         "ATI Radeon HD 4800 Series",        6,  14, 10, 6764    },
+
+    /* TODO: Add information about legacy ATI hardware, Intel and other cards. */
+};
+
+/* Context activation is done by the caller. */
+static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+    unsigned int i;
+
+    for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
+    {
+        if (!quirk_table[i].match(gl_info, gl_renderer)) continue;
+        TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
+        quirk_table[i].apply(gl_info);
+    }
+
+    /* Find out if PBOs work as they are supposed to. */
+    test_pbo_functionality(gl_info);
+
+    /* Fixup the driver version we'll report to the app. */
+    gl_info->driver_version        = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
+    gl_info->driver_version_hipart = MAKEDWORD_VERSION(7, 1);
+    for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); ++i)
+    {
+        if (gl_info->gl_vendor == driver_version_table[i].vendor
+                && gl_info->gl_card == driver_version_table[i].card)
+        {
+            TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB.\n",
+                    gl_info->gl_vendor, gl_info->gl_card);
+
+            gl_info->driver_version = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
+                    driver_version_table[i].lopart_lo);
+            gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
+                    driver_version_table[i].hipart_lo);
+            gl_info->driver_description = driver_version_table[i].description;
+            break;
+        }
+    }
+    TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08X-0x%08X.\n",
+            gl_info->driver_version_hipart, gl_info->driver_version);
+}
+
+static DWORD wined3d_parse_gl_version(const char *gl_version)
+{
+    const char *ptr = gl_version;
+    int major, minor;
+
+    major = atoi(ptr);
+    if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
+
+    while (isdigit(*ptr)) ++ptr;
+    if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
+
+    minor = atoi(ptr);
+
+    TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
+
+    return MAKEDWORD_VERSION(major, minor);
+}
+
+static GL_Vendors wined3d_guess_vendor(const char *gl_vendor, const char *gl_renderer)
+{
+    if (strstr(gl_vendor, "NVIDIA"))
+        return VENDOR_NVIDIA;
+
+    if (strstr(gl_vendor, "ATI"))
+        return VENDOR_ATI;
+
+    if (strstr(gl_vendor, "Intel(R)")
+            || strstr(gl_renderer, "Intel(R)")
+            || strstr(gl_vendor, "Intel Inc."))
+        return VENDOR_INTEL;
+
+    if (strstr(gl_vendor, "Mesa")
+            || strstr(gl_vendor, "Tungsten Graphics, Inc."))
+        return VENDOR_MESA;
+
+    FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning VENDOR_WINE.\n", debugstr_a(gl_vendor));
+
+    return VENDOR_WINE;
+}
+
+static GL_Cards wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+        GL_Vendors *vendor, unsigned int *vidmem)
+{
+    /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of
+     * different GPUs with roughly the same features. In most cases GPUs from a
+     * certain family differ in clockspeeds, the amount of video memory and the
+     * number of shader pipelines.
+     *
+     * A Direct3D device object contains the PCI id (vendor + device) of the
+     * videocard which is used for rendering. Various applications use this
+     * information to get a rough estimation of the features of the card and
+     * some might use it for enabling 3d effects only on certain types of
+     * videocards. In some cases games might even use it to work around bugs
+     * which happen on certain videocards/driver combinations. The problem is
+     * that OpenGL only exposes a rendering string containing the name of the
+     * videocard and not the PCI id.
+     *
+     * Various games depend on the PCI id, so somehow we need to provide one.
+     * A simple option is to parse the renderer string and translate this to
+     * the right PCI id. This is a lot of work because there are more than 200
+     * GPUs just for Nvidia. Various cards share the same renderer string, so
+     * the amount of code might be 'small' but there are quite a number of
+     * exceptions which would make this a pain to maintain. Another way would
+     * be to query the PCI id from the operating system (assuming this is the
+     * videocard which is used for rendering which is not always the case).
+     * This would work but it is not very portable. Second it would not work
+     * well in, let's say, a remote X situation in which the amount of 3d
+     * features which can be used is limited.
+     *
+     * As said most games only use the PCI id to get an indication of the
+     * capabilities of the card. It doesn't really matter if the given id is
+     * the correct one if we return the id of a card with similar 3d features.
+     *
+     * The code below checks the OpenGL capabilities of a videocard and matches
+     * that to a certain level of Direct3D functionality. Once a card passes
+     * the Direct3D9 check, we know that the card (in case of Nvidia) is at
+     * least a GeforceFX. To give a better estimate we do a basic check on the
+     * renderer string but if that won't pass we return a default card. This
+     * way is better than maintaining a full card database as even without a
+     * full database we can return a card with similar features. Second the
+     * size of the database can be made quite small because when you know what
+     * type of 3d functionality a card has, you know to which GPU family the
+     * GPU must belong. Because of this you only have to check a small part of
+     * the renderer string to distinguishes between different models from that
+     * family.
+     *
+     * The code also selects a default amount of video memory which we will
+     * use for an estimation of the amount of free texture memory. In case of
+     * real D3D the amount of texture memory includes video memory and system
+     * memory (to be specific AGP memory or in case of PCIE TurboCache /
+     * HyperMemory). We don't know how much system memory can be addressed by
+     * the system but we can make a reasonable estimation about the amount of
+     * video memory. If the value is slightly wrong it doesn't matter as we
+     * didn't include AGP-like memory which makes the amount of addressable
+     * memory higher and second OpenGL isn't that critical it moves to system
+     * memory behind our backs if really needed. Note that the amount of video
+     * memory can be overruled using a registry setting. */
+
+    switch (*vendor)
+    {
+        case VENDOR_NVIDIA:
+            /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
+             * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
+             */
+            if (WINE_D3D9_CAPABLE(gl_info) && gl_info->supported[NV_VERTEX_PROGRAM3])
+            {
+                /* Geforce 200 - highend */
+                if (strstr(gl_renderer, "GTX 280")
+                        || strstr(gl_renderer, "GTX 285")
+                        || strstr(gl_renderer, "GTX 295"))
+                {
+                    *vidmem = 1024;
+                    return CARD_NVIDIA_GEFORCE_GTX280;
+                }
+
+                /* Geforce 200 - midend high */
+                if (strstr(gl_renderer, "GTX 275"))
+                {
+                    *vidmem = 896;
+                    return CARD_NVIDIA_GEFORCE_GTX275;
+                }
+
+                /* Geforce 200 - midend */
+                if (strstr(gl_renderer, "GTX 260"))
+                {
+                    *vidmem = 1024;
+                    return CARD_NVIDIA_GEFORCE_GTX260;
+                }
+
+                /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
+                if (strstr(gl_renderer, "9800")
+                        || strstr(gl_renderer, "GTS 150")
+                        || strstr(gl_renderer, "GTS 250"))
+                {
+                    *vidmem = 512;
+                    return CARD_NVIDIA_GEFORCE_9800GT;
+                }
+
+                /* Geforce9 - midend */
+                if (strstr(gl_renderer, "9600"))
+                {
+                    *vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
+                    return CARD_NVIDIA_GEFORCE_9600GT;
+                }
+
+                /* Geforce9 - midend low / Geforce 200 - low */
+                if (strstr(gl_renderer, "9500")
+                        || strstr(gl_renderer, "GT 120")
+                        || strstr(gl_renderer, "GT 130"))
+                {
+                    *vidmem = 256; /* The 9500GT has 256-1024MB */
+                    return CARD_NVIDIA_GEFORCE_9500GT;
+                }
+
+                /* Geforce9 - lowend */
+                if (strstr(gl_renderer, "9400"))
+                {
+                    *vidmem = 256; /* The 9400GT has 256-1024MB */
+                    return CARD_NVIDIA_GEFORCE_9400GT;
+                }
+
+                /* Geforce9 - lowend low */
+                if (strstr(gl_renderer, "9100")
+                        || strstr(gl_renderer, "9200")
+                        || strstr(gl_renderer, "9300")
+                        || strstr(gl_renderer, "G 100"))
+                {
+                    *vidmem = 256; /* The 9100-9300 cards have 256MB */
+                    return CARD_NVIDIA_GEFORCE_9200;
+                }
+
+                /* Geforce8 - highend */
+                if (strstr(gl_renderer, "8800"))
+                {
+                    *vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
+                    return CARD_NVIDIA_GEFORCE_8800GTS;
+                }
+
+                /* Geforce8 - midend mobile */
+                if (strstr(gl_renderer, "8600 M"))
+                {
+                    *vidmem = 512;
+                    return CARD_NVIDIA_GEFORCE_8600MGT;
+                }
+
+                /* Geforce8 - midend */
+                if (strstr(gl_renderer, "8600")
+                        || strstr(gl_renderer, "8700"))
+                {
+                    *vidmem = 256;
+                    return CARD_NVIDIA_GEFORCE_8600GT;
+                }
+
+                /* Geforce8 - lowend */
+                if (strstr(gl_renderer, "8300")
+                        || strstr(gl_renderer, "8400")
+                        || strstr(gl_renderer, "8500"))
+                {
+                    *vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
+                    return CARD_NVIDIA_GEFORCE_8300GS;
+                }
+
+                /* Geforce7 - highend */
+                if (strstr(gl_renderer, "7800")
+                        || strstr(gl_renderer, "7900")
+                        || strstr(gl_renderer, "7950")
+                        || strstr(gl_renderer, "Quadro FX 4")
+                        || strstr(gl_renderer, "Quadro FX 5"))
+                {
+                    *vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
+                    return CARD_NVIDIA_GEFORCE_7800GT;
+                }
+
+                /* Geforce7 midend */
+                if (strstr(gl_renderer, "7600")
+                        || strstr(gl_renderer, "7700"))
+                {
+                    *vidmem = 256; /* The 7600 uses 256-512MB */
+                    return CARD_NVIDIA_GEFORCE_7600;
+                }
+
+                /* Geforce7 lower medium */
+                if (strstr(gl_renderer, "7400"))
+                {
+                    *vidmem = 256; /* The 7400 uses 256-512MB */
+                    return CARD_NVIDIA_GEFORCE_7400;
+                }
+
+                /* Geforce7 lowend */
+                if (strstr(gl_renderer, "7300"))
+                {
+                    *vidmem = 256; /* Mac Pros with this card have 256 MB */
+                    return CARD_NVIDIA_GEFORCE_7300;
+                }
+
+                /* Geforce6 highend */
+                if (strstr(gl_renderer, "6800"))
+                {
+                    *vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
+                    return CARD_NVIDIA_GEFORCE_6800;
+                }
+
+                /* Geforce6 - midend */
+                if (strstr(gl_renderer, "6600")
+                        || strstr(gl_renderer, "6610")
+                        || strstr(gl_renderer, "6700"))
+                {
+                    *vidmem = 128; /* A 6600GT has 128-256MB */
+                    return CARD_NVIDIA_GEFORCE_6600GT;
+                }
+
+                /* Geforce6/7 lowend */
+                *vidmem = 64; /* */
+                return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
             }
 
             }
 
-            len = GL_Extensions - Start;
-            if (len == 0 || len >= sizeof(ThisExtn))
-                continue;
+            if (WINE_D3D9_CAPABLE(gl_info))
+            {
+                /* GeforceFX - highend */
+                if (strstr(gl_renderer, "5800")
+                        || strstr(gl_renderer, "5900")
+                        || strstr(gl_renderer, "5950")
+                        || strstr(gl_renderer, "Quadro FX"))
+                {
+                    *vidmem = 256; /* 5800-5900 cards use 256MB */
+                    return CARD_NVIDIA_GEFORCEFX_5800;
+                }
 
 
-            memcpy(ThisExtn, Start, len);
-            ThisExtn[len] = '\0';
-            TRACE_(d3d_caps)("- %s\n", ThisExtn);
+                /* GeforceFX - midend */
+                if (strstr(gl_renderer, "5600")
+                        || strstr(gl_renderer, "5650")
+                        || strstr(gl_renderer, "5700")
+                        || strstr(gl_renderer, "5750"))
+                {
+                    *vidmem = 128; /* A 5600 uses 128-256MB */
+                    return CARD_NVIDIA_GEFORCEFX_5600;
+                }
 
 
-            for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
-                if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
-                    TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
-                    gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
-                    break;
+                /* GeforceFX - lowend */
+                *vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
+                return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
+            }
+
+            if (WINE_D3D8_CAPABLE(gl_info))
+            {
+                if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
+                {
+                    *vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
+                    return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
                 }
                 }
+
+                *vidmem = 64; /* Geforce3 cards have 64-128MB */
+                return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
             }
             }
-        }
 
 
-        LEAVE_GL();
+            if (WINE_D3D7_CAPABLE(gl_info))
+            {
+                if (strstr(gl_renderer, "GeForce4 MX"))
+                {
+                    /* Most Geforce4MX GPUs have at least 64MB of memory, some
+                     * early models had 32MB but most have 64MB or even 128MB. */
+                    *vidmem = 64;
+                    return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
+                }
 
 
-        /* Now work out what GL support this card really has */
-#define USE_GL_FUNC(type, pfn, ext, replace) { \
-            DWORD ver = ver_for_ext(ext); \
-            if(gl_info->supported[ext]) gl_info->pfn = (type) pwglGetProcAddress(#pfn); \
-            else if(ver && ver <= gl_info->gl_version) gl_info->pfn = (type) pwglGetProcAddress(#replace); \
-            else gl_info->pfn = NULL; \
-        }
-        GL_EXT_FUNCS_GEN;
-#undef USE_GL_FUNC
+                if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
+                {
+                    *vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
+                    return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
+                }
 
 
-#define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type) pwglGetProcAddress(#pfn);
-        WGL_EXT_FUNCS_GEN;
-#undef USE_GL_FUNC
+                if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
+                {
+                    *vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
+                    return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
+                }
 
 
-        ENTER_GL();
-        /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
-         * loading the functions, otherwise the code above will load the extension entry points instead of the
-         * core functions, which may not work
-         */
-        for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
-            if (gl_info->supported[EXTENSION_MAP[i].extension] == FALSE &&
-                EXTENSION_MAP[i].version <= gl_info->gl_version && EXTENSION_MAP[i].version) {
-                TRACE_(d3d_caps)(" GL CORE: %s support\n", EXTENSION_MAP[i].extension_string);
-                gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
+                /* Most Geforce1 cards have 32MB, there are also some rare 16
+                 * and 64MB (Dell) models. */
+                *vidmem = 32;
+                return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
             }
             }
-        }
 
 
-        if (gl_info->supported[APPLE_FENCE]) {
-            /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
-             * The apple extension interacts with some other apple exts. Disable the NV
-             * extension if the apple one is support to prevent confusion in other parts
-             * of the code
-             */
-            gl_info->supported[NV_FENCE] = FALSE;
-        }
-        if (gl_info->supported[APPLE_FLOAT_PIXELS]) {
-            /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
+            if (strstr(gl_renderer, "TNT2"))
+            {
+                *vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
+                return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
+            }
+
+            *vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
+            return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
+
+        case VENDOR_ATI:
+            /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
              *
              *
-             * The enums are the same:
-             * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881A
-             * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881B
-             * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
-             * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
-             * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         =  0x140B
-             */
-            if(!gl_info->supported[ARB_TEXTURE_FLOAT]) {
-                TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels\n");
-                gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
+             * Beware: renderer string do not match exact card model,
+             * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
+            if (WINE_D3D9_CAPABLE(gl_info))
+            {
+                /* Radeon R7xx HD4800 - highend */
+                if (strstr(gl_renderer, "HD 4800")          /* Radeon RV7xx HD48xx generic renderer string */
+                        || strstr(gl_renderer, "HD 4830")   /* Radeon RV770 */
+                        || strstr(gl_renderer, "HD 4850")   /* Radeon RV770 */
+                        || strstr(gl_renderer, "HD 4870")   /* Radeon RV770 */
+                        || strstr(gl_renderer, "HD 4890"))  /* Radeon RV790 */
+                {
+                    *vidmem = 512; /* note: HD4890 cards use 1024MB */
+                    return CARD_ATI_RADEON_HD4800;
+                }
+
+                /* Radeon R740 HD4700 - midend */
+                if (strstr(gl_renderer, "HD 4700")          /* Radeon RV770 */
+                        || strstr(gl_renderer, "HD 4770"))  /* Radeon RV740 */
+                {
+                    *vidmem = 512;
+                    return CARD_ATI_RADEON_HD4700;
+                }
+
+                /* Radeon R730 HD4600 - midend */
+                if (strstr(gl_renderer, "HD 4600")          /* Radeon RV730 */
+                        || strstr(gl_renderer, "HD 4650")   /* Radeon RV730 */
+                        || strstr(gl_renderer, "HD 4670"))  /* Radeon RV730 */
+                {
+                    *vidmem = 512;
+                    return CARD_ATI_RADEON_HD4600;
+                }
+
+                /* Radeon R710 HD4500/HD4350 - lowend */
+                if (strstr(gl_renderer, "HD 4350")          /* Radeon RV710 */
+                        || strstr(gl_renderer, "HD 4550"))  /* Radeon RV710 */
+                {
+                    *vidmem = 256;
+                    return CARD_ATI_RADEON_HD4350;
+                }
+
+                /* Radeon R6xx HD2900/HD3800 - highend */
+                if (strstr(gl_renderer, "HD 2900")
+                        || strstr(gl_renderer, "HD 3870")
+                        || strstr(gl_renderer, "HD 3850"))
+                {
+                    *vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
+                    return CARD_ATI_RADEON_HD2900;
+                }
+
+                /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
+                if (strstr(gl_renderer, "HD 2600")
+                        || strstr(gl_renderer, "HD 3830")
+                        || strstr(gl_renderer, "HD 3690")
+                        || strstr(gl_renderer, "HD 3650"))
+                {
+                    *vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
+                    return CARD_ATI_RADEON_HD2600;
+                }
+
+                /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
+                if (strstr(gl_renderer, "HD 2300")
+                        || strstr(gl_renderer, "HD 2400")
+                        || strstr(gl_renderer, "HD 3470")
+                        || strstr(gl_renderer, "HD 3450")
+                        || strstr(gl_renderer, "HD 3430")
+                        || strstr(gl_renderer, "HD 3400"))
+                {
+                    *vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
+                    return CARD_ATI_RADEON_HD2300;
+                }
+
+                /* Radeon R6xx/R7xx integrated */
+                if (strstr(gl_renderer, "HD 3100")
+                        || strstr(gl_renderer, "HD 3200")
+                        || strstr(gl_renderer, "HD 3300"))
+                {
+                    *vidmem = 128; /* 128MB */
+                    return CARD_ATI_RADEON_HD3200;
+                }
+
+                /* Radeon R5xx */
+                if (strstr(gl_renderer, "X1600")
+                        || strstr(gl_renderer, "X1650")
+                        || strstr(gl_renderer, "X1800")
+                        || strstr(gl_renderer, "X1900")
+                        || strstr(gl_renderer, "X1950"))
+                {
+                    *vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
+                    return CARD_ATI_RADEON_X1600;
+                }
+
+                /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
+                if (strstr(gl_renderer, "X700")
+                        || strstr(gl_renderer, "X800")
+                        || strstr(gl_renderer, "X850")
+                        || strstr(gl_renderer, "X1300")
+                        || strstr(gl_renderer, "X1400")
+                        || strstr(gl_renderer, "X1450")
+                        || strstr(gl_renderer, "X1550"))
+                {
+                    *vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
+                    return CARD_ATI_RADEON_X700;
+                }
+
+                /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
+                if (strstr(gl_renderer, "Radeon Xpress"))
+                {
+                    *vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
+                    return CARD_ATI_RADEON_XPRESS_200M;
+                }
+
+                /* Radeon R3xx */
+                *vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
+                return CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
             }
             }
-            if(!gl_info->supported[ARB_HALF_FLOAT_PIXEL]) {
-                TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels\n");
-                gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
+
+            if (WINE_D3D8_CAPABLE(gl_info))
+            {
+                *vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
+                return CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
             }
             }
-        }
-        if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
-            TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
-            gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
-        }
-        if (gl_info->supported[NV_TEXTURE_SHADER2]) {
-            if(gl_info->supported[NV_REGISTER_COMBINERS]) {
-                /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
-                 * are supported. The nv extensions provide the same functionality as the
-                 * ATI one, and a bit more(signed pixelformats)
-                 */
-                gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
+
+            if (WINE_D3D7_CAPABLE(gl_info))
+            {
+                *vidmem = 32; /* There are models with up to 64MB */
+                return CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
             }
             }
-        }
-        if (gl_info->supported[ARB_DRAW_BUFFERS]) {
-            glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
-            gl_info->max_buffers = gl_max;
-            TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
-        }
-        if (gl_info->supported[ARB_MULTITEXTURE]) {
-            glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
-            gl_info->max_textures = min(MAX_TEXTURES, gl_max);
-            TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
-
-            if (gl_info->supported[NV_REGISTER_COMBINERS]) {
-                GLint tmp;
-                glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
-                gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
-            } else {
-                gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
+
+            *vidmem = 16; /* There are 16-32MB models */
+            return CARD_ATI_RAGE_128PRO;
+
+        case VENDOR_INTEL:
+            if (strstr(gl_renderer, "X3100"))
+            {
+                /* MacOS calls the card GMA X3100, Google findings also suggest the name GM965 */
+                *vidmem = 128;
+                return CARD_INTEL_X3100;
             }
             }
-            TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
 
 
-            if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
-                GLint tmp;
-                glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
-                gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
-            } else {
-                gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
+            if (strstr(gl_renderer, "GMA 950") || strstr(gl_renderer, "945GM"))
+            {
+                /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
+                *vidmem = 64;
+                return CARD_INTEL_I945GM;
             }
             }
-            TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
-
-            if (gl_info->supported[ARB_VERTEX_SHADER]) {
-                GLint tmp;
-                glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
-                gl_info->max_vertex_samplers = tmp;
-                glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
-                gl_info->max_combined_samplers = tmp;
-
-                /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
-                 * is known at shader link time. In a vertex shader + pixel shader combination this isn't
-                 * an issue because then the sampler setup only depends on the two shaders. If a pixel
-                 * shader is used with fixed function vertex processing we're fine too because fixed function
-                 * vertex processing doesn't use any samplers. If fixed function fragment processing is
-                 * used we have to make sure that all vertex sampler setups are valid together with all
-                 * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
-                 * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
-                 * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
-                 * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
-                 * a fixed function pipeline anymore.
-                 *
-                 * So this is just a check to check that our assumption holds true. If not, write a warning
-                 * and reduce the number of vertex samplers or probably disable vertex texture fetch.
-                 */
-                if(gl_info->max_vertex_samplers &&
-                   MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers) {
-                    FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers\n",
-                          gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
-                    FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers\n");
-                    if( gl_info->max_combined_samplers > MAX_TEXTURES )
-                        gl_info->max_vertex_samplers =
-                            gl_info->max_combined_samplers - MAX_TEXTURES;
-                    else
-                        gl_info->max_vertex_samplers = 0;
-                }
-            } else {
-                gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
+
+            if (strstr(gl_renderer, "915GM")) return CARD_INTEL_I915GM;
+            if (strstr(gl_renderer, "915G")) return CARD_INTEL_I915G;
+            if (strstr(gl_renderer, "865G")) return CARD_INTEL_I865G;
+            if (strstr(gl_renderer, "855G")) return CARD_INTEL_I855G;
+            if (strstr(gl_renderer, "830G")) return CARD_INTEL_I830G;
+            return CARD_INTEL_I915G;
+
+        case VENDOR_MESA:
+        case VENDOR_WINE:
+        default:
+            /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
+             * for Nvidia was because the hardware and drivers they make are of good quality. This makes
+             * them a good generic choice. */
+            *vendor = VENDOR_NVIDIA;
+            if (WINE_D3D9_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCEFX_5600;
+            if (WINE_D3D8_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE3;
+            if (WINE_D3D7_CAPABLE(gl_info)) return CARD_NVIDIA_GEFORCE;
+            if (WINE_D3D6_CAPABLE(gl_info)) return CARD_NVIDIA_RIVA_TNT;
+            return CARD_NVIDIA_RIVA_128;
+    }
+}
+
+/* Context activation is done by the caller. */
+static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info)
+{
+    const char *GL_Extensions    = NULL;
+    const char *WGL_Extensions   = NULL;
+    const char *gl_string        = NULL;
+    GLint       gl_max;
+    GLfloat     gl_floatv[2];
+    unsigned    i;
+    HDC         hdc;
+    unsigned int vidmem=0;
+    char *gl_renderer;
+    DWORD gl_version;
+    size_t len;
+
+    TRACE_(d3d_caps)("(%p)\n", gl_info);
+
+    ENTER_GL();
+
+    gl_string = (const char *)glGetString(GL_RENDERER);
+    TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_string));
+    if (!gl_string)
+    {
+        ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
+        return FALSE;
+    }
+
+    len = strlen(gl_string) + 1;
+    gl_renderer = HeapAlloc(GetProcessHeap(), 0, len);
+    if (!gl_renderer)
+    {
+        ERR_(d3d_caps)("Failed to allocate gl_renderer memory.\n");
+        return FALSE;
+    }
+    memcpy(gl_renderer, gl_string, len);
+
+    gl_string = (const char *)glGetString(GL_VENDOR);
+    TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_string));
+    if (!gl_string)
+    {
+        ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
+        HeapFree(GetProcessHeap(), 0, gl_renderer);
+        return FALSE;
+    }
+    gl_info->gl_vendor = wined3d_guess_vendor(gl_string, gl_renderer);
+    TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
+
+    /* Parse the GL_VERSION field into major and minor information */
+    gl_string = (const char *)glGetString(GL_VERSION);
+    TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_string));
+    if (!gl_string)
+    {
+        ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
+        HeapFree(GetProcessHeap(), 0, gl_renderer);
+        return FALSE;
+    }
+    gl_version = wined3d_parse_gl_version(gl_string);
+
+    /*
+     * Initialize openGL extension related variables
+     *  with Default values
+     */
+    memset(gl_info->supported, 0, sizeof(gl_info->supported));
+    gl_info->max_buffers        = 1;
+    gl_info->max_textures       = 1;
+    gl_info->max_texture_stages = 1;
+    gl_info->max_fragment_samplers = 1;
+    gl_info->max_vertex_samplers = 0;
+    gl_info->max_combined_samplers = gl_info->max_fragment_samplers + gl_info->max_vertex_samplers;
+    gl_info->max_sampler_stages = 1;
+    gl_info->ps_arb_max_temps = 0;
+    gl_info->ps_arb_max_instructions = 0;
+    gl_info->vs_arb_max_temps = 0;
+    gl_info->vs_arb_max_instructions = 0;
+    gl_info->vs_glsl_constantsF = 0;
+    gl_info->ps_glsl_constantsF = 0;
+    gl_info->vs_arb_constantsF = 0;
+    gl_info->ps_arb_constantsF = 0;
+    gl_info->ps_arb_max_local_constants = 0;
+
+    /* Retrieve opengl defaults */
+    glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
+    gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
+    TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
+
+    glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
+    gl_info->max_lights = gl_max;
+    TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
+
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
+    gl_info->max_texture_size = gl_max;
+    TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
+
+    glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
+    gl_info->max_pointsizemin = gl_floatv[0];
+    gl_info->max_pointsize = gl_floatv[1];
+    TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
+
+    /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
+    GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
+    if (!GL_Extensions)
+    {
+        ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
+        HeapFree(GetProcessHeap(), 0, gl_renderer);
+        return FALSE;
+    }
+
+    TRACE_(d3d_caps)("GL_Extensions reported:\n");
+
+    gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
+
+    while (*GL_Extensions)
+    {
+        const char *start;
+        char current_ext[256];
+
+        while (isspace(*GL_Extensions)) ++GL_Extensions;
+        start = GL_Extensions;
+        while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
+
+        len = GL_Extensions - start;
+        if (!len || len >= sizeof(current_ext)) continue;
+
+        memcpy(current_ext, start, len);
+        current_ext[len] = '\0';
+        TRACE_(d3d_caps)("- %s\n", debugstr_a(current_ext));
+
+        for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
+        {
+            if (!strcmp(current_ext, EXTENSION_MAP[i].extension_string))
+            {
+                TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
+                gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
+                break;
             }
             }
-            TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
-            TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
-        }
-        if (gl_info->supported[ARB_VERTEX_BLEND]) {
-            glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
-            gl_info->max_blends = gl_max;
-            TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
-        }
-        if (gl_info->supported[EXT_TEXTURE3D]) {
-            glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
-            gl_info->max_texture3d_size = gl_max;
-            TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
-        }
-        if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
-            glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
-            gl_info->max_anisotropy = gl_max;
-            TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
-        }
-        if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
-            gl_info->ps_arb_version = PS_VERSION_11;
-            GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
-            gl_info->ps_arb_constantsF = gl_max;
-            TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
-            GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
-            gl_info->ps_arb_max_temps = gl_max;
-            TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d\n", gl_info->ps_arb_max_temps);
-            GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
-            gl_info->ps_arb_max_instructions = gl_max;
-            TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d\n", gl_info->ps_arb_max_instructions);
-        }
-        if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
-            gl_info->vs_arb_version = VS_VERSION_11;
-            GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
-            gl_info->vs_arb_constantsF = gl_max;
-            TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
-            GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
-            gl_info->vs_arb_max_temps = gl_max;
-            TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d\n", gl_info->vs_arb_max_temps);
-            GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
-            gl_info->vs_arb_max_instructions = gl_max;
-            TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d\n", gl_info->vs_arb_max_instructions);
-
-            gl_info->arb_vs_offset_limit = test_arb_vs_offset_limit(gl_info);
         }
         }
-        if (gl_info->supported[ARB_VERTEX_SHADER]) {
-            glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
-            gl_info->vs_glsl_constantsF = gl_max / 4;
-            TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
+    }
+
+    LEAVE_GL();
+
+    /* Now work out what GL support this card really has */
+#define USE_GL_FUNC(type, pfn, ext, replace) \
+{ \
+    DWORD ver = ver_for_ext(ext); \
+    if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
+    else if (ver && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
+    else gl_info->pfn = NULL; \
+}
+    GL_EXT_FUNCS_GEN;
+#undef USE_GL_FUNC
+
+#define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
+    WGL_EXT_FUNCS_GEN;
+#undef USE_GL_FUNC
+
+    ENTER_GL();
+
+    /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
+     * loading the functions, otherwise the code above will load the extension entry points instead of the
+     * core functions, which may not work. */
+    for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
+    {
+        if (!gl_info->supported[EXTENSION_MAP[i].extension]
+                && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
+        {
+            TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
+            gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
         }
         }
-        if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
-            glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
-            gl_info->ps_glsl_constantsF = gl_max / 4;
-            TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
-            glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
-            gl_info->max_glsl_varyings = gl_max;
-            TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings)\n", gl_max, gl_max / 4);
+    }
+
+    if (gl_info->supported[APPLE_FENCE])
+    {
+        /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
+         * The apple extension interacts with some other apple exts. Disable the NV
+         * extension if the apple one is support to prevent confusion in other parts
+         * of the code. */
+        gl_info->supported[NV_FENCE] = FALSE;
+    }
+    if (gl_info->supported[APPLE_FLOAT_PIXELS])
+    {
+        /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
+         *
+         * The enums are the same:
+         * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881A
+         * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881B
+         * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
+         * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
+         * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         = 0x140B
+         */
+        if (!gl_info->supported[ARB_TEXTURE_FLOAT])
+        {
+            TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
+            gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
         }
         }
-        if (gl_info->supported[EXT_VERTEX_SHADER]) {
-            gl_info->vs_ati_version = VS_VERSION_11;
+        if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
+        {
+            TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
+            gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
         }
         }
-        if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
-            gl_info->vs_nv_version = VS_VERSION_30;
-        } else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
-            gl_info->vs_nv_version = VS_VERSION_20;
-        } else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
-            gl_info->vs_nv_version = VS_VERSION_11;
-        } else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
-            gl_info->vs_nv_version = VS_VERSION_10;
+    }
+    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+    {
+        TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
+        gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
+    }
+    if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
+    {
+        TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
+        gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
+    }
+    if (gl_info->supported[NV_TEXTURE_SHADER2])
+    {
+        if (gl_info->supported[NV_REGISTER_COMBINERS])
+        {
+            /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
+             * are supported. The nv extensions provide the same functionality as the
+             * ATI one, and a bit more(signed pixelformats). */
+            gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
         }
         }
-        if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
-            gl_info->ps_nv_version = PS_VERSION_30;
-        } else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
-            gl_info->ps_nv_version = PS_VERSION_20;
+    }
+    if (gl_info->supported[ARB_DRAW_BUFFERS])
+    {
+        glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
+        gl_info->max_buffers = gl_max;
+        TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
+    }
+    if (gl_info->supported[ARB_MULTITEXTURE])
+    {
+        glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
+        gl_info->max_textures = min(MAX_TEXTURES, gl_max);
+        TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->max_textures);
+
+        if (gl_info->supported[NV_REGISTER_COMBINERS])
+        {
+            GLint tmp;
+            glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
+            gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
         }
         }
-        if (gl_info->supported[NV_LIGHT_MAX_EXPONENT]) {
-            glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->max_shininess);
-        } else {
-            gl_info->max_shininess = 128.0;
+        else
+        {
+            gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
         }
         }
-        if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
-            /* If we have full NP2 texture support, disable GL_ARB_texture_rectangle because we will never use it.
-             * This saves a few redundant glDisable calls
-             */
-            gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
+        TRACE_(d3d_caps)("Max texture stages: %d.\n", gl_info->max_texture_stages);
+
+        if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+        {
+            GLint tmp;
+            glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+            gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
         }
         }
-        if(gl_info->supported[ATI_FRAGMENT_SHADER]) {
-            /* Disable NV_register_combiners and fragment shader if this is supported.
-             * generally the NV extensions are preferred over the ATI ones, and this
-             * extension is disabled if register_combiners and texture_shader2 are both
-             * supported. So we reach this place only if we have incomplete NV dxlevel 8
-             * fragment processing support
-             */
-            gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
-            gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
-            gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
-            gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
-            gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
+        else
+        {
+            gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
         }
         }
-        if(gl_info->supported[NV_HALF_FLOAT]) {
-            /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float */
-            gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
+        TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->max_fragment_samplers);
+
+        if (gl_info->supported[ARB_VERTEX_SHADER])
+        {
+            GLint tmp;
+            glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+            gl_info->max_vertex_samplers = tmp;
+            glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+            gl_info->max_combined_samplers = tmp;
+
+            /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
+             * is known at shader link time. In a vertex shader + pixel shader combination this isn't
+             * an issue because then the sampler setup only depends on the two shaders. If a pixel
+             * shader is used with fixed function vertex processing we're fine too because fixed function
+             * vertex processing doesn't use any samplers. If fixed function fragment processing is
+             * used we have to make sure that all vertex sampler setups are valid together with all
+             * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
+             * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
+             * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
+             * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
+             * a fixed function pipeline anymore.
+             *
+             * So this is just a check to check that our assumption holds true. If not, write a warning
+             * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
+            if (gl_info->max_vertex_samplers && gl_info->max_combined_samplers < 12
+                    && MAX_TEXTURES + gl_info->max_vertex_samplers > gl_info->max_combined_samplers)
+            {
+                FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
+                        gl_info->max_vertex_samplers, gl_info->max_combined_samplers);
+                FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
+                if (gl_info->max_combined_samplers > MAX_TEXTURES)
+                    gl_info->max_vertex_samplers = gl_info->max_combined_samplers - MAX_TEXTURES;
+                else
+                    gl_info->max_vertex_samplers = 0;
+            }
         }
         }
-        if(gl_info->supported[ARB_POINT_SPRITE]) {
-            gl_info->max_point_sprite_units = gl_info->max_textures;
-        } else {
-            gl_info->max_point_sprite_units = 0;
+        else
+        {
+            gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
         }
         }
+        TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->max_vertex_samplers);
+        TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->max_combined_samplers);
+    }
+    if (gl_info->supported[ARB_VERTEX_BLEND])
+    {
+        glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+        gl_info->max_blends = gl_max;
+        TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->max_blends);
+    }
+    if (gl_info->supported[EXT_TEXTURE3D])
+    {
+        glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
+        gl_info->max_texture3d_size = gl_max;
+        TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->max_texture3d_size);
     }
     }
-    checkGLcall("extension detection\n");
+    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+    {
+        glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
+        gl_info->max_anisotropy = gl_max;
+        TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->max_anisotropy);
+    }
+    if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+    {
+        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+        gl_info->ps_arb_constantsF = gl_max;
+        TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->ps_arb_constantsF);
+        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+        gl_info->ps_arb_max_temps = gl_max;
+        TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->ps_arb_max_temps);
+        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+        gl_info->ps_arb_max_instructions = gl_max;
+        TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->ps_arb_max_instructions);
+        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
+        gl_info->ps_arb_max_local_constants = gl_max;
+        TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->ps_arb_max_instructions);
+    }
+    if (gl_info->supported[ARB_VERTEX_PROGRAM])
+    {
+        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+        gl_info->vs_arb_constantsF = gl_max;
+        TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->vs_arb_constantsF);
+        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+        gl_info->vs_arb_max_temps = gl_max;
+        TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->vs_arb_max_temps);
+        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+        gl_info->vs_arb_max_instructions = gl_max;
+        TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->vs_arb_max_instructions);
+
+        if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
+    }
+    if (gl_info->supported[ARB_VERTEX_SHADER])
+    {
+        glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
+        gl_info->vs_glsl_constantsF = gl_max / 4;
+        TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->vs_glsl_constantsF);
+    }
+    if (gl_info->supported[ARB_FRAGMENT_SHADER])
+    {
+        glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
+        gl_info->ps_glsl_constantsF = gl_max / 4;
+        TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->ps_glsl_constantsF);
+        glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
+        gl_info->max_glsl_varyings = gl_max;
+        TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
+    }
+    if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
+    {
+        glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->max_shininess);
+    }
+    else
+    {
+        gl_info->max_shininess = 128.0f;
+    }
+    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+    {
+        /* If we have full NP2 texture support, disable
+         * GL_ARB_texture_rectangle because we will never use it.
+         * This saves a few redundant glDisable calls. */
+        gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
+    }
+    if (gl_info->supported[ATI_FRAGMENT_SHADER])
+    {
+        /* Disable NV_register_combiners and fragment shader if this is supported.
+         * generally the NV extensions are preferred over the ATI ones, and this
+         * extension is disabled if register_combiners and texture_shader2 are both
+         * supported. So we reach this place only if we have incomplete NV dxlevel 8
+         * fragment processing support. */
+        gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
+        gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
+        gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
+        gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
+        gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
+    }
+    if (gl_info->supported[NV_HALF_FLOAT])
+    {
+        /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
+        gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
+    }
+    if (gl_info->supported[ARB_POINT_SPRITE])
+    {
+        gl_info->max_point_sprite_units = gl_info->max_textures;
+    }
+    else
+    {
+        gl_info->max_point_sprite_units = 0;
+    }
+    checkGLcall("extension detection");
+
+    LEAVE_GL();
 
     /* In some cases the number of texture stages can be larger than the number
      * of samplers. The GF4 for example can use only 2 samplers (no fragment
 
     /* In some cases the number of texture stages can be larger than the number
      * of samplers. The GF4 for example can use only 2 samplers (no fragment
@@ -1029,8 +1869,8 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
 
     /* We can only use ORM_FBO when the hardware supports it. */
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
 
     /* We can only use ORM_FBO when the hardware supports it. */
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
-        WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
-        wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
+        WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to backbuffer offscreen rendering mode.\n");
+        wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
     }
 
     /* MRTs are currently only supported when FBOs are used. */
     }
 
     /* MRTs are currently only supported when FBOs are used. */
@@ -1038,357 +1878,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
         gl_info->max_buffers = 1;
     }
 
         gl_info->max_buffers = 1;
     }
 
-    /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
-     * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
-     * in case of the latest videocards in the number of pixel/vertex pipelines.
-     *
-     * A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
-     * rendering. Various games use this information to get a rough estimation of the features of the card
-     * and some might use it for enabling 3d effects only on certain types of videocards. In some cases
-     * games might even use it to work around bugs which happen on certain videocards/driver combinations.
-     * The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
-     * not the PCI id.
-     *
-     * Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
-     * the renderer string and translate this to the right PCI id. This is a lot of work because there are more
-     * than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
-     * be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
-     * Another way would be to query the PCI id from the operating system (assuming this is the videocard which
-     * is used for rendering which is not always the case). This would work but it is not very portable. Second
-     * it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
-     * is limited.
-     *
-     * As said most games only use the PCI id to get an indication of the capabilities of the card.
-     * It doesn't really matter if the given id is the correct one if we return the id of a card with
-     * similar 3d features.
-     *
-     * The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
-     * Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
-     * is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
-     * won't pass we return a default card. This way is better than maintaining a full card database as even
-     * without a full database we can return a card with similar features. Second the size of the database
-     * can be made quite small because when you know what type of 3d functionality a card has, you know to which
-     * GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
-     * to distinguishes between different models from that family.
-     *
-     * The code also selects a default amount of video memory which we will use for an estimation of the amount
-     * of free texture memory. In case of real D3D the amount of texture memory includes video memory and system
-     * memory (to be specific AGP memory or in case of PCIE TurboCache/HyperMemory). We don't know how much
-     * system memory can be addressed by the system but we can make a reasonable estimation about the amount of
-     * video memory. If the value is slightly wrong it doesn't matter as we didn't include AGP-like memory which
-     * makes the amount of addressable memory higher and second OpenGL isn't that critical it moves to system
-     * memory behind our backs if really needed.
-     * Note that the amount of video memory can be overruled using a registry setting.
-     */
-    switch (gl_info->gl_vendor) {
-        case VENDOR_NVIDIA:
-            /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
-             * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
-             */
-            if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
-                /* Geforce 200 - highend */
-                if(strstr(gl_info->gl_renderer, "GTX 280") ||
-                   strstr(gl_info->gl_renderer, "GTX 285") ||
-                   strstr(gl_info->gl_renderer, "GTX 295"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280;
-                    vidmem = 1024;
-                }
-                /* Geforce 200 - midend high */
-                if(strstr(gl_info->gl_renderer, "GTX 275")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX275;
-                    vidmem = 896;
-                }
-                /* Geforce 200 - midend */
-                if(strstr(gl_info->gl_renderer, "GTX 260")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX260;
-                    vidmem = 1024;
-                }
-                /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
-                else if(strstr(gl_info->gl_renderer, "9800") ||
-                        strstr(gl_info->gl_renderer, "GTS 150") ||
-                        strstr(gl_info->gl_renderer, "GTS 250"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT;
-                    vidmem = 512;
-                }
-                /* Geforce9 - midend */
-                else if(strstr(gl_info->gl_renderer, "9600")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9600GT;
-                    vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
-                }
-                /* Geforce9 - midend low / Geforce 200 - low*/
-                else if(strstr(gl_info->gl_renderer, "9500") ||
-                        strstr(gl_info->gl_renderer, "GT 120") ||
-                        strstr(gl_info->gl_renderer, "GT 130"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9500GT;
-                    vidmem = 256; /* The 9500GT has 256-1024MB */
-                }
-                /* Geforce9 - lowend */
-                else if(strstr(gl_info->gl_renderer, "9400")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9400GT;
-                    vidmem = 256; /* The 9400GT has 256-1024MB */
-                }
-                /* Geforce9 - lowend low */
-                else if(strstr(gl_info->gl_renderer, "9100") ||
-                        strstr(gl_info->gl_renderer, "9200") ||
-                        strstr(gl_info->gl_renderer, "9300") ||
-                        strstr(gl_info->gl_renderer, "G 100"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9200;
-                    vidmem = 256; /* The 9100-9300 cards have 256MB */
-                }
-                /* Geforce8 - highend */
-                else if (strstr(gl_info->gl_renderer, "8800")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
-                    vidmem = 320; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
-                }
-                /* Geforce8 - midend mobile */
-                else if(strstr(gl_info->gl_renderer, "8600 M")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600MGT;
-                    vidmem = 512;
-                }
-                /* Geforce8 - midend */
-                else if(strstr(gl_info->gl_renderer, "8600") ||
-                        strstr(gl_info->gl_renderer, "8700"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_8600GT;
-                    vidmem = 256;
-                }
-                /* Geforce8 - lowend */
-                else if(strstr(gl_info->gl_renderer, "8300") ||
-                        strstr(gl_info->gl_renderer, "8400") ||
-                        strstr(gl_info->gl_renderer, "8500"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_8300GS;
-                    vidmem = 128; /* 128-256MB for a 8300, 256-512MB for a 8400 */
-                }
-                /* Geforce7 - highend */
-                else if(strstr(gl_info->gl_renderer, "7800") ||
-                        strstr(gl_info->gl_renderer, "7900") ||
-                        strstr(gl_info->gl_renderer, "7950") ||
-                        strstr(gl_info->gl_renderer, "Quadro FX 4") ||
-                        strstr(gl_info->gl_renderer, "Quadro FX 5"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
-                    vidmem = 256; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
-                }
-                /* Geforce7 midend */
-                else if(strstr(gl_info->gl_renderer, "7600") ||
-                        strstr(gl_info->gl_renderer, "7700")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_7600;
-                    vidmem = 256; /* The 7600 uses 256-512MB */
-                /* Geforce7 lower medium */
-                } else if(strstr(gl_info->gl_renderer, "7400")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_7400;
-                    vidmem = 256; /* The 7400 uses 256-512MB */
-                }
-                /* Geforce7 lowend */
-                else if(strstr(gl_info->gl_renderer, "7300")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_7300;
-                    vidmem = 256; /* Mac Pros with this card have 256 MB */
-                }
-                /* Geforce6 highend */
-                else if(strstr(gl_info->gl_renderer, "6800"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
-                    vidmem = 128; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
-                }
-                /* Geforce6 - midend */
-                else if(strstr(gl_info->gl_renderer, "6600") ||
-                        strstr(gl_info->gl_renderer, "6610") ||
-                        strstr(gl_info->gl_renderer, "6700"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
-                    vidmem = 128; /* A 6600GT has 128-256MB */
-                }
-                /* Geforce6/7 lowend */
-                else {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
-                    vidmem = 64; /* */
-                }
-            } else if(WINE_D3D9_CAPABLE(gl_info)) {
-                /* GeforceFX - highend */
-                if (strstr(gl_info->gl_renderer, "5800") ||
-                    strstr(gl_info->gl_renderer, "5900") ||
-                    strstr(gl_info->gl_renderer, "5950") ||
-                    strstr(gl_info->gl_renderer, "Quadro FX"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
-                    vidmem = 256; /* 5800-5900 cards use 256MB */
-                }
-                /* GeforceFX - midend */
-                else if(strstr(gl_info->gl_renderer, "5600") ||
-                        strstr(gl_info->gl_renderer, "5650") ||
-                        strstr(gl_info->gl_renderer, "5700") ||
-                        strstr(gl_info->gl_renderer, "5750"))
-                {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
-                    vidmem = 128; /* A 5600 uses 128-256MB */
-                }
-                /* GeforceFX - lowend */
-                else {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
-                    vidmem = 64; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
-                }
-            } else if(WINE_D3D8_CAPABLE(gl_info)) {
-                if (strstr(gl_info->gl_renderer, "GeForce4 Ti") || strstr(gl_info->gl_renderer, "Quadro4")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
-                    vidmem = 64; /* Geforce4 Ti cards have 64-128MB */
-                }
-                else {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
-                    vidmem = 64; /* Geforce3 cards have 64-128MB */
-                }
-            } else if(WINE_D3D7_CAPABLE(gl_info)) {
-                if (strstr(gl_info->gl_renderer, "GeForce4 MX")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
-                    vidmem = 64; /* Most Geforce4MX GPUs have at least 64MB of memory, some early models had 32MB but most have 64MB or even 128MB */
-                }
-                else if(strstr(gl_info->gl_renderer, "GeForce2 MX") || strstr(gl_info->gl_renderer, "Quadro2 MXR")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
-                    vidmem = 32; /* Geforce2MX GPUs have 32-64MB of video memory */
-                }
-                else if(strstr(gl_info->gl_renderer, "GeForce2") || strstr(gl_info->gl_renderer, "Quadro2")) {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
-                    vidmem = 32; /* Geforce2 GPUs have 32-64MB of video memory */
-                }
-                else {
-                    gl_info->gl_card = CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
-                    vidmem = 32; /* Most Geforce1 cards have 32MB, there are also some rare 16 and 64MB (Dell) models */
-                }
-            } else {
-                if (strstr(gl_info->gl_renderer, "TNT2")) {
-                    gl_info->gl_card = CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
-                    vidmem = 32; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
-                }
-                else {
-                    gl_info->gl_card = CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
-                    vidmem = 16; /* Most TNT boards have 16MB, some rare models have 8MB */
-                }
-            }
-            break;
-        case VENDOR_ATI:
-            if(WINE_D3D9_CAPABLE(gl_info)) {
-                /* Radeon R6xx HD2900/HD3800 - highend */
-                if (strstr(gl_info->gl_renderer, "HD 2900") ||
-                    strstr(gl_info->gl_renderer, "HD 3870") ||
-                    strstr(gl_info->gl_renderer, "HD 3850"))
-                {
-                    gl_info->gl_card = CARD_ATI_RADEON_HD2900;
-                    vidmem = 512; /* HD2900/HD3800 uses 256-1024MB */
-                }
-                /* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
-                else if (strstr(gl_info->gl_renderer, "HD 2600") ||
-                         strstr(gl_info->gl_renderer, "HD 3830") ||
-                         strstr(gl_info->gl_renderer, "HD 3690") ||
-                         strstr(gl_info->gl_renderer, "HD 3650"))
-                {
-                    gl_info->gl_card = CARD_ATI_RADEON_HD2600;
-                    vidmem = 256; /* HD2600/HD3600 uses 256-512MB */
-                }
-                /* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
-                else if (strstr(gl_info->gl_renderer, "HD 2300") ||
-                         strstr(gl_info->gl_renderer, "HD 2400") ||
-                         strstr(gl_info->gl_renderer, "HD 3470") ||
-                         strstr(gl_info->gl_renderer, "HD 3450") ||
-                         strstr(gl_info->gl_renderer, "HD 3430"))
-                {
-                    gl_info->gl_card = CARD_ATI_RADEON_HD2300;
-                    vidmem = 128; /* HD2300 uses at least 128MB, HD2400 uses 256MB */
-                }
-                /* Radeon R6xx/R7xx integrated */
-                else if (strstr(gl_info->gl_renderer, "HD 3100") ||
-                         strstr(gl_info->gl_renderer, "HD 3200") ||
-                         strstr(gl_info->gl_renderer, "HD 3300"))
-                {
-                    gl_info->gl_card = CARD_ATI_RADEON_HD3200;
-                    vidmem = 128; /* 128MB */
-                }
-                /* Radeon R5xx */
-                else if (strstr(gl_info->gl_renderer, "X1600") ||
-                         strstr(gl_info->gl_renderer, "X1650") ||
-                         strstr(gl_info->gl_renderer, "X1800") ||
-                         strstr(gl_info->gl_renderer, "X1900") ||
-                         strstr(gl_info->gl_renderer, "X1950"))
-                {
-                    gl_info->gl_card = CARD_ATI_RADEON_X1600;
-                    vidmem = 128; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
-                }
-                /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
-                else if(strstr(gl_info->gl_renderer, "X700") ||
-                        strstr(gl_info->gl_renderer, "X800") ||
-                        strstr(gl_info->gl_renderer, "X850") ||
-                        strstr(gl_info->gl_renderer, "X1300") ||
-                        strstr(gl_info->gl_renderer, "X1400") ||
-                        strstr(gl_info->gl_renderer, "X1450") ||
-                        strstr(gl_info->gl_renderer, "X1550"))
-                {
-                    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 */
-                    vidmem = 64; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
-                }
-            } else if(WINE_D3D8_CAPABLE(gl_info)) {
-                gl_info->gl_card = CARD_ATI_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
-                vidmem = 64; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
-            } else if(WINE_D3D7_CAPABLE(gl_info)) {
-                gl_info->gl_card = CARD_ATI_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
-                vidmem = 32; /* There are models with up to 64MB */
-            } else {
-                gl_info->gl_card = CARD_ATI_RAGE_128PRO;
-                vidmem = 16; /* There are 16-32MB models */
-            }
-            break;
-        case VENDOR_INTEL:
-            if (strstr(gl_info->gl_renderer, "GMA 950") ||
-                strstr(gl_info->gl_renderer, "945GM")) {
-                /* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
-                gl_info->gl_card = CARD_INTEL_I945GM;
-                vidmem = 64;
-            } else if (strstr(gl_info->gl_renderer, "915GM")) {
-                gl_info->gl_card = CARD_INTEL_I915GM;
-            } else if (strstr(gl_info->gl_renderer, "915G")) {
-                gl_info->gl_card = CARD_INTEL_I915G;
-            } else if (strstr(gl_info->gl_renderer, "865G")) {
-                gl_info->gl_card = CARD_INTEL_I865G;
-            } else if (strstr(gl_info->gl_renderer, "855G")) {
-                gl_info->gl_card = CARD_INTEL_I855G;
-            } else if (strstr(gl_info->gl_renderer, "830G")) {
-                gl_info->gl_card = CARD_INTEL_I830G;
-            } else {
-                gl_info->gl_card = CARD_INTEL_I915G;
-            }
-            break;
-        case VENDOR_MESA:
-        case VENDOR_WINE:
-        default:
-            /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice 
-             * for Nvidia was because the hardware and drivers they make are of good quality. This makes
-             * them a good generic choice.
-             */
-            gl_info->gl_vendor = VENDOR_NVIDIA;
-            if(WINE_D3D9_CAPABLE(gl_info))
-                gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5600;
-            else if(WINE_D3D8_CAPABLE(gl_info))
-                gl_info->gl_card = CARD_NVIDIA_GEFORCE3;
-            else if(WINE_D3D7_CAPABLE(gl_info))
-                gl_info->gl_card = CARD_NVIDIA_GEFORCE;
-            else if(WINE_D3D6_CAPABLE(gl_info))
-                gl_info->gl_card = CARD_NVIDIA_RIVA_TNT;
-            else
-                gl_info->gl_card = CARD_NVIDIA_RIVA_128;
-    }
+    gl_info->gl_card = wined3d_guess_card(gl_info, gl_renderer, &gl_info->gl_vendor, &vidmem);
     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
 
     /* If we have an estimate use it, else default to 64MB;  */
     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", gl_info->gl_vendor, gl_info->gl_card);
 
     /* If we have an estimate use it, else default to 64MB;  */
@@ -1413,31 +1903,6 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
 
     stateLookup[WINELOOKUP_WARPPARAM][WINED3DTADDRESS_MIRRORONCE - minLookup[WINELOOKUP_WARPPARAM]] =
              gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
 
-    magLookup[WINED3DTEXF_NONE        - WINED3DTEXF_NONE]  = GL_NEAREST;
-    magLookup[WINED3DTEXF_POINT       - WINED3DTEXF_NONE] = GL_NEAREST;
-    magLookup[WINED3DTEXF_LINEAR      - WINED3DTEXF_NONE] = GL_LINEAR;
-    magLookup[WINED3DTEXF_ANISOTROPIC - WINED3DTEXF_NONE] =
-             gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
-
-
-    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_NONE]     = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_POINT]    = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_LINEAR]   = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_NONE]    = GL_NEAREST;
-    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_POINT]   = GL_NEAREST_MIPMAP_NEAREST;
-    minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_LINEAR]  = GL_NEAREST_MIPMAP_LINEAR;
-    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_NONE]   = GL_LINEAR;
-    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_POINT]  = GL_LINEAR_MIPMAP_NEAREST;
-    minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_NONE]
-            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_POINT]
-            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
-    minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_LINEAR]
-            = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
-
-/* TODO: config lookups */
-
     /* Make sure there's an active HDC else the WGL extensions will fail */
     hdc = pwglGetCurrentDC();
     if (hdc) {
     /* Make sure there's an active HDC else the WGL extensions will fail */
     hdc = pwglGetCurrentDC();
     if (hdc) {
@@ -1452,7 +1917,6 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
             while (*WGL_Extensions != 0x00) {
                 const char *Start;
                 char ThisExtn[256];
             while (*WGL_Extensions != 0x00) {
                 const char *Start;
                 char ThisExtn[256];
-                size_t len;
 
                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
                 Start = WGL_Extensions;
 
                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
                 Start = WGL_Extensions;
@@ -1466,7 +1930,7 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
 
                 memcpy(ThisExtn, Start, len);
                 ThisExtn[len] = '\0';
 
                 memcpy(ThisExtn, Start, len);
                 ThisExtn[len] = '\0';
-                TRACE_(d3d_caps)("- %s\n", ThisExtn);
+                TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
 
                 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
 
                 if (!strcmp(ThisExtn, "WGL_ARB_pbuffer")) {
                     gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
@@ -1483,9 +1947,12 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
             }
         }
     }
             }
         }
     }
-    LEAVE_GL();
 
 
-    return return_value;
+    fixup_extensions(gl_info, gl_renderer);
+    add_gl_compat_wrappers(gl_info);
+
+    HeapFree(GetProcessHeap(), 0, gl_renderer);
+    return TRUE;
 }
 
 /**********************************************************
 }
 
 /**********************************************************
@@ -1532,40 +1999,39 @@ static UINT     WINAPI IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Ad
 
     /* TODO: Store modes per adapter and read it from the adapter structure */
     if (Adapter == 0) { /* Display */
 
     /* TODO: Store modes per adapter and read it from the adapter structure */
     if (Adapter == 0) { /* Display */
-        int i = 0;
-        int j = 0;
+        unsigned int i = 0;
+        unsigned int j = 0;
+        DEVMODEW mode;
 
 
-        if (!DEBUG_SINGLE_MODE) {
-            DEVMODEW DevModeW;
+        memset(&mode, 0, sizeof(mode));
+        mode.dmSize = sizeof(mode);
 
 
-            ZeroMemory(&DevModeW, sizeof(DevModeW));
-            DevModeW.dmSize = sizeof(DevModeW);
-            while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
-                j++;
-                switch (Format)
-                {
-                    case WINED3DFMT_UNKNOWN:
-                        /* This is for D3D8, do not enumerate P8 here */
-                        if (DevModeW.dmBitsPerPel == 32 ||
-                            DevModeW.dmBitsPerPel == 16) i++;
-                        break;
-                    case WINED3DFMT_X8R8G8B8:
-                        if (DevModeW.dmBitsPerPel == 32) i++;
-                        break;
-                    case WINED3DFMT_R5G6B5:
-                        if (DevModeW.dmBitsPerPel == 16) i++;
-                        break;
-                    case WINED3DFMT_P8:
-                        if (DevModeW.dmBitsPerPel == 8) i++;
-                        break;
-                    default:
-                        /* Skip other modes as they do not match the requested format */
-                        break;
-                }
+        while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
+        {
+            ++j;
+            switch (Format)
+            {
+                case WINED3DFMT_UNKNOWN:
+                    /* This is for D3D8, do not enumerate P8 here */
+                    if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
+                    break;
+
+                case WINED3DFMT_X8R8G8B8:
+                    if (mode.dmBitsPerPel == 32) ++i;
+                    break;
+
+                case WINED3DFMT_R5G6B5:
+                    if (mode.dmBitsPerPel == 16) ++i;
+                    break;
+
+                case WINED3DFMT_P8:
+                    if (mode.dmBitsPerPel == 8) ++i;
+                    break;
+
+                default:
+                    /* Skip other modes as they do not match the requested format */
+                    break;
             }
             }
-        } else {
-            i = 1;
-            j = 1;
         }
 
         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
         }
 
         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
@@ -1589,7 +2055,8 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
     }
 
     /* TODO: Store modes per adapter and read it from the adapter structure */
     }
 
     /* TODO: Store modes per adapter and read it from the adapter structure */
-    if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
+    if (Adapter == 0)
+    {
         DEVMODEW DevModeW;
         int ModeIdx = 0;
         UINT i = 0;
         DEVMODEW DevModeW;
         int ModeIdx = 0;
         UINT i = 0;
@@ -1635,7 +2102,7 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
             pMode->Width        = DevModeW.dmPelsWidth;
             pMode->Height       = DevModeW.dmPelsHeight;
         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) {
             pMode->Width        = DevModeW.dmPelsWidth;
             pMode->Height       = DevModeW.dmPelsHeight;
-            pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
+            pMode->RefreshRate  = DEFAULT_REFRESH_RATE;
             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
 
             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
 
@@ -1653,14 +2120,9 @@ static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapte
                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
                 DevModeW.dmBitsPerPel);
 
                 pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format),
                 DevModeW.dmBitsPerPel);
 
-    } else if (DEBUG_SINGLE_MODE) {
-        /* Return one setting of the format requested */
-        if (Mode > 0) return WINED3DERR_INVALIDCALL;
-        pMode->Width        = 800;
-        pMode->Height       = 600;
-        pMode->RefreshRate  = 60;
-        pMode->Format       = (Format == WINED3DFMT_UNKNOWN) ? WINED3DFMT_X8R8G8B8 : Format;
-    } else {
+    }
+    else
+    {
         FIXME_(d3d_caps)("Adapter not primary display\n");
     }
 
         FIXME_(d3d_caps)("Adapter not primary display\n");
     }
 
@@ -1687,7 +2149,7 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT A
         pMode->Width        = DevModeW.dmPelsWidth;
         pMode->Height       = DevModeW.dmPelsHeight;
         bpp                 = DevModeW.dmBitsPerPel;
         pMode->Width        = DevModeW.dmPelsWidth;
         pMode->Height       = DevModeW.dmPelsHeight;
         bpp                 = DevModeW.dmBitsPerPel;
-        pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
+        pMode->RefreshRate  = DEFAULT_REFRESH_RATE;
         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
         {
             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
         {
             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
@@ -1708,6 +2170,7 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT A
 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
 static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags,
                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
+    size_t len;
 
     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
 
 
     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %x, pId=%p)\n", This, Adapter, Flags, pIdentifier);
 
@@ -1717,44 +2180,70 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad
 
     /* Return the information requested */
     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
 
     /* Return the information requested */
     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
-    strcpy(pIdentifier->Driver, This->adapters[Adapter].driver);
-    if(This->adapters[Adapter].gl_info.driver_description)
-        strcpy(pIdentifier->Description, This->adapters[Adapter].gl_info.driver_description);
-    else /* Copy default description "Direct3D HAL" */
-        strcpy(pIdentifier->Description, This->adapters[Adapter].description);
-
-    /* Note dx8 doesn't supply a DeviceName */
-    if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
-    pIdentifier->DriverVersion->u.HighPart = This->adapters[Adapter].gl_info.driver_version_hipart;
-    pIdentifier->DriverVersion->u.LowPart = This->adapters[Adapter].gl_info.driver_version;
-    *(pIdentifier->VendorId) = This->adapters[Adapter].gl_info.gl_vendor;
-    *(pIdentifier->DeviceId) = This->adapters[Adapter].gl_info.gl_card;
-    *(pIdentifier->SubSysId) = 0;
-    *(pIdentifier->Revision) = 0;
-    *pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
+
+    if (pIdentifier->driver_size)
+    {
+        len = min(strlen(This->adapters[Adapter].driver), pIdentifier->driver_size - 1);
+        memcpy(pIdentifier->driver, This->adapters[Adapter].driver, len);
+        pIdentifier->driver[len] = '\0';
+    }
+
+    if (pIdentifier->description_size)
+    {
+        const char *description;
+
+        if (This->adapters[Adapter].gl_info.driver_description)
+            description = This->adapters[Adapter].gl_info.driver_description;
+        else
+            description = This->adapters[Adapter].description;
+
+        len = min(strlen(description), pIdentifier->description_size - 1);
+        memcpy(pIdentifier->description, description, len);
+        pIdentifier->description[len] = '\0';
+    }
+
+    /* Note that d3d8 doesn't supply a device name. */
+    if (pIdentifier->device_name_size)
+    {
+        static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
+
+        len = strlen(device_name);
+        if (len >= pIdentifier->device_name_size)
+        {
+            ERR("Device name size too small.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        memcpy(pIdentifier->device_name, device_name, len);
+        pIdentifier->device_name[len] = '\0';
+    }
+
+    pIdentifier->driver_version.u.HighPart = This->adapters[Adapter].gl_info.driver_version_hipart;
+    pIdentifier->driver_version.u.LowPart = This->adapters[Adapter].gl_info.driver_version;
+    pIdentifier->vendor_id = This->adapters[Adapter].gl_info.gl_vendor;
+    pIdentifier->device_id = This->adapters[Adapter].gl_info.gl_card;
+    pIdentifier->subsystem_id = 0;
+    pIdentifier->revision = 0;
+    memcpy(&pIdentifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(pIdentifier->device_identifier));
 
     if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
     {
         TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
 
     if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
     {
         TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
-        *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
+        pIdentifier->device_id = wined3d_settings.pci_device_id;
     }
 
     if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
         TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
     }
 
     if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
         TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
-        *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
+        pIdentifier->vendor_id = wined3d_settings.pci_vendor_id;
     }
 
     }
 
-    if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
-        *(pIdentifier->WHQLLevel) = 0;
-    } else {
-        *(pIdentifier->WHQLLevel) = 1;
-    }
+    pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
 
     return WINED3D_OK;
 }
 
 
     return WINED3D_OK;
 }
 
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_GL_Info *gl_info,
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
 {
     short redSize, greenSize, blueSize, alphaSize, colorBits;
         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
 {
     short redSize, greenSize, blueSize, alphaSize, colorBits;
@@ -1803,7 +2292,7 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_GL_I
     return FALSE;
 }
 
     return FALSE;
 }
 
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_GL_Info *gl_info,
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
 {
     short depthSize, stencilSize;
         const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
 {
     short depthSize, stencilSize;
@@ -1879,10 +2368,9 @@ static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT
     return WINED3DERR_NOTAVAILABLE;
 }
 
     return WINED3DERR_NOTAVAILABLE;
 }
 
-static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
-                                                       WINED3DFORMAT SurfaceFormat,
-                                                       BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD*   pQualityLevels) {
-
+static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
+        WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
+{
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
     const struct GlPixelFormatDesc *glDesc;
     const struct WineD3DAdapter *adapter;
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
     const struct GlPixelFormatDesc *glDesc;
     const struct WineD3DAdapter *adapter;
@@ -1902,7 +2390,10 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface, U
 
     /* TODO: handle Windowed, add more quality levels */
 
 
     /* TODO: handle Windowed, add more quality levels */
 
-    if (WINED3DMULTISAMPLE_NONE == MultiSampleType) return WINED3D_OK;
+    if (WINED3DMULTISAMPLE_NONE == MultiSampleType) {
+        if(pQualityLevels) *pQualityLevels = 1;
+        return WINED3D_OK;
+    }
 
     /* By default multisampling is disabled right now as it causes issues
      * on some Nvidia driver versions and it doesn't work well in combination
 
     /* By default multisampling is disabled right now as it causes issues
      * on some Nvidia driver versions and it doesn't work well in combination
@@ -2092,7 +2583,7 @@ static BOOL CheckDepthStencilCapability(struct WineD3DAdapter *adapter,
     int it=0;
 
     /* Only allow depth/stencil formats */
     int it=0;
 
     /* Only allow depth/stencil formats */
-    if (!(ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) return FALSE;
+    if (!(ds_format_desc->depth_size || ds_format_desc->stencil_size)) return FALSE;
 
     /* Walk through all WGL pixel formats to find a match */
     for (it = 0; it < adapter->nCfgs; ++it)
 
     /* Walk through all WGL pixel formats to find a match */
     for (it = 0; it < adapter->nCfgs; ++it)
@@ -2179,7 +2670,7 @@ static BOOL CheckRenderTargetCapability(struct WineD3DAdapter *adapter,
 
 static BOOL CheckSrgbReadCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
 {
 
 static BOOL CheckSrgbReadCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
 {
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
 
     /* Check for supported sRGB formats (Texture loading and framebuffer) */
     if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
 
     /* Check for supported sRGB formats (Texture loading and framebuffer) */
     if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
@@ -2259,7 +2750,7 @@ static BOOL CheckWrapAndMipCapability(struct WineD3DAdapter *adapter, const stru
 static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
 {
 static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
         WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
 {
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     const shader_backend_t *shader_backend;
     const struct fragment_pipeline *fp;
 
     const shader_backend_t *shader_backend;
     const struct fragment_pipeline *fp;
 
@@ -2539,7 +3030,7 @@ static BOOL CheckSurfaceCapability(struct WineD3DAdapter *adapter, const struct
 
 static BOOL CheckVertexTextureCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
 {
 
 static BOOL CheckVertexTextureCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
 {
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
 
     if (!GL_LIMITS(vertex_samplers)) {
         TRACE_(d3d_caps)("[FAILED]\n");
 
     if (!GL_LIMITS(vertex_samplers)) {
         TRACE_(d3d_caps)("[FAILED]\n");
@@ -2563,12 +3054,13 @@ static BOOL CheckVertexTextureCapability(struct WineD3DAdapter *adapter, const s
     return FALSE;
 }
 
     return FALSE;
 }
 
-static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, 
+static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType,
         WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
         WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
-        WINED3DSURFTYPE SurfaceType) {
+        WINED3DSURFTYPE SurfaceType)
+{
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
     struct WineD3DAdapter *adapter = &This->adapters[Adapter];
     IWineD3DImpl *This = (IWineD3DImpl *)iface;
     struct WineD3DAdapter *adapter = &This->adapters[Adapter];
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
     const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
     DWORD UsageCaps = 0;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
     const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
     DWORD UsageCaps = 0;
@@ -3047,18 +3539,6 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
         return WINED3DERR_NOTAVAILABLE;
     }
 
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    /* This format is nothing special and it is supported perfectly.
-     * However, ati and nvidia driver on windows do not mark this format as
-     * supported (tested with the dxCapsViewer) and pretending to
-     * support this format uncovers a bug in Battlefield 1942 (fonts are missing)
-     * So do the same as Windows drivers and pretend not to support it on dx8 and 9
-     * Enable it on dx7. It will need additional checking on dx10 when we support it.
-     */
-    if(This->dxVersion > 7 && CheckFormat == WINED3DFMT_R8G8B8) {
-        TRACE_(d3d_caps)("[FAILED]\n");
-        return WINED3DERR_NOTAVAILABLE;
-    }
-
     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
      * usage flags match. */
     /* When the UsageCaps exactly matches Usage return WINED3D_OK except for the situation in which
      * WINED3DUSAGE_AUTOGENMIPMAP isn't around, then WINED3DOK_NOAUTOGEN is returned if all the other
      * usage flags match. */
@@ -3105,7 +3585,7 @@ static const shader_backend_t *select_shader_backend(struct WineD3DAdapter *adap
 static const struct fragment_pipeline *select_fragment_implementation(struct WineD3DAdapter *adapter,
         WINED3DDEVTYPE DeviceType)
 {
 static const struct fragment_pipeline *select_fragment_implementation(struct WineD3DAdapter *adapter,
         WINED3DDEVTYPE DeviceType)
 {
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     int vs_selected_mode;
     int ps_selected_mode;
 
     int vs_selected_mode;
     int ps_selected_mode;
 
@@ -3125,7 +3605,7 @@ static const struct fragment_pipeline *select_fragment_implementation(struct Win
 
 static const struct blit_shader *select_blit_implementation(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType)
 {
 
 static const struct blit_shader *select_blit_implementation(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType)
 {
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     int vs_selected_mode;
     int ps_selected_mode;
 
     int vs_selected_mode;
     int ps_selected_mode;
 
@@ -3144,7 +3624,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
 
     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
     struct WineD3DAdapter *adapter = &This->adapters[Adapter];
 
     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
     struct WineD3DAdapter *adapter = &This->adapters[Adapter];
-    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
     int vs_selected_mode;
     int ps_selected_mode;
     struct shader_caps shader_caps;
     int vs_selected_mode;
     int ps_selected_mode;
     struct shader_caps shader_caps;
@@ -3446,14 +3926,14 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
 
     pCaps->MaxTextureRepeat = 32768;
     pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
 
     pCaps->MaxTextureRepeat = 32768;
     pCaps->MaxTextureAspectRatio = GL_LIMITS(texture_size);
-    pCaps->MaxVertexW = 1.0;
+    pCaps->MaxVertexW = 1.0f;
 
 
-    pCaps->GuardBandLeft = 0;
-    pCaps->GuardBandTop = 0;
-    pCaps->GuardBandRight = 0;
-    pCaps->GuardBandBottom = 0;
+    pCaps->GuardBandLeft = 0.0f;
+    pCaps->GuardBandTop = 0.0f;
+    pCaps->GuardBandRight = 0.0f;
+    pCaps->GuardBandBottom = 0.0f;
 
 
-    pCaps->ExtentsAdjust = 0;
+    pCaps->ExtentsAdjust = 0.0f;
 
     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
                           WINED3DSTENCILCAPS_INCRSAT |
 
     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
                           WINED3DSTENCILCAPS_INCRSAT |
@@ -3465,9 +3945,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
                               WINED3DSTENCILCAPS_INCR;
     }
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
                               WINED3DSTENCILCAPS_INCR;
     }
-    if ( This->dxVersion > 8 &&
-        ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
-            GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
+    if (GL_SUPPORT(EXT_STENCIL_TWO_SIDE) || GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
 
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
 
@@ -3483,14 +3961,13 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
     pCaps->MaxPointSize    = GL_LIMITS(pointsize);
 
 
     pCaps->MaxPointSize    = GL_LIMITS(pointsize);
 
 
+    /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
                                   WINED3DVTXPCAPS_LOCALVIEWER       |
                                   WINED3DVTXPCAPS_VERTEXFOG         |
                                   WINED3DVTXPCAPS_TEXGEN;
     pCaps->VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
                                   WINED3DVTXPCAPS_LOCALVIEWER       |
                                   WINED3DVTXPCAPS_VERTEXFOG         |
                                   WINED3DVTXPCAPS_TEXGEN;
-                                  /* FIXME: Add 
-                                     D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
 
     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
     pCaps->MaxVertexIndex      = 0xFFFFF;
 
     pCaps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
     pCaps->MaxVertexIndex      = 0xFFFFF;
@@ -3539,7 +4016,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
     if(ps_selected_mode == SHADER_NONE) {
         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
     if(ps_selected_mode == SHADER_NONE) {
         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
         pCaps->PixelShaderVersion           = WINED3DPS_VERSION(0,0);
-        pCaps->PixelShader1xMaxValue        = 0.0;
+        pCaps->PixelShader1xMaxValue        = 0.0f;
     } else {
         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
     } else {
         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
@@ -3762,7 +4239,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     } else {
         object->surface_alignment = D3D8_PITCH_ALIGNMENT;
     }
     } else {
         object->surface_alignment = D3D8_PITCH_ALIGNMENT;
     }
-    object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
+    object->posFixup[0] = 1.0f; /* This is needed to get the x coord unmodified through a MAD. */
 
     /* Set the state up as invalid until the device is fully created */
     object->state   = WINED3DERR_DRIVERINTERNALERROR;
 
     /* Set the state up as invalid until the device is fully created */
     object->state   = WINED3DERR_DRIVERINTERNALERROR;
@@ -3788,6 +4265,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     object->shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
     object->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
     object->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
     object->shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
     object->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
     object->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
+    object->vs_clipping = shader_caps.VSClipping;
 
     memset(&ffp_caps, 0, sizeof(ffp_caps));
     frag_pipeline = select_fragment_implementation(adapter, DeviceType);
 
     memset(&ffp_caps, 0, sizeof(ffp_caps));
     frag_pipeline = select_fragment_implementation(adapter, DeviceType);
@@ -3853,366 +4331,6 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
     return IUnknown_Release(volumeParent);
 }
 
     return IUnknown_Release(volumeParent);
 }
 
-static BOOL match_apple(const WineD3D_GL_Info *gl_info)
-{
-    /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
-     * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
-     * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
-     *
-     * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
-     * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
-     * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
-     * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
-     * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
-     * the chance that other implementations support them is rather small since Win32 QuickTime uses
-     * DirectDraw, not OpenGL.
-     */
-    if(gl_info->supported[APPLE_FENCE] &&
-       gl_info->supported[APPLE_CLIENT_STORAGE] &&
-       gl_info->supported[APPLE_FLUSH_RENDER] &&
-       gl_info->supported[APPLE_YCBCR_422]) {
-        TRACE_(d3d_caps)("GL_APPLE_fence, GL_APPLE_client_storage, GL_APPLE_flush_render and GL_ycbcr_422 are supported\n");
-        TRACE_(d3d_caps)("Activating MacOS fixups\n");
-        return TRUE;
-    } else {
-        TRACE_(d3d_caps)("Apple extensions are not supported\n");
-        TRACE_(d3d_caps)("Not activating MacOS fixups\n");
-        return FALSE;
-    }
-}
-
-static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
-    /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
-     * but glTexSubImage from a PBO fails miserably, with the first line repeated over
-     * all the texture. This function detects this bug by its symptom and disables PBOs
-     * if the test fails.
-     *
-     * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
-     * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
-     * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
-     * read back is compared to the original. If they are equal PBOs are assumed to work,
-     * otherwise the PBO extension is disabled.
-     */
-    GLuint texture, pbo;
-    static const unsigned int pattern[] = {
-        0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
-        0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
-        0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
-        0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
-    };
-    unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
-
-    if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
-        /* No PBO -> No point in testing them */
-        return;
-    }
-
-    while(glGetError());
-    glGenTextures(1, &texture);
-    glBindTexture(GL_TEXTURE_2D, texture);
-
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
-    checkGLcall("Specifying the PBO test texture\n");
-
-    GL_EXTCALL(glGenBuffersARB(1, &pbo));
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
-    GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
-    checkGLcall("Specifying the PBO test pbo\n");
-
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
-    checkGLcall("Loading the PBO test texture\n");
-
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-    glFinish(); /* just to be sure */
-
-    memset(check, 0, sizeof(check));
-    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
-    checkGLcall("Reading back the PBO test texture\n");
-
-    glDeleteTextures(1, &texture);
-    GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
-    checkGLcall("PBO test cleanup\n");
-
-    if(memcmp(check, pattern, sizeof(check)) != 0) {
-        WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
-        WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
-        gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
-    } else {
-        TRACE_(d3d_caps)("PBO test successful\n");
-    }
-}
-
-/* Certain applications(Steam) complain if we report an outdated driver version. In general,
- * reporting a driver version is moot because we are not the Windows driver, and we have different
- * bugs, features, etc.
- *
- * If a card is not found in this table, the gl driver version is reported
- */
-struct driver_version_information {
-    WORD vendor;                        /* reported PCI card vendor ID  */
-    WORD card;                          /* reported PCI card device ID  */
-    const char *description;                  /* Description of the card e.g. NVIDIA RIVA TNT */
-    WORD hipart_hi, hipart_lo;          /* driver hiword to report      */
-    WORD lopart_hi, lopart_lo;          /* driver loword to report      */
-};
-
-static const struct driver_version_information driver_version_table[] = {
-    /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
-     * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
-     * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
-     * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
-     *
-     * All version numbers used below are from the Linux nvidia drivers.
-     */
-    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  7,  1,  8,  6      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        7,  1,  8,  6      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               7,  1,  8,  6      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        9,  6,  4,  3      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", 7,  1,  8,  6      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  9,  6,  4,  3      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           9,  6,  4,  3      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          9,  6,  4,  3      },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           7,  15, 11, 8044   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           7,  15, 11, 8044   },
-
-    /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
-    {VENDOR_ATI,        CARD_ATI_RADEON_9500,           "ATI Radeon 9500",                  6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_X700,           "ATI Radeon X700 SE",               6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          "ATI Radeon X1600 Series",          6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         "ATI Mobility Radeon HD 2300",      6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            6,  14, 10, 6764    },
-
-    /* TODO: Add information about legacy ATI hardware, Intel and other cards */
-};
-
-static BOOL match_ati_r300_to_500(const WineD3D_GL_Info *gl_info) {
-    if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
-    if(gl_info->gl_card == CARD_ATI_RADEON_9500) return TRUE;
-    if(gl_info->gl_card == CARD_ATI_RADEON_X700) return TRUE;
-    if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return TRUE;
-    return FALSE;
-}
-
-static BOOL match_geforce5(const WineD3D_GL_Info *gl_info) {
-    if(gl_info->gl_vendor == VENDOR_NVIDIA) {
-        if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static BOOL match_apple_intel(const WineD3D_GL_Info *gl_info) {
-    return gl_info->gl_vendor == VENDOR_INTEL && match_apple(gl_info);
-}
-
-static BOOL match_apple_nonr500ati(const WineD3D_GL_Info *gl_info) {
-    if(!match_apple(gl_info)) return FALSE;
-    if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
-    if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return FALSE;
-    return TRUE;
-}
-
-static BOOL match_fglrx(const WineD3D_GL_Info *gl_info) {
-    if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
-    if(match_apple(gl_info)) return FALSE;
-    if(strstr(gl_info->gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers */
-    return TRUE;
-}
-
-static void quirk_arb_constants(WineD3D_GL_Info *gl_info) {
-    TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF);
-    gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
-    TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL\n", gl_info->ps_arb_constantsF);
-    gl_info->ps_glsl_constantsF = gl_info->ps_arb_constantsF;
-}
-
-static void quirk_apple_glsl_constants(WineD3D_GL_Info *gl_info) {
-    quirk_arb_constants(gl_info);
-    /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
-     * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
-     * allow 48 different offsets or other helper immediate values
-     */
-    TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use\n");
-    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
-}
-
-/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
- * on more than one texture unit. This means that the d3d9 visual point size test will cause a
- * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
- * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
- * most games, but avoids the crash
- *
- * A more sophisticated way would be to find all units that need texture coordinates and enable
- * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
- * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
- *
- * Note that disabling the extension entirely does not gain predictability because there is no point
- * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension.
- */
-static void quirk_one_point_sprite(WineD3D_GL_Info *gl_info) {
-    if(gl_info->supported[ARB_POINT_SPRITE]) {
-        TRACE("Limiting point sprites to one texture unit\n");
-        gl_info->max_point_sprite_units = 1;
-    }
-}
-
-static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) {
-    quirk_arb_constants(gl_info);
-
-    /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
-     * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
-     * If real NP2 textures are used, the driver falls back to software. We could just remove the
-     * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconventient
-     * due to the non-normalized texture coordinates. Thus set an internal extension flag,
-     * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
-     * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
-     *
-     * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
-     * has this extension promoted to core. The extension loading code sets this extension supported
-     * due to that, so this code works on fglrx as well.
-     */
-    TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
-    gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
-    gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
-
-    /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
-     * it is generally more efficient. Reserve just 8 constants
-     */
-    TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use\n");
-    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
-}
-
-static void quirk_no_np2(WineD3D_GL_Info *gl_info) {
-    /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
-     *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
-     *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
-     *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
-     *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
-     *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
-     *
-     *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
-     *  triggering the software fallback. There is not much we can do here apart from disabling the
-     *  software-emulated extension and reenable ARB_tex_rect (which was previously disabled
-     *  in IWineD3DImpl_FillGLCaps).
-     *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
-     *  post-processing effects in the game "Max Payne 2").
-     *  The behaviour can be verified through a simple test app attached in bugreport #14724.
-     */
-    TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
-    gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
-    gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
-}
-
-static void quirk_texcoord_w(WineD3D_GL_Info *gl_info) {
-    /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
-     * with fixed function fragment processing. Ideally this flag should be detected with a test shader
-     * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
-     * do not like vertex shaders in feedback mode and return an error, even though it should be valid
-     * according to the spec.
-     *
-     * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
-     * makes the shader slower and eats instruction slots which should be available to the d3d app.
-     *
-     * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
-     * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
-     * this workaround is activated on cards that do not need it, it won't break things, just affect
-     * performance negatively.
-     */
-    TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
-    gl_info->set_texcoord_w = TRUE;
-}
-
-struct driver_quirk quirk_table[] = {
-    {
-        match_ati_r300_to_500,
-        quirk_ati_dx9,
-        "ATI GLSL constant and normalized texrect quirk"
-    },
-    /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
-     * used it falls back to software. While the compiler can detect if the shader uses all declared
-     * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
-     * using relative addressing falls back to software.
-     *
-     * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
-     */
-    {
-        match_apple,
-        quirk_apple_glsl_constants,
-        "Apple GLSL uniform override"
-    },
-    {
-        match_geforce5,
-        quirk_no_np2,
-        "Geforce 5 NP2 disable"
-    },
-    {
-        match_apple_intel,
-        quirk_texcoord_w,
-        "Init texcoord .w for Apple Intel GPU driver"
-    },
-    {
-        match_apple_nonr500ati,
-        quirk_texcoord_w,
-        "Init texcoord .w for Apple ATI >= r600 GPU driver"
-    },
-    {
-        match_fglrx,
-        quirk_one_point_sprite,
-        "Fglrx point sprite crash workaround"
-    }
-};
-
-static void fixup_extensions(WineD3D_GL_Info *gl_info) {
-    unsigned int i;
-
-    for(i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); i++) {
-        if(!quirk_table[i].match(gl_info)) continue;
-        TRACE_(d3d_caps)("Applying driver quirk \"%s\"\n", quirk_table[i].description);
-        quirk_table[i].apply(gl_info);
-    }
-
-    /* Find out if PBOs work as they are supposed to */
-    test_pbo_functionality(gl_info);
-
-    /* Fixup the driver version */
-    for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
-        if(gl_info->gl_vendor == driver_version_table[i].vendor &&
-           gl_info->gl_card   == driver_version_table[i].card) {
-            TRACE_(d3d_caps)("Found card 0x%04x, 0x%04x in driver version DB\n", gl_info->gl_vendor, gl_info->gl_card);
-
-            gl_info->driver_version        = MAKEDWORD_VERSION(driver_version_table[i].lopart_hi,
-                                                               driver_version_table[i].lopart_lo);
-            gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
-                                                               driver_version_table[i].hipart_lo);
-            strcpy(gl_info->driver_description, driver_version_table[i].description);
-            break;
-        }
-    }
-}
-
 static void WINE_GLAPI invalid_func(const void *data)
 {
     ERR("Invalid vertex attribute function called\n");
 static void WINE_GLAPI invalid_func(const void *data)
 {
     ERR("Invalid vertex attribute function called\n");
@@ -4243,13 +4361,16 @@ static void WINE_GLAPI position_float4(const void *data)
 {
     const GLfloat *pos = data;
 
 {
     const GLfloat *pos = data;
 
-    if (pos[3] < eps && pos[3] > -eps)
-        glVertex3fv(pos);
-    else {
-        float w = 1.0 / pos[3];
+    if (pos[3] != 0.0f && pos[3] != 1.0f)
+    {
+        float w = 1.0f / pos[3];
 
         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
     }
 
         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
     }
+    else
+    {
+        glVertex3fv(pos);
+    }
 }
 
 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
 }
 
 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
@@ -4277,7 +4398,7 @@ static void WINE_GLAPI warn_no_specular_func(const void *data)
     WARN("GL_EXT_secondary_color not supported\n");
 }
 
     WARN("GL_EXT_secondary_color not supported\n");
 }
 
-static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
+static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
 {
     position_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
     position_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
 {
     position_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
     position_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
@@ -4435,11 +4556,11 @@ BOOL InitAdapters(IWineD3DImpl *This)
      * otherwise because we have to use winex11.drv's override
      */
 #ifdef USE_WIN32_OPENGL
      * otherwise because we have to use winex11.drv's override
      */
 #ifdef USE_WIN32_OPENGL
-    glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
-    glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
+    wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
+    wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
 #else
 #else
-    glFinish = (void*)pwglGetProcAddress("wglFinish");
-    glFlush = (void*)pwglGetProcAddress("wglFlush");
+    wglFinish = (void*)pwglGetProcAddress("wglFinish");
+    wglFlush = (void*)pwglGetProcAddress("wglFlush");
 #endif
 
     glEnableWINE = glEnable;
 #endif
 
     glEnableWINE = glEnable;
@@ -4448,7 +4569,8 @@ BOOL InitAdapters(IWineD3DImpl *This)
     /* For now only one default adapter */
     {
         struct WineD3DAdapter *adapter = &This->adapters[0];
     /* For now only one default adapter */
     {
         struct WineD3DAdapter *adapter = &This->adapters[0];
-        const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+        const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+        struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
         int iPixelFormat;
         int res;
         int i;
         int iPixelFormat;
         int res;
         int i;
@@ -4461,31 +4583,26 @@ BOOL InitAdapters(IWineD3DImpl *This)
         adapter->monitorPoint.x = -1;
         adapter->monitorPoint.y = -1;
 
         adapter->monitorPoint.x = -1;
         adapter->monitorPoint.y = -1;
 
-        if (!WineD3D_CreateFakeGLContext()) {
+        if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
+        {
             ERR("Failed to get a gl context for default adapter\n");
             ERR("Failed to get a gl context for default adapter\n");
-            WineD3D_ReleaseFakeGLContext();
             goto nogl_adapter;
         }
 
         ret = IWineD3DImpl_FillGLCaps(&adapter->gl_info);
         if(!ret) {
             ERR("Failed to initialize gl caps for default adapter\n");
             goto nogl_adapter;
         }
 
         ret = IWineD3DImpl_FillGLCaps(&adapter->gl_info);
         if(!ret) {
             ERR("Failed to initialize gl caps for default adapter\n");
-            WineD3D_ReleaseFakeGLContext();
+            WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
             goto nogl_adapter;
         }
         ret = initPixelFormats(&adapter->gl_info);
         if(!ret) {
             ERR("Failed to init gl formats\n");
             goto nogl_adapter;
         }
         ret = initPixelFormats(&adapter->gl_info);
         if(!ret) {
             ERR("Failed to init gl formats\n");
-            WineD3D_ReleaseFakeGLContext();
+            WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
             goto nogl_adapter;
         }
 
             goto nogl_adapter;
         }
 
-        hdc = pwglGetCurrentDC();
-        if(!hdc) {
-            ERR("Failed to get gl HDC\n");
-            WineD3D_ReleaseFakeGLContext();
-            goto nogl_adapter;
-        }
+        hdc = fake_gl_ctx.dc;
 
         adapter->driver = "Display";
         adapter->description = "Direct3D HAL";
 
         adapter->driver = "Display";
         adapter->description = "Direct3D HAL";
@@ -4622,7 +4739,7 @@ BOOL InitAdapters(IWineD3DImpl *This)
             {
                 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
 
             {
                 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
 
-                WineD3D_ReleaseFakeGLContext();
+                WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
                 goto nogl_adapter;
             }
                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
                 goto nogl_adapter;
             }
@@ -4647,10 +4764,7 @@ BOOL InitAdapters(IWineD3DImpl *This)
             }
         }
 
             }
         }
 
-        fixup_extensions(&adapter->gl_info);
-        add_gl_compat_wrappers(&adapter->gl_info);
-
-        WineD3D_ReleaseFakeGLContext();
+        WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
 
         select_shader_mode(&adapter->gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &adapter->gl_info);
 
         select_shader_mode(&adapter->gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
         select_shader_max_constants(ps_selected_mode, vs_selected_mode, &adapter->gl_info);
index 68821b4..5a2c7e7 100644 (file)
@@ -32,6 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
 #include <stdio.h>
 #include <math.h>
 
 #include <stdio.h>
 #include <math.h>
 
+/* GL locking is done by the caller */
 static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
         UINT min_vertex_idx, UINT max_vertex_idx, UINT count, UINT idx_size,
         const void *idx_data, UINT start_idx)
 static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
         UINT min_vertex_idx, UINT max_vertex_idx, UINT count, UINT idx_size,
         const void *idx_data, UINT start_idx)
@@ -68,8 +69,10 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
  * Slower GL version which extracts info about each vertex in turn
  */
 
  * Slower GL version which extracts info about each vertex in turn
  */
 
-static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT NumVertexes,
-        GLenum glPrimType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx)
+/* GL locking is done by the caller */
+static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context *context,
+        const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType,
+        const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx)
 {
     unsigned int               textureNo    = 0;
     const WORD                *pIdxBufS     = NULL;
 {
     unsigned int               textureNo    = 0;
     const WORD                *pIdxBufS     = NULL;
@@ -84,6 +87,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
     const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
     const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
     const struct wined3d_stream_info_element *element;
     const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
     const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
     const struct wined3d_stream_info_element *element;
+    UINT num_untracked_materials;
     DWORD tex_mask = 0;
 
     TRACE("Using slow vertex array code\n");
     DWORD tex_mask = 0;
 
     TRACE("Using slow vertex array code\n");
@@ -109,22 +113,38 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
     VTRACE(("glBegin(%x)\n", glPrimType));
     glBegin(glPrimType);
 
     VTRACE(("glBegin(%x)\n", glPrimType));
     glBegin(glPrimType);
 
-    element = &si->elements[WINED3D_FFP_POSITION];
-    if (element->data) position = element->data + streamOffset[element->stream_idx];
+    if (si->use_map & (1 << WINED3D_FFP_POSITION))
+    {
+        element = &si->elements[WINED3D_FFP_POSITION];
+        position = element->data + streamOffset[element->stream_idx];
+    }
 
 
-    element = &si->elements[WINED3D_FFP_NORMAL];
-    if (element->data) normal = element->data + streamOffset[element->stream_idx];
-    else glNormal3f(0, 0, 0);
+    if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+    {
+        element = &si->elements[WINED3D_FFP_NORMAL];
+        normal = element->data + streamOffset[element->stream_idx];
+    }
+    else
+    {
+        glNormal3f(0, 0, 0);
+    }
 
 
-    element = &si->elements[WINED3D_FFP_DIFFUSE];
-    if (element->data) diffuse = element->data + streamOffset[element->stream_idx];
-    else glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-    if (This->activeContext->num_untracked_materials && element->format_desc->format != WINED3DFMT_A8R8G8B8)
+    if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+    {
+        element = &si->elements[WINED3D_FFP_DIFFUSE];
+        diffuse = element->data + streamOffset[element->stream_idx];
+    }
+    else
+    {
+        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+    }
+    num_untracked_materials = context->num_untracked_materials;
+    if (num_untracked_materials && element->format_desc->format != WINED3DFMT_A8R8G8B8)
         FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format_desc->format));
 
         FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format_desc->format));
 
-    element = &si->elements[WINED3D_FFP_SPECULAR];
-    if (element->data)
+    if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
     {
     {
+        element = &si->elements[WINED3D_FFP_SPECULAR];
         specular = element->data + streamOffset[element->stream_idx];
 
         /* special case where the fog density is stored in the specular alpha channel */
         specular = element->data + streamOffset[element->stream_idx];
 
         /* special case where the fog density is stored in the specular alpha channel */
@@ -159,7 +179,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
     for (textureNo = 0; textureNo < texture_stages; ++textureNo)
     {
         int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
     for (textureNo = 0; textureNo < texture_stages; ++textureNo)
     {
         int coordIdx = This->stateBlock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
-        int texture_idx = This->texUnitMap[textureNo];
+        DWORD texture_idx = This->texUnitMap[textureNo];
 
         if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
         {
 
         if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
         {
@@ -169,7 +189,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
 
         if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
 
 
         if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
 
-        if (texture_idx == -1) continue;
+        if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;
 
         if (coordIdx > 7)
         {
 
         if (coordIdx > 7)
         {
@@ -182,9 +202,9 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
             continue;
         }
 
             continue;
         }
 
-        element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
-        if (element->data)
+        if (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
         {
         {
+            element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
             texCoords[coordIdx] = element->data + streamOffset[element->stream_idx];
             tex_mask |= (1 << textureNo);
         }
             texCoords[coordIdx] = element->data + streamOffset[element->stream_idx];
             tex_mask |= (1 << textureNo);
         }
@@ -227,7 +247,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
         {
             int coord_idx;
             const void *ptr;
         {
             int coord_idx;
             const void *ptr;
-            int texture_idx;
+            DWORD texture_idx;
 
             if (!(tmp_tex_mask & 1)) continue;
 
 
             if (!(tmp_tex_mask & 1)) continue;
 
@@ -244,18 +264,20 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
             const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;
 
             diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].format_desc->emit_idx](ptrToCoords);
             const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;
 
             diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].format_desc->emit_idx](ptrToCoords);
-            if(This->activeContext->num_untracked_materials) {
+            if (num_untracked_materials)
+            {
                 DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
                 unsigned char i;
                 float color[4];
 
                 DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
                 unsigned char i;
                 float color[4];
 
-                color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0;
-                color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0;
-                color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0;
-                color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0;
+                color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0f;
+                color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0f;
+                color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0f;
+                color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0f;
 
 
-                for(i = 0; i < This->activeContext->num_untracked_materials; i++) {
-                    glMaterialfv(GL_FRONT_AND_BACK, This->activeContext->untracked_materials[i], color);
+                for (i = 0; i < num_untracked_materials; ++i)
+                {
+                    glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], color);
                 }
             }
         }
                 }
             }
         }
@@ -295,6 +317,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
     checkGLcall("glEnd and previous calls");
 }
 
     checkGLcall("glEnd and previous calls");
 }
 
+/* GL locking is done by the caller */
 static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format, const UINT index, const void *ptr)
 {
     switch(format)
 static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format, const UINT index, const void *ptr)
 {
     switch(format)
@@ -397,6 +420,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format
     }
 }
 
     }
 }
 
+/* GL locking is done by the caller */
 static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices,
         GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx)
 {
 static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices,
         GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx)
 {
@@ -442,8 +466,9 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream
             }
         }
 
             }
         }
 
-        for(i = MAX_ATTRIBS - 1; i >= 0; i--) {
-            if(!si->elements[i].data) continue;
+        for (i = MAX_ATTRIBS - 1; i >= 0; i--)
+        {
+            if (!(si->use_map & (1 << i))) continue;
 
             ptr = si->elements[i].data +
                   si->elements[i].stride * SkipnStrides +
 
             ptr = si->elements[i].data +
                   si->elements[i].stride * SkipnStrides +
@@ -457,6 +482,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream
     glEnd();
 }
 
     glEnd();
 }
 
+/* GL locking is done by the caller */
 static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wined3d_stream_info *si,
         UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex,
         UINT startIdx)
 static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wined3d_stream_info *si,
         UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex,
         UINT startIdx)
@@ -496,6 +522,8 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine
 
     for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i)
     {
 
     for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i)
     {
+        if (!(si->use_map & (1 << i))) continue;
+
         if (stateblock->streamFlags[si->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA)
         {
             instancedData[numInstancedAttribs] = i;
         if (stateblock->streamFlags[si->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA)
         {
             instancedData[numInstancedAttribs] = i;
@@ -532,7 +560,11 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_i
 
     for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i)
     {
 
     for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i)
     {
-        struct wined3d_stream_info_element *e = &s->elements[i];
+        struct wined3d_stream_info_element *e;
+
+        if (!(s->use_map & (1 << i))) continue;
+
+        e = &s->elements[i];
         if (e->buffer_object)
         {
             struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
         if (e->buffer_object)
         {
             struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
@@ -549,30 +581,42 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
 
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl          *target;
 
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl          *target;
+    struct wined3d_context *context;
     unsigned int i;
 
     if (!index_count) return;
 
     unsigned int i;
 
     if (!index_count) return;
 
-    /* Invalidate the back buffer memory so LockRect will read it the next time */
-    for(i = 0; i < GL_LIMITS(buffers); i++) {
-        target = (IWineD3DSurfaceImpl *) This->render_targets[i];
-        if (target) {
-            IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL);
-            IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE);
+    if (This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE])
+    {
+        /* Invalidate the back buffer memory so LockRect will read it the next time */
+        for (i = 0; i < GL_LIMITS(buffers); ++i)
+        {
+            target = (IWineD3DSurfaceImpl *)This->render_targets[i];
+            if (target)
+            {
+                IWineD3DSurface_LoadLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, NULL);
+                IWineD3DSurface_ModifyLocation((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
+            }
         }
     }
 
     /* Signals other modules that a drawing is in progress and the stateblock finalized */
     This->isInDraw = TRUE;
 
         }
     }
 
     /* Signals other modules that a drawing is in progress and the stateblock finalized */
     This->isInDraw = TRUE;
 
-    ActivateContext(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
+    context = ActivateContext(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
 
     if (This->stencilBufferTarget) {
         /* Note that this depends on the ActivateContext call above to set
 
     if (This->stencilBufferTarget) {
         /* Note that this depends on the ActivateContext call above to set
-         * This->render_offscreen properly */
-        DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
-        surface_load_ds_location(This->stencilBufferTarget, location);
-        surface_modify_ds_location(This->stencilBufferTarget, location);
+         * This->render_offscreen properly. We don't currently take the
+         * Z-compare function into account, but we could skip loading the
+         * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
+         * that we never copy the stencil data.*/
+        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]
+                || This->stateBlock->renderState[WINED3DRS_ZENABLE])
+            surface_load_ds_location(This->stencilBufferTarget, context, location);
+        if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE])
+            surface_modify_ds_location(This->stencilBufferTarget, location);
     }
 
     /* Ok, we will be updating the screen from here onwards so grab the lock */
     }
 
     /* Ok, we will be updating the screen from here onwards so grab the lock */
@@ -587,7 +631,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
 
         if (!use_vs(This->stateBlock))
         {
 
         if (!use_vs(This->stateBlock))
         {
-            if (!This->strided_streams.position_transformed && This->activeContext->num_untracked_materials
+            if (!This->strided_streams.position_transformed && context->num_untracked_materials
                     && This->stateBlock->renderState[WINED3DRS_LIGHTING])
             {
                 static BOOL warned;
                     && This->stateBlock->renderState[WINED3DRS_LIGHTING])
             {
                 static BOOL warned;
@@ -599,7 +643,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
                 }
                 emulation = TRUE;
             }
                 }
                 emulation = TRUE;
             }
-            else if(This->activeContext->fog_coord && This->stateBlock->renderState[WINED3DRS_FOGENABLE]) {
+            else if (context->fog_coord && This->stateBlock->renderState[WINED3DRS_FOGENABLE])
+            {
                 /* Either write a pipeline replacement shader or convert the specular alpha from unsigned byte
                  * to a float in the vertex buffer
                  */
                 /* Either write a pipeline replacement shader or convert the specular alpha from unsigned byte
                  * to a float in the vertex buffer
                  */
@@ -633,7 +678,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
                 }
                 drawStridedSlowVs(iface, stream_info, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx);
             } else {
                 }
                 drawStridedSlowVs(iface, stream_info, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx);
             } else {
-                drawStridedSlow(iface, stream_info, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx);
+                drawStridedSlow(iface, context, stream_info, index_count,
+                        glPrimType, idxData, idxSize, minIndex, StartIdx);
             }
         } else if(This->instancedDraw) {
             /* Instancing emulation with mixing immediate mode and arrays */
             }
         } else if(This->instancedDraw) {
             /* Instancing emulation with mixing immediate mode and arrays */
@@ -653,7 +699,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
 #ifdef SHOW_FRAME_MAKEUP
     {
         static long int primCounter = 0;
 #ifdef SHOW_FRAME_MAKEUP
     {
         static long int primCounter = 0;
-        /* NOTE: set primCounter to the value reported by drawprim 
+        /* NOTE: set primCounter to the value reported by drawprim
            before you want to to write frame makeup to /tmp */
         if (primCounter >= 0) {
             WINED3DLOCKED_RECT r;
            before you want to to write frame makeup to /tmp */
         if (primCounter >= 0) {
             WINED3DLOCKED_RECT r;
@@ -695,7 +741,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
 
 static void normalize_normal(float *n) {
     float length = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
 
 static void normalize_normal(float *n) {
     float length = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
-    if(length == 0.0) return;
+    if (length == 0.0f) return;
     length = sqrt(length);
     n[0] = n[0] / length;
     n[1] = n[1] / length;
     length = sqrt(length);
     n[0] = n[0] / length;
     n[1] = n[1] / length;
@@ -727,7 +773,7 @@ static void normalize_normal(float *n) {
 HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
                             struct WineD3DRectPatch *patch) {
     unsigned int i, j, num_quads, out_vertex_size, buffer_size, d3d_out_vertex_size;
 HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
                             struct WineD3DRectPatch *patch) {
     unsigned int i, j, num_quads, out_vertex_size, buffer_size, d3d_out_vertex_size;
-    float max_x = 0.0, max_y = 0.0, max_z = 0.0, neg_z = 0.0;
+    float max_x = 0.0f, max_y = 0.0f, max_z = 0.0f, neg_z = 0.0f;
     struct wined3d_stream_info stream_info;
     struct wined3d_stream_info_element *e;
     const BYTE *data;
     struct wined3d_stream_info stream_info;
     struct wined3d_stream_info_element *e;
     const BYTE *data;
@@ -736,6 +782,11 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     GLenum feedback_type;
     GLfloat *feedbuffer;
 
     GLenum feedback_type;
     GLfloat *feedbuffer;
 
+    /* Simply activate the context for blitting. This disables all the things we don't want and
+     * takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the
+     * patch (as opposed to normal draws) will most likely need different changes anyway. */
+    ActivateContext(This, NULL, CTXUSAGE_BLIT);
+
     /* First, locate the position data. This is provided in a vertex buffer in the stateblock.
      * Beware of vbos
      */
     /* First, locate the position data. This is provided in a vertex buffer in the stateblock.
      * Beware of vbos
      */
@@ -786,19 +837,14 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     patch->has_normals = TRUE;
     patch->has_texcoords = FALSE;
 
     patch->has_normals = TRUE;
     patch->has_texcoords = FALSE;
 
-    /* Simply activate the context for blitting. This disables all the things we don't want and
-     * takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the
-     * patch (as opposed to normal draws) will most likely need different changes anyway
-     */
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_BLIT);
     ENTER_GL();
 
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
     checkGLcall("glLoadIndentity()");
     ENTER_GL();
 
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
     checkGLcall("glLoadIndentity()");
-    glScalef(1 / (max_x) , 1 / (max_y), max_z == 0 ? 1 : 1 / ( 2 * max_z));
-    glTranslatef(0, 0, 0.5);
+    glScalef(1.0f / (max_x), 1.0f / (max_y), max_z == 0.0f ? 1.0f : 1.0f / (2.0f * max_z));
+    glTranslatef(0.0f, 0.0f, 0.5f);
     checkGLcall("glScalef");
     glViewport(-max_x, -max_y, 2 * (max_x), 2 * (max_y));
     checkGLcall("glViewport");
     checkGLcall("glScalef");
     glViewport(-max_x, -max_y, 2 * (max_x), 2 * (max_y));
     checkGLcall("glViewport");
@@ -810,11 +856,11 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FILLMODE));
     if(patch->has_normals) {
     checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_FILLMODE));
     if(patch->has_normals) {
-        static const GLfloat black[] = {0, 0, 0, 0};
-        static const GLfloat red[]   = {1, 0, 0, 0};
-        static const GLfloat green[] = {0, 1, 0, 0};
-        static const GLfloat blue[]  = {0, 0, 1, 0};
-        static const GLfloat white[] = {1, 1, 1, 1};
+        static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
+        static const GLfloat red[]   = {1.0f, 0.0f, 0.0f, 0.0f};
+        static const GLfloat green[] = {0.0f, 1.0f, 0.0f, 0.0f};
+        static const GLfloat blue[]  = {0.0f, 0.0f, 1.0f, 0.0f};
+        static const GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f};
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
@@ -833,21 +879,21 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
         glLightfv(GL_LIGHT0, GL_AMBIENT, black);
         glLightfv(GL_LIGHT0, GL_POSITION, red);
         glEnable(GL_LIGHT0);
         glLightfv(GL_LIGHT0, GL_AMBIENT, black);
         glLightfv(GL_LIGHT0, GL_POSITION, red);
         glEnable(GL_LIGHT0);
-        checkGLcall("Setting up light 1\n");
+        checkGLcall("Setting up light 1");
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(1));
         glLightfv(GL_LIGHT1, GL_DIFFUSE, green);
         glLightfv(GL_LIGHT1, GL_SPECULAR, black);
         glLightfv(GL_LIGHT1, GL_AMBIENT, black);
         glLightfv(GL_LIGHT1, GL_POSITION, green);
         glEnable(GL_LIGHT1);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(1));
         glLightfv(GL_LIGHT1, GL_DIFFUSE, green);
         glLightfv(GL_LIGHT1, GL_SPECULAR, black);
         glLightfv(GL_LIGHT1, GL_AMBIENT, black);
         glLightfv(GL_LIGHT1, GL_POSITION, green);
         glEnable(GL_LIGHT1);
-        checkGLcall("Setting up light 2\n");
+        checkGLcall("Setting up light 2");
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(2));
         glLightfv(GL_LIGHT2, GL_DIFFUSE, blue);
         glLightfv(GL_LIGHT2, GL_SPECULAR, black);
         glLightfv(GL_LIGHT2, GL_AMBIENT, black);
         glLightfv(GL_LIGHT2, GL_POSITION, blue);
         glEnable(GL_LIGHT2);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_ACTIVELIGHT(2));
         glLightfv(GL_LIGHT2, GL_DIFFUSE, blue);
         glLightfv(GL_LIGHT2, GL_SPECULAR, black);
         glLightfv(GL_LIGHT2, GL_AMBIENT, black);
         glLightfv(GL_LIGHT2, GL_POSITION, blue);
         glEnable(GL_LIGHT2);
-        checkGLcall("Setting up light 3\n");
+        checkGLcall("Setting up light 3");
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_MATERIAL);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORVERTEX));
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_MATERIAL);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORVERTEX));
@@ -855,7 +901,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, white);
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, white);
-        checkGLcall("Setting up materials\n");
+        checkGLcall("Setting up materials");
     }
 
     /* Enable the needed maps.
     }
 
     /* Enable the needed maps.
@@ -895,18 +941,18 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     feedbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size * sizeof(float) * 8);
 
     glMap2f(GL_MAP2_VERTEX_3,
     feedbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size * sizeof(float) * 8);
 
     glMap2f(GL_MAP2_VERTEX_3,
-            0, 1, vtxStride / sizeof(float), info->Width,
-            0, 1, info->Stride * vtxStride / sizeof(float), info->Height,
+            0.0f, 1.0f, vtxStride / sizeof(float), info->Width,
+            0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
             (const GLfloat *)data);
     checkGLcall("glMap2f");
     if(patch->has_texcoords) {
         glMap2f(GL_MAP2_TEXTURE_COORD_4,
             (const GLfloat *)data);
     checkGLcall("glMap2f");
     if(patch->has_texcoords) {
         glMap2f(GL_MAP2_TEXTURE_COORD_4,
-                0, 1, vtxStride / sizeof(float), info->Width,
-                0, 1, info->Stride * vtxStride / sizeof(float), info->Height,
+                0.0f, 1.0f, vtxStride / sizeof(float), info->Width,
+                0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
                 (const GLfloat *)data);
         checkGLcall("glMap2f");
     }
                 (const GLfloat *)data);
         checkGLcall("glMap2f");
     }
-    glMapGrid2f(ceilf(patch->numSegs[0]), 0.0, 1.0, ceilf(patch->numSegs[1]), 0.0, 1.0);
+    glMapGrid2f(ceilf(patch->numSegs[0]), 0.0f, 1.0f, ceilf(patch->numSegs[1]), 0.0f, 1.0f);
     checkGLcall("glMapGrid2f");
 
     glFeedbackBuffer(buffer_size * 2, feedback_type, feedbuffer);
     checkGLcall("glMapGrid2f");
 
     glFeedbackBuffer(buffer_size * 2, feedback_type, feedbuffer);
@@ -914,19 +960,17 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     glRenderMode(GL_FEEDBACK);
 
     glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
     glRenderMode(GL_FEEDBACK);
 
     glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
-    checkGLcall("glEvalMesh2\n");
+    checkGLcall("glEvalMesh2");
 
     i = glRenderMode(GL_RENDER);
     if(i == -1) {
         LEAVE_GL();
         ERR("Feedback failed. Expected %d elements back\n", buffer_size);
 
     i = glRenderMode(GL_RENDER);
     if(i == -1) {
         LEAVE_GL();
         ERR("Feedback failed. Expected %d elements back\n", buffer_size);
-        Sleep(10000);
         HeapFree(GetProcessHeap(), 0, feedbuffer);
         return WINED3DERR_DRIVERINTERNALERROR;
     } else if(i != buffer_size) {
         LEAVE_GL();
         ERR("Unexpected amount of elements returned. Expected %d, got %d\n", buffer_size, i);
         HeapFree(GetProcessHeap(), 0, feedbuffer);
         return WINED3DERR_DRIVERINTERNALERROR;
     } else if(i != buffer_size) {
         LEAVE_GL();
         ERR("Unexpected amount of elements returned. Expected %d, got %d\n", buffer_size, i);
-        Sleep(10000);
         HeapFree(GetProcessHeap(), 0, feedbuffer);
         return WINED3DERR_DRIVERINTERNALERROR;
     } else {
         HeapFree(GetProcessHeap(), 0, feedbuffer);
         return WINED3DERR_DRIVERINTERNALERROR;
     } else {
@@ -950,7 +994,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
          */
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 2 + 2]; /* x, triangle 2 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 2 + 3]; /* y, triangle 2 */
          */
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 2 + 2]; /* x, triangle 2 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 2 + 3]; /* y, triangle 2 */
-        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 2 + 4] - 0.5) * 4 * max_z; /* z, triangle 3 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 2 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 3 */
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 2 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 2 + 6];
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 2 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 2 + 6];
@@ -960,7 +1004,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
 
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 1 + 2]; /* x, triangle 2 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 1 + 3]; /* y, triangle 2 */
 
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 1 + 2]; /* x, triangle 2 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 1 + 3]; /* y, triangle 2 */
-        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 1 + 4] - 0.5) * 4 * max_z; /* z, triangle 2 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 1 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 2 */
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 1 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 1 + 6];
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 1 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 1 + 6];
@@ -970,7 +1014,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
 
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 0 + 2]; /* x, triangle 1 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 0 + 3]; /* y, triangle 1 */
 
         patch->mem[i + 0] =  feedbuffer[j + out_vertex_size * 0 + 2]; /* x, triangle 1 */
         patch->mem[i + 1] =  feedbuffer[j + out_vertex_size * 0 + 3]; /* y, triangle 1 */
-        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 0 + 4] - 0.5) * 4 * max_z; /* z, triangle 1 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 0 + 4] - 0.5f) * 4.0f * max_z; /* z, triangle 1 */
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 0 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 0 + 6];
         if(patch->has_normals) {
             patch->mem[i + 3] = feedbuffer[j + out_vertex_size * 0 + 5];
             patch->mem[i + 4] = feedbuffer[j + out_vertex_size * 0 + 6];
@@ -981,18 +1025,18 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
 
     if(patch->has_normals) {
         /* Now do the same with reverse light directions */
 
     if(patch->has_normals) {
         /* Now do the same with reverse light directions */
-        static const GLfloat x[] = {-1,  0,  0, 0};
-        static const GLfloat y[] = { 0, -1,  0, 0};
-        static const GLfloat z[] = { 0,  0, -1, 0};
+        static const GLfloat x[] = {-1.0f,  0.0f,  0.0f, 0.0f};
+        static const GLfloat y[] = { 0.0f, -1.0f,  0.0f, 0.0f};
+        static const GLfloat z[] = { 0.0f,  0.0f, -1.0f, 0.0f};
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
-        checkGLcall("Setting up reverse light directions\n");
+        checkGLcall("Setting up reverse light directions");
 
         glRenderMode(GL_FEEDBACK);
         checkGLcall("glRenderMode(GL_FEEDBACK)");
         glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
 
         glRenderMode(GL_FEEDBACK);
         checkGLcall("glRenderMode(GL_FEEDBACK)");
         glEvalMesh2(GL_FILL, 0, ceilf(patch->numSegs[0]), 0, ceilf(patch->numSegs[1]));
-        checkGLcall("glEvalMesh2\n");
+        checkGLcall("glEvalMesh2");
         i = glRenderMode(GL_RENDER);
         checkGLcall("glRenderMode(GL_RENDER)");
 
         i = glRenderMode(GL_RENDER);
         checkGLcall("glRenderMode(GL_RENDER)");
 
@@ -1006,29 +1050,29 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
                 ERR("Unexpected polygon: %f corners\n", feedbuffer[j + 1]);
                 continue;
             }
                 ERR("Unexpected polygon: %f corners\n", feedbuffer[j + 1]);
                 continue;
             }
-            if(patch->mem[i + 3] == 0.0)
+            if(patch->mem[i + 3] == 0.0f)
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 2 + 5];
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 2 + 5];
-            if(patch->mem[i + 4] == 0.0)
+            if(patch->mem[i + 4] == 0.0f)
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 2 + 6];
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 2 + 6];
-            if(patch->mem[i + 5] == 0.0)
+            if(patch->mem[i + 5] == 0.0f)
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 2 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
 
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 2 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
 
-            if(patch->mem[i + 3] == 0.0)
+            if(patch->mem[i + 3] == 0.0f)
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 1 + 5];
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 1 + 5];
-            if(patch->mem[i + 4] == 0.0)
+            if(patch->mem[i + 4] == 0.0f)
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 1 + 6];
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 1 + 6];
-            if(patch->mem[i + 5] == 0.0)
+            if(patch->mem[i + 5] == 0.0f)
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 1 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
 
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 1 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
 
-            if(patch->mem[i + 3] == 0.0)
+            if(patch->mem[i + 3] == 0.0f)
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 0 + 5];
                 patch->mem[i + 3] = -feedbuffer[j + out_vertex_size * 0 + 5];
-            if(patch->mem[i + 4] == 0.0)
+            if(patch->mem[i + 4] == 0.0f)
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 0 + 6];
                 patch->mem[i + 4] = -feedbuffer[j + out_vertex_size * 0 + 6];
-            if(patch->mem[i + 5] == 0.0)
+            if(patch->mem[i + 5] == 0.0f)
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 0 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
                 patch->mem[i + 5] = -feedbuffer[j + out_vertex_size * 0 + 7];
             normalize_normal(patch->mem + i + 3);
             i += d3d_out_vertex_size;
index 1fc48cc..9166041 100644 (file)
@@ -133,7 +133,7 @@ static void WINE_GLAPI wine_glGetIntegerv(GLenum pname, GLint* params) {
 
 static void (WINE_GLAPI *old_multitex_glGetFloatv) (GLenum pname, GLfloat* params) = NULL;
 static void WINE_GLAPI wine_glGetFloatv(GLenum pname, GLfloat* params) {
 
 static void (WINE_GLAPI *old_multitex_glGetFloatv) (GLenum pname, GLfloat* params) = NULL;
 static void WINE_GLAPI wine_glGetFloatv(GLenum pname, GLfloat* params) {
-    if(pname == GL_ACTIVE_TEXTURE) *params = 0.0;
+    if (pname == GL_ACTIVE_TEXTURE) *params = 0.0f;
     else old_multitex_glGetFloatv(pname, params);
 }
 
     else old_multitex_glGetFloatv(pname, params);
 }
 
@@ -147,7 +147,7 @@ static void WINE_GLAPI wine_glGetDoublev(GLenum pname, GLdouble* params) {
 static void (WINE_GLAPI *old_fogcoord_glEnable) (GLenum cap) = NULL;
 static void WINE_GLAPI wine_glEnable(GLenum cap) {
     if(cap == GL_FOG) {
 static void (WINE_GLAPI *old_fogcoord_glEnable) (GLenum cap) = NULL;
 static void WINE_GLAPI wine_glEnable(GLenum cap) {
     if(cap == GL_FOG) {
-        WineD3DContext *ctx = getActiveContext();
+        struct wined3d_context *ctx = context_get_current();
         ctx->fog_enabled = 1;
         if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
     }
         ctx->fog_enabled = 1;
         if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
     }
@@ -157,7 +157,7 @@ static void WINE_GLAPI wine_glEnable(GLenum cap) {
 static void (WINE_GLAPI *old_fogcoord_glDisable) (GLenum cap) = NULL;
 static void WINE_GLAPI wine_glDisable(GLenum cap) {
     if(cap == GL_FOG) {
 static void (WINE_GLAPI *old_fogcoord_glDisable) (GLenum cap) = NULL;
 static void WINE_GLAPI wine_glDisable(GLenum cap) {
     if(cap == GL_FOG) {
-        WineD3DContext *ctx = getActiveContext();
+        struct wined3d_context *ctx = context_get_current();
         ctx->fog_enabled = 0;
         if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
     }
         ctx->fog_enabled = 0;
         if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
     }
@@ -166,8 +166,9 @@ static void WINE_GLAPI wine_glDisable(GLenum cap) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogi) (GLenum pname, GLint param) = NULL;
 static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogi) (GLenum pname, GLint param) = NULL;
 static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
+    struct wined3d_context *ctx = context_get_current();
+
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
-        WineD3DContext *ctx = getActiveContext();
         ctx->gl_fog_source = param;
         if(param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
         ctx->gl_fog_source = param;
         if(param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
@@ -177,9 +178,9 @@ static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            getActiveContext()->fogstart = param;
+            ctx->fogstart = param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            getActiveContext()->fogend = param;
+            ctx->fogend = param;
         }
         old_fogcoord_glFogi(pname, param);
     }
         }
         old_fogcoord_glFogi(pname, param);
     }
@@ -187,8 +188,8 @@ static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogiv) (GLenum pname, const GLint *param) = NULL;
 static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogiv) (GLenum pname, const GLint *param) = NULL;
 static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
+    struct wined3d_context *ctx = context_get_current();
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
-        WineD3DContext *ctx = getActiveContext();
         ctx->gl_fog_source = *param;
         if(*param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
         ctx->gl_fog_source = *param;
         if(*param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
@@ -198,9 +199,9 @@ static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            getActiveContext()->fogstart = *param;
+            ctx->fogstart = *param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            getActiveContext()->fogend = *param;
+            ctx->fogend = *param;
         }
         old_fogcoord_glFogiv(pname, param);
     }
         }
         old_fogcoord_glFogiv(pname, param);
     }
@@ -208,8 +209,8 @@ static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogf) (GLenum pname, GLfloat param) = NULL;
 static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogf) (GLenum pname, GLfloat param) = NULL;
 static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
+    struct wined3d_context *ctx = context_get_current();
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
-        WineD3DContext *ctx = getActiveContext();
         ctx->gl_fog_source = (GLint) param;
         if(param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
         ctx->gl_fog_source = (GLint) param;
         if(param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
@@ -219,9 +220,9 @@ static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            getActiveContext()->fogstart = param;
+            ctx->fogstart = param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            getActiveContext()->fogend = param;
+            ctx->fogend = param;
         }
         old_fogcoord_glFogf(pname, param);
     }
         }
         old_fogcoord_glFogf(pname, param);
     }
@@ -229,8 +230,8 @@ static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogfv) (GLenum pname, const GLfloat *param) = NULL;
 static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) {
 
 static void (WINE_GLAPI *old_fogcoord_glFogfv) (GLenum pname, const GLfloat *param) = NULL;
 static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) {
+    struct wined3d_context *ctx = context_get_current();
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
     if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
-        WineD3DContext *ctx = getActiveContext();
         ctx->gl_fog_source = (GLint) *param;
         if(*param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
         ctx->gl_fog_source = (GLint) *param;
         if(*param == GL_FRAGMENT_DEPTH_EXT) {
             if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
@@ -240,15 +241,14 @@ static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) {
         }
     } else {
         if(pname == GL_FOG_COLOR) {
         }
     } else {
         if(pname == GL_FOG_COLOR) {
-            WineD3DContext *ctx = getActiveContext();
             ctx->fogcolor[0] = param[0];
             ctx->fogcolor[1] = param[1];
             ctx->fogcolor[2] = param[2];
             ctx->fogcolor[3] = param[3];
         } else if(pname == GL_FOG_START) {
             ctx->fogcolor[0] = param[0];
             ctx->fogcolor[1] = param[1];
             ctx->fogcolor[2] = param[2];
             ctx->fogcolor[3] = param[3];
         } else if(pname == GL_FOG_START) {
-            getActiveContext()->fogstart = *param;
+            ctx->fogstart = *param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            getActiveContext()->fogend = *param;
+            ctx->fogend = *param;
         }
         old_fogcoord_glFogfv(pname, param);
     }
         }
         old_fogcoord_glFogfv(pname, param);
     }
@@ -269,15 +269,15 @@ static void (WINE_GLAPI *old_fogcoord_glFogCoordfvEXT) (const GLfloat *f) = NULL
 static void (WINE_GLAPI *old_fogcoord_glFogCoorddvEXT) (const GLdouble *f) = NULL;
 
 static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
 static void (WINE_GLAPI *old_fogcoord_glFogCoorddvEXT) (const GLdouble *f) = NULL;
 
 static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
-    WineD3DContext *ctx = getActiveContext();
+    struct wined3d_context *ctx = context_get_current();
     if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
         GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
         GLfloat i;
 
         i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart);
     if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
         GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
         GLfloat i;
 
         i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart);
-        c[0] = i * c[0] + (1.0 - i) * ctx->fogcolor[0];
-        c[1] = i * c[1] + (1.0 - i) * ctx->fogcolor[1];
-        c[2] = i * c[2] + (1.0 - i) * ctx->fogcolor[2];
+        c[0] = i * c[0] + (1.0f - i) * ctx->fogcolor[0];
+        c[1] = i * c[1] + (1.0f - i) * ctx->fogcolor[1];
+        c[2] = i * c[2] + (1.0f - i) * ctx->fogcolor[2];
 
         old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]);
         old_fogcoord_glVertex4f(x, y, z, w);
 
         old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]);
         old_fogcoord_glVertex4f(x, y, z, w);
@@ -291,15 +291,15 @@ static void WINE_GLAPI wine_glVertex4fv(const GLfloat *pos) {
 }
 
 static void WINE_GLAPI wine_glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
 }
 
 static void WINE_GLAPI wine_glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
-    wine_glVertex4f(x, y, z, 1.0);
+    wine_glVertex4f(x, y, z, 1.0f);
 }
 
 static void WINE_GLAPI wine_glVertex3fv(const GLfloat *pos) {
 }
 
 static void WINE_GLAPI wine_glVertex3fv(const GLfloat *pos) {
-    wine_glVertex4f(pos[0], pos[1], pos[2], 1.0);
+    wine_glVertex4f(pos[0], pos[1], pos[2], 1.0f);
 }
 
 }
 
-static void wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-    WineD3DContext *ctx = getActiveContext();
+static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+    struct wined3d_context *ctx = context_get_current();
     ctx->color[0] = r;
     ctx->color[1] = g;
     ctx->color[2] = b;
     ctx->color[0] = r;
     ctx->color[1] = g;
     ctx->color[2] = b;
@@ -307,43 +307,44 @@ static void wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
     old_fogcoord_glColor4f(r, g, b, a);
 }
 
     old_fogcoord_glColor4f(r, g, b, a);
 }
 
-static void wine_glColor4fv(const GLfloat *c) {
+static void WINE_GLAPI wine_glColor4fv(const GLfloat *c) {
     wine_glColor4f(c[0], c[1], c[2], c[3]);
 }
 
     wine_glColor4f(c[0], c[1], c[2], c[3]);
 }
 
-static void wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
-    wine_glColor4f(r, g, b, 1.0);
+static void WINE_GLAPI wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
+    wine_glColor4f(r, g, b, 1.0f);
 }
 
 }
 
-static void wine_glColor3fv(const GLfloat *c) {
-    wine_glColor4f(c[0], c[1], c[2], 1.0);
+static void WINE_GLAPI wine_glColor3fv(const GLfloat *c) {
+    wine_glColor4f(c[0], c[1], c[2], 1.0f);
 }
 
 }
 
-static void wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
-    wine_glColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+static void WINE_GLAPI wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
+    wine_glColor4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
 }
 
 /* In D3D the fog coord is a UBYTE, so there's no problem with using the single
  * precision function
  */
 }
 
 /* In D3D the fog coord is a UBYTE, so there's no problem with using the single
  * precision function
  */
-static void wine_glFogCoordfEXT(GLfloat f) {
-    WineD3DContext *ctx = getActiveContext();
+static void WINE_GLAPI wine_glFogCoordfEXT(GLfloat f) {
+    struct wined3d_context *ctx = context_get_current();
     ctx->fog_coord_value = f;
 }
     ctx->fog_coord_value = f;
 }
-static void wine_glFogCoorddEXT(GLdouble f) {
+static void WINE_GLAPI wine_glFogCoorddEXT(GLdouble f) {
     wine_glFogCoordfEXT(f);
 }
     wine_glFogCoordfEXT(f);
 }
-static void wine_glFogCoordfvEXT(const GLfloat *f) {
+static void WINE_GLAPI wine_glFogCoordfvEXT(const GLfloat *f) {
     wine_glFogCoordfEXT(*f);
 }
     wine_glFogCoordfEXT(*f);
 }
-static void wine_glFogCoorddvEXT(const GLdouble *f) {
+static void WINE_GLAPI wine_glFogCoorddvEXT(const GLdouble *f) {
     wine_glFogCoordfEXT(*f);
 }
 
 /* End GL_EXT_fog_coord emulation */
 
 #define GLINFO_LOCATION (*gl_info)
     wine_glFogCoordfEXT(*f);
 }
 
 /* End GL_EXT_fog_coord emulation */
 
 #define GLINFO_LOCATION (*gl_info)
-void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info) {
+void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info)
+{
     if(!GL_SUPPORT(ARB_MULTITEXTURE)) {
         TRACE("Applying GL_ARB_multitexture emulation hooks\n");
         gl_info->glActiveTextureARB         = wine_glActiveTextureARB;
     if(!GL_SUPPORT(ARB_MULTITEXTURE)) {
         TRACE("Applying GL_ARB_multitexture emulation hooks\n");
         gl_info->glActiveTextureARB         = wine_glActiveTextureARB;
index ca50305..b6fac0c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * GLSL pixel and vertex shader implementation
  *
 /*
  * GLSL pixel and vertex shader implementation
  *
- * Copyright 2006 Jason Green 
+ * Copyright 2006 Jason Green
  * Copyright 2006-2007 Henri Verbeet
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Copyright 2009 Henri Verbeet for CodeWeavers
  * Copyright 2006-2007 Henri Verbeet
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Copyright 2009 Henri Verbeet for CodeWeavers
@@ -83,7 +83,8 @@ struct constant_heap
 
 /* GLSL shader private data */
 struct shader_glsl_priv {
 
 /* GLSL shader private data */
 struct shader_glsl_priv {
-    struct hash_table_t *glsl_program_lookup;
+    struct wined3d_shader_buffer shader_buffer;
+    struct wine_rb_tree program_lookup;
     struct glsl_shader_prog_link *glsl_program;
     struct constant_heap vconst_heap;
     struct constant_heap pconst_heap;
     struct glsl_shader_prog_link *glsl_program;
     struct constant_heap vconst_heap;
     struct constant_heap pconst_heap;
@@ -94,6 +95,7 @@ struct shader_glsl_priv {
 
 /* Struct to maintain data about a linked GLSL program */
 struct glsl_shader_prog_link {
 
 /* Struct to maintain data about a linked GLSL program */
 struct glsl_shader_prog_link {
+    struct wine_rb_entry        program_lookup_entry;
     struct list                 vshader_entry;
     struct list                 pshader_entry;
     GLhandleARB                 programId;
     struct list                 vshader_entry;
     struct list                 pshader_entry;
     GLhandleARB                 programId;
@@ -102,7 +104,7 @@ struct glsl_shader_prog_link {
     GLint                       vuniformI_locations[MAX_CONST_I];
     GLint                       puniformI_locations[MAX_CONST_I];
     GLint                       posFixup_location;
     GLint                       vuniformI_locations[MAX_CONST_I];
     GLint                       puniformI_locations[MAX_CONST_I];
     GLint                       posFixup_location;
-    GLint                       np2Fixup_location[MAX_FRAGMENT_SAMPLERS];
+    GLint                       np2Fixup_location;
     GLint                       bumpenvmat_location[MAX_TEXTURES];
     GLint                       luminancescale_location[MAX_TEXTURES];
     GLint                       luminanceoffset_location[MAX_TEXTURES];
     GLint                       bumpenvmat_location[MAX_TEXTURES];
     GLint                       luminancescale_location[MAX_TEXTURES];
     GLint                       luminanceoffset_location[MAX_TEXTURES];
@@ -113,6 +115,7 @@ struct glsl_shader_prog_link {
     struct vs_compile_args      vs_args;
     struct ps_compile_args      ps_args;
     UINT                        constant_version;
     struct vs_compile_args      vs_args;
     struct ps_compile_args      ps_args;
     UINT                        constant_version;
+    const struct ps_np2fixup_info *np2Fixup_info;
 };
 
 typedef struct {
 };
 
 typedef struct {
@@ -122,9 +125,59 @@ typedef struct {
     struct vs_compile_args      vs_args;
 } glsl_program_key_t;
 
     struct vs_compile_args      vs_args;
 } glsl_program_key_t;
 
+struct shader_glsl_ctx_priv {
+    const struct vs_compile_args    *cur_vs_args;
+    const struct ps_compile_args    *cur_ps_args;
+    struct ps_np2fixup_info         *cur_np2fixup_info;
+};
+
+struct glsl_ps_compiled_shader
+{
+    struct ps_compile_args          args;
+    struct ps_np2fixup_info         np2fixup;
+    GLhandleARB                     prgId;
+};
+
+struct glsl_pshader_private
+{
+    struct glsl_ps_compiled_shader  *gl_shaders;
+    UINT                            num_gl_shaders, shader_array_size;
+};
+
+struct glsl_vs_compiled_shader
+{
+    struct vs_compile_args          args;
+    GLhandleARB                     prgId;
+};
+
+struct glsl_vshader_private
+{
+    struct glsl_vs_compiled_shader  *gl_shaders;
+    UINT                            num_gl_shaders, shader_array_size;
+};
+
+/* Extract a line from the info log.
+ * Note that this modifies the source string. */
+static char *get_info_log_line(char **ptr)
+{
+    char *p, *q;
+
+    p = *ptr;
+    if (!(q = strstr(p, "\n")))
+    {
+        if (!*p) return NULL;
+        *ptr += strlen(p);
+        return p;
+    }
+    *q = '\0';
+    *ptr = q + 1;
+
+    return p;
+}
 
 /** Prints the GLSL info log which will contain error messages if they exist */
 
 /** Prints the GLSL info log which will contain error messages if they exist */
-static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
+/* GL locking is done by the caller */
+static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleARB obj)
 {
     int infologLength = 0;
     char *infoLog;
 {
     int infologLength = 0;
     char *infoLog;
@@ -140,10 +193,8 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
         "Vertex shader(s) linked, no fragment shader(s) defined. \n ",      /* fglrx, with \n */
         "Vertex shader(s) linked, no fragment shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader was successfully compiled to run on hardware.\n"
         "Vertex shader(s) linked, no fragment shader(s) defined. \n ",      /* fglrx, with \n */
         "Vertex shader(s) linked, no fragment shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader was successfully compiled to run on hardware.\n"
-        "WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported",
         "Fragment shader(s) linked, no vertex shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader(s) linked, no vertex shader(s) defined. \n ",      /* fglrx, with \n */
         "Fragment shader(s) linked, no vertex shader(s) defined.",          /* fglrx, no \n   */
         "Fragment shader(s) linked, no vertex shader(s) defined. \n ",      /* fglrx, with \n */
-        "WARNING: 0:2: extension 'GL_ARB_draw_buffers' is not supported\n"  /* MacOS ati      */
     };
 
     if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
     };
 
     if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
@@ -156,6 +207,8 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
      * that if there are errors. */
     if (infologLength > 1)
     {
      * that if there are errors. */
     if (infologLength > 1)
     {
+        char *ptr, *line;
+
         /* Fglrx doesn't terminate the string properly, but it tells us the proper length.
          * So use HEAP_ZERO_MEMORY to avoid uninitialized bytes
          */
         /* Fglrx doesn't terminate the string properly, but it tells us the proper length.
          * So use HEAP_ZERO_MEMORY to avoid uninitialized bytes
          */
@@ -169,10 +222,17 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
                 break;
             }
         }
                 break;
             }
         }
-        if(is_spam) {
-            TRACE("Spam received from GLSL shader #%u: %s\n", obj, debugstr_a(infoLog));
-        } else {
-            FIXME("Error received from GLSL shader #%u: %s\n", obj, debugstr_a(infoLog));
+
+        ptr = infoLog;
+        if (is_spam)
+        {
+            TRACE("Spam received from GLSL shader #%u:\n", obj);
+            while ((line = get_info_log_line(&ptr))) TRACE("    %s\n", line);
+        }
+        else
+        {
+            FIXME("Error received from GLSL shader #%u:\n", obj);
+            while ((line = get_info_log_line(&ptr))) FIXME("    %s\n", line);
         }
         HeapFree(GetProcessHeap(), 0, infoLog);
     }
         }
         HeapFree(GetProcessHeap(), 0, infoLog);
     }
@@ -181,7 +241,9 @@ static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
 /**
  * Loads (pixel shader) samplers
  */
 /**
  * Loads (pixel shader) samplers
  */
-static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, DWORD *tex_unit_map, GLhandleARB programId)
+/* GL locking is done by the caller */
+static void shader_glsl_load_psamplers(const struct wined3d_gl_info *gl_info,
+        DWORD *tex_unit_map, GLhandleARB programId)
 {
     GLint name_loc;
     int i;
 {
     GLint name_loc;
     int i;
@@ -204,7 +266,9 @@ static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, DWORD *te
     }
 }
 
     }
 }
 
-static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, DWORD *tex_unit_map, GLhandleARB programId)
+/* GL locking is done by the caller */
+static void shader_glsl_load_vsamplers(const struct wined3d_gl_info *gl_info,
+        DWORD *tex_unit_map, GLhandleARB programId)
 {
     GLint name_loc;
     char sampler_name[20];
 {
     GLint name_loc;
     char sampler_name[20];
@@ -227,7 +291,8 @@ static void shader_glsl_load_vsamplers(const WineD3D_GL_Info *gl_info, DWORD *te
     }
 }
 
     }
 }
 
-static inline void walk_constant_heap(const WineD3D_GL_Info *gl_info, const float *constants,
+/* GL locking is done by the caller */
+static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants,
         const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
 {
     int stack_idx = 0;
         const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
 {
     int stack_idx = 0;
@@ -288,21 +353,23 @@ static inline void walk_constant_heap(const WineD3D_GL_Info *gl_info, const floa
     checkGLcall("walk_constant_heap()");
 }
 
     checkGLcall("walk_constant_heap()");
 }
 
-static inline void apply_clamped_constant(const WineD3D_GL_Info *gl_info, GLint location, const GLfloat *data)
+/* GL locking is done by the caller */
+static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, GLint location, const GLfloat *data)
 {
     GLfloat clamped_constant[4];
 
     if (location == -1) return;
 
 {
     GLfloat clamped_constant[4];
 
     if (location == -1) return;
 
-    clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0 ? 1.0 : data[0];
-    clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0 ? 1.0 : data[1];
-    clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0 ? 1.0 : data[2];
-    clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0 ? 1.0 : data[3];
+    clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0f ? 1.0f : data[0];
+    clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0f ? 1.0f : data[1];
+    clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0f ? 1.0f : data[2];
+    clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0f ? 1.0f : data[3];
 
     GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
 }
 
 
     GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
 }
 
-static inline void walk_constant_heap_clamped(const WineD3D_GL_Info *gl_info, const float *constants,
+/* GL locking is done by the caller */
+static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const float *constants,
         const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
 {
     int stack_idx = 0;
         const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
 {
     int stack_idx = 0;
@@ -362,7 +429,8 @@ static inline void walk_constant_heap_clamped(const WineD3D_GL_Info *gl_info, co
 }
 
 /* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
-static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
         const float *constants, const GLint *constant_locations, const struct constant_heap *heap,
         unsigned char *stack, UINT version)
 {
         const float *constants, const GLint *constant_locations, const struct constant_heap *heap,
         unsigned char *stack, UINT version)
 {
@@ -392,7 +460,8 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const Wine
 }
 
 /* Loads integer constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads integer constants (aka uniforms) into the currently set GLSL program. */
-static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
         const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set)
 {
     unsigned int i;
         const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set)
 {
     unsigned int i;
@@ -428,16 +497,37 @@ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const Wine
 }
 
 /* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
-static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
         GLhandleARB programId, const BOOL *constants, WORD constants_set)
 {
     GLint tmp_loc;
     unsigned int i;
     char tmp_name[8];
         GLhandleARB programId, const BOOL *constants, WORD constants_set)
 {
     GLint tmp_loc;
     unsigned int i;
     char tmp_name[8];
-    char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
-    const char* prefix = is_pshader? "PB":"VB";
+    const char *prefix;
     struct list* ptr;
 
     struct list* ptr;
 
+    switch (This->baseShader.reg_maps.shader_version.type)
+    {
+        case WINED3D_SHADER_TYPE_VERTEX:
+            prefix = "VB";
+            break;
+
+        case WINED3D_SHADER_TYPE_GEOMETRY:
+            prefix = "GB";
+            break;
+
+        case WINED3D_SHADER_TYPE_PIXEL:
+            prefix = "PB";
+            break;
+
+        default:
+            FIXME("Unknown shader type %#x.\n",
+                    This->baseShader.reg_maps.shader_version.type);
+            prefix = "UB";
+            break;
+    }
+
     /* TODO: Benchmark and see if it would be beneficial to store the
      * locations of the constants to avoid looking up each time */
     for (i = 0; constants_set; constants_set >>= 1, ++i)
     /* TODO: Benchmark and see if it would be beneficial to store the
      * locations of the constants to avoid looking up each time */
     for (i = 0; constants_set; constants_set >>= 1, ++i)
@@ -478,15 +568,15 @@ 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(struct wine_rb_entry *entry, void *context)
 {
 {
-    struct glsl_shader_prog_link *entry = value;
-    entry->constant_version = 0;
+    WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0;
 }
 
 /**
  * Loads the texture dimensions for NP2 fixup into the currently set GLSL program.
  */
 }
 
 /**
  * Loads the texture dimensions for NP2 fixup into the currently set GLSL program.
  */
+/* GL locking is done by the caller (state handler) */
 static void shader_glsl_load_np2fixup_constants(
     IWineD3DDevice* device,
     char usePixelShader,
 static void shader_glsl_load_np2fixup_constants(
     IWineD3DDevice* device,
     char usePixelShader,
@@ -505,39 +595,45 @@ static void shader_glsl_load_np2fixup_constants(
         return;
     }
 
         return;
     }
 
-    if (prog->ps_args.np2_fixup) {
+    if (prog->ps_args.np2_fixup && -1 != prog->np2Fixup_location) {
+        const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+        const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock;
         UINT i;
         UINT fixup = prog->ps_args.np2_fixup;
         UINT i;
         UINT fixup = prog->ps_args.np2_fixup;
-        const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
-        const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock;
+        GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
 
         for (i = 0; fixup; fixup >>= 1, ++i) {
 
         for (i = 0; fixup; fixup >>= 1, ++i) {
-            if (-1 != prog->np2Fixup_location[i]) {
-                const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
-                if (!tex) {
-                    FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
-                    continue;
-                } else {
-                    const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
-                    GL_EXTCALL(glUniform2fvARB(prog->np2Fixup_location[i], 1, tex_dim));
-                }
+            const unsigned char idx = prog->np2Fixup_info->idx[i];
+            const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
+            GLfloat* tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+
+            if (!tex) {
+                FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
+                continue;
+            }
+
+            if (idx % 2) {
+                tex_dim[2] = tex->baseTexture.pow2Matrix[0]; tex_dim[3] = tex->baseTexture.pow2Matrix[5];
+            } else {
+                tex_dim[0] = tex->baseTexture.pow2Matrix[0]; tex_dim[1] = tex->baseTexture.pow2Matrix[5];
             }
         }
             }
         }
+
+        GL_EXTCALL(glUniform4fvARB(prog->np2Fixup_location, prog->np2Fixup_info->num_consts, np2fixup_constants));
     }
 }
 
 /**
  * Loads the app-supplied constants into the currently set GLSL program.
  */
     }
 }
 
 /**
  * Loads the app-supplied constants into the currently set GLSL program.
  */
-static void shader_glsl_load_constants(
-    IWineD3DDevice* device,
-    char usePixelShader,
-    char useVertexShader) {
-   
-    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) device;
-    struct shader_glsl_priv *priv = deviceImpl->shader_priv;
-    IWineD3DStateBlockImpl* stateBlock = deviceImpl->stateBlock;
-    const WineD3D_GL_Info *gl_info = &deviceImpl->adapter->gl_info;
+/* GL locking is done by the caller (state handler) */
+static void shader_glsl_load_constants(const struct wined3d_context *context,
+        char usePixelShader, char useVertexShader)
+{
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DStateBlockImpl* stateBlock = device->stateBlock;
+    struct shader_glsl_priv *priv = device->shader_priv;
 
     GLhandleARB programId;
     struct glsl_shader_prog_link *prog = priv->glsl_program;
 
     GLhandleARB programId;
     struct glsl_shader_prog_link *prog = priv->glsl_program;
@@ -567,7 +663,7 @@ static void shader_glsl_load_constants(
                 stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants);
 
         /* Upload the position fixup params */
                 stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants);
 
         /* Upload the position fixup params */
-        GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
+        GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &device->posFixup[0]));
         checkGLcall("glUniform4fvARB");
     }
 
         checkGLcall("glUniform4fvARB");
     }
 
@@ -590,20 +686,21 @@ static void shader_glsl_load_constants(
         /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
          * It can't be 0 for a valid texbem instruction.
          */
         /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
          * It can't be 0 for a valid texbem instruction.
          */
-        for(i = 0; i < ((IWineD3DPixelShaderImpl *) pshader)->numbumpenvmatconsts; i++) {
-            IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pshader;
-            int stage = ps->luminanceconst[i].texunit;
+        for(i = 0; i < MAX_TEXTURES; i++) {
+            const float *data;
+
+            if(prog->bumpenvmat_location[i] == -1) continue;
 
 
-            const float *data = (const float *)&stateBlock->textureState[(int)ps->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
+            data = (const float *)&stateBlock->textureState[i][WINED3DTSS_BUMPENVMAT00];
             GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location[i], 1, 0, data));
             checkGLcall("glUniformMatrix2fvARB");
 
             /* texbeml needs the luminance scale and offset too. If texbeml is used, needsbumpmat
              * is set too, so we can check that in the needsbumpmat check
              */
             GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location[i], 1, 0, data));
             checkGLcall("glUniformMatrix2fvARB");
 
             /* texbeml needs the luminance scale and offset too. If texbeml is used, needsbumpmat
              * is set too, so we can check that in the needsbumpmat check
              */
-            if(ps->baseShader.reg_maps.luminanceparams[stage]) {
-                const GLfloat *scale = (const GLfloat *)&stateBlock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
-                const GLfloat *offset = (const GLfloat *)&stateBlock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
+            if(prog->luminancescale_location[i] != -1) {
+                const GLfloat *scale = (const GLfloat *)&stateBlock->textureState[i][WINED3DTSS_BUMPENVLSCALE];
+                const GLfloat *offset = (const GLfloat *)&stateBlock->textureState[i][WINED3DTSS_BUMPENVLOFFSET];
 
                 GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
                 checkGLcall("glUniform1fvARB");
 
                 GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
                 checkGLcall("glUniform1fvARB");
@@ -614,13 +711,15 @@ static void shader_glsl_load_constants(
 
         if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
             float correction_params[4];
 
         if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
             float correction_params[4];
-            if(deviceImpl->render_offscreen) {
-                correction_params[0] = 0.0;
-                correction_params[1] = 1.0;
+
+            if (context->render_offscreen)
+            {
+                correction_params[0] = 0.0f;
+                correction_params[1] = 1.0f;
             } else {
                 /* position is window relative, not viewport relative */
             } else {
                 /* position is window relative, not viewport relative */
-                correction_params[0] = ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
-                correction_params[1] = -1.0;
+                correction_params[0] = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height;
+                correction_params[1] = -1.0f;
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
@@ -629,7 +728,7 @@ static void shader_glsl_load_constants(
     if (priv->next_constant_version == UINT_MAX)
     {
         TRACE("Max constant version reached, resetting to 0.\n");
     if (priv->next_constant_version == UINT_MAX)
     {
         TRACE("Max constant version reached, resetting to 0.\n");
-        hash_table_for_each_entry(priv->glsl_program_lookup, reset_program_constant_version, NULL);
+        wine_rb_for_each_entry(&priv->program_lookup, reset_program_constant_version, NULL);
         priv->next_constant_version = 1;
     }
     else
         priv->next_constant_version = 1;
     }
     else
@@ -693,24 +792,38 @@ static void shader_glsl_update_float_pixel_constants(IWineD3DDevice *iface, UINT
     }
 }
 
     }
 }
 
+static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info)
+{
+    unsigned int ret = GL_LIMITS(glsl_varyings) / 4;
+    /* 4.0 shaders do not write clip coords because d3d10 does not support user clipplanes */
+    if(shader_major > 3) return ret;
+
+    /* 3.0 shaders may need an extra varying for the clip coord on some cards(mostly dx10 ones) */
+    if (gl_info->quirks & WINED3D_QUIRK_GLSL_CLIP_VARYING) ret -= 1;
+    return ret;
+}
+
 /** Generate the variable & register declarations for the GLSL output target */
 /** Generate the variable & register declarations for the GLSL output target */
-static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
-        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info,
-        const struct ps_compile_args *ps_args)
+static void shader_generate_glsl_declarations(const struct wined3d_context *context,
+        struct wined3d_shader_buffer *buffer, IWineD3DBaseShader *iface,
+        const shader_reg_maps *reg_maps, struct shader_glsl_ctx_priv *ctx_priv)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+    const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i, extra_constants_needed = 0;
     const local_constant *lconst;
     unsigned int i, extra_constants_needed = 0;
     const local_constant *lconst;
+    DWORD map;
 
     /* There are some minor differences between pixel and vertex shaders */
     char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
 
     /* There are some minor differences between pixel and vertex shaders */
     char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
-    for (i = 0; i < This->baseShader.limits.label; i++) {
-        if (reg_maps->labels[i])
-            shader_addline(buffer, "void subroutine%u();\n", i);
+    for (i = 0, map = reg_maps->labels; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i);
     }
 
     /* Declare the constants (aka uniforms) */
     }
 
     /* Declare the constants (aka uniforms) */
@@ -737,9 +850,11 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                 /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix).
                  * Subtract another uniform for immediate values, which have to be loaded via uniform by the driver as well.
                  * The shader code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex shader code, so one vec4 should be enough
                 /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix).
                  * Subtract another uniform for immediate values, which have to be loaded via uniform by the driver as well.
                  * The shader code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex shader code, so one vec4 should be enough
-                 * (Unfortunately the Nvidia driver doesn't store 128 and -128 in one float
+                 * (Unfortunately the Nvidia driver doesn't store 128 and -128 in one float).
+                 *
+                 * Writing gl_ClipPos requires one uniform for each clipplane as well.
                  */
                  */
-                max_constantsF = GL_LIMITS(vshader_constantsF) - 3;
+                max_constantsF = GL_LIMITS(vshader_constantsF) - 3 - GL_LIMITS(clipplanes);
                 max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants);
                 /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
                  * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
                 max_constantsF -= count_bits(This->baseShader.reg_maps.integer_constants);
                 /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
                  * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
@@ -784,35 +899,28 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
             shader_addline(buffer, "void order_ps_input();\n");
         }
     } else {
             shader_addline(buffer, "void order_ps_input();\n");
         }
     } else {
-        IWineD3DPixelShaderImpl *ps_impl = (IWineD3DPixelShaderImpl *) This;
-
-        ps_impl->numbumpenvmatconsts = 0;
-        for(i = 0; i < (sizeof(reg_maps->bumpmat) / sizeof(reg_maps->bumpmat[0])); i++) {
-            if(!reg_maps->bumpmat[i]) {
-                continue;
-            }
+        for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
 
 
-            ps_impl->bumpenvmatconst[(int) ps_impl->numbumpenvmatconsts].texunit = i;
             shader_addline(buffer, "uniform mat2 bumpenvmat%d;\n", i);
 
             shader_addline(buffer, "uniform mat2 bumpenvmat%d;\n", i);
 
-            if(reg_maps->luminanceparams) {
-                ps_impl->luminanceconst[(int) ps_impl->numbumpenvmatconsts].texunit = i;
+            if (reg_maps->luminanceparams & (1 << i))
+            {
                 shader_addline(buffer, "uniform float luminancescale%d;\n", i);
                 shader_addline(buffer, "uniform float luminanceoffset%d;\n", i);
                 extra_constants_needed++;
                 shader_addline(buffer, "uniform float luminancescale%d;\n", i);
                 shader_addline(buffer, "uniform float luminanceoffset%d;\n", i);
                 extra_constants_needed++;
-            } else {
-                ps_impl->luminanceconst[(int) ps_impl->numbumpenvmatconsts].texunit = -1;
             }
 
             extra_constants_needed++;
             }
 
             extra_constants_needed++;
-            ps_impl->numbumpenvmatconsts++;
         }
 
         }
 
-        if(ps_args->srgb_correction) {
-            shader_addline(buffer, "const vec4 srgb_mul_low = vec4(%f, %f, %f, %f);\n",
-                            srgb_mul_low, srgb_mul_low, srgb_mul_low, srgb_mul_low);
-            shader_addline(buffer, "const vec4 srgb_comparison = vec4(%f, %f, %f, %f);\n",
-                            srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
+        if (ps_args->srgb_correction)
+        {
+            shader_addline(buffer, "const vec4 srgb_const0 = vec4(%.8e, %.8e, %.8e, %.8e);\n",
+                    srgb_pow, srgb_mul_high, srgb_sub_high, srgb_mul_low);
+            shader_addline(buffer, "const vec4 srgb_const1 = vec4(%.8e, 0.0, 0.0, 0.0);\n",
+                    srgb_cmp);
         }
         if(reg_maps->vpos || reg_maps->usesdsy) {
             if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) {
         }
         if(reg_maps->vpos || reg_maps->usesdsy) {
             if(This->baseShader.limits.constant_float + extra_constants_needed + 1 < GL_LIMITS(pshader_constantsF)) {
@@ -825,14 +933,14 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                  */
                 FIXME("Cannot find a free uniform for vpos correction params\n");
                 shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
                  */
                 FIXME("Cannot find a free uniform for vpos correction params\n");
                 shader_addline(buffer, "const vec4 ycorrection = vec4(%f, %f, 0.0, 0.0);\n",
-                               device->render_offscreen ? 0.0 : ((IWineD3DSurfaceImpl *) device->render_targets[0])->currentDesc.Height,
-                               device->render_offscreen ? 1.0 : -1.0);
+                        context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
+                        context->render_offscreen ? 1.0f : -1.0f);
             }
             shader_addline(buffer, "vec4 vpos;\n");
         }
     }
 
             }
             shader_addline(buffer, "vec4 vpos;\n");
         }
     }
 
-    /* Declare texture samplers */ 
+    /* Declare texture samplers */
     for (i = 0; i < This->baseShader.limits.sampler; i++) {
         if (reg_maps->sampler_type[i])
         {
     for (i = 0; i < This->baseShader.limits.sampler; i++) {
         if (reg_maps->sampler_type[i])
         {
@@ -848,15 +956,6 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                     } else {
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
                     } else {
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
-
-                    if (pshader && ps_args->np2_fixup & (1 << i))
-                    {
-                        /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
-                         * while D3D has them in the (normalized) [0,1]x[0,1] range.
-                         * samplerNP2Fixup stores texture dimensions and is updated through
-                         * shader_glsl_load_np2fixup_constants when the sampler changes. */
-                        shader_addline(buffer, "uniform vec2 %csamplerNP2Fixup%u;\n", prefix, i);
-                    }
                     break;
                 case WINED3DSTT_CUBE:
                     shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i);
                     break;
                 case WINED3DSTT_CUBE:
                     shader_addline(buffer, "uniform samplerCube %csampler%u;\n", prefix, i);
@@ -871,17 +970,48 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
             }
         }
     }
             }
         }
     }
-    
+
+    /* Declare uniforms for NP2 texcoord fixup:
+     * This is NOT done inside the loop that declares the texture samplers since the NP2 fixup code
+     * is currently only used for the GeforceFX series and when forcing the ARB_npot extension off.
+     * Modern cards just skip the code anyway, so put it inside a separate loop. */
+    if (pshader && ps_args->np2_fixup) {
+
+        struct ps_np2fixup_info* const fixup = ctx_priv->cur_np2fixup_info;
+        UINT cur = 0;
+
+        /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
+         * while D3D has them in the (normalized) [0,1]x[0,1] range.
+         * samplerNP2Fixup stores texture dimensions and is updated through
+         * shader_glsl_load_np2fixup_constants when the sampler changes. */
+
+        for (i = 0; i < This->baseShader.limits.sampler; ++i) {
+            if (reg_maps->sampler_type[i]) {
+                if (!(ps_args->np2_fixup & (1 << i))) continue;
+
+                if (WINED3DSTT_2D != reg_maps->sampler_type[i]) {
+                    FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
+                    continue;
+                }
+
+                fixup->idx[i] = cur++;
+            }
+        }
+
+        fixup->num_consts = (cur + 1) >> 1;
+        shader_addline(buffer, "uniform vec4 %csamplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
+    }
+
     /* Declare address variables */
     /* Declare address variables */
-    for (i = 0; i < This->baseShader.limits.address; i++) {
-        if (reg_maps->address[i])
-            shader_addline(buffer, "ivec4 A%d;\n", i);
+    for (i = 0, map = reg_maps->address; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i);
     }
 
     /* Declare texture coordinate temporaries and initialize them */
     }
 
     /* Declare texture coordinate temporaries and initialize them */
-    for (i = 0; i < This->baseShader.limits.texcoord; i++) {
-        if (reg_maps->texcoord[i]) 
-            shader_addline(buffer, "vec4 T%u = gl_TexCoord[%u];\n", i, i);
+    for (i = 0, map = reg_maps->texcoord; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "vec4 T%u = gl_TexCoord[%u];\n", i, i);
     }
 
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
     }
 
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
@@ -891,13 +1021,13 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
     {
         if (use_vs(device->stateBlock))
         {
     {
         if (use_vs(device->stateBlock))
         {
-            shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
+            shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(reg_maps->shader_version.major, gl_info));
         } else {
             /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed.
              * For fixed function vertex processing + 3.0 pixel shader we need a separate function in the
              * pixel shader that reads the fixed function color into the packed input registers.
              */
         } else {
             /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed.
              * For fixed function vertex processing + 3.0 pixel shader we need a separate function in the
              * pixel shader that reads the fixed function color into the packed input registers.
              */
-            shader_addline(buffer, "vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
+            shader_addline(buffer, "vec4 IN[%u];\n", vec4_varyings(reg_maps->shader_version.major, gl_info));
         }
     }
 
         }
     }
 
@@ -907,15 +1037,18 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
     }
 
     /* Declare temporary variables */
     }
 
     /* Declare temporary variables */
-    for(i = 0; i < This->baseShader.limits.temporary; i++) {
-        if (reg_maps->temporary[i])
-            shader_addline(buffer, "vec4 R%u;\n", i);
+    for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+    {
+        if (map & 1) shader_addline(buffer, "vec4 R%u;\n", i);
     }
 
     /* Declare attributes */
     }
 
     /* Declare attributes */
-    for (i = 0; i < This->baseShader.limits.attributes; i++) {
-        if (reg_maps->attributes[i])
-            shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
+    if (reg_maps->shader_version.type == WINED3D_SHADER_TYPE_VERTEX)
+    {
+        for (i = 0, map = reg_maps->input_registers; map; map >>= 1, ++i)
+        {
+            if (map & 1) shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
+        }
     }
 
     /* Declare loop registers aLx */
     }
 
     /* Declare loop registers aLx */
@@ -971,22 +1104,22 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i
 
 /** Used for opcode modifiers - They multiply the result by the specified amount */
 static const char * const shift_glsl_tab[] = {
 
 /** Used for opcode modifiers - They multiply the result by the specified amount */
 static const char * const shift_glsl_tab[] = {
-    "",           /*  0 (none) */ 
-    "2.0 * ",     /*  1 (x2)   */ 
-    "4.0 * ",     /*  2 (x4)   */ 
-    "8.0 * ",     /*  3 (x8)   */ 
-    "16.0 * ",    /*  4 (x16)  */ 
-    "32.0 * ",    /*  5 (x32)  */ 
-    "",           /*  6 (x64)  */ 
-    "",           /*  7 (x128) */ 
-    "",           /*  8 (d256) */ 
-    "",           /*  9 (d128) */ 
-    "",           /* 10 (d64)  */ 
-    "",           /* 11 (d32)  */ 
-    "0.0625 * ",  /* 12 (d16)  */ 
-    "0.125 * ",   /* 13 (d8)   */ 
-    "0.25 * ",    /* 14 (d4)   */ 
-    "0.5 * "      /* 15 (d2)   */ 
+    "",           /*  0 (none) */
+    "2.0 * ",     /*  1 (x2)   */
+    "4.0 * ",     /*  2 (x4)   */
+    "8.0 * ",     /*  3 (x8)   */
+    "16.0 * ",    /*  4 (x16)  */
+    "32.0 * ",    /*  5 (x32)  */
+    "",           /*  6 (x64)  */
+    "",           /*  7 (x128) */
+    "",           /*  8 (d256) */
+    "",           /*  9 (d128) */
+    "",           /* 10 (d64)  */
+    "",           /* 11 (d32)  */
+    "0.0625 * ",  /* 12 (d16)  */
+    "0.125 * ",   /* 13 (d8)   */
+    "0.25 * ",    /* 14 (d4)   */
+    "0.5 * "      /* 15 (d2)   */
 };
 
 /* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
 };
 
 /* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
@@ -1050,7 +1183,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
 
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-    const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
@@ -1065,7 +1198,8 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             /* vertex shaders */
             if (!pshader)
             {
             /* vertex shaders */
             if (!pshader)
             {
-                if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
+                struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+                if (priv->cur_vs_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
                 sprintf(register_name, "attrib%u", reg->idx);
                 break;
             }
                 sprintf(register_name, "attrib%u", reg->idx);
                 break;
             }
@@ -1074,7 +1208,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             if (This->baseShader.reg_maps.shader_version.major >= 3)
             {
                 DWORD idx = ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg->idx];
             if (This->baseShader.reg_maps.shader_version.major >= 3)
             {
                 DWORD idx = ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg->idx];
-                DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
+                unsigned int in_count = vec4_varyings(This->baseShader.reg_maps.shader_version.major, gl_info);
 
                 if (reg->rel_addr)
                 {
 
                 if (reg->rel_addr)
                 {
@@ -1175,11 +1309,9 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
 
         case WINED3DSPR_COLOROUT:
             if (reg->idx >= GL_LIMITS(buffers))
 
         case WINED3DSPR_COLOROUT:
             if (reg->idx >= GL_LIMITS(buffers))
-                WARN("Write to render target %u, only %d supported\n", reg->idx, 4);
+                WARN("Write to render target %u, only %d supported\n", reg->idx, GL_LIMITS(buffers));
 
 
-            if (GL_SUPPORT(ARB_DRAW_BUFFERS)) sprintf(register_name, "gl_FragData[%u]", reg->idx);
-            /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
-            else sprintf(register_name, "gl_FragColor");
+            sprintf(register_name, "gl_FragData[%u]", reg->idx);
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
@@ -1224,13 +1356,13 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             switch (reg->immconst_type)
             {
                 case WINED3D_IMMCONST_FLOAT:
             switch (reg->immconst_type)
             {
                 case WINED3D_IMMCONST_FLOAT:
-                    sprintf(register_name, "%.8e", *(float *)reg->immconst_data);
+                    sprintf(register_name, "%.8e", *(const float *)reg->immconst_data);
                     break;
 
                 case WINED3D_IMMCONST_FLOAT4:
                     sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
                     break;
 
                 case WINED3D_IMMCONST_FLOAT4:
                     sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
-                            *(float *)&reg->immconst_data[0], *(float *)&reg->immconst_data[1],
-                            *(float *)&reg->immconst_data[2], *(float *)&reg->immconst_data[3]);
+                            *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
+                            *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
                     break;
 
                 default:
                     break;
 
                 default:
@@ -1344,7 +1476,7 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
-static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer,
+static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer,
         const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst)
 {
     glsl_dst_param_t glsl_dst;
         const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst)
 {
     glsl_dst_param_t glsl_dst;
@@ -1357,7 +1489,7 @@ static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer,
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
-static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const struct wined3d_shader_instruction *ins)
+static DWORD shader_glsl_append_dst(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins)
 {
     return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
 }
 {
     return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
 }
@@ -1599,11 +1731,11 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
 
     if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
 
     if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
-        IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
-        fixup = This->cur_args->color_fixup[sampler];
+        const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+        fixup = priv->cur_ps_args->color_fixup[sampler];
         sampler_base = "Psampler";
 
         sampler_base = "Psampler";
 
-        if(This->cur_args->np2_fixup & (1 << sampler)) {
+        if(priv->cur_ps_args->np2_fixup & (1 << sampler)) {
             if(bias) {
                 FIXME("Biased sampling from NP2 textures is unsupported\n");
             } else {
             if(bias) {
                 FIXME("Biased sampling from NP2 textures is unsupported\n");
             } else {
@@ -1627,7 +1759,11 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
         shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
     } else {
         if (np2_fixup) {
         shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
     } else {
         if (np2_fixup) {
-            shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
+            const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+            const unsigned char idx = priv->cur_np2fixup_info->idx[sampler];
+
+            shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup[%u].%s)%s);\n", idx >> 1,
+                           (idx % 2) ? "zw" : "xy", dst_swizzle);
         } else if(dx && dy) {
             shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
         } else {
         } else if(dx && dy) {
             shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
         } else {
@@ -1641,15 +1777,13 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
- * 
  * Begin processing individual instruction opcodes
  * Begin processing individual instruction opcodes
- * 
  ****************************************************************************/
 
 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
 static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
 {
  ****************************************************************************/
 
 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
 static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD write_mask;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD write_mask;
@@ -1676,7 +1810,7 @@ static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 {
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
@@ -1714,7 +1848,7 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
 static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
 {
 /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
 static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD dst_write_mask, src_write_mask;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD dst_write_mask, src_write_mask;
@@ -1762,7 +1896,7 @@ static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
  * GLSL uses the value as-is. */
 static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
 {
  * GLSL uses the value as-is. */
 static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD dst_write_mask;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     DWORD dst_write_mask;
@@ -1786,7 +1920,7 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
  * GLSL uses the value as-is. */
 static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
 {
  * GLSL uses the value as-is. */
 static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     DWORD dst_write_mask;
     unsigned int dst_size;
     glsl_src_param_t src0_param;
     DWORD dst_write_mask;
     unsigned int dst_size;
@@ -1806,7 +1940,7 @@ static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
 /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
 static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
 {
 /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
 static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src_param;
     const char *instruction;
     DWORD write_mask;
     glsl_src_param_t src_param;
     const char *instruction;
     DWORD write_mask;
@@ -1910,7 +2044,7 @@ static void shader_glsl_rcp(const struct wined3d_shader_instruction *ins)
 
 static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
 {
 
 static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src_param;
     DWORD write_mask;
     unsigned int mask_size;
     glsl_src_param_t src_param;
     DWORD write_mask;
     unsigned int mask_size;
@@ -2128,8 +2262,8 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins)
             src0_param.param_str, src1_param.param_str, src2_param.param_str);
 }
 
             src0_param.param_str, src1_param.param_str, src2_param.param_str);
 }
 
-/** Handles transforming all WINED3DSIO_M?x? opcodes for 
-    Vertex shaders to GLSL codes */
+/* Handles transforming all WINED3DSIO_M?x? opcodes for
+   Vertex shaders to GLSL codes */
 static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
 {
     int i;
 static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
 {
     int i;
@@ -2185,7 +2319,7 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
 }
 
 /**
 }
 
 /**
-    The LRP instruction performs a component-wise linear interpolation 
+    The LRP instruction performs a component-wise linear interpolation
     between the second and third operands using the first operand as the
     blend factor.  Equation:  (dst = src2 + src0 * (src1 - src2))
     This is equivalent to mix(src2, src1, src0);
     between the second and third operands using the first operand as the
     blend factor.  Equation:  (dst = src2 + src0 * (src1 - src2))
     This is equivalent to mix(src2, src1, src0);
@@ -2282,7 +2416,7 @@ static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
 /** Process the WINED3DSIO_SINCOS instruction in GLSL:
  * VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
  * can handle it.  But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
 /** Process the WINED3DSIO_SINCOS instruction in GLSL:
  * VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
  * can handle it.  But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
- * 
+ *
  * dst.x = cos(src0.?)
  * dst.y = sin(src0.?)
  * dst.z = dst.z
  * dst.x = cos(src0.?)
  * dst.y = sin(src0.?)
  * dst.z = dst.z
@@ -2346,22 +2480,33 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
         }
     }
 
         }
     }
 
-    if(control_values) {
-        if(control_values[2] > 0) {
-            shader_addline(ins->ctx->buffer, "for (aL%u = %d; aL%u < (%d * %d + %d); aL%u += %d) {\n",
-                    shader->baseShader.cur_loop_depth, control_values[1],
-                    shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
-                    shader->baseShader.cur_loop_depth, control_values[2]);
-        } else if(control_values[2] == 0) {
-            shader_addline(ins->ctx->buffer, "for (aL%u = %d, tmpInt%u = 0; tmpInt%u < %d; tmpInt%u++) {\n",
-                    shader->baseShader.cur_loop_depth, control_values[1], shader->baseShader.cur_loop_depth,
-                    shader->baseShader.cur_loop_depth, control_values[0],
+    if (control_values)
+    {
+        struct wined3d_shader_loop_control loop_control;
+        loop_control.count = control_values[0];
+        loop_control.start = control_values[1];
+        loop_control.step = (int)control_values[2];
+
+        if (loop_control.step > 0)
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.count, loop_control.step, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.step);
+        }
+        else if (loop_control.step < 0)
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.count, loop_control.step, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.step);
+        }
+        else
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start, shader->baseShader.cur_loop_depth,
+                    shader->baseShader.cur_loop_depth, loop_control.count,
                     shader->baseShader.cur_loop_depth);
                     shader->baseShader.cur_loop_depth);
-        } else {
-            shader_addline(ins->ctx->buffer, "for (aL%u = %d; aL%u > (%d * %d + %d); aL%u += %d) {\n",
-                    shader->baseShader.cur_loop_depth, control_values[1],
-                    shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
-                    shader->baseShader.cur_loop_depth, control_values[2]);
         }
     } else {
         shader_addline(ins->ctx->buffer,
         }
     } else {
         shader_addline(ins->ctx->buffer,
@@ -2488,10 +2633,17 @@ static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
     shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
 }
 
     shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
 }
 
+static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
+{
+    /* No-op. The closing } is written when a new function is started, and at the end of the shader. This
+     * function only suppresses the unhandled instruction warning
+     */
+}
+
 /*********************************************
  * Pixel Shader Specific Code begins here
  ********************************************/
 /*********************************************
  * Pixel Shader Specific Code begins here
  ********************************************/
-static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
@@ -2584,7 +2736,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-    const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, dx_param, dy_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, dx_param, dy_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
@@ -2594,7 +2746,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
 
     if(!GL_SUPPORT(ARB_SHADER_TEXTURE_LOD)) {
         FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
 
     if(!GL_SUPPORT(ARB_SHADER_TEXTURE_LOD)) {
         FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
-        return pshader_glsl_tex(ins);
+        return shader_glsl_tex(ins);
     }
 
     sampler_idx = ins->src[1].reg.idx;
     }
 
     sampler_idx = ins->src[1].reg.idx;
@@ -2617,6 +2769,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, lod_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, lod_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
@@ -2635,7 +2788,8 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
-    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
+    if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD]
+            && shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
     {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
@@ -2645,10 +2799,10 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
             "%s", coord_param.param_str);
 }
 
             "%s", coord_param.param_str);
 }
 
-static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 {
     /* FIXME: Make this work for more than just 2D textures */
 {
     /* FIXME: Make this work for more than just 2D textures */
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
 
     if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
     DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
 
     if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
@@ -2694,7 +2848,7 @@ static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 /** Process the WINED3DSIO_TEXDP3TEX instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src,
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 /** Process the WINED3DSIO_TEXDP3TEX instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src,
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
-static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     glsl_sample_function_t sample_function;
 {
     glsl_src_param_t src0_param;
     glsl_sample_function_t sample_function;
@@ -2738,7 +2892,7 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_TEXDP3 instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
 
 /** Process the WINED3DSIO_TEXDP3 instruction in GLSL:
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
-static void pshader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     DWORD dstreg = ins->dst[0].reg.idx;
 {
     glsl_src_param_t src0_param;
     DWORD dstreg = ins->dst[0].reg.idx;
@@ -2759,7 +2913,7 @@ static void pshader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_TEXDEPTH instruction in GLSL:
  * Calculate the depth as dst.x / dst.y   */
 
 /** Process the WINED3DSIO_TEXDEPTH instruction in GLSL:
  * Calculate the depth as dst.x / dst.y   */
-static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
 
 {
     glsl_dst_param_t dst_param;
 
@@ -2780,7 +2934,7 @@ static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
  * Calculate tmp0.y = TexCoord[dstreg] . src.xyz;  (tmp0.x has already been calculated)
  * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
  */
  * Calculate tmp0.y = TexCoord[dstreg] . src.xyz;  (tmp0.x has already been calculated)
  * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
  */
-static void pshader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD dstreg = ins->dst[0].reg.idx;
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD dstreg = ins->dst[0].reg.idx;
@@ -2794,11 +2948,11 @@ static void pshader_glsl_texm3x2depth(const struct wined3d_shader_instruction *i
 
 /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
  * Calculate the 1st of a 2-row matrix multiplication. */
 
 /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
  * Calculate the 1st of a 2-row matrix multiplication. */
-static void pshader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     glsl_src_param_t src0_param;
 
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@@ -2807,12 +2961,12 @@ static void pshader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins
 
 /** Process the WINED3DSIO_TEXM3X3PAD instruction in GLSL
  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
 
 /** Process the WINED3DSIO_TEXM3X3PAD instruction in GLSL
  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
-static void pshader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     glsl_src_param_t src0_param;
 
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     glsl_src_param_t src0_param;
 
@@ -2821,11 +2975,11 @@ static void pshader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
-static void pshader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
     glsl_sample_function_t sample_function;
     glsl_src_param_t src0_param;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
     glsl_sample_function_t sample_function;
@@ -2841,7 +2995,7 @@ static void pshader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins
 
 /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */
 
 /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */
-static void pshader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
@@ -2865,7 +3019,7 @@ static void pshader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply */
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in GLSL
  * Perform the 3rd row of a 3x3 matrix multiply */
-static void pshader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
@@ -2883,15 +3037,15 @@ static void pshader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
-/** Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL 
+/* Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
-static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg];
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg];
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@@ -2914,13 +3068,13 @@ static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *in
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
-/** Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL 
+/* Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
-static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD reg = ins->dst[0].reg.idx;
-    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     glsl_src_param_t src0_param;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     glsl_src_param_t src0_param;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@@ -2950,7 +3104,7 @@ static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *i
  * Apply a fake bump map transform.
  * texbem is pshader <= 1.3 only, this saves a few version checks
  */
  * Apply a fake bump map transform.
  * texbem is pshader <= 1.3 only, this saves a few version checks
  */
-static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
@@ -3009,7 +3163,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-static void pshader_glsl_bem(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param, src1_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
 {
     glsl_src_param_t src0_param, src1_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
@@ -3024,7 +3178,7 @@ static void pshader_glsl_bem(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
 
 /** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
-static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
@@ -3040,7 +3194,7 @@ static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_TEXREG2GB instruction in GLSL
  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
 
 /** Process the WINED3DSIO_TEXREG2GB instruction in GLSL
  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
-static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
@@ -3056,7 +3210,7 @@ static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL
  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
 
 /** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL
  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
-static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
 {
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
@@ -3073,7 +3227,7 @@ static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins
 
 /** Process the WINED3DSIO_TEXKILL instruction in GLSL.
  * If any of the first 3 components are < 0, discard this pixel */
 
 /** Process the WINED3DSIO_TEXKILL instruction in GLSL.
  * If any of the first 3 components are < 0, discard this pixel */
-static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_texkill(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
 
 {
     glsl_dst_param_t dst_param;
 
@@ -3094,7 +3248,7 @@ static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins)
 
 /** Process the WINED3DSIO_DP2ADD instruction in GLSL.
  * dst = dot2(src0, src1) + src2 */
 
 /** Process the WINED3DSIO_DP2ADD instruction in GLSL.
  * dst = dot2(src0, src1) + src2 */
-static void pshader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
 {
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
@@ -3118,52 +3272,52 @@ static void pshader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-static void pshader_glsl_input_pack(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer,
-        const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps,
+static void shader_glsl_input_pack(IWineD3DPixelShader *iface, struct wined3d_shader_buffer *buffer,
+        const struct wined3d_shader_signature_element *input_signature, const struct shader_reg_maps *reg_maps,
         enum vertexprocessing_mode vertexprocessing)
 {
     unsigned int i;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
         enum vertexprocessing_mode vertexprocessing)
 {
     unsigned int i;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
+    WORD map = reg_maps->input_registers;
 
 
-    for (i = 0; i < MAX_REG_INPUT; ++i)
+    for (i = 0; map; map >>= 1, ++i)
     {
     {
-        DWORD usage, usage_idx;
+        const char *semantic_name;
+        UINT semantic_idx;
         char reg_mask[6];
 
         /* Unused */
         char reg_mask[6];
 
         /* Unused */
-        if (!reg_maps->packed_input[i]) continue;
+        if (!(map & 1)) continue;
 
 
-        usage = semantics_in[i].usage;
-        usage_idx = semantics_in[i].usage_idx;
-        shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask);
+        semantic_name = input_signature[i].semantic_name;
+        semantic_idx = input_signature[i].semantic_idx;
+        shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask);
 
 
-        switch (usage)
+        if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
         {
         {
-            case WINED3DDECLUSAGE_TEXCOORD:
-                if (usage_idx < 8 && vertexprocessing == pretransformed)
-                    shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
-                            This->input_reg_map[i], reg_mask, usage_idx, reg_mask);
-                else
-                    shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                            This->input_reg_map[i], reg_mask, reg_mask);
-                break;
-
-            case WINED3DDECLUSAGE_COLOR:
-                if (usage_idx == 0)
-                    shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n",
-                            This->input_reg_map[i], reg_mask, reg_mask);
-                else if (usage_idx == 1)
-                    shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n",
-                            This->input_reg_map[i], reg_mask, reg_mask);
-                else
-                    shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                            This->input_reg_map[i], reg_mask, reg_mask);
-                break;
-
-            default:
+            if (semantic_idx < 8 && vertexprocessing == pretransformed)
+                shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
+                        This->input_reg_map[i], reg_mask, semantic_idx, reg_mask);
+            else
                 shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
                         This->input_reg_map[i], reg_mask, reg_mask);
                 shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
                         This->input_reg_map[i], reg_mask, reg_mask);
-                break;
+        }
+        else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+        {
+            if (semantic_idx == 0)
+                shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n",
+                        This->input_reg_map[i], reg_mask, reg_mask);
+            else if (semantic_idx == 1)
+                shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n",
+                        This->input_reg_map[i], reg_mask, reg_mask);
+            else
+                shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                        This->input_reg_map[i], reg_mask, reg_mask);
+        }
+        else
+        {
+            shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                    This->input_reg_map[i], reg_mask, reg_mask);
         }
     }
 }
         }
     }
 }
@@ -3173,20 +3327,23 @@ static void pshader_glsl_input_pack(IWineD3DPixelShader *iface, SHADER_BUFFER *b
  ********************************************/
 
 static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry) {
  ********************************************/
 
 static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry) {
-    glsl_program_key_t *key;
+    glsl_program_key_t key;
 
 
-    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;
+    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);
+    if (wine_rb_put(&priv->program_lookup, &key, &entry->program_lookup_entry) == -1)
+    {
+        ERR("Failed to insert program entry.\n");
+    }
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
         IWineD3DVertexShader *vshader, IWineD3DPixelShader *pshader, struct vs_compile_args *vs_args,
         struct ps_compile_args *ps_args) {
 }
 
 static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
         IWineD3DVertexShader *vshader, IWineD3DPixelShader *pshader, struct vs_compile_args *vs_args,
         struct ps_compile_args *ps_args) {
+    struct wine_rb_entry *entry;
     glsl_program_key_t key;
 
     key.vshader = vshader;
     glsl_program_key_t key;
 
     key.vshader = vshader;
@@ -3194,20 +3351,21 @@ static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_p
     key.vs_args = *vs_args;
     key.ps_args = *ps_args;
 
     key.vs_args = *vs_args;
     key.ps_args = *ps_args;
 
-    return hash_table_get(priv->glsl_program_lookup, &key);
+    entry = wine_rb_get(&priv->program_lookup, &key);
+    return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL;
 }
 
 }
 
-static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info,
         struct glsl_shader_prog_link *entry)
 {
         struct glsl_shader_prog_link *entry)
 {
-    glsl_program_key_t *key;
+    glsl_program_key_t key;
 
 
-    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.vshader = entry->vshader;
+    key.pshader = entry->pshader;
+    key.vs_args = entry->vs_args;
+    key.ps_args = entry->ps_args;
+    wine_rb_remove(&priv->program_lookup, &key);
 
     GL_EXTCALL(glDeleteObjectARB(entry->programId));
     if (entry->vshader) list_remove(&entry->vshader_entry);
 
     GL_EXTCALL(glDeleteObjectARB(entry->programId));
     if (entry->vshader) list_remove(&entry->vshader_entry);
@@ -3217,28 +3375,33 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
-static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, const DWORD *map,
-        const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps_in,
-        const struct wined3d_shader_semantic *semantics_out, const struct shader_reg_maps *reg_maps_out)
+static void handle_ps3_input(struct wined3d_shader_buffer *buffer, const struct wined3d_gl_info *gl_info, const DWORD *map,
+        const struct wined3d_shader_signature_element *input_signature, const struct shader_reg_maps *reg_maps_in,
+        const struct wined3d_shader_signature_element *output_signature, const struct shader_reg_maps *reg_maps_out)
 {
     unsigned int i, j;
 {
     unsigned int i, j;
-    DWORD usage, usage_idx, usage_out, usage_idx_out;
+    const char *semantic_name_in, *semantic_name_out;
+    UINT semantic_idx_in, semantic_idx_out;
     DWORD *set;
     DWORD in_idx;
     DWORD *set;
     DWORD in_idx;
-    DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
+    unsigned int in_count = vec4_varyings(3, gl_info);
     char reg_mask[6], reg_mask_out[6];
     char destination[50];
     char reg_mask[6], reg_mask_out[6];
     char destination[50];
+    WORD input_map, output_map;
 
     set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
 
 
     set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
 
-    if (!semantics_out) {
+    if (!output_signature)
+    {
         /* Save gl_FrontColor & gl_FrontSecondaryColor before overwriting them. */
         shader_addline(buffer, "vec4 front_color = gl_FrontColor;\n");
         shader_addline(buffer, "vec4 front_secondary_color = gl_FrontSecondaryColor;\n");
     }
 
         /* Save gl_FrontColor & gl_FrontSecondaryColor before overwriting them. */
         shader_addline(buffer, "vec4 front_color = gl_FrontColor;\n");
         shader_addline(buffer, "vec4 front_secondary_color = gl_FrontSecondaryColor;\n");
     }
 
-    for(i = 0; i < MAX_REG_INPUT; i++) {
-        if (!reg_maps_in->packed_input[i]) continue;
+    input_map = reg_maps_in->input_registers;
+    for (i = 0; input_map; input_map >>= 1, ++i)
+    {
+        if (!(input_map & 1)) continue;
 
         in_idx = map[i];
         if (in_idx >= (in_count + 2)) {
 
         in_idx = map[i];
         if (in_idx >= (in_count + 2)) {
@@ -3259,56 +3422,65 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_in
             sprintf(destination, "IN[%u]", in_idx);
         }
 
             sprintf(destination, "IN[%u]", in_idx);
         }
 
-        usage = semantics_in[i].usage;
-        usage_idx = semantics_in[i].usage_idx;
-        set[map[i]] = shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask);
-
-        if(!semantics_out) {
-            switch(usage) {
-                case WINED3DDECLUSAGE_COLOR:
-                    if (usage_idx == 0)
-                        shader_addline(buffer, "%s%s = front_color%s;\n",
-                                       destination, reg_mask, reg_mask);
-                    else if (usage_idx == 1)
-                        shader_addline(buffer, "%s%s = front_secondary_color%s;\n",
-                                       destination, reg_mask, reg_mask);
-                    else
-                        shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                                       destination, reg_mask, reg_mask);
-                    break;
-
-                case WINED3DDECLUSAGE_TEXCOORD:
-                    if (usage_idx < 8) {
-                        shader_addline(buffer, "%s%s = gl_TexCoord[%u]%s;\n",
-                                       destination, reg_mask, usage_idx, reg_mask);
-                    } else {
-                        shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                                       destination, reg_mask, reg_mask);
-                    }
-                    break;
-
-                case WINED3DDECLUSAGE_FOG:
-                    shader_addline(buffer, "%s%s = vec4(gl_FogFragCoord, 0.0, 0.0, 0.0)%s;\n",
-                                   destination, reg_mask, reg_mask);
-                    break;
+        semantic_name_in = input_signature[i].semantic_name;
+        semantic_idx_in = input_signature[i].semantic_idx;
+        set[map[i]] = input_signature[i].mask;
+        shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask);
 
 
-                default:
+        if (!output_signature)
+        {
+            if (shader_match_semantic(semantic_name_in, WINED3DDECLUSAGE_COLOR))
+            {
+                if (semantic_idx_in == 0)
+                    shader_addline(buffer, "%s%s = front_color%s;\n",
+                            destination, reg_mask, reg_mask);
+                else if (semantic_idx_in == 1)
+                    shader_addline(buffer, "%s%s = front_secondary_color%s;\n",
+                            destination, reg_mask, reg_mask);
+                else
+                    shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                            destination, reg_mask, reg_mask);
+            }
+            else if (shader_match_semantic(semantic_name_in, WINED3DDECLUSAGE_TEXCOORD))
+            {
+                if (semantic_idx_in < 8)
+                {
+                    shader_addline(buffer, "%s%s = gl_TexCoord[%u]%s;\n",
+                            destination, reg_mask, semantic_idx_in, reg_mask);
+                }
+                else
+                {
                     shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
                     shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                                   destination, reg_mask, reg_mask);
+                            destination, reg_mask, reg_mask);
+                }
+            }
+            else if (shader_match_semantic(semantic_name_in, WINED3DDECLUSAGE_FOG))
+            {
+                shader_addline(buffer, "%s%s = vec4(gl_FogFragCoord, 0.0, 0.0, 0.0)%s;\n",
+                        destination, reg_mask, reg_mask);
+            }
+            else
+            {
+                shader_addline(buffer, "%s%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                        destination, reg_mask, reg_mask);
             }
         } else {
             BOOL found = FALSE;
             }
         } else {
             BOOL found = FALSE;
-            for(j = 0; j < MAX_REG_OUTPUT; j++) {
-                if (!reg_maps_out->packed_output[j]) continue;
 
 
-                usage_out = semantics_out[j].usage;
-                usage_idx_out = semantics_out[j].usage_idx;
-                shader_glsl_get_write_mask(&semantics_out[j].reg, reg_mask_out);
+            output_map = reg_maps_out->output_registers;
+            for (j = 0; output_map; output_map >>= 1, ++j)
+            {
+                if (!(output_map & 1)) continue;
+
+                semantic_name_out = output_signature[j].semantic_name;
+                semantic_idx_out = output_signature[j].semantic_idx;
+                shader_glsl_write_mask_to_str(output_signature[j].mask, reg_mask_out);
 
 
-                if(usage == usage_out &&
-                   usage_idx == usage_idx_out) {
+                if (semantic_idx_in == semantic_idx_out
+                        && !strcmp(semantic_name_in, semantic_name_out))
+                {
                     shader_addline(buffer, "%s%s = OUT[%u]%s;\n",
                     shader_addline(buffer, "%s%s = OUT[%u]%s;\n",
-                                   destination, reg_mask, j, reg_mask);
+                            destination, reg_mask, j, reg_mask);
                     found = TRUE;
                 }
             }
                     found = TRUE;
                 }
             }
@@ -3324,7 +3496,8 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_in
      * input varyings are assigned above, if the optimizer works properly.
      */
     for(i = 0; i < in_count + 2; i++) {
      * input varyings are assigned above, if the optimizer works properly.
      */
     for(i = 0; i < in_count + 2; i++) {
-        if(set[i] != WINED3DSP_WRITEMASK_ALL) {
+        if (set[i] && set[i] != WINED3DSP_WRITEMASK_ALL)
+        {
             unsigned int size = 0;
             memset(reg_mask, 0, sizeof(reg_mask));
             if(!(set[i] & WINED3DSP_WRITEMASK_0)) {
             unsigned int size = 0;
             memset(reg_mask, 0, sizeof(reg_mask));
             if(!(set[i] & WINED3DSP_WRITEMASK_0)) {
@@ -3363,8 +3536,9 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_in
     HeapFree(GetProcessHeap(), 0, set);
 }
 
     HeapFree(GetProcessHeap(), 0, set);
 }
 
-static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexshader,
-        IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info)
+/* GL locking is done by the caller */
+static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer *buffer,
+        IWineD3DVertexShader *vertexshader, IWineD3DPixelShader *pixelshader, const struct wined3d_gl_info *gl_info)
 {
     GLhandleARB ret = 0;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
 {
     GLhandleARB ret = 0;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
@@ -3373,142 +3547,145 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     DWORD vs_major = vs->baseShader.reg_maps.shader_version.major;
     DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
     unsigned int i;
     DWORD vs_major = vs->baseShader.reg_maps.shader_version.major;
     DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
     unsigned int i;
-    SHADER_BUFFER buffer;
-    DWORD usage, usage_idx, writemask;
+    const char *semantic_name;
+    UINT semantic_idx;
     char reg_mask[6];
     char reg_mask[6];
-    const struct wined3d_shader_semantic *semantics_out;
+    const struct wined3d_shader_signature_element *output_signature;
 
 
-    shader_buffer_init(&buffer);
+    shader_buffer_clear(buffer);
 
 
-    shader_addline(&buffer, "#version 120\n");
+    shader_addline(buffer, "#version 120\n");
 
     if(vs_major < 3 && ps_major < 3) {
         /* That one is easy: The vertex shader writes to the builtin varyings, the pixel shader reads from them.
          * Take care about the texcoord .w fixup though if we're using the fixed function fragment pipeline
          */
         device = (IWineD3DDeviceImpl *) vs->baseShader.device;
 
     if(vs_major < 3 && ps_major < 3) {
         /* That one is easy: The vertex shader writes to the builtin varyings, the pixel shader reads from them.
          * Take care about the texcoord .w fixup though if we're using the fixed function fragment pipeline
          */
         device = (IWineD3DDeviceImpl *) vs->baseShader.device;
-        if((GLINFO_LOCATION).set_texcoord_w && ps_major == 0 && vs_major > 0 &&
-            !device->frag_pipe->ffp_proj_control) {
-            shader_addline(&buffer, "void order_ps_input() {\n");
+        if (((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W)
+                && ps_major == 0 && vs_major > 0 && !device->frag_pipe->ffp_proj_control)
+        {
+            shader_addline(buffer, "void order_ps_input() {\n");
             for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
                 if(vs->baseShader.reg_maps.texcoord_mask[i] != 0 &&
                    vs->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
             for(i = 0; i < min(8, MAX_REG_TEXCRD); i++) {
                 if(vs->baseShader.reg_maps.texcoord_mask[i] != 0 &&
                    vs->baseShader.reg_maps.texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL) {
-                    shader_addline(&buffer, "gl_TexCoord[%u].w = 1.0;\n", i);
+                    shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", i);
                 }
             }
                 }
             }
-            shader_addline(&buffer, "}\n");
+            shader_addline(buffer, "}\n");
         } else {
         } else {
-            shader_addline(&buffer, "void order_ps_input() { /* do nothing */ }\n");
+            shader_addline(buffer, "void order_ps_input() { /* do nothing */ }\n");
         }
     } else if(ps_major < 3 && vs_major >= 3) {
         }
     } else if(ps_major < 3 && vs_major >= 3) {
-        /* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */
-        semantics_out = vs->semantics_out;
-
-        shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
-        for(i = 0; i < MAX_REG_OUTPUT; i++) {
-            if (!vs->baseShader.reg_maps.packed_output[i]) continue;
-
-            usage = semantics_out[i].usage;
-            usage_idx = semantics_out[i].usage_idx;
-            writemask = shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask);
-
-            switch(usage) {
-                case WINED3DDECLUSAGE_COLOR:
-                    if (usage_idx == 0)
-                        shader_addline(&buffer, "gl_FrontColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
-                    else if (usage_idx == 1)
-                        shader_addline(&buffer, "gl_FrontSecondaryColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
-                    break;
+        WORD map = vs->baseShader.reg_maps.output_registers;
 
 
-                case WINED3DDECLUSAGE_POSITION:
-                    shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
-                    break;
+        /* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */
+        output_signature = vs->output_signature;
 
 
-                case WINED3DDECLUSAGE_TEXCOORD:
-                    if (usage_idx < 8) {
-                        if(!(GLINFO_LOCATION).set_texcoord_w || ps_major > 0) writemask |= WINED3DSP_WRITEMASK_3;
+        shader_addline(buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            DWORD write_mask;
 
 
-                        shader_addline(&buffer, "gl_TexCoord[%u]%s = OUT[%u]%s;\n",
-                                        usage_idx, reg_mask, i, reg_mask);
-                        if(!(writemask & WINED3DSP_WRITEMASK_3)) {
-                            shader_addline(&buffer, "gl_TexCoord[%u].w = 1.0;\n", usage_idx);
-                        }
-                    }
-                    break;
+            if (!(map & 1)) continue;
 
 
-                case WINED3DDECLUSAGE_PSIZE:
-                    shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i);
-                    break;
+            semantic_name = output_signature[i].semantic_name;
+            semantic_idx = output_signature[i].semantic_idx;
+            write_mask = output_signature[i].mask;
+            shader_glsl_write_mask_to_str(write_mask, reg_mask);
 
 
-                case WINED3DDECLUSAGE_FOG:
-                    shader_addline(&buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]);
-                    break;
+            if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+            {
+                if (semantic_idx == 0)
+                    shader_addline(buffer, "gl_FrontColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+                else if (semantic_idx == 1)
+                    shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+            }
+            else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
+            {
+                shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+            }
+            else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
+            {
+                if (semantic_idx < 8)
+                {
+                    if (!((GLINFO_LOCATION).quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0)
+                        write_mask |= WINED3DSP_WRITEMASK_3;
 
 
-                default:
-                    break;
+                    shader_addline(buffer, "gl_TexCoord[%u]%s = OUT[%u]%s;\n",
+                            semantic_idx, reg_mask, i, reg_mask);
+                    if (!(write_mask & WINED3DSP_WRITEMASK_3))
+                        shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
+                }
+            }
+            else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
+            {
+                shader_addline(buffer, "gl_PointSize = OUT[%u].x;\n", i);
+            }
+            else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
+            {
+                shader_addline(buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]);
             }
         }
             }
         }
-        shader_addline(&buffer, "}\n");
+        shader_addline(buffer, "}\n");
 
     } else if(ps_major >= 3 && vs_major >= 3) {
 
     } else if(ps_major >= 3 && vs_major >= 3) {
-        semantics_out = vs->semantics_out;
+        WORD map = vs->baseShader.reg_maps.output_registers;
+
+        output_signature = vs->output_signature;
 
         /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
 
         /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
-        shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
-        shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
+        shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info));
+        shader_addline(buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
 
         /* First, sort out position and point size. Those are not passed to the pixel shader */
 
         /* First, sort out position and point size. Those are not passed to the pixel shader */
-        for(i = 0; i < MAX_REG_OUTPUT; i++) {
-            if (!vs->baseShader.reg_maps.packed_output[i]) continue;
-
-            usage = semantics_out[i].usage;
-            usage_idx = semantics_out[i].usage_idx;
-            shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask);
-
-            switch(usage) {
-                case WINED3DDECLUSAGE_POSITION:
-                    shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
-                    break;
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
 
 
-                case WINED3DDECLUSAGE_PSIZE:
-                    shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i);
-                    break;
+            semantic_name = output_signature[i].semantic_name;
+            shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask);
 
 
-                default:
-                    break;
+            if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
+            {
+                shader_addline(buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+            }
+            else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
+            {
+                shader_addline(buffer, "gl_PointSize = OUT[%u].x;\n", i);
             }
         }
 
         /* Then, fix the pixel shader input */
             }
         }
 
         /* Then, fix the pixel shader input */
-        handle_ps3_input(&buffer, gl_info, ps->input_reg_map,
-                ps->semantics_in, &ps->baseShader.reg_maps, semantics_out, &vs->baseShader.reg_maps);
+        handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->input_signature,
+                &ps->baseShader.reg_maps, output_signature, &vs->baseShader.reg_maps);
 
 
-        shader_addline(&buffer, "}\n");
+        shader_addline(buffer, "}\n");
     } else if(ps_major >= 3 && vs_major < 3) {
     } else if(ps_major >= 3 && vs_major < 3) {
-        shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
-        shader_addline(&buffer, "void order_ps_input() {\n");
+        shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(3, gl_info));
+        shader_addline(buffer, "void order_ps_input() {\n");
         /* The vertex shader wrote to the builtin varyings. There is no need to figure out position and
          * point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't
          * read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings
          */
         /* The vertex shader wrote to the builtin varyings. There is no need to figure out position and
          * point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't
          * read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings
          */
-        handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->semantics_in, &ps->baseShader.reg_maps, NULL, NULL);
-        shader_addline(&buffer, "}\n");
+        handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->input_signature,
+                &ps->baseShader.reg_maps, NULL, NULL);
+        shader_addline(buffer, "}\n");
     } else {
         ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major);
     }
 
     ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
     checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
     } else {
         ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major);
     }
 
     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, &buffer.buffer, NULL)");
+    GL_EXTCALL(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)");
 
-    shader_buffer_free(&buffer);
     return ret;
 }
 
     return ret;
 }
 
-static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD3D_GL_Info *gl_info,
+/* GL locking is done by the caller */
+static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
         GLhandleARB programId, char prefix)
 {
     const local_constant *lconst;
         GLhandleARB programId, char prefix)
 {
     const local_constant *lconst;
@@ -3522,80 +3699,363 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD
         tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
         GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
     }
         tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
         GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, value));
     }
-    checkGLcall("Hardcoding local constants\n");
+    checkGLcall("Hardcoding local constants");
 }
 
 }
 
-/** Sets the GLSL program ID for the given pixel and vertex shader combination.
- * It sets the programId on the current StateBlock (because it should be called
- * inside of the DrawPrimitive() part of the render loop).
- *
- * If a program for the given combination does not exist, create one, and store
- * the program in the hash table.  If it creates a program, it will link the
- * given objects, too.
- */
-static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use_vs) {
-    IWineD3DDeviceImpl *This               = (IWineD3DDeviceImpl *)iface;
-    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;
-    struct glsl_shader_prog_link *entry    = NULL;
-    GLhandleARB programId                  = 0;
-    GLhandleARB reorder_shader_id          = 0;
-    unsigned int i;
-    char glsl_name[8];
-    GLhandleARB vshader_id, pshader_id;
-    struct ps_compile_args ps_compile_args;
-    struct vs_compile_args vs_compile_args;
+/* GL locking is done by the caller */
+static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
+        struct wined3d_shader_buffer *buffer, IWineD3DPixelShaderImpl *This,
+        const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info)
+{
+    const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    CONST DWORD *function = This->baseShader.function;
+    struct shader_glsl_ctx_priv priv_ctx;
 
 
-    if(use_vs) {
-        find_vs_compile_args((IWineD3DVertexShaderImpl*)This->stateBlock->vertexShader, This->stateBlock, &vs_compile_args);
-    } else {
-        /* FIXME: Do we really have to spend CPU cycles to generate a few zeroed bytes? */
-        memset(&vs_compile_args, 0, sizeof(vs_compile_args));
+    /* Create the hw GLSL shader object and assign it as the shader->prgId */
+    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+
+    memset(&priv_ctx, 0, sizeof(priv_ctx));
+    priv_ctx.cur_ps_args = args;
+    priv_ctx.cur_np2fixup_info = np2fixup_info;
+
+    shader_addline(buffer, "#version 120\n");
+
+    if(GL_SUPPORT(ARB_SHADER_TEXTURE_LOD) && reg_maps->usestexldd) {
+        shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
     }
     }
-    if(use_ps) {
-        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? */
-        memset(&ps_compile_args, 0, sizeof(ps_compile_args));
+    if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+        /* The spec says that it doesn't have to be explicitly enabled, but the nvidia
+         * drivers write a warning if we don't do so
+         */
+        shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
     }
     }
-    entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args);
-    if (entry) {
-        priv->glsl_program = entry;
-        return;
+
+    /* Base Declarations */
+    shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShader *)This, reg_maps, &priv_ctx);
+
+    /* Pack 3.0 inputs */
+    if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
+    {
+        shader_glsl_input_pack((IWineD3DPixelShader *) This, buffer, This->input_signature, reg_maps, args->vp_mode);
     }
 
     }
 
-    /* If we get to this point, then no matching program exists, so we create one */
-    programId = GL_EXTCALL(glCreateProgramObjectARB());
-    TRACE("Created new GLSL shader program %u\n", programId);
+    /* Base Shader Body */
+    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function, &priv_ctx);
 
 
-    /* Create the entry */
-    entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
-    entry->programId = programId;
-    entry->vshader = vshader;
-    entry->pshader = pshader;
-    entry->vs_args = vs_compile_args;
-    entry->ps_args = ps_compile_args;
+    /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
+    if (reg_maps->shader_version.major < 2)
+    {
+        /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
+        shader_addline(buffer, "gl_FragData[0] = R0;\n");
+    }
+
+    if (args->srgb_correction)
+    {
+        shader_addline(buffer, "tmp0.xyz = pow(gl_FragData[0].xyz, vec3(srgb_const0.x));\n");
+        shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n");
+        shader_addline(buffer, "tmp1.xyz = gl_FragData[0].xyz * vec3(srgb_const0.w);\n");
+        shader_addline(buffer, "bvec3 srgb_compare = lessThan(gl_FragData[0].xyz, vec3(srgb_const1.x));\n");
+        shader_addline(buffer, "gl_FragData[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n");
+        shader_addline(buffer, "gl_FragData[0] = clamp(gl_FragData[0], 0.0, 1.0);\n");
+    }
+    /* Pixel shader < 3.0 do not replace the fog stage.
+     * This implements linear fog computation and blending.
+     * TODO: non linear fog
+     * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
+     * -1/(e-s) and e/(e-s) respectively.
+     */
+    if (reg_maps->shader_version.major < 3)
+    {
+        switch(args->fog) {
+            case FOG_OFF: break;
+            case FOG_LINEAR:
+                shader_addline(buffer, "float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);\n");
+                shader_addline(buffer, "float fogend = gl_Fog.end * -fogstart;\n");
+                shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);\n");
+                shader_addline(buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog);\n");
+                break;
+            case FOG_EXP:
+                /* 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, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog);\n");
+                break;
+            case FOG_EXP2:
+                /* 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, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog);\n");
+                break;
+        }
+    }
+
+    shader_addline(buffer, "}\n");
+
+    TRACE("Compiling shader object %u\n", shader_obj);
+    GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer->buffer, NULL));
+    GL_EXTCALL(glCompileShaderARB(shader_obj));
+    print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
+
+    /* Store the shader object */
+    return shader_obj;
+}
+
+/* GL locking is done by the caller */
+static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context,
+        struct wined3d_shader_buffer *buffer, IWineD3DVertexShaderImpl *This,
+        const struct vs_compile_args *args)
+{
+    const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    CONST DWORD *function = This->baseShader.function;
+    struct shader_glsl_ctx_priv priv_ctx;
+
+    /* Create the hw GLSL shader program and assign it as the shader->prgId */
+    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+
+    shader_addline(buffer, "#version 120\n");
+
+    memset(&priv_ctx, 0, sizeof(priv_ctx));
+    priv_ctx.cur_vs_args = args;
+
+    /* Base Declarations */
+    shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShader *)This, reg_maps, &priv_ctx);
+
+    /* Base Shader Body */
+    shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function, &priv_ctx);
+
+    /* Unpack 3.0 outputs */
+    if (reg_maps->shader_version.major >= 3) shader_addline(buffer, "order_ps_input(OUT);\n");
+    else shader_addline(buffer, "order_ps_input();\n");
+
+    /* 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");
+    } else if (!reg_maps->fog) {
+        shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
+    }
+
+    /* Write the final position.
+     *
+     * OpenGL coordinates specify the center of the pixel while d3d coords specify
+     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+     * contains 1.0 to allow a mad.
+     */
+    shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n");
+    shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n");
+    shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
+
+    /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
+     *
+     * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run
+     * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
+     * which is the same as z = z * 2 - w.
+     */
+    shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n");
+
+    shader_addline(buffer, "}\n");
+
+    TRACE("Compiling shader object %u\n", shader_obj);
+    GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer->buffer, NULL));
+    GL_EXTCALL(glCompileShaderARB(shader_obj));
+    print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
+
+    return shader_obj;
+}
+
+static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
+        struct wined3d_shader_buffer *buffer, IWineD3DPixelShaderImpl *shader,
+        const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
+{
+    UINT i;
+    DWORD new_size;
+    struct glsl_ps_compiled_shader *new_array;
+    struct glsl_pshader_private    *shader_data;
+    struct ps_np2fixup_info        *np2fixup = NULL;
+    GLhandleARB ret;
+
+    if(!shader->backend_priv) {
+        shader->backend_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+    }
+    shader_data = shader->backend_priv;
+
+    /* 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_data->num_gl_shaders; i++) {
+        if(memcmp(&shader_data->gl_shaders[i].args, args, sizeof(*args)) == 0) {
+            if(args->np2_fixup) *np2fixup_info = &shader_data->gl_shaders[i].np2fixup;
+            return shader_data->gl_shaders[i].prgId;
+        }
+    }
+
+    TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
+    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+        if (shader_data->num_gl_shaders)
+        {
+            new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders,
+                                    new_size * sizeof(*shader_data->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader_data->gl_shaders));
+            new_size = 1;
+        }
+
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader_data->gl_shaders = new_array;
+        shader_data->shader_array_size = new_size;
+    }
+
+    shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+    memset(&shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup, 0, sizeof(struct ps_np2fixup_info));
+    if (args->np2_fixup) np2fixup = &shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup;
+
+    pixelshader_update_samplers(&shader->baseShader.reg_maps,
+            ((IWineD3DDeviceImpl *)shader->baseShader.device)->stateBlock->textures);
+
+    shader_buffer_clear(buffer);
+    ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
+    shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+    *np2fixup_info = np2fixup;
+
+    return ret;
+}
+
+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;
+}
+
+static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
+        struct wined3d_shader_buffer *buffer, IWineD3DVertexShaderImpl *shader,
+        const struct vs_compile_args *args)
+{
+    UINT i;
+    DWORD new_size;
+    struct glsl_vs_compiled_shader *new_array;
+    DWORD use_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.use_map;
+    struct glsl_vshader_private *shader_data;
+    GLhandleARB ret;
+
+    if(!shader->backend_priv) {
+        shader->backend_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+    }
+    shader_data = shader->backend_priv;
+
+    /* 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_data->num_gl_shaders; i++) {
+        if(vs_args_equal(&shader_data->gl_shaders[i].args, args, use_map)) {
+            return shader_data->gl_shaders[i].prgId;
+        }
+    }
+
+    TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
+
+    if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+        if (shader_data->num_gl_shaders)
+        {
+            new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+            new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders,
+                                    new_size * sizeof(*shader_data->gl_shaders));
+        } else {
+            new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader_data->gl_shaders));
+            new_size = 1;
+        }
+
+        if(!new_array) {
+            ERR("Out of memory\n");
+            return 0;
+        }
+        shader_data->gl_shaders = new_array;
+        shader_data->shader_array_size = new_size;
+    }
+
+    shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+    shader_buffer_clear(buffer);
+    ret = shader_glsl_generate_vshader(context, buffer, shader, args);
+    shader_data->gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+
+    return ret;
+}
+
+/** Sets the GLSL program ID for the given pixel and vertex shader combination.
+ * It sets the programId on the current StateBlock (because it should be called
+ * inside of the DrawPrimitive() part of the render loop).
+ *
+ * If a program for the given combination does not exist, create one, and store
+ * the program in the hash table.  If it creates a program, it will link the
+ * given objects, too.
+ */
+
+/* GL locking is done by the caller */
+static void set_glsl_shader_program(const struct wined3d_context *context,
+        IWineD3DDeviceImpl *device, BOOL use_ps, BOOL use_vs)
+{
+    IWineD3DVertexShader *vshader = use_vs ? device->stateBlock->vertexShader : NULL;
+    IWineD3DPixelShader *pshader = use_ps ? device->stateBlock->pixelShader : NULL;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct shader_glsl_priv *priv = device->shader_priv;
+    struct glsl_shader_prog_link *entry    = NULL;
+    GLhandleARB programId                  = 0;
+    GLhandleARB reorder_shader_id          = 0;
+    unsigned int i;
+    char glsl_name[8];
+    struct ps_compile_args ps_compile_args;
+    struct vs_compile_args vs_compile_args;
+
+    if (vshader) find_vs_compile_args((IWineD3DVertexShaderImpl *)vshader, device->stateBlock, &vs_compile_args);
+    if (pshader) find_ps_compile_args((IWineD3DPixelShaderImpl *)pshader, device->stateBlock, &ps_compile_args);
+
+    entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args);
+    if (entry) {
+        priv->glsl_program = entry;
+        return;
+    }
+
+    /* If we get to this point, then no matching program exists, so we create one */
+    programId = GL_EXTCALL(glCreateProgramObjectARB());
+    TRACE("Created new GLSL shader program %u\n", programId);
+
+    /* Create the entry */
+    entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
+    entry->programId = programId;
+    entry->vshader = vshader;
+    entry->pshader = pshader;
+    entry->vs_args = vs_compile_args;
+    entry->ps_args = ps_compile_args;
     entry->constant_version = 0;
     entry->constant_version = 0;
+    entry->np2Fixup_info = NULL;
     /* Add the hash table entry */
     add_glsl_program_entry(priv, entry);
 
     /* Set the current program */
     priv->glsl_program = entry;
 
     /* Add the hash table entry */
     add_glsl_program_entry(priv, 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 */
     /* Attach GLSL vshader */
-    if (vshader_id) {
-        const unsigned int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
+    if (vshader)
+    {
+        GLhandleARB vshader_id = find_glsl_vshader(context, &priv->shader_buffer,
+                (IWineD3DVertexShaderImpl *)vshader, &vs_compile_args);
+        WORD map = ((IWineD3DBaseShaderImpl *)vshader)->baseShader.reg_maps.input_registers;
         char tmp_name[10];
 
         char tmp_name[10];
 
-        reorder_shader_id = generate_param_reorder_function(vshader, pshader, gl_info);
+        reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
         TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId);
         GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id));
         checkGLcall("glAttachObjectARB");
         TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId);
         GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id));
         checkGLcall("glAttachObjectARB");
@@ -3617,25 +4077,23 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
          * We have to do this here because we need to know the Program ID
          * in order to make the bindings work, and it has to be done prior
          * to linking the GLSL program. */
          * We have to do this here because we need to know the Program ID
          * in order to make the bindings work, and it has to be done prior
          * to linking the GLSL program. */
-        for (i = 0; i < max_attribs; ++i) {
-            if (((IWineD3DBaseShaderImpl*)vshader)->baseShader.reg_maps.attributes[i]) {
-                snprintf(tmp_name, sizeof(tmp_name), "attrib%i", i);
-                GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
-            }
+        for (i = 0; map; map >>= 1, ++i)
+        {
+            if (!(map & 1)) continue;
+
+            snprintf(tmp_name, sizeof(tmp_name), "attrib%u", i);
+            GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
         }
         checkGLcall("glBindAttribLocationARB");
 
         list_add_head(&((IWineD3DBaseShaderImpl *)vshader)->baseShader.linked_programs, &entry->vshader_entry);
     }
 
         }
         checkGLcall("glBindAttribLocationARB");
 
         list_add_head(&((IWineD3DBaseShaderImpl *)vshader)->baseShader.linked_programs, &entry->vshader_entry);
     }
 
-    if(use_ps) {
-        pshader_id = find_gl_pshader((IWineD3DPixelShaderImpl *) pshader, &ps_compile_args);
-    } else {
-        pshader_id = 0;
-    }
-
     /* Attach GLSL pshader */
     /* Attach GLSL pshader */
-    if (pshader_id) {
+    if (pshader)
+    {
+        GLhandleARB pshader_id = find_glsl_pshader(context, &priv->shader_buffer,
+                (IWineD3DPixelShaderImpl *)pshader, &ps_compile_args, &entry->np2Fixup_info);
         TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId);
         GL_EXTCALL(glAttachObjectARB(programId, pshader_id));
         checkGLcall("glAttachObjectARB");
         TRACE("Attaching GLSL shader object %u to program %u\n", pshader_id, programId);
         GL_EXTCALL(glAttachObjectARB(programId, pshader_id));
         checkGLcall("glAttachObjectARB");
@@ -3668,25 +4126,22 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     }
 
     if(pshader) {
     }
 
     if(pshader) {
-        for(i = 0; i < ((IWineD3DPixelShaderImpl*)pshader)->numbumpenvmatconsts; i++) {
-            char name[32];
-            sprintf(name, "bumpenvmat%d", ((IWineD3DPixelShaderImpl*)pshader)->bumpenvmatconst[i].texunit);
+        char name[32];
+
+        for(i = 0; i < MAX_TEXTURES; i++) {
+            sprintf(name, "bumpenvmat%u", i);
             entry->bumpenvmat_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
             entry->bumpenvmat_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
-            sprintf(name, "luminancescale%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
+            sprintf(name, "luminancescale%u", i);
             entry->luminancescale_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
             entry->luminancescale_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
-            sprintf(name, "luminanceoffset%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
+            sprintf(name, "luminanceoffset%u", i);
             entry->luminanceoffset_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
         }
             entry->luminanceoffset_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
         }
-    }
 
 
-    if (use_ps && ps_compile_args.np2_fixup) {
-        char name[32];
-        for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
-            if (ps_compile_args.np2_fixup & (1 << i)) {
-                sprintf(name, "PsamplerNP2Fixup%u", i);
-                entry->np2Fixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
+        if (ps_compile_args.np2_fixup) {
+            if (entry->np2Fixup_info) {
+                entry->np2Fixup_location = GL_EXTCALL(glGetUniformLocationARB(programId, "PsamplerNP2Fixup"));
             } else {
             } else {
-                entry->np2Fixup_location[i] = -1;
+                FIXME("NP2 texcoord fixup needed for this pixelshader, but no fixup uniform found.\n");
             }
         }
     }
             }
         }
     }
@@ -3697,7 +4152,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
 
     if (pshader
             && ((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version.major >= 3
 
     if (pshader
             && ((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version.major >= 3
-            && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
+            && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > vec4_varyings(3, gl_info))
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
@@ -3717,14 +4172,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
      * fixed function fragment processing setups. So once the program is linked these samplers
      * won't change.
      */
      * fixed function fragment processing setups. So once the program is linked these samplers
      * won't change.
      */
-    if(vshader_id) {
-        /* Load vertex shader samplers */
-        shader_glsl_load_vsamplers(gl_info, This->texUnitMap, programId);
-    }
-    if(pshader_id) {
-        /* Load pixel shader samplers */
-        shader_glsl_load_psamplers(gl_info, This->texUnitMap, programId);
-    }
+    if (vshader) shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
+    if (pshader) shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
 
     /* If the local constants do not have to be loaded with the environment constants,
      * load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
 
     /* If the local constants do not have to be loaded with the environment constants,
      * load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
@@ -3738,7 +4187,8 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     }
 }
 
     }
 }
 
-static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
+/* GL locking is done by the caller */
+static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type)
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
@@ -3812,16 +4262,18 @@ static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum t
     return program_id;
 }
 
     return program_id;
 }
 
-static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    struct shader_glsl_priv *priv = This->shader_priv;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+/* GL locking is done by the caller */
+static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
+{
+    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct shader_glsl_priv *priv = device->shader_priv;
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
 
     old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
 
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
 
     old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
 
-    if (useVS || usePS) set_glsl_shader_program(iface, usePS, useVS);
+    if (useVS || usePS) set_glsl_shader_program(context, device, usePS, useVS);
     else priv->glsl_program = NULL;
 
     current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
     else priv->glsl_program = NULL;
 
     current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
@@ -3839,11 +4291,20 @@ static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
     if (program_id) TRACE("Using GLSL program %u\n", program_id);
     GL_EXTCALL(glUseProgramObjectARB(program_id));
     checkGLcall("glUseProgramObjectARB");
     if (program_id) TRACE("Using GLSL program %u\n", program_id);
     GL_EXTCALL(glUseProgramObjectARB(program_id));
     checkGLcall("glUseProgramObjectARB");
+
+    /* In case that NP2 texcoord fixup data is found for the selected program, trigger a reload of the
+     * constants. This has to be done because it can't be guaranteed that sampler() (from state.c) is
+     * called between selecting the shader and using it, which results in wrong fixup for some frames. */
+    if (priv->glsl_program && priv->glsl_program->np2Fixup_info)
+    {
+        shader_glsl_load_np2fixup_constants((IWineD3DDevice *)device, usePS, useVS);
+    }
 }
 
 }
 
+/* GL locking is done by the caller */
 static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 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;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
 
     struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB *blt_program = &priv->depth_blt_program[tex_type];
 
@@ -3858,9 +4319,10 @@ static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum tex_types t
     }
 }
 
     }
 }
 
+/* GL locking is done by the caller */
 static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 static void shader_glsl_deselect_depth_blt(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB program_id;
 
     struct shader_glsl_priv *priv = This->shader_priv;
     GLhandleARB program_id;
 
@@ -3876,7 +4338,8 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     struct shader_glsl_priv *priv = device->shader_priv;
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
     struct shader_glsl_priv *priv = device->shader_priv;
-    const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
 
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
 
@@ -3886,15 +4349,45 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     if(pshader) {
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     if(pshader) {
+        struct glsl_pshader_private *shader_data;
         ps = (IWineD3DPixelShaderImpl *) This;
         ps = (IWineD3DPixelShaderImpl *) This;
-        if(ps->num_gl_shaders == 0) return;
+        shader_data = ps->backend_priv;
+        if(!shader_data || shader_data->num_gl_shaders == 0)
+        {
+            HeapFree(GetProcessHeap(), 0, shader_data);
+            ps->backend_priv = NULL;
+            return;
+        }
+
+        context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+        gl_info = context->gl_info;
+
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
-            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
+        {
+            ENTER_GL();
+            shader_glsl_select(context, FALSE, FALSE);
+            LEAVE_GL();
+        }
     } else {
     } else {
+        struct glsl_vshader_private *shader_data;
         vs = (IWineD3DVertexShaderImpl *) This;
         vs = (IWineD3DVertexShaderImpl *) This;
-        if(vs->num_gl_shaders == 0) return;
+        shader_data = vs->backend_priv;
+        if(!shader_data || shader_data->num_gl_shaders == 0)
+        {
+            HeapFree(GetProcessHeap(), 0, shader_data);
+            vs->backend_priv = NULL;
+            return;
+        }
+
+        context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+        gl_info = context->gl_info;
+
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
-            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
+        {
+            ENTER_GL();
+            shader_glsl_select(context, FALSE, FALSE);
+            LEAVE_GL();
+        }
     }
 
     linked_programs = &This->baseShader.linked_programs;
     }
 
     linked_programs = &This->baseShader.linked_programs;
@@ -3903,6 +4396,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     if (linked_programs->next) {
         struct glsl_shader_prog_link *entry, *entry2;
 
     if (linked_programs->next) {
         struct glsl_shader_prog_link *entry, *entry2;
 
+        ENTER_GL();
         if(pshader) {
             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
                 delete_glsl_program_entry(priv, gl_info, entry);
         if(pshader) {
             LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
                 delete_glsl_program_entry(priv, gl_info, entry);
@@ -3912,62 +4406,57 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
                 delete_glsl_program_entry(priv, gl_info, entry);
             }
         }
                 delete_glsl_program_entry(priv, gl_info, entry);
             }
         }
+        LEAVE_GL();
     }
 
     if(pshader) {
         UINT i;
     }
 
     if(pshader) {
         UINT i;
+        struct glsl_pshader_private *shader_data = ps->backend_priv;
 
         ENTER_GL();
 
         ENTER_GL();
-        for(i = 0; i < ps->num_gl_shaders; i++) {
-            TRACE("deleting pshader %u\n", ps->gl_shaders[i].prgId);
-            GL_EXTCALL(glDeleteObjectARB(ps->gl_shaders[i].prgId));
+        for(i = 0; i < shader_data->num_gl_shaders; i++) {
+            TRACE("deleting pshader %u\n", shader_data->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(shader_data->gl_shaders[i].prgId));
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
-        ps->gl_shaders = NULL;
-        ps->num_gl_shaders = 0;
-        ps->shader_array_size = 0;
+        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+        HeapFree(GetProcessHeap(), 0, shader_data);
+        ps->backend_priv = NULL;
     } else {
         UINT i;
     } else {
         UINT i;
+        struct glsl_vshader_private *shader_data = vs->backend_priv;
 
         ENTER_GL();
 
         ENTER_GL();
-        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));
+        for(i = 0; i < shader_data->num_gl_shaders; i++) {
+            TRACE("deleting vshader %u\n", shader_data->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(shader_data->gl_shaders[i].prgId));
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, vs->gl_shaders);
-        vs->gl_shaders = NULL;
-        vs->num_gl_shaders = 0;
-        vs->shader_array_size = 0;
+        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+        HeapFree(GetProcessHeap(), 0, shader_data);
+        vs->backend_priv = NULL;
     }
 }
 
     }
 }
 
-static unsigned int glsl_program_key_hash(const void *key)
+static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
 {
     const glsl_program_key_t *k = key;
 {
     const glsl_program_key_t *k = key;
+    const struct glsl_shader_prog_link *prog = WINE_RB_ENTRY_VALUE(entry,
+            const struct glsl_shader_prog_link, program_lookup_entry);
+    int cmp;
 
 
-    unsigned int hash = ((DWORD_PTR) k->vshader) | ((DWORD_PTR) k->pshader) << 16;
-    hash += ~(hash << 15);
-    hash ^=  (hash >> 10);
-    hash +=  (hash << 3);
-    hash ^=  (hash >> 6);
-    hash += ~(hash << 11);
-    hash ^=  (hash >> 16);
+    if (k->vshader > prog->vshader) return 1;
+    else if (k->vshader < prog->vshader) return -1;
 
 
-    return hash;
-}
+    if (k->pshader > prog->pshader) return 1;
+    else if (k->pshader < prog->pshader) return -1;
 
 
-static BOOL glsl_program_key_compare(const void *keya, const void *keyb)
-{
-    const glsl_program_key_t *ka = keya;
-    const glsl_program_key_t *kb = keyb;
+    if (k->vshader && (cmp = memcmp(&k->vs_args, &prog->vs_args, sizeof(prog->vs_args)))) return cmp;
+    if (k->pshader && (cmp = memcmp(&k->ps_args, &prog->ps_args, sizeof(prog->ps_args)))) return cmp;
 
 
-    return ka->vshader == kb->vshader && ka->pshader == kb->pshader &&
-           (memcmp(&ka->ps_args, &kb->ps_args, sizeof(kb->ps_args)) == 0) &&
-           (memcmp(&ka->vs_args, &kb->vs_args, sizeof(kb->vs_args)) == 0);
+    return 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)
@@ -3994,50 +4483,73 @@ static void constant_heap_free(struct constant_heap *heap)
     HeapFree(GetProcessHeap(), 0, heap->entries);
 }
 
     HeapFree(GetProcessHeap(), 0, heap->entries);
 }
 
+static const struct wine_rb_functions wined3d_glsl_program_rb_functions =
+{
+    wined3d_rb_alloc,
+    wined3d_rb_realloc,
+    wined3d_rb_free,
+    glsl_program_key_compare,
+};
+
 static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 static HRESULT shader_glsl_alloc(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     SIZE_T stack_size = wined3d_log2i(max(GL_LIMITS(vshader_constantsF), GL_LIMITS(pshader_constantsF))) + 1;
 
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     SIZE_T stack_size = wined3d_log2i(max(GL_LIMITS(vshader_constantsF), GL_LIMITS(pshader_constantsF))) + 1;
 
+    if (!shader_buffer_init(&priv->shader_buffer))
+    {
+        ERR("Failed to initialize shader buffer.\n");
+        goto fail;
+    }
+
     priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack));
     if (!priv->stack)
     {
         ERR("Failed to allocate memory.\n");
     priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack));
     if (!priv->stack)
     {
         ERR("Failed to allocate memory.\n");
-        HeapFree(GetProcessHeap(), 0, priv);
-        return E_OUTOFMEMORY;
+        goto fail;
     }
 
     if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
     {
         ERR("Failed to initialize vertex shader constant heap\n");
     }
 
     if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
     {
         ERR("Failed to initialize vertex shader constant heap\n");
-        HeapFree(GetProcessHeap(), 0, priv->stack);
-        HeapFree(GetProcessHeap(), 0, priv);
-        return E_OUTOFMEMORY;
+        goto fail;
     }
 
     if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
     {
         ERR("Failed to initialize pixel shader constant heap\n");
     }
 
     if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
     {
         ERR("Failed to initialize pixel shader constant heap\n");
-        constant_heap_free(&priv->vconst_heap);
-        HeapFree(GetProcessHeap(), 0, priv->stack);
-        HeapFree(GetProcessHeap(), 0, priv);
-        return E_OUTOFMEMORY;
+        goto fail;
+    }
+
+    if (wine_rb_init(&priv->program_lookup, &wined3d_glsl_program_rb_functions) == -1)
+    {
+        ERR("Failed to initialize rbtree.\n");
+        goto fail;
     }
 
     }
 
-    priv->glsl_program_lookup = hash_table_create(glsl_program_key_hash, glsl_program_key_compare);
     priv->next_constant_version = 1;
 
     This->shader_priv = priv;
     return WINED3D_OK;
     priv->next_constant_version = 1;
 
     This->shader_priv = priv;
     return WINED3D_OK;
+
+fail:
+    constant_heap_free(&priv->pconst_heap);
+    constant_heap_free(&priv->vconst_heap);
+    HeapFree(GetProcessHeap(), 0, priv->stack);
+    shader_buffer_free(&priv->shader_buffer);
+    HeapFree(GetProcessHeap(), 0, priv);
+    return E_OUTOFMEMORY;
 }
 
 }
 
+/* Context activation is done by the caller. */
 static void shader_glsl_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 static void shader_glsl_free(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
+    const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = This->shader_priv;
     int i;
 
     struct shader_glsl_priv *priv = This->shader_priv;
     int i;
 
+    ENTER_GL();
     for (i = 0; i < tex_type_count; ++i)
     {
         if (priv->depth_blt_program[i])
     for (i = 0; i < tex_type_count; ++i)
     {
         if (priv->depth_blt_program[i])
@@ -4045,10 +4557,12 @@ static void shader_glsl_free(IWineD3DDevice *iface) {
             GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i]));
         }
     }
             GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program[i]));
         }
     }
+    LEAVE_GL();
 
 
-    hash_table_destroy(priv->glsl_program_lookup, NULL, NULL);
+    wine_rb_destroy(&priv->program_lookup, NULL, NULL);
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
+    HeapFree(GetProcessHeap(), 0, priv->stack);
 
     HeapFree(GetProcessHeap(), 0, This->shader_priv);
     This->shader_priv = NULL;
 
     HeapFree(GetProcessHeap(), 0, This->shader_priv);
     This->shader_priv = NULL;
@@ -4059,185 +4573,19 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
     return FALSE;
 }
 
     return FALSE;
 }
 
-static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface,
-        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
-{
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
-    const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
-    CONST DWORD *function = This->baseShader.function;
-    const char *fragcolor;
-    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
-
-    /* Create the hw GLSL shader object and assign it as the shader->prgId */
-    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
-
-    shader_addline(buffer, "#version 120\n");
-
-    if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
-        shader_addline(buffer, "#extension GL_ARB_draw_buffers : enable\n");
-    }
-    if(GL_SUPPORT(ARB_SHADER_TEXTURE_LOD) && reg_maps->usestexldd) {
-        shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
-    }
-    if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-        /* The spec says that it doesn't have to be explicitly enabled, but the nvidia
-         * drivers write a warning if we don't do so
-         */
-        shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
-    }
-
-    /* Base Declarations */
-    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
-
-    /* Pack 3.0 inputs */
-    if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
-    {
-        pshader_glsl_input_pack(iface, buffer, This->semantics_in, reg_maps, args->vp_mode);
-    }
-
-    /* Base Shader Body */
-    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
-
-    /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
-    if (reg_maps->shader_version.major < 2)
-    {
-        /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
-        if(GL_SUPPORT(ARB_DRAW_BUFFERS))
-            shader_addline(buffer, "gl_FragData[0] = R0;\n");
-        else
-            shader_addline(buffer, "gl_FragColor = R0;\n");
-    }
-
-    if(GL_SUPPORT(ARB_DRAW_BUFFERS)) {
-        fragcolor = "gl_FragData[0]";
-    } else {
-        fragcolor = "gl_FragColor";
-    }
-    if(args->srgb_correction) {
-        shader_addline(buffer, "tmp0.xyz = pow(%s.xyz, vec3(%f, %f, %f)) * vec3(%f, %f, %f) - vec3(%f, %f, %f);\n",
-                        fragcolor, srgb_pow, srgb_pow, srgb_pow, srgb_mul_high, srgb_mul_high, srgb_mul_high,
-                        srgb_sub_high, srgb_sub_high, srgb_sub_high);
-        shader_addline(buffer, "tmp1.xyz = %s.xyz * srgb_mul_low.xyz;\n", fragcolor);
-        shader_addline(buffer, "%s.x = %s.x < srgb_comparison.x ? tmp1.x : tmp0.x;\n", fragcolor, fragcolor);
-        shader_addline(buffer, "%s.y = %s.y < srgb_comparison.y ? tmp1.y : tmp0.y;\n", fragcolor, fragcolor);
-        shader_addline(buffer, "%s.z = %s.z < srgb_comparison.z ? tmp1.z : tmp0.z;\n", fragcolor, fragcolor);
-        shader_addline(buffer, "%s = clamp(%s, 0.0, 1.0);\n", fragcolor, fragcolor);
-    }
-    /* Pixel shader < 3.0 do not replace the fog stage.
-     * This implements linear fog computation and blending.
-     * TODO: non linear fog
-     * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
-     * -1/(e-s) and e/(e-s) respectively.
-     */
-    if (reg_maps->shader_version.major < 3)
-    {
-        switch(args->fog) {
-            case FOG_OFF: break;
-            case FOG_LINEAR:
-                shader_addline(buffer, "float fogstart = -1.0 / (gl_Fog.end - gl_Fog.start);\n");
-                shader_addline(buffer, "float fogend = gl_Fog.end * -fogstart;\n");
-                shader_addline(buffer, "float Fog = clamp(gl_FogFragCoord * fogstart + fogend, 0.0, 1.0);\n");
-                shader_addline(buffer, "%s.xyz = mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);
-                break;
-            case FOG_EXP:
-                /* 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:
-                /* 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;
-        }
-    }
-
-    shader_addline(buffer, "}\n");
-
-    TRACE("Compiling shader object %u\n", shader_obj);
-    GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer->buffer, NULL));
-    GL_EXTCALL(glCompileShaderARB(shader_obj));
-    print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
-
-    /* Store the shader object */
-    return shader_obj;
-}
-
-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;
-    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
-
-    /* Create the hw GLSL shader program and assign it as the shader->prgId */
-    GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
-
-    shader_addline(buffer, "#version 120\n");
-
-    /* Base Declarations */
-    shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
-
-    /* Base Shader Body */
-    shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function);
-
-    /* Unpack 3.0 outputs */
-    if (reg_maps->shader_version.major >= 3) shader_addline(buffer, "order_ps_input(OUT);\n");
-    else shader_addline(buffer, "order_ps_input();\n");
-
-    /* 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");
-    } else if (!reg_maps->fog) {
-        shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
-    }
-
-    /* Write the final position.
-     *
-     * OpenGL coordinates specify the center of the pixel while d3d coords specify
-     * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
-     * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
-     * contains 1.0 to allow a mad.
-     */
-    shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n");
-    shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n");
-
-    /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
-     *
-     * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run
-     * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
-     * which is the same as z = z * 2 - w.
-     */
-    shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n");
-
-    shader_addline(buffer, "}\n");
-
-    TRACE("Compiling shader object %u\n", shader_obj);
-    GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer->buffer, NULL));
-    GL_EXTCALL(glCompileShaderARB(shader_obj));
-    print_glsl_info_log(&GLINFO_LOCATION, 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 struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
 {
     /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
 {
     /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
-     * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
-     * vs_nv_version which is based on NV_vertex_program.
+     * models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support based
+     * on the version of NV_vertex_program.
      * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
      * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
      * supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
      * of native instructions, so use that here. For more info see the pixel shader versioning code below.
      */
      * For Ati cards there's no way using glsl (it abstracts the lowlevel info away) and also not
      * using ARB_vertex_program. It is safe to assume that when a card supports pixel shader 2.0 it
      * supports vertex shader 2.0 too and the way around. We can detect ps2.0 using the maximum number
      * of native instructions, so use that here. For more info see the pixel shader versioning code below.
      */
-    if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
+    if ((gl_info->supported[NV_VERTEX_PROGRAM2] && !gl_info->supported[NV_VERTEX_PROGRAM3])
+            || gl_info->ps_arb_max_instructions <= 512)
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
     else
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(2,0);
     else
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
@@ -4255,7 +4603,8 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
      * of instructions is 512 or less we have to do with ps2.0 hardware.
      * NOTE: ps3.0 hardware requires 512 or more instructions but ati and nvidia offer 'enough' (1024 vs 4096) on their most basic ps3.0 hardware.
      */
      * of instructions is 512 or less we have to do with ps2.0 hardware.
      * NOTE: ps3.0 hardware requires 512 or more instructions but ati and nvidia offer 'enough' (1024 vs 4096) on their most basic ps3.0 hardware.
      */
-    if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.ps_arb_max_instructions <= 512))
+    if ((gl_info->supported[NV_FRAGMENT_PROGRAM] && !gl_info->supported[NV_FRAGMENT_PROGRAM2])
+            || (gl_info->ps_arb_max_instructions <= 512))
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
     else
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(2,0);
     else
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
@@ -4276,6 +4625,8 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
      */
     pCaps->PixelShader1xMaxValue = 8.0;
     TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (pCaps->PixelShaderVersion >> 8) & 0xff, pCaps->PixelShaderVersion & 0xff);
      */
     pCaps->PixelShader1xMaxValue = 8.0;
     TRACE_(d3d_caps)("Hardware pixel shader version %d.%d enabled (GLSL)\n", (pCaps->PixelShaderVersion >> 8) & 0xff, pCaps->PixelShaderVersion & 0xff);
+
+    pCaps->VSClipping = TRUE;
 }
 
 static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
@@ -4301,7 +4652,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
 {
     /* WINED3DSIH_ABS           */ shader_glsl_map2gl,
     /* WINED3DSIH_ADD           */ shader_glsl_arith,
 {
     /* WINED3DSIH_ABS           */ shader_glsl_map2gl,
     /* WINED3DSIH_ADD           */ shader_glsl_arith,
-    /* WINED3DSIH_BEM           */ pshader_glsl_bem,
+    /* WINED3DSIH_BEM           */ shader_glsl_bem,
     /* WINED3DSIH_BREAK         */ shader_glsl_break,
     /* WINED3DSIH_BREAKC        */ shader_glsl_breakc,
     /* WINED3DSIH_BREAKP        */ NULL,
     /* WINED3DSIH_BREAK         */ shader_glsl_break,
     /* WINED3DSIH_BREAKC        */ shader_glsl_breakc,
     /* WINED3DSIH_BREAKP        */ NULL,
@@ -4314,7 +4665,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_DEF           */ NULL,
     /* WINED3DSIH_DEFB          */ NULL,
     /* WINED3DSIH_DEFI          */ NULL,
     /* WINED3DSIH_DEF           */ NULL,
     /* WINED3DSIH_DEFB          */ NULL,
     /* WINED3DSIH_DEFI          */ NULL,
-    /* WINED3DSIH_DP2ADD        */ pshader_glsl_dp2add,
+    /* WINED3DSIH_DP2ADD        */ shader_glsl_dp2add,
     /* WINED3DSIH_DP3           */ shader_glsl_dot,
     /* WINED3DSIH_DP4           */ shader_glsl_dot,
     /* WINED3DSIH_DST           */ shader_glsl_dst,
     /* WINED3DSIH_DP3           */ shader_glsl_dot,
     /* WINED3DSIH_DP4           */ shader_glsl_dot,
     /* WINED3DSIH_DST           */ shader_glsl_dst,
@@ -4352,7 +4703,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_POW           */ shader_glsl_pow,
     /* WINED3DSIH_RCP           */ shader_glsl_rcp,
     /* WINED3DSIH_REP           */ shader_glsl_rep,
     /* WINED3DSIH_POW           */ shader_glsl_pow,
     /* WINED3DSIH_RCP           */ shader_glsl_rcp,
     /* WINED3DSIH_REP           */ shader_glsl_rep,
-    /* WINED3DSIH_RET           */ NULL,
+    /* WINED3DSIH_RET           */ shader_glsl_ret,
     /* WINED3DSIH_RSQ           */ shader_glsl_rsq,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_glsl_compare,
     /* WINED3DSIH_RSQ           */ shader_glsl_rsq,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_glsl_compare,
@@ -4360,32 +4711,49 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_SINCOS        */ shader_glsl_sincos,
     /* WINED3DSIH_SLT           */ shader_glsl_compare,
     /* WINED3DSIH_SUB           */ shader_glsl_arith,
     /* WINED3DSIH_SINCOS        */ shader_glsl_sincos,
     /* WINED3DSIH_SLT           */ shader_glsl_compare,
     /* WINED3DSIH_SUB           */ shader_glsl_arith,
-    /* WINED3DSIH_TEX           */ pshader_glsl_tex,
-    /* WINED3DSIH_TEXBEM        */ pshader_glsl_texbem,
-    /* WINED3DSIH_TEXBEML       */ pshader_glsl_texbem,
-    /* WINED3DSIH_TEXCOORD      */ pshader_glsl_texcoord,
-    /* WINED3DSIH_TEXDEPTH      */ pshader_glsl_texdepth,
-    /* WINED3DSIH_TEXDP3        */ pshader_glsl_texdp3,
-    /* WINED3DSIH_TEXDP3TEX     */ pshader_glsl_texdp3tex,
-    /* WINED3DSIH_TEXKILL       */ pshader_glsl_texkill,
+    /* WINED3DSIH_TEX           */ shader_glsl_tex,
+    /* WINED3DSIH_TEXBEM        */ shader_glsl_texbem,
+    /* WINED3DSIH_TEXBEML       */ shader_glsl_texbem,
+    /* WINED3DSIH_TEXCOORD      */ shader_glsl_texcoord,
+    /* WINED3DSIH_TEXDEPTH      */ shader_glsl_texdepth,
+    /* WINED3DSIH_TEXDP3        */ shader_glsl_texdp3,
+    /* WINED3DSIH_TEXDP3TEX     */ shader_glsl_texdp3tex,
+    /* WINED3DSIH_TEXKILL       */ shader_glsl_texkill,
     /* WINED3DSIH_TEXLDD        */ shader_glsl_texldd,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
     /* WINED3DSIH_TEXLDD        */ shader_glsl_texldd,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
-    /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_glsl_texm3x2depth,
-    /* WINED3DSIH_TEXM3x2PAD    */ pshader_glsl_texm3x2pad,
-    /* WINED3DSIH_TEXM3x2TEX    */ pshader_glsl_texm3x2tex,
-    /* WINED3DSIH_TEXM3x3       */ pshader_glsl_texm3x3,
+    /* WINED3DSIH_TEXM3x2DEPTH  */ shader_glsl_texm3x2depth,
+    /* WINED3DSIH_TEXM3x2PAD    */ shader_glsl_texm3x2pad,
+    /* WINED3DSIH_TEXM3x2TEX    */ shader_glsl_texm3x2tex,
+    /* WINED3DSIH_TEXM3x3       */ shader_glsl_texm3x3,
     /* WINED3DSIH_TEXM3x3DIFF   */ NULL,
     /* WINED3DSIH_TEXM3x3DIFF   */ NULL,
-    /* WINED3DSIH_TEXM3x3PAD    */ pshader_glsl_texm3x3pad,
-    /* WINED3DSIH_TEXM3x3SPEC   */ pshader_glsl_texm3x3spec,
-    /* WINED3DSIH_TEXM3x3TEX    */ pshader_glsl_texm3x3tex,
-    /* WINED3DSIH_TEXM3x3VSPEC  */ pshader_glsl_texm3x3vspec,
-    /* WINED3DSIH_TEXREG2AR     */ pshader_glsl_texreg2ar,
-    /* WINED3DSIH_TEXREG2GB     */ pshader_glsl_texreg2gb,
-    /* WINED3DSIH_TEXREG2RGB    */ pshader_glsl_texreg2rgb,
+    /* WINED3DSIH_TEXM3x3PAD    */ shader_glsl_texm3x3pad,
+    /* WINED3DSIH_TEXM3x3SPEC   */ shader_glsl_texm3x3spec,
+    /* WINED3DSIH_TEXM3x3TEX    */ shader_glsl_texm3x3tex,
+    /* WINED3DSIH_TEXM3x3VSPEC  */ shader_glsl_texm3x3vspec,
+    /* WINED3DSIH_TEXREG2AR     */ shader_glsl_texreg2ar,
+    /* WINED3DSIH_TEXREG2GB     */ shader_glsl_texreg2gb,
+    /* WINED3DSIH_TEXREG2RGB    */ shader_glsl_texreg2rgb,
 };
 
 };
 
+static void shader_glsl_handle_instruction(const struct wined3d_shader_instruction *ins) {
+    SHADER_HANDLER hw_fct;
+
+    /* Select handler */
+    hw_fct = shader_glsl_instruction_handler_table[ins->handler_idx];
+
+    /* Unhandled opcode */
+    if (!hw_fct)
+    {
+        FIXME("Backend can't handle opcode %#x\n", ins->handler_idx);
+        return;
+    }
+    hw_fct(ins);
+
+    shader_glsl_add_instruction_modifiers(ins);
+}
+
 const shader_backend_t glsl_shader_backend = {
 const shader_backend_t glsl_shader_backend = {
-    shader_glsl_instruction_handler_table,
+    shader_glsl_handle_instruction,
     shader_glsl_select,
     shader_glsl_select_depth_blt,
     shader_glsl_deselect_depth_blt,
     shader_glsl_select,
     shader_glsl_select_depth_blt,
     shader_glsl_deselect_depth_blt,
@@ -4397,9 +4765,6 @@ const shader_backend_t glsl_shader_backend = {
     shader_glsl_alloc,
     shader_glsl_free,
     shader_glsl_dirty_const,
     shader_glsl_alloc,
     shader_glsl_free,
     shader_glsl_dirty_const,
-    shader_glsl_generate_pshader,
-    shader_glsl_generate_vshader,
     shader_glsl_get_caps,
     shader_glsl_color_fixup_supported,
     shader_glsl_get_caps,
     shader_glsl_color_fixup_supported,
-    shader_glsl_add_instruction_modifiers,
 };
 };
index f7e331d..a0a576b 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
-static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+
+/* GL locking for state handlers is done by the caller. */
+
+static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     BOOL bumpmap = FALSE;
 
     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
     BOOL bumpmap = FALSE;
 
     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
@@ -445,12 +449,12 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
                   stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
     }
 
                   stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
     }
 
-    checkGLcall("set_tex_op_nvrc()\n");
-
+    checkGLcall("set_tex_op_nvrc()");
 }
 
 
 }
 
 
-static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
@@ -542,7 +546,8 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
     }
 }
 
     }
 }
 
-static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
 
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
 
@@ -557,7 +562,8 @@ static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     nvts_activate_dimensions(sampler, stateblock, context);
 }
 
     nvts_activate_dimensions(sampler, stateblock, context);
 }
 
-static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
     float mat[2][2];
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
     float mat[2][2];
@@ -584,7 +590,8 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
     GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
     GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
@@ -592,9 +599,12 @@ static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION (*gl_info)
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION (*gl_info)
+/* Context activation is done by the caller. */
 static void nvrc_enable(IWineD3DDevice *iface, BOOL enable) { }
 
 static void nvrc_enable(IWineD3DDevice *iface, BOOL enable) { }
 
+/* Context activation is done by the caller. */
 static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
 static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
+    ENTER_GL();
     if(enable) {
         glEnable(GL_TEXTURE_SHADER_NV);
         checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
     if(enable) {
         glEnable(GL_TEXTURE_SHADER_NV);
         checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
@@ -602,9 +612,11 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
         glDisable(GL_TEXTURE_SHADER_NV);
         checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
     }
         glDisable(GL_TEXTURE_SHADER_NV);
         checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
     }
+    LEAVE_GL();
 }
 
 }
 
-static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps)
+static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype,
+        const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD                        |
                             WINED3DTEXOPCAPS_ADDSIGNED                  |
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD                        |
                             WINED3DTEXOPCAPS_ADDSIGNED                  |
@@ -659,6 +671,7 @@ static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info
 }
 
 static HRESULT nvrc_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
 }
 
 static HRESULT nvrc_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
+/* Context activation is done by the caller. */
 static void nvrc_fragment_free(IWineD3DDevice *iface) {}
 
 /* Two fixed function pipeline implementations using GL_NV_register_combiners and
 static void nvrc_fragment_free(IWineD3DDevice *iface) {}
 
 /* Two fixed function pipeline implementations using GL_NV_register_combiners and
@@ -687,137 +700,137 @@ static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 static const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
 }
 
 static const struct StateEntryTemplate nvrc_fragmentstate_template[] = {
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     nvts_bumpenvmat     }, NV_TEXTURE_SHADER2              },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, 0                               },
-    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
-    { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
-    { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              nvrc_texfactor      }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          nvrc_colorop        }, WINED3D_GL_EXT_NONE             },
+    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              nvrc_texfactor      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, 0                               },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   nvts_texdim         }, NV_TEXTURE_SHADER2              },
-    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
 const struct fragment_pipeline nvts_fragment_pipeline = {
 };
 
 const struct fragment_pipeline nvts_fragment_pipeline = {
index 338e66e..a5447d0 100644 (file)
@@ -22,7 +22,6 @@
 #include "winerror.h"
 #include "wine/debug.h"
 
 #include "winerror.h"
 #include "wine/debug.h"
 
-#include <assert.h>
 #include <string.h>
 
 #include "wined3d_private.h"
 #include <string.h>
 
 #include "wined3d_private.h"
@@ -78,7 +77,9 @@ DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) {
         case WINEDDPCAPS_2BIT: return 4;
         case WINEDDPCAPS_4BIT: return 16;
         case WINEDDPCAPS_8BIT: return 256;
         case WINEDDPCAPS_2BIT: return 4;
         case WINEDDPCAPS_4BIT: return 16;
         case WINEDDPCAPS_8BIT: return 256;
-        default: assert(0); return 256;
+        default:
+            FIXME("Unhandled size bits %#x.\n", dwFlags & SIZE_BITS);
+            return 256;
     }
 }
 
     }
 }
 
index 33148c8..6ac145c 100644 (file)
@@ -178,6 +178,10 @@ static void pshader_set_limits(IWineD3DPixelShaderImpl *This)
             This->baseShader.limits.label = 16;
             break;
 
             This->baseShader.limits.label = 16;
             break;
 
+        case WINED3D_SHADER_VERSION(4,0):
+            FIXME("Using 3.0 limits for 4.0 shader\n");
+            /* Fall through */
+
         case WINED3D_SHADER_VERSION(3,0):
             This->baseShader.limits.temporary = 32;
             This->baseShader.limits.constant_float = 224;
         case WINED3D_SHADER_VERSION(3,0):
             This->baseShader.limits.temporary = 32;
             This->baseShader.limits.constant_float = 224;
@@ -238,8 +242,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     list_init(&This->baseShader.constantsI);
 
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
     list_init(&This->baseShader.constantsI);
 
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction,
-                                    GL_LIMITS(pshader_constantsF));
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe,
+            reg_maps, NULL, This->input_signature, NULL,
+            pFunction, GL_LIMITS(pshader_constantsF));
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
@@ -294,7 +299,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
 {
     WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type;
     unsigned int i;
 {
     WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type;
     unsigned int i;
@@ -338,29 +343,6 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD
     }
 }
 
     }
 }
 
-static GLuint pixelshader_compile(IWineD3DPixelShaderImpl *This, const struct ps_compile_args *args)
-{
-    CONST DWORD *function = This->baseShader.function;
-    GLuint retval;
-    SHADER_BUFFER buffer;
-    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
-
-    TRACE("(%p) : function %p\n", This, function);
-
-    pixelshader_update_samplers(&This->baseShader.reg_maps,
-            ((IWineD3DDeviceImpl *)This->baseShader.device)->stateBlock->textures);
-
-    /* Generate the HW shader */
-    TRACE("(%p) : Generating hardware program\n", This);
-    This->cur_args = args;
-    shader_buffer_init(&buffer);
-    retval = device->shader_backend->shader_generate_pshader((IWineD3DPixelShader *)This, &buffer, args);
-    shader_buffer_free(&buffer);
-    This->cur_args = NULL;
-
-    return retval;
-}
-
 const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
 {
     /*** IUnknown methods ***/
 const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
 {
     /*** IUnknown methods ***/
@@ -439,44 +421,3 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
         }
     }
 }
         }
     }
 }
-
-GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args)
-{
-    UINT i;
-    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),
-     * 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) {
-            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->num_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 = pixelshader_compile(shader, args);
-    return shader->gl_shaders[shader->num_gl_shaders++].prgId;
-}
index 481177f..2a2c1b1 100644 (file)
@@ -62,38 +62,22 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
     TRACE("(%p) : Releasing from %d\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
     TRACE("(%p) : Releasing from %d\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
-        ENTER_GL();
         /* Queries are specific to the GL context that created them. Not
          * deleting the query will obviously leak it, but that's still better
          * than potentially deleting a different query with the same id in this
          * context, and (still) leaking the actual query. */
         /* Queries are specific to the GL context that created them. Not
          * deleting the query will obviously leak it, but that's still better
          * than potentially deleting a different query with the same id in this
          * context, and (still) leaking the actual query. */
-        if(This->type == WINED3DQUERYTYPE_EVENT) {
-            if (((WineQueryEventData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
-                    || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
-            {
-                FIXME("Query was created in a different context, skipping deletion\n");
-            }
-            else if(GL_SUPPORT(APPLE_FENCE))
-            {
-                GL_EXTCALL(glDeleteFencesAPPLE(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
-                checkGLcall("glDeleteFencesAPPLE");
-            } else if(GL_SUPPORT(NV_FENCE)) {
-                GL_EXTCALL(glDeleteFencesNV(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
-                checkGLcall("glDeleteFencesNV");
-            }
-        } else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
-            if (((WineQueryOcclusionData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
-                    || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
-            {
-                FIXME("Query was created in a different context, skipping deletion\n");
-            }
-            else
-            {
-                GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
-                checkGLcall("glDeleteQueriesARB");
-            }
+        if (This->type == WINED3DQUERYTYPE_EVENT)
+        {
+            struct wined3d_event_query *query = This->extendedData;
+
+            if (query->context) context_free_event_query(query);
+        }
+        else if (This->type == WINED3DQUERYTYPE_OCCLUSION)
+        {
+            struct wined3d_occlusion_query *query = This->extendedData;
+
+            if (query->context) context_free_occlusion_query(query);
         }
         }
-        LEAVE_GL();
 
         HeapFree(GetProcessHeap(), 0, This->extendedData);
         HeapFree(GetProcessHeap(), 0, This);
 
         HeapFree(GetProcessHeap(), 0, This->extendedData);
         HeapFree(GetProcessHeap(), 0, This);
@@ -286,7 +270,7 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
 
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
 
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
-    GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
+    struct wined3d_occlusion_query *query = This->extendedData;
     DWORD* data = pData;
     GLuint available;
     GLuint samples;
     DWORD* data = pData;
     GLuint available;
     GLuint samples;
@@ -294,6 +278,8 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
 
     TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
 
     TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
+    if (!query->context) This->state = QUERY_CREATED;
+
     if (This->state == QUERY_CREATED)
     {
         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
     if (This->state == QUERY_CREATED)
     {
         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
@@ -316,26 +302,27 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
         return S_OK;
     }
 
         return S_OK;
     }
 
-    if (((WineQueryOcclusionData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
-            || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
+    if (query->context->tid != GetCurrentThreadId())
     {
     {
-        FIXME("%p Wrong context, returning 1.\n", This);
+        FIXME("%p Wrong thread, returning 1.\n", This);
         *data = 1;
         return S_OK;
     }
 
         *data = 1;
         return S_OK;
     }
 
+    ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+
     ENTER_GL();
 
     ENTER_GL();
 
-    GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
-    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
+    GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
+    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
     TRACE("(%p) : available %d.\n", This, available);
 
     if (available)
     {
         if (data)
         {
     TRACE("(%p) : available %d.\n", This, available);
 
     if (available)
     {
         if (data)
         {
-            GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
-            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
+            GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples));
+            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
             TRACE("(%p) : Returning %d samples.\n", This, samples);
             *data = samples;
         }
             TRACE("(%p) : Returning %d samples.\n", This, samples);
             *data = samples;
         }
@@ -353,32 +340,52 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
 
 static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
 
 static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
+    struct wined3d_event_query *query = This->extendedData;
     BOOL* data = pData;
     BOOL* data = pData;
-    WineD3DContext *ctx;
+
     TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
     TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
-    ctx = ((WineQueryEventData *)This->extendedData)->ctx;
-    if(pData == NULL || dwSize == 0) {
+    if (!pData || !dwSize) return S_OK;
+
+    if (!query->context)
+    {
+        ERR("Query not started, returning TRUE.\n");
+        *data = TRUE;
+
         return S_OK;
         return S_OK;
-    } if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
+    }
+
+    if (query->context->tid != GetCurrentThreadId())
+    {
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
-        FIXME("Query context not active, reporting GPU idle\n");
+        FIXME("Wrong thread, reporting GPU idle.\n");
         *data = TRUE;
         *data = TRUE;
-    } else if(GL_SUPPORT(APPLE_FENCE)) {
-        ENTER_GL();
-        *data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
+
+        return S_OK;
+    }
+
+    ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+
+    ENTER_GL();
+
+    if (GL_SUPPORT(APPLE_FENCE))
+    {
+        *data = GL_EXTCALL(glTestFenceAPPLE(query->id));
         checkGLcall("glTestFenceAPPLE");
         checkGLcall("glTestFenceAPPLE");
-        LEAVE_GL();
-    } else if(GL_SUPPORT(NV_FENCE)) {
-        ENTER_GL();
-        *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
+    }
+    else if (GL_SUPPORT(NV_FENCE))
+    {
+        *data = GL_EXTCALL(glTestFenceNV(query->id));
         checkGLcall("glTestFenceNV");
         checkGLcall("glTestFenceNV");
-        LEAVE_GL();
-    } else {
+    }
+    else
+    {
         WARN("(%p): reporting GPU idle\n", This);
         *data = TRUE;
     }
 
         WARN("(%p): reporting GPU idle\n", This);
         *data = TRUE;
     }
 
+    LEAVE_GL();
+
     return S_OK;
 }
 
     return S_OK;
 }
 
@@ -455,29 +462,47 @@ static HRESULT  WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface,  DWORD
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
 
     TRACE("(%p) : dwIssueFlags %#x, type D3DQUERY_EVENT\n", This, dwIssueFlags);
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
 
     TRACE("(%p) : dwIssueFlags %#x, type D3DQUERY_EVENT\n", This, dwIssueFlags);
-    if (dwIssueFlags & WINED3DISSUE_END) {
-        WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
-        if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
-            /* GL fences can be used only from the context that created them,
-             * so if a different context is active, don't bother setting the query. The penalty
-             * of a context switch is most likely higher than the gain of a correct query result
-             *
-             * If the query is used from a different thread, don't bother creating a multithread
-             * context - there's no point in doing that as the query would be unusable anyway
-             */
-            WARN("Query context not active\n");
-        } else if(GL_SUPPORT(APPLE_FENCE)) {
-            ENTER_GL();
-            GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
+    if (dwIssueFlags & WINED3DISSUE_END)
+    {
+        struct wined3d_event_query *query = This->extendedData;
+        struct wined3d_context *context;
+
+        if (query->context)
+        {
+            if (query->context->tid != GetCurrentThreadId())
+            {
+                context_free_event_query(query);
+                context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
+                context_alloc_event_query(context, query);
+            }
+            else
+            {
+                ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+            }
+        }
+        else
+        {
+            context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
+            context_alloc_event_query(context, query);
+        }
+
+        ENTER_GL();
+
+        if (GL_SUPPORT(APPLE_FENCE))
+        {
+            GL_EXTCALL(glSetFenceAPPLE(query->id));
             checkGLcall("glSetFenceAPPLE");
             checkGLcall("glSetFenceAPPLE");
-            LEAVE_GL();
-        } else if (GL_SUPPORT(NV_FENCE)) {
-            ENTER_GL();
-            GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
+        }
+        else if (GL_SUPPORT(NV_FENCE))
+        {
+            GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
             checkGLcall("glSetFenceNV");
             checkGLcall("glSetFenceNV");
-            LEAVE_GL();
         }
         }
-    } else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
+
+        LEAVE_GL();
+    }
+    else if(dwIssueFlags & WINED3DISSUE_BEGIN)
+    {
         /* Started implicitly at device creation */
         ERR("Event query issued with START flag - what to do?\n");
     }
         /* Started implicitly at device creation */
         ERR("Event query issued with START flag - what to do?\n");
     }
@@ -494,34 +519,67 @@ static HRESULT  WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface,  DWORD
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIssueFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
 
 static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIssueFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
 
-    if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
-        WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
+    if (GL_SUPPORT(ARB_OCCLUSION_QUERY))
+    {
+        struct wined3d_occlusion_query *query = This->extendedData;
+        struct wined3d_context *context;
 
 
-        if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
-            FIXME("Not the owning context, can't start query\n");
-        } else {
-            ENTER_GL();
-            /* This is allowed according to msdn and our tests. Reset the query and restart */
-            if (dwIssueFlags & WINED3DISSUE_BEGIN) {
-                if(This->state == QUERY_BUILDING) {
+        /* This is allowed according to msdn and our tests. Reset the query and restart */
+        if (dwIssueFlags & WINED3DISSUE_BEGIN)
+        {
+            if (This->state == QUERY_BUILDING)
+            {
+                if (query->context->tid != GetCurrentThreadId())
+                {
+                    FIXME("Wrong thread, can't restart query.\n");
+
+                    context_free_occlusion_query(query);
+                    context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
+                    context_alloc_occlusion_query(context, query);
+                }
+                else
+                {
+                    ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+
+                    ENTER_GL();
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
+                    LEAVE_GL();
                 }
                 }
-
-                GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
-                checkGLcall("glBeginQuery()");
             }
             }
-            if (dwIssueFlags & WINED3DISSUE_END) {
-                /* Msdn says _END on a non-building occlusion query returns an error, but
-                 * our tests show that it returns OK. But OpenGL doesn't like it, so avoid
-                 * generating an error
-                 */
-                if(This->state == QUERY_BUILDING) {
+            else
+            {
+                if (query->context) context_free_occlusion_query(query);
+                context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
+                context_alloc_occlusion_query(context, query);
+            }
+
+            ENTER_GL();
+            GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id));
+            checkGLcall("glBeginQuery()");
+            LEAVE_GL();
+        }
+        if (dwIssueFlags & WINED3DISSUE_END) {
+            /* Msdn says _END on a non-building occlusion query returns an error, but
+             * our tests show that it returns OK. But OpenGL doesn't like it, so avoid
+             * generating an error
+             */
+            if (This->state == QUERY_BUILDING)
+            {
+                if (query->context->tid != GetCurrentThreadId())
+                {
+                    FIXME("Wrong thread, can't end query.\n");
+                }
+                else
+                {
+                    ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+
+                    ENTER_GL();
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
+                    LEAVE_GL();
                 }
             }
                 }
             }
-            LEAVE_GL();
         }
     } else {
         FIXME("(%p) : Occlusion queries not supported\n", This);
         }
     } else {
         FIXME("(%p) : Occlusion queries not supported\n", This);
index 807240b..89ea7f3 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
-HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
         WINED3DPOOL pool, IUnknown *parent)
 {
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
         WINED3DPOOL pool, IUnknown *parent)
 {
+    struct IWineD3DResourceClass *resource = &((IWineD3DResourceImpl *)iface)->resource;
+
     resource->wineD3DDevice = device;
     resource->parent = parent;
     resource->resourceType = resource_type;
     resource->wineD3DDevice = device;
     resource->parent = parent;
     resource->resourceType = resource_type;
@@ -68,6 +70,8 @@ HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYP
         WineD3DAdapterChangeGLRam(device, size);
     }
 
         WineD3DAdapterChangeGLRam(device, size);
     }
 
+    device_resource_add(device, iface);
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -96,10 +100,7 @@ void resource_cleanup(IWineD3DResource *iface)
     This->resource.allocatedMemory = 0;
     This->resource.heapMemory = 0;
 
     This->resource.allocatedMemory = 0;
     This->resource.heapMemory = 0;
 
-    if (This->resource.wineD3DDevice != NULL) {
-        IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface);
-    }/* NOTE: this is not really an error for system memory resources */
-    return;
+    if (This->resource.wineD3DDevice) device_resource_released(This->resource.wineD3DDevice, iface);
 }
 
 HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice** ppDevice)
 }
 
 HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice** ppDevice)
index a626d52..ead2769 100644 (file)
@@ -349,6 +349,7 @@ static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_
     src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     src->reg.idx = param & WINED3DSP_REGNUM_MASK;
     src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     src->reg.idx = param & WINED3DSP_REGNUM_MASK;
+    src->reg.array_idx = ~0U;
     src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
     src->reg.rel_addr = rel_addr;
     src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
     src->reg.rel_addr = rel_addr;
@@ -360,6 +361,7 @@ static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_
     dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     dst->reg.idx = param & WINED3DSP_REGNUM_MASK;
     dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
             | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
     dst->reg.idx = param & WINED3DSP_REGNUM_MASK;
+    dst->reg.array_idx = ~0U;
     dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT;
     dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT;
     dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
     dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT;
     dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT;
     dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
index 5cc445d..91aa882 100644 (file)
@@ -28,6 +28,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
 #define WINED3D_SM4_OPCODE_MASK                 0xff
 
 
 #define WINED3D_SM4_OPCODE_MASK                 0xff
 
+#define WINED3D_SM4_REGISTER_ORDER_SHIFT        20
+#define WINED3D_SM4_REGISTER_ORDER_MASK         (0x3 << WINED3D_SM4_REGISTER_ORDER_SHIFT)
+
 #define WINED3D_SM4_REGISTER_TYPE_SHIFT         12
 #define WINED3D_SM4_REGISTER_TYPE_MASK          (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
 
 #define WINED3D_SM4_REGISTER_TYPE_SHIFT         12
 #define WINED3D_SM4_REGISTER_TYPE_MASK          (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
 
@@ -46,19 +49,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 enum wined3d_sm4_opcode
 {
     WINED3D_SM4_OP_ADD      = 0x00,
 enum wined3d_sm4_opcode
 {
     WINED3D_SM4_OP_ADD      = 0x00,
+    WINED3D_SM4_OP_DP3      = 0x10,
+    WINED3D_SM4_OP_DP4      = 0x11,
     WINED3D_SM4_OP_EXP      = 0x19,
     WINED3D_SM4_OP_EXP      = 0x19,
+    WINED3D_SM4_OP_LOG      = 0x2f,
+    WINED3D_SM4_OP_MIN      = 0x33,
+    WINED3D_SM4_OP_MAX      = 0x34,
     WINED3D_SM4_OP_MOV      = 0x36,
     WINED3D_SM4_OP_MUL      = 0x38,
     WINED3D_SM4_OP_RET      = 0x3e,
     WINED3D_SM4_OP_MOV      = 0x36,
     WINED3D_SM4_OP_MUL      = 0x38,
     WINED3D_SM4_OP_RET      = 0x3e,
+    WINED3D_SM4_OP_RSQ      = 0x44,
     WINED3D_SM4_OP_SINCOS   = 0x4d,
 };
 
 enum wined3d_sm4_register_type
 {
     WINED3D_SM4_OP_SINCOS   = 0x4d,
 };
 
 enum wined3d_sm4_register_type
 {
-    WINED3D_SM4_RT_TEMP     = 0x0,
-    WINED3D_SM4_RT_INPUT    = 0x1,
-    WINED3D_SM4_RT_OUTPUT   = 0x2,
-    WINED3D_SM4_RT_IMMCONST = 0x4,
+    WINED3D_SM4_RT_TEMP         = 0x0,
+    WINED3D_SM4_RT_INPUT        = 0x1,
+    WINED3D_SM4_RT_OUTPUT       = 0x2,
+    WINED3D_SM4_RT_IMMCONST     = 0x4,
+    WINED3D_SM4_RT_CONSTBUFFER  = 0x8,
 };
 
 enum wined3d_sm4_immconst_type
 };
 
 enum wined3d_sm4_immconst_type
@@ -92,20 +102,30 @@ struct sysval_map
 static const struct wined3d_sm4_opcode_info opcode_table[] =
 {
     {WINED3D_SM4_OP_ADD,    WINED3DSIH_ADD,         1,  2},
 static const struct wined3d_sm4_opcode_info opcode_table[] =
 {
     {WINED3D_SM4_OP_ADD,    WINED3DSIH_ADD,         1,  2},
+    {WINED3D_SM4_OP_DP3,    WINED3DSIH_DP3,         1,  2},
+    {WINED3D_SM4_OP_DP4,    WINED3DSIH_DP4,         1,  2},
     {WINED3D_SM4_OP_EXP,    WINED3DSIH_EXP,         1,  1},
     {WINED3D_SM4_OP_EXP,    WINED3DSIH_EXP,         1,  1},
+    {WINED3D_SM4_OP_LOG,    WINED3DSIH_LOG,         1,  1},
+    {WINED3D_SM4_OP_MIN,    WINED3DSIH_MIN,         1,  2},
+    {WINED3D_SM4_OP_MAX,    WINED3DSIH_MAX,         1,  2},
     {WINED3D_SM4_OP_MOV,    WINED3DSIH_MOV,         1,  1},
     {WINED3D_SM4_OP_MUL,    WINED3DSIH_MUL,         1,  2},
     {WINED3D_SM4_OP_RET,    WINED3DSIH_RET,         0,  0},
     {WINED3D_SM4_OP_MOV,    WINED3DSIH_MOV,         1,  1},
     {WINED3D_SM4_OP_MUL,    WINED3DSIH_MUL,         1,  2},
     {WINED3D_SM4_OP_RET,    WINED3DSIH_RET,         0,  0},
+    {WINED3D_SM4_OP_RSQ,    WINED3DSIH_RSQ,         1,  1},
     {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS,      1,  2},
 };
 
 static const WINED3DSHADER_PARAM_REGISTER_TYPE register_type_table[] =
 {
     {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS,      1,  2},
 };
 
 static const WINED3DSHADER_PARAM_REGISTER_TYPE register_type_table[] =
 {
-    /* WINED3D_SM4_RT_TEMP */       WINED3DSPR_TEMP,
-    /* WINED3D_SM4_RT_INPUT */      WINED3DSPR_INPUT,
-    /* WINED3D_SM4_RT_OUTPUT */     WINED3DSPR_OUTPUT,
-    /* UNKNOWN */                   0,
-    /* WINED3D_SM4_RT_IMMCONST */   WINED3DSPR_IMMCONST,
+    /* WINED3D_SM4_RT_TEMP */           WINED3DSPR_TEMP,
+    /* WINED3D_SM4_RT_INPUT */          WINED3DSPR_INPUT,
+    /* WINED3D_SM4_RT_OUTPUT */         WINED3DSPR_OUTPUT,
+    /* UNKNOWN */                       0,
+    /* WINED3D_SM4_RT_IMMCONST */       WINED3DSPR_IMMCONST,
+    /* UNKNOWN */                       0,
+    /* UNKNOWN */                       0,
+    /* UNKNOWN */                       0,
+    /* WINED3D_SM4_RT_CONSTBUFFER */    WINED3DSPR_CONSTBUFFER,
 };
 
 static const struct sysval_map sysval_map[] =
 };
 
 static const struct sysval_map sysval_map[] =
@@ -265,6 +285,7 @@ static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wine
     struct wined3d_sm4_data *priv = data;
     DWORD token = *(*ptr)++;
     enum wined3d_sm4_register_type register_type;
     struct wined3d_sm4_data *priv = data;
     DWORD token = *(*ptr)++;
     enum wined3d_sm4_register_type register_type;
+    DWORD order;
 
     register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
     if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
 
     register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
     if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
@@ -277,6 +298,16 @@ static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wine
         src_param->reg.type = register_type_table[register_type];
     }
 
         src_param->reg.type = register_type_table[register_type];
     }
 
+    order = (token & WINED3D_SM4_REGISTER_ORDER_MASK) >> WINED3D_SM4_REGISTER_ORDER_SHIFT;
+
+    if (order < 1) src_param->reg.idx = ~0U;
+    else src_param->reg.idx = *(*ptr)++;
+
+    if (order < 2) src_param->reg.array_idx = ~0U;
+    else src_param->reg.array_idx = *(*ptr)++;
+
+    if (order > 2) FIXME("Unhandled order %u.\n", order);
+
     if (register_type == WINED3D_SM4_RT_IMMCONST)
     {
         enum wined3d_sm4_immconst_type immconst_type =
     if (register_type == WINED3D_SM4_RT_IMMCONST)
     {
         enum wined3d_sm4_immconst_type immconst_type =
@@ -304,7 +335,6 @@ static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wine
     }
     else
     {
     }
     else
     {
-        src_param->reg.idx = *(*ptr)++;
         src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
     }
 
         src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
     }
 
@@ -319,8 +349,8 @@ static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wine
 {
     struct wined3d_sm4_data *priv = data;
     DWORD token = *(*ptr)++;
 {
     struct wined3d_sm4_data *priv = data;
     DWORD token = *(*ptr)++;
-    UINT register_idx = *(*ptr)++;
     enum wined3d_sm4_register_type register_type;
     enum wined3d_sm4_register_type register_type;
+    DWORD order;
 
     register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
     if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
 
     register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
     if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
@@ -333,7 +363,16 @@ static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wine
         dst_param->reg.type = register_type_table[register_type];
     }
 
         dst_param->reg.type = register_type_table[register_type];
     }
 
-    dst_param->reg.idx = register_idx;
+    order = (token & WINED3D_SM4_REGISTER_ORDER_MASK) >> WINED3D_SM4_REGISTER_ORDER_SHIFT;
+
+    if (order < 1) dst_param->reg.idx = ~0U;
+    else dst_param->reg.idx = *(*ptr)++;
+
+    if (order < 2) dst_param->reg.array_idx = ~0U;
+    else dst_param->reg.array_idx = *(*ptr)++;
+
+    if (order > 2) FIXME("Unhandled order %u.\n", order);
+
     dst_param->write_mask = (token & WINED3D_SM4_WRITEMASK_MASK) >> WINED3D_SM4_WRITEMASK_SHIFT;
     dst_param->modifiers = 0;
     dst_param->shift = 0;
     dst_param->write_mask = (token & WINED3D_SM4_WRITEMASK_MASK) >> WINED3D_SM4_WRITEMASK_SHIFT;
     dst_param->modifiers = 0;
     dst_param->shift = 0;
index ad1593c..2df21ad 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
 
-#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
+#define GLINFO_LOCATION (*context->gl_info)
 
 
-static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+/* GL locking for state handlers is done by the caller. */
 
 
-static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+
+static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* Used for states which are not mapped to a gl state as-is, but used somehow different,
      * e.g as a parameter for drawing, or which are unimplemented in windows d3d
      */
     /* Used for states which are not mapped to a gl state as-is, but used somehow different,
      * e.g as a parameter for drawing, or which are unimplemented in windows d3d
      */
@@ -51,15 +54,13 @@ static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     }
 }
 
     }
 }
 
-static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    /* Print a WARN, this allows the stateblock code to loop over all states to generate a display
-     * list without causing confusing terminal output. Deliberately no special debug name here
-     * because its undefined.
-     */
-    WARN("undefined state %d\n", state);
+static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+    ERR("Undefined state.\n");
 }
 
 }
 
-static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
 
     switch(Value) {
     WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
 
     switch(Value) {
@@ -80,7 +81,8 @@ static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* Lighting is not enabled if transformed vertices are drawn
      * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
      * This state reads the decoded vertex declaration, so if it is dirty don't do anything. The
     /* Lighting is not enabled if transformed vertices are drawn
      * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
      * This state reads the decoded vertex declaration, so if it is dirty don't do anything. The
@@ -102,7 +104,8 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* No z test without depth stencil buffers */
     if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
         TRACE("No Z buffer - disabling depth test\n");
     /* No z test without depth stencil buffers */
     if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
         TRACE("No Z buffer - disabling depth test\n");
@@ -130,7 +133,8 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
     }
 }
 
     }
 }
 
-static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
      * switch
      */
     /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
      * switch
      */
@@ -156,7 +160,8 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
         case WINED3DSHADE_FLAT:
             glShadeModel(GL_FLAT);
     switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
         case WINED3DSHADE_FLAT:
             glShadeModel(GL_FLAT);
@@ -174,7 +179,8 @@ static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
         glEnable(GL_DITHER);
         checkGLcall("glEnable GL_DITHER");
     if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
         glEnable(GL_DITHER);
         checkGLcall("glEnable GL_DITHER");
@@ -184,7 +190,8 @@ static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
      * this has to be merged with ZENABLE and ZFUNC
      */
     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
      * this has to be merged with ZENABLE and ZFUNC
      */
@@ -197,7 +204,8 @@ static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
 
     if(glParm) {
     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
 
     if(glParm) {
@@ -220,7 +228,8 @@ static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     }
 }
 
     }
 }
 
-static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
 
@@ -229,7 +238,8 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
     checkGLcall("glLightModel for MODEL_AMBIENT");
 }
 
     checkGLcall("glLightModel for MODEL_AMBIENT");
 }
 
-static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     int srcBlend = GL_ZERO;
     int dstBlend = GL_ZERO;
     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
     int srcBlend = GL_ZERO;
     int dstBlend = GL_ZERO;
     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
@@ -441,11 +451,13 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     }
 }
 
     }
 }
 
-static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
 }
 
     WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
 }
 
-static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
 
     TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
     float col[4];
 
     TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
@@ -454,7 +466,8 @@ static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     checkGLcall("glBlendColor");
 }
 
     checkGLcall("glBlendColor");
 }
 
-static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     int glParm = 0;
     float ref;
     BOOL enable_ckey = FALSE;
     int glParm = 0;
     float ref;
     BOOL enable_ckey = FALSE;
@@ -508,7 +521,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
 
     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
         glParm = GL_NOTEQUAL;
 
     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
         glParm = GL_NOTEQUAL;
-        ref = 0.0;
+        ref = 0.0f;
     } else {
         ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
         glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
     } else {
         ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
         glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
@@ -519,11 +532,12 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     }
 }
 
     }
 }
 
-static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
-    if (use_vs(stateblock))
+    if (!stateblock->wineD3DDevice->vs_clipping && use_vs(stateblock))
     {
         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
     {
         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
@@ -550,16 +564,18 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     if (stateblock->renderState[WINED3DRS_CLIPPING]) {
         enable  = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
         disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
     if (stateblock->renderState[WINED3DRS_CLIPPING]) {
         enable  = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
         disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
-        if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
-            glDisable(GL_DEPTH_CLAMP_NV);
-            checkGLcall("glDisable(GL_DEPTH_CLAMP_NV)");
+        if (GL_SUPPORT(ARB_DEPTH_CLAMP))
+        {
+            glDisable(GL_DEPTH_CLAMP);
+            checkGLcall("glDisable(GL_DEPTH_CLAMP)");
         }
     } else {
         disable = 0xffffffff;
         enable  = 0x00;
         }
     } else {
         disable = 0xffffffff;
         enable  = 0x00;
-        if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
-            glEnable(GL_DEPTH_CLAMP_NV);
-            checkGLcall("glEnable(GL_DEPTH_CLAMP_NV)");
+        if (GL_SUPPORT(ARB_DEPTH_CLAMP))
+        {
+            glEnable(GL_DEPTH_CLAMP);
+            checkGLcall("glEnable(GL_DEPTH_CLAMP)");
         }
     }
 
         }
     }
 
@@ -587,11 +603,13 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
 }
 
     WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
 }
 
-static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     int blendEquation = GL_FUNC_ADD;
     int blendEquationAlpha = GL_FUNC_ADD;
 
     int blendEquation = GL_FUNC_ADD;
     int blendEquationAlpha = GL_FUNC_ADD;
 
@@ -632,8 +650,8 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
     }
 }
 
     }
 }
 
-static void
-state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
      * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
      * specular color. This is wrong:
     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
      * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
      * specular color. This is wrong:
@@ -732,7 +750,8 @@ state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
     checkGLcall("glMaterialfv(GL_EMISSION)");
 }
 
     checkGLcall("glMaterialfv(GL_EMISSION)");
 }
 
-static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     unsigned int i;
 
     /* Note the texture color applies to all textures whereas
     unsigned int i;
 
     /* Note the texture color applies to all textures whereas
@@ -754,8 +773,9 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void
-renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
+static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
+        GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
+{
     glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
     checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
     GL_EXTCALL(glActiveStencilFaceEXT(face));
     glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
     checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
     GL_EXTCALL(glActiveStencilFaceEXT(face));
@@ -766,8 +786,8 @@ renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLi
     checkGLcall("glStencilOp(...)");
 }
 
     checkGLcall("glStencilOp(...)");
 }
 
-static void
-state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD onesided_enable = FALSE;
     DWORD twosided_enable = FALSE;
     GLint func = GL_ALWAYS;
     DWORD onesided_enable = FALSE;
     DWORD twosided_enable = FALSE;
     GLint func = GL_ALWAYS;
@@ -821,10 +841,10 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
              * and other stencil functions which do not use two sided stencil do not have
              * to set it back
              */
              * and other stencil functions which do not use two sided stencil do not have
              * to set it back
              */
-            renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask,
-                                         stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
-            renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask,
-                                         stencilFail, depthFail, stencilPass);
+            renderstate_stencil_twosided(context, GL_BACK,
+                    func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
+            renderstate_stencil_twosided(context, GL_FRONT,
+                    func, ref, mask, stencilFail, depthFail, stencilPass);
         } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
             GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
             checkGLcall("glStencilFuncSeparateATI(...)");
         } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
             GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
             checkGLcall("glStencilFuncSeparateATI(...)");
@@ -856,7 +876,8 @@ state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *c
     }
 }
 
     }
 }
 
-static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
@@ -874,7 +895,8 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock
     glStencilMask(mask);
 }
 
     glStencilMask(mask);
 }
 
-static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
@@ -887,7 +909,8 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glStencilMask");
 }
 
     checkGLcall("glStencilMask");
 }
 
-static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
 
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
 
@@ -924,7 +947,8 @@ static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock
     }
 }
 
     }
 }
 
-void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float fogstart, fogend;
     union {
         DWORD d;
     float fogstart, fogend;
     union {
         DWORD d;
@@ -933,13 +957,13 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
 
     switch(context->fog_source) {
         case FOGSOURCE_VS:
 
     switch(context->fog_source) {
         case FOGSOURCE_VS:
-            fogstart = 1.0;
-            fogend = 0.0;
+            fogstart = 1.0f;
+            fogend = 0.0f;
             break;
 
         case FOGSOURCE_COORD:
             break;
 
         case FOGSOURCE_COORD:
-            fogstart = 255.0;
-            fogend = 0.0;
+            fogstart = 255.0f;
+            fogend = 0.0f;
             break;
 
         case FOGSOURCE_FFP:
             break;
 
         case FOGSOURCE_FFP:
@@ -949,8 +973,8 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
             fogend = tmpvalue.f;
             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
             if(fogstart == fogend) {
             fogend = tmpvalue.f;
             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
             if(fogstart == fogend) {
-                fogstart = -1.0 / 0.0;
-                fogend = 0.0;
+                fogstart = -1.0f / 0.0f;
+                fogend = 0.0f;
             }
             break;
 
             }
             break;
 
@@ -959,8 +983,8 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
              * Still this is needed to make the compiler happy
              */
             ERR("Unexpected fog coordinate source\n");
              * Still this is needed to make the compiler happy
              */
             ERR("Unexpected fog coordinate source\n");
-            fogstart = 0.0;
-            fogend = 0.0;
+            fogstart = 0.0f;
+            fogend = 0.0f;
     }
 
     glFogf(GL_FOG_START, fogstart);
     }
 
     glFogf(GL_FOG_START, fogstart);
@@ -972,7 +996,8 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     TRACE("Fog End == %f\n", fogend);
 }
 
     TRACE("Fog End == %f\n", fogend);
 }
 
-void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     enum fogsource new_source;
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
     enum fogsource new_source;
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
@@ -1113,13 +1138,15 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     }
 }
 
     }
 }
 
-static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
         WARN("Range fog enabled, but not supported by this opengl implementation\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
         WARN("Range fog enabled, but not supported by this opengl implementation\n");
     }
 }
 
-static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
         glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
         checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
         glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
         checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
@@ -1129,14 +1156,16 @@ static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
-void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1146,11 +1175,10 @@ void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
 }
 
     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
 }
 
-static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     GLenum Parm = 0;
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     GLenum Parm = 0;
-    const struct wined3d_stream_info_element *diffuse = &device->strided_streams.elements[WINED3D_FFP_DIFFUSE];
-    BOOL isDiffuseSupplied;
 
     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
      * The vertex declaration will call this function if the fixed function pipeline is used.
 
     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
      * The vertex declaration will call this function if the fixed function pipeline is used.
@@ -1160,10 +1188,10 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
         return;
     }
 
         return;
     }
 
-    isDiffuseSupplied = diffuse->data || diffuse->buffer_object;
-
     context->num_untracked_materials = 0;
     context->num_untracked_materials = 0;
-    if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
+    if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
+            && stateblock->renderState[WINED3DRS_COLORVERTEX])
+    {
         TRACE("diff %d, amb %d, emis %d, spec %d\n",
               stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
               stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
         TRACE("diff %d, amb %d, emis %d, spec %d\n",
               stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
               stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
@@ -1258,7 +1286,8 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     context->tracking_parm = Parm;
 }
 
     context->tracking_parm = Parm;
 }
 
-static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD                 d;
         WINED3DLINEPATTERN    lp;
     union {
         DWORD                 d;
         WINED3DLINEPATTERN    lp;
@@ -1278,7 +1307,8 @@ static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1306,7 +1336,8 @@ static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
 }
 
 
 }
 
 
-static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(isStateDirty(context, STATE_VDECL)) {
         return;
     }
     if(isStateDirty(context, STATE_VDECL)) {
         return;
     }
@@ -1315,8 +1346,7 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
      * by zero and is not properly defined in opengl, so avoid it
      */
     if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]
      * by zero and is not properly defined in opengl, so avoid it
      */
     if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]
-            && (stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].data
-            || stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].buffer_object))
+            && (stateblock->wineD3DDevice->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
     {
         glEnable(GL_NORMALIZE);
         checkGLcall("glEnable(GL_NORMALIZE);");
     {
         glEnable(GL_NORMALIZE);
         checkGLcall("glEnable(GL_NORMALIZE);");
@@ -1326,24 +1356,28 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     } tmpvalue;
 
     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
     union {
         DWORD d;
         float f;
     } tmpvalue;
 
     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
-    if(tmpvalue.f != 1.0) {
+    if (tmpvalue.f != 1.0f)
+    {
         FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
     }
     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
         FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
     }
     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
-    if(tmpvalue.f != 64.0) {
+    if (tmpvalue.f != 64.0f)
+    {
         FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
     }
 
 }
 
         FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
     }
 
 }
 
-static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1363,7 +1397,8 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfEXT(...)");
 }
 
     checkGLcall("glPointParameterfEXT(...)");
 }
 
-static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1383,7 +1418,8 @@ static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfARB(...)");
 }
 
     checkGLcall("glPointParameterfARB(...)");
 }
 
-static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* TODO: Group this with the viewport */
     /*
      * POINTSCALEENABLE controls how point size value is treated. If set to
     /* TODO: Group this with the viewport */
     /*
      * POINTSCALEENABLE controls how point size value is treated. If set to
@@ -1453,7 +1489,13 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
     checkGLcall("glPointSize(...);");
 }
 
     checkGLcall("glPointSize(...);");
 }
 
-static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+    WARN("token: %#x\n", stateblock->renderState[WINED3DRS_DEBUGMONITORTOKEN]);
+}
+
+static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
 
     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
     DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
 
     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
@@ -1478,7 +1520,8 @@ static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
     }
 }
 
     }
 }
 
-static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
     if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
@@ -1488,7 +1531,8 @@ static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
         TRACE("Last Pixel Drawing Enabled\n");
     } else {
     if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
         TRACE("Last Pixel Drawing Enabled\n");
     } else {
@@ -1502,7 +1546,8 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     BOOL warned = FALSE;
     /* TODO: NV_POINT_SPRITE */
     if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
     BOOL warned = FALSE;
     /* TODO: NV_POINT_SPRITE */
     if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
@@ -1512,7 +1557,8 @@ static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
         BOOL warned = FALSE;
         if(GL_LIMITS(point_sprite_units) < GL_LIMITS(textures) && !warned) {
     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
         BOOL warned = FALSE;
         if(GL_LIMITS(point_sprite_units) < GL_LIMITS(textures) && !warned) {
@@ -1530,7 +1576,8 @@ static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /**
      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
      http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
     /**
      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
      http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
@@ -1560,13 +1607,15 @@ static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     }
 }
 
     }
 }
 
-static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
         WARN("Multisample antialiasing not supported by gl\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
         WARN("Multisample antialiasing not supported by gl\n");
     }
 }
 
-static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
         glEnable(GL_MULTISAMPLE_ARB);
         checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
     if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
         glEnable(GL_MULTISAMPLE_ARB);
         checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
@@ -1576,7 +1625,8 @@ static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     }
 }
 
     }
 }
 
-static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
         glEnable(GL_SCISSOR_TEST);
         checkGLcall("glEnable(GL_SCISSOR_TEST)");
     if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
         glEnable(GL_SCISSOR_TEST);
         checkGLcall("glEnable(GL_SCISSOR_TEST)");
@@ -1586,7 +1636,8 @@ static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD
     }
 }
 
     }
 }
 
-static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1605,7 +1656,8 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
     if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
@@ -1615,31 +1667,36 @@ static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
         FIXME(" Stippled Alpha not supported yet.\n");
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
         FIXME(" Stippled Alpha not supported yet.\n");
 }
 
-static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_ANTIALIAS])
         FIXME(" Antialias not supported yet.\n");
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_ANTIALIAS])
         FIXME(" Antialias not supported yet.\n");
 }
 
-static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
         FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
         FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
 }
 
-static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
         FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
         FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
 }
 
-static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1659,109 +1716,127 @@ static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
         FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
         FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
 }
 
-static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
         FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
 }
 
     TRACE("Stub\n");
     if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
         FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
 }
 
-static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     TRACE("Stub\n");
     if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
         FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
 }
 
     TRACE("Stub\n");
     if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
         FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
 }
 
-static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_WRAPU]) {
         FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_WRAPU]) {
         FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
     }
 }
 
-static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_WRAPV]) {
         FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_WRAPV]) {
         FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
     }
 }
 
-static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
     }
 }
 
-static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_ROP2]) {
         FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_ROP2]) {
         FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
     }
 }
 
-static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
     }
 }
 
-static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
     }
 }
 
-static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
     }
 }
 
-static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
     }
 }
 
-static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
         FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
         FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
     }
 }
 
-static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
     }
 }
 
-static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
     }
 }
 
-static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
     }
 }
 
-static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
     }
 }
 
-static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_EXTENTS]) {
         FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
     }
 }
 
     if(stateblock->renderState[WINED3DRS_EXTENTS]) {
         FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
     }
 }
 
-static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
     }
     if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
     }
@@ -1815,7 +1890,8 @@ static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* op
 }
 
 /* Setup the texture operations texture stage states */
 }
 
 /* Setup the texture operations texture stage states */
-static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *iface,
+        BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
 {
     GLenum src1, src2, src3;
     GLenum opr1, opr2, opr3;
 {
     GLenum src1, src2, src3;
     GLenum opr1, opr2, opr3;
@@ -1826,7 +1902,6 @@ static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTE
     GLenum opr=0, invopr, src3_target, opr3_target;
     BOOL Handled = FALSE;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLenum opr=0, invopr, src3_target, opr3_target;
     BOOL Handled = FALSE;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* for GLINFO_LOCATION */
 
     TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
 
 
     TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
 
@@ -2840,7 +2915,8 @@ static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTE
 }
 
 
 }
 
 
-static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
@@ -2891,14 +2967,15 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
     }
 
         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
     }
 
-    set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
+    set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
                 stateblock->textureState[stage][WINED3DTSS_COLOROP],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
 }
 
                 stateblock->textureState[stage][WINED3DTSS_COLOROP],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
                 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
 }
 
-void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
@@ -2992,12 +3069,13 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext
                          mapped_stage,
                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
     } else {
                          mapped_stage,
                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
     } else {
-        set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
+        set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
                     op, arg1, arg2, arg0);
     }
 }
 
                     op, arg1, arg2, arg0);
     }
 }
 
-static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
     BOOL generated;
     DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
     BOOL generated;
@@ -3022,7 +3100,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
 
     set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
             stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw,
 
     set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
             stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw,
-            stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].stride
+            stateblock->wineD3DDevice->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
             ? stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format
             : WINED3DFMT_UNKNOWN,
             stateblock->wineD3DDevice->frag_pipe->ffp_proj_control);
             ? stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format
             : WINED3DFMT_UNKNOWN,
             stateblock->wineD3DDevice->frag_pipe->ffp_proj_control);
@@ -3033,8 +3111,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
         if(generated) {
             FIXME("Non-power2 texture being used with generated texture coords\n");
         }
         if(generated) {
             FIXME("Non-power2 texture being used with generated texture coords\n");
         }
-        /* NP2 texcoord fixup is implemented for pixelshaders (currently only in GLSL backend) so
-           only enable the fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
+        /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
+           fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
         if (!use_ps(stateblock)) {
             TRACE("Non power two matrix multiply fixup\n");
             glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
         if (!use_ps(stateblock)) {
             TRACE("Non power two matrix multiply fixup\n");
             glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
@@ -3042,7 +3120,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
+static void unloadTexCoords(const struct wined3d_context *context)
+{
     unsigned int texture_idx;
 
     for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
     unsigned int texture_idx;
 
     for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
@@ -3051,7 +3130,8 @@ static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
     }
 }
 
     }
 }
 
-static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si, GLuint *curVBO)
+static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
+        const struct wined3d_stream_info *si, GLuint *curVBO)
 {
     const UINT *offset = stateblock->streamOffset;
     unsigned int mapped_stage = 0;
 {
     const UINT *offset = stateblock->streamOffset;
     unsigned int mapped_stage = 0;
@@ -3059,14 +3139,14 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const struct wined
 
     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
 
     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
-        const struct wined3d_stream_info_element *e;
 
         mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
         if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
 
 
         mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
         if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
 
-        e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
-        if (coordIdx < MAX_TEXTURES && (e->data || e->buffer_object))
+        if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
         {
         {
+            const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+
             TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
                     textureNo, mapped_stage, coordIdx, e->data);
 
             TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
                     textureNo, mapped_stage, coordIdx, e->data);
 
@@ -3098,13 +3178,14 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const struct wined
     checkGLcall("loadTexCoords");
 }
 
     checkGLcall("loadTexCoords");
 }
 
-static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
-    static const GLfloat s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
-    static const GLfloat t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
-    static const GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
-    static const GLfloat q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
+    static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
+    static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
+    static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
+    static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
 
     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
     {
 
     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
     {
@@ -3266,12 +3347,13 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
          */
         GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
 
          */
         GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
 
-        unloadTexCoords(stateblock);
-        loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
+        unloadTexCoords(context);
+        loadTexCoords(context, stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
     }
 }
 
     }
 }
 
-static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
@@ -3282,14 +3364,16 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
        return;
     }
 
        return;
     }
 
-    device->shader_backend->shader_load_constants((IWineD3DDevice *)device, use_ps(stateblock), use_vs(stateblock));
+    device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock));
 }
 
 }
 
-static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
 
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
 
-    if(stateblock->pixelShader && stage != 0 &&
-       ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
+    if (stateblock->pixelShader && stage != 0
+            && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.luminanceparams & (1 << stage)))
+    {
         /* The pixel shader has to know the luminance scale. Do a constants update if it
          * isn't scheduled anyway
          */
         /* The pixel shader has to know the luminance scale. Do a constants update if it
          * isn't scheduled anyway
          */
@@ -3300,7 +3384,8 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     const DWORD sampler = state - STATE_SAMPLER(0);
     IWineD3DBaseTexture *texture = stateblock->textures[sampler];
 
     const DWORD sampler = state - STATE_SAMPLER(0);
     IWineD3DBaseTexture *texture = stateblock->textures[sampler];
 
@@ -3308,7 +3393,7 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, W
 
     if(!texture) return;
     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
 
     if(!texture) return;
     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
-     * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
+     * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
      * scaling is reapplied or removed, the texture matrix has to be reapplied
      *
      * The mapped stage is already active because the sampler() function below, which is part of the
      * scaling is reapplied or removed, the texture matrix has to be reapplied
      *
      * The mapped stage is already active because the sampler() function below, which is part of the
@@ -3326,7 +3411,8 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
     union {
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
     union {
@@ -3356,7 +3442,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
         IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
         tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB);
         IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
         IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
         tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB);
         IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
-        IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
+        basetexture_apply_state_changes(stateblock->textures[sampler],
+                stateblock->textureState[sampler], stateblock->samplerState[sampler]);
 
         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
 
         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
@@ -3376,8 +3463,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
             }
         }
 
             }
         }
 
-        /* Trigger shader constant reloading (for NP2 texcoord fixup)
-         * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */
+        /* Trigger shader constant reloading (for NP2 texcoord fixup) */
         if (!tex_impl->baseTexture.pow2Matrix_identity) {
             IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice;
             d3ddevice->shader_backend->shader_load_np2fixup_constants(
         if (!tex_impl->baseTexture.pow2Matrix_identity) {
             IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice;
             d3ddevice->shader_backend->shader_load_np2fixup_constants(
@@ -3398,7 +3484,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
     }
 }
 
     }
 }
 
-void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_pshader = use_ps(stateblock);
     BOOL use_vshader = use_vs(stateblock);
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_pshader = use_ps(stateblock);
     BOOL use_vshader = use_vs(stateblock);
@@ -3435,7 +3522,7 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     }
 
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
     }
 
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
-        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
+        device->shader_backend->shader_select(context, use_pshader, use_vshader);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
@@ -3443,10 +3530,12 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DC
     }
 }
 
     }
 }
 
-static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
-    if(stateblock->pixelShader && stage != 0 &&
-       ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
+    if (stateblock->pixelShader && stage != 0
+            && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.bumpmat & (1 << stage)))
+    {
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
          * anyway
          */
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
          * anyway
          */
@@ -3457,7 +3546,8 @@ static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     /* This function is called by transform_view below if the view matrix was changed too
      *
      * Deliberately no check if the vertex declaration is dirty because the vdecl state
     /* This function is called by transform_view below if the view matrix was changed too
      *
      * Deliberately no check if the vertex declaration is dirty because the vdecl state
@@ -3485,7 +3575,8 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
     }
 }
 
-static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     UINT index = state - STATE_CLIPPLANE(0);
 
     if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
     UINT index = state - STATE_CLIPPLANE(0);
 
     if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
@@ -3493,9 +3584,20 @@ static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     }
 
     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
     }
 
     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
+    if(!use_vs(stateblock)) {
+        glMatrixMode(GL_MODELVIEW);
+        glPushMatrix();
+        glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
+    } else {
+        /* with vertex shaders, clip planes are not transformed in direct3d,
+         * in OpenGL they are still transformed by the model view.
+         * Use this to swap the y coordinate if necessary
+         */
+        glMatrixMode(GL_MODELVIEW);
+        glPushMatrix();
+        glLoadIdentity();
+        if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
+    }
 
     TRACE("Clipplane [%f,%f,%f,%f]\n",
           stateblock->clipplane[index][0],
 
     TRACE("Clipplane [%f,%f,%f,%f]\n",
           stateblock->clipplane[index][0],
@@ -3508,7 +3610,8 @@ static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     glPopMatrix();
 }
 
     glPopMatrix();
 }
 
-static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
     GLenum glMat;
     TRACE("Setting world matrix %d\n", matrix);
     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
     GLenum glMat;
     TRACE("Setting world matrix %d\n", matrix);
@@ -3547,7 +3650,8 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     static BOOL once = FALSE;
 
     switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
     static BOOL once = FALSE;
 
     switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
@@ -3566,7 +3670,8 @@ static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
 
     switch(val) {
     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
 
     switch(val) {
@@ -3608,7 +3713,8 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     unsigned int k;
 
     /* If we are changing the View matrix, reset the light and clipping planes to the new view
     unsigned int k;
 
     /* If we are changing the View matrix, reset the light and clipping planes to the new view
@@ -3665,7 +3771,8 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine
     }
 }
 
     }
 }
 
-static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
@@ -3704,7 +3811,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
              * problem either.
              */
             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
              * problem either.
              */
             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
-            if(stateblock->wineD3DDevice->render_offscreen) {
+            if (context->render_offscreen)
+            {
                 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
             } else {
                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
                 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
             } else {
                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
@@ -3718,7 +3826,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
              * replacement shader.
              */
             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
              * replacement shader.
              */
             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
-            if(stateblock->wineD3DDevice->render_offscreen) {
+            if (context->render_offscreen)
+            {
                 glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
             } else {
                 glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
                 glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
             } else {
                 glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
@@ -3727,12 +3836,14 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
         checkGLcall("glOrtho");
 
         /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
         checkGLcall("glOrtho");
 
         /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
-        glTranslatef(0.5, 0.5, 0);
-        checkGLcall("glTranslatef(0.5, 0.5, 0)");
+        glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
+        checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
+
         /* D3D texture coordinates are flipped compared to OpenGL ones, so
          * render everything upside down when rendering offscreen. */
         /* D3D texture coordinates are flipped compared to OpenGL ones, so
          * render everything upside down when rendering offscreen. */
-        if (stateblock->wineD3DDevice->render_offscreen) {
-            glScalef(1.0, -1.0, 1.0);
+        if (context->render_offscreen)
+        {
+            glScalef(1.0f, -1.0f, 1.0f);
             checkGLcall("glScalef");
         }
     } else {
             checkGLcall("glScalef");
         }
     } else {
@@ -3773,16 +3884,24 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
          * glScalef(1.0, flip, 2.0);
          */
 
          * glScalef(1.0, flip, 2.0);
          */
 
-        if (stateblock->wineD3DDevice->render_offscreen) {
+        /* Translate by slightly less than a half pixel to force a top-left
+         * filling convention. We want the difference to be large enough that
+         * it doesn't get lost due to rounding inside the driver, but small
+         * enough to prevent it from interfering with any anti-aliasing. */
+        GLfloat xoffset = (63.0f / 64.0f) / stateblock->viewport.Width;
+        GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
+
+        if (context->render_offscreen)
+        {
             /* D3D texture coordinates are flipped compared to OpenGL ones, so
              * render everything upside down when rendering offscreen. */
             /* D3D texture coordinates are flipped compared to OpenGL ones, so
              * render everything upside down when rendering offscreen. */
-            glTranslatef(1.0 / stateblock->viewport.Width, 1.0 / stateblock->viewport.Height, -1.0);
-            checkGLcall("glTranslatef(1.0 / width, 1.0 / height, -1.0)");
-            glScalef(1.0, -1.0, 2.0);
+            glTranslatef(xoffset, -yoffset, -1.0f);
+            checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
+            glScalef(1.0f, -1.0f, 2.0f);
         } else {
         } else {
-            glTranslatef(1.0 / stateblock->viewport.Width, -1.0 / stateblock->viewport.Height, -1.0);
-            checkGLcall("glTranslatef(1.0 / width, -1.0 / height, -1.0)");
-            glScalef(1.0, 1.0, 2.0);
+            glTranslatef(xoffset, yoffset, -1.0f);
+            checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
+            glScalef(1.0f, 1.0f, 2.0f);
         }
         checkGLcall("glScalef");
 
         }
         checkGLcall("glScalef");
 
@@ -3795,7 +3914,8 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
  * stateblock impl is required for GL_SUPPORT
  * TODO: Only load / unload arrays if we have to.
  */
  * stateblock impl is required for GL_SUPPORT
  * TODO: Only load / unload arrays if we have to.
  */
-static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
+static inline void unloadVertexData(const struct wined3d_context *context)
+{
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_NORMAL_ARRAY);
     glDisableClientState(GL_COLOR_ARRAY);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_NORMAL_ARRAY);
     glDisableClientState(GL_COLOR_ARRAY);
@@ -3805,21 +3925,13 @@ static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
     }
     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
     }
-    unloadTexCoords(stateblock);
+    unloadTexCoords(context);
 }
 
 }
 
-static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, WineD3DContext *context, int i)
+static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i)
 {
     GL_EXTCALL(glDisableVertexAttribArrayARB(i));
     checkGLcall("glDisableVertexAttribArrayARB(reg)");
 {
     GL_EXTCALL(glDisableVertexAttribArrayARB(i));
     checkGLcall("glDisableVertexAttribArrayARB(reg)");
-    /* Some Windows drivers(NV GF 7) use the latest value that was used when drawing with the now
-     * deactivated stream disabled, some other drivers(ATI, NV GF 8) set the undefined values to 0x00.
-     * Let's set them to 0x00 to avoid hitting some undefined aspects of OpenGL. All that is really
-     * important here is the glDisableVertexAttribArrayARB call above. The test shows that the refrast
-     * keeps dereferencing the pointers, which would cause crashes in some games like Half Life 2: Episode Two.
-     */
-    GL_EXTCALL(glVertexAttrib4NubARB(i, 0, 0, 0, 0));
-    checkGLcall("glVertexAttrib4NubARB(i, 0, 0, 0, 0)");
 
     context->numbered_array_mask &= ~(1 << i);
 }
 
     context->numbered_array_mask &= ~(1 << i);
 }
@@ -3827,7 +3939,7 @@ static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, Win
 /* This should match any arrays loaded in loadNumberedArrays
  * TODO: Only load / unload arrays if we have to.
  */
 /* This should match any arrays loaded in loadNumberedArrays
  * TODO: Only load / unload arrays if we have to.
  */
-static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineD3DContext *context)
+static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
 {
     /* disable any attribs (this is the same for both GLSL and ARB modes) */
     GLint maxAttribs = 16;
 {
     /* disable any attribs (this is the same for both GLSL and ARB modes) */
     GLint maxAttribs = 16;
@@ -3844,7 +3956,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, Wine
 }
 
 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
 }
 
 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
-        const struct wined3d_stream_info *stream_info, WineD3DContext *context)
+        const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
 {
     GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
     int i;
 {
     GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
     int i;
@@ -4018,7 +4130,8 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
 }
 
 /* Used from 2 different functions, and too big to justify making it inlined */
 }
 
 /* Used from 2 different functions, and too big to justify making it inlined */
-static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si)
+static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
+        const struct wined3d_stream_info *si)
 {
     const UINT *offset = stateblock->streamOffset;
     GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
 {
     const UINT *offset = stateblock->streamOffset;
     GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
@@ -4030,11 +4143,11 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     /* Blend Data ---------------------------------------------- */
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     /* Blend Data ---------------------------------------------- */
-    e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
-    if (e->data || e->buffer_object
-            || si->elements[WINED3D_FFP_BLENDINDICES].data
-            || si->elements[WINED3D_FFP_BLENDINDICES].buffer_object)
+    if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
+            || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
     {
     {
+        e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
+
         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
             TRACE("Blend %d %p %d\n", e->format_desc->component_count,
                     e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]);
         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
             TRACE("Blend %d %p %d\n", e->format_desc->component_count,
                     e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]);
@@ -4061,8 +4174,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
 
             checkGLcall("glWeightPointerARB");
 
 
             checkGLcall("glWeightPointerARB");
 
-            if (si->elements[WINED3D_FFP_BLENDINDICES].data
-                    || (si->elements[WINED3D_FFP_BLENDINDICES].buffer_object))
+            if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
             {
                 static BOOL warned;
                 if (!warned)
             {
                 static BOOL warned;
                 if (!warned)
@@ -4086,8 +4198,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     }
 
     /* Point Size ----------------------------------------------*/
     }
 
     /* Point Size ----------------------------------------------*/
-    e = &si->elements[WINED3D_FFP_PSIZE];
-    if (e->data || e->buffer_object)
+    if (si->use_map & (1 << WINED3D_FFP_PSIZE))
     {
         /* no such functionality in the fixed function GL pipeline */
         TRACE("Cannot change ptSize here in openGl\n");
     {
         /* no such functionality in the fixed function GL pipeline */
         TRACE("Cannot change ptSize here in openGl\n");
@@ -4095,11 +4206,11 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     }
 
     /* Vertex Pointers -----------------------------------------*/
     }
 
     /* Vertex Pointers -----------------------------------------*/
-    e = &si->elements[WINED3D_FFP_POSITION];
-    if (e->data || e->buffer_object)
+    if (si->use_map & (1 << WINED3D_FFP_POSITION))
     {
         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data));
 
     {
         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data));
 
+        e = &si->elements[WINED3D_FFP_POSITION];
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
@@ -4129,10 +4240,11 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     }
 
     /* Normals -------------------------------------------------*/
     }
 
     /* Normals -------------------------------------------------*/
-    e = &si->elements[WINED3D_FFP_NORMAL];
-    if (e->data || e->buffer_object)
+    if (si->use_map & (1 << WINED3D_FFP_NORMAL))
     {
         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data));
     {
         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data));
+
+        e = &si->elements[WINED3D_FFP_NORMAL];
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
@@ -4159,11 +4271,11 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     /* NOTE: Unless we write a vertex shader to swizzle the colour*/
     /* , or the user doesn't care and wants the speed advantage   */
 
     /* NOTE: Unless we write a vertex shader to swizzle the colour*/
     /* , or the user doesn't care and wants the speed advantage   */
 
-    e = &si->elements[WINED3D_FFP_DIFFUSE];
-    if (e->data || e->buffer_object)
+    if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
     {
         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
 
     {
         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
 
+        e = &si->elements[WINED3D_FFP_DIFFUSE];
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
         if (curVBO != e->buffer_object)
         {
             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
@@ -4183,22 +4295,52 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     }
 
     /* Specular Colour ------------------------------------------*/
     }
 
     /* Specular Colour ------------------------------------------*/
-    e = &si->elements[WINED3D_FFP_SPECULAR];
-    if (e->data || e->buffer_object)
+    if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
     {
         TRACE("setting specular colour\n");
         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
 
     {
         TRACE("setting specular colour\n");
         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
 
+        e = &si->elements[WINED3D_FFP_SPECULAR];
         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+            GLenum type = e->format_desc->gl_vtx_type;
+            GLint format = e->format_desc->gl_vtx_format;
+
             if (curVBO != e->buffer_object)
             {
                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
                 checkGLcall("glBindBufferARB");
                 curVBO = e->buffer_object;
             }
             if (curVBO != e->buffer_object)
             {
                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
                 checkGLcall("glBindBufferARB");
                 curVBO = e->buffer_object;
             }
-            GL_EXTCALL(glSecondaryColorPointerEXT)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type,
-                    e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
-            checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
+
+            if(format != 4 || (GLINFO_LOCATION.quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
+            {
+                /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
+                 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
+                 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
+                 * 4 component secondary colors use it
+                 */
+                GL_EXTCALL(glSecondaryColorPointerEXT)(format, type,
+                        e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
+            }
+            else
+            {
+                switch(type)
+                {
+                    case GL_UNSIGNED_BYTE:
+                        GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE,
+                                e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                        checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
+                        break;
+
+                    default:
+                        FIXME("Add 4 component specular color pointers for type %x\n", type);
+                        /* Make sure that the right color component is dropped */
+                        GL_EXTCALL(glSecondaryColorPointerEXT)(3, type,
+                                e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                        checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
+                }
+            }
             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
         } else {
             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
         } else {
@@ -4219,7 +4361,7 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
     }
 
     /* Texture coords -------------------------------------------*/
     }
 
     /* Texture coords -------------------------------------------*/
-    loadTexCoords(stateblock, si, &curVBO);
+    loadTexCoords(context, stateblock, si, &curVBO);
 }
 
 static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
 }
 
 static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
@@ -4245,7 +4387,8 @@ static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_i
     return;
 }
 
     return;
 }
 
-static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL fixup = FALSE;
     struct wined3d_stream_info *dataLocations = &device->strided_streams;
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL fixup = FALSE;
     struct wined3d_stream_info *dataLocations = &device->strided_streams;
@@ -4284,18 +4427,23 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
             device->useDrawStridedSlow = FALSE;
         }
     }
             device->useDrawStridedSlow = FALSE;
         }
     }
-    else if (fixup || (!dataLocations->elements[WINED3D_FFP_PSIZE].data
-            && !dataLocations->position_transformed
-            && (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA)
-            || (!dataLocations->elements[WINED3D_FFP_DIFFUSE].data
-            && !dataLocations->elements[WINED3D_FFP_SPECULAR].data))))
+    else
     {
     {
-        /* Load the vertex data using named arrays */
-        load_named = TRUE;
-        device->useDrawStridedSlow = FALSE;
-    } else {
-        TRACE("Not loading vertex data\n");
-        device->useDrawStridedSlow = TRUE;
+        WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
+        slow_mask |= -!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
+
+        if (fixup || (!dataLocations->position_transformed
+                && !(dataLocations->use_map & slow_mask)))
+        {
+            /* Load the vertex data using named arrays */
+            load_named = TRUE;
+            device->useDrawStridedSlow = FALSE;
+        }
+        else
+        {
+            TRACE("Not loading vertex data\n");
+            device->useDrawStridedSlow = TRUE;
+        }
     }
 
     if (context->numberedArraysLoaded && !load_numbered)
     }
 
     if (context->numberedArraysLoaded && !load_numbered)
@@ -4306,7 +4454,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     }
     else if (context->namedArraysLoaded)
     {
     }
     else if (context->namedArraysLoaded)
     {
-        unloadVertexData(stateblock);
+        unloadVertexData(context);
         context->namedArraysLoaded = FALSE;
     }
 
         context->namedArraysLoaded = FALSE;
     }
 
@@ -4319,12 +4467,13 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
     else if (load_named)
     {
         TRACE("Loading vertex data\n");
     else if (load_named)
     {
         TRACE("Loading vertex data\n");
-        loadVertexData(stateblock, dataLocations);
+        loadVertexData(context, stateblock, dataLocations);
         context->namedArraysLoaded = TRUE;
     }
 }
 
         context->namedArraysLoaded = TRUE;
     }
 }
 
-static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     BOOL updateFog = FALSE;
     BOOL useVertexShaderFunction = use_vs(stateblock);
     BOOL usePixelShaderFunction = use_ps(stateblock);
     BOOL updateFog = FALSE;
     BOOL useVertexShaderFunction = use_vs(stateblock);
     BOOL usePixelShaderFunction = use_ps(stateblock);
@@ -4332,6 +4481,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
     /* Some stuff is in the device until we have per context tracking */
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL wasrhw = context->last_was_rhw;
+    unsigned int i;
 
     transformed = device->strided_streams.position_transformed;
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
 
     transformed = device->strided_streams.position_transformed;
     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
@@ -4359,9 +4509,11 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
         /* This sets the shader output position correction constants.
          * TODO: Move to the viewport state
          */
         /* This sets the shader output position correction constants.
          * TODO: Move to the viewport state
          */
-        if (useVertexShaderFunction) {
-            device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
-            device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
+        if (useVertexShaderFunction)
+        {
+            GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
+            device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
+            device->posFixup[3] = device->posFixup[1] * yoffset;
         }
     }
 
         }
     }
 
@@ -4400,28 +4552,32 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
 
         if(context->last_was_vshader) {
             updateFog = TRUE;
 
         if(context->last_was_vshader) {
             updateFog = TRUE;
-            if(!isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
+            if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
                 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
             }
                 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
             }
+            for(i = 0; i < GL_LIMITS(clipplanes); i++) {
+                clipplane(STATE_CLIPPLANE(i), stateblock, context);
+            }
         }
         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
         }
     } else {
         if(!context->last_was_vshader) {
         }
         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
         }
     } else {
         if(!context->last_was_vshader) {
-            unsigned int i;
             static BOOL warned = FALSE;
             static BOOL warned = FALSE;
-            /* Disable all clip planes to get defined results on all drivers. See comment in the
-             * state_clipping state handler
-             */
-            for(i = 0; i < GL_LIMITS(clipplanes); i++) {
-                glDisable(GL_CLIP_PLANE0 + i);
-                checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
-            }
+            if(!device->vs_clipping) {
+                /* Disable all clip planes to get defined results on all drivers. See comment in the
+                 * state_clipping state handler
+                 */
+                for(i = 0; i < GL_LIMITS(clipplanes); i++) {
+                    glDisable(GL_CLIP_PLANE0 + i);
+                    checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
+                }
 
 
-            if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
-                FIXME("Clipping not supported with vertex shaders\n");
-                warned = TRUE;
+                if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
+                    FIXME("Clipping not supported with vertex shaders\n");
+                    warned = TRUE;
+                }
             }
             if(wasrhw) {
                 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
             }
             if(wasrhw) {
                 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
@@ -4437,6 +4593,14 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
                 }
             }
             updateFog = TRUE;
                 }
             }
             updateFog = TRUE;
+
+            /* Vertex shader clipping ignores the view matrix. Update all clipplanes
+             * (Note: ARB shaders can read the clip planes for clipping emulation even if
+             * device->vs_clipping is false.
+             */
+            for(i = 0; i < GL_LIMITS(clipplanes); i++) {
+                clipplane(STATE_CLIPPLANE(i), stateblock, context);
+            }
         }
     }
 
         }
     }
 
@@ -4444,7 +4608,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
      * application
      */
     if (!isStateDirty(context, STATE_PIXELSHADER)) {
      * application
      */
     if (!isStateDirty(context, STATE_PIXELSHADER)) {
-        device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
+        device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
@@ -4466,7 +4630,8 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
     }
 }
 
-static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     UINT width, height;
     IWineD3DSurfaceImpl *target;
 
     UINT width, height;
     IWineD3DSurfaceImpl *target;
 
@@ -4474,13 +4639,14 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     checkGLcall("glDepthRange");
     /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
      */
     checkGLcall("glDepthRange");
     /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
      */
-    if(stateblock->wineD3DDevice->render_offscreen) {
+    if (context->render_offscreen)
+    {
         glViewport(stateblock->viewport.X,
                    stateblock->viewport.Y,
                    stateblock->viewport.Width, stateblock->viewport.Height);
     } else {
         target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
         glViewport(stateblock->viewport.X,
                    stateblock->viewport.Y,
                    stateblock->viewport.Width, stateblock->viewport.Height);
     } else {
         target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
-        target->get_drawable_size(target, &width, &height);
+        target->get_drawable_size(context, &width, &height);
 
         glViewport(stateblock->viewport.X,
                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
 
         glViewport(stateblock->viewport.X,
                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
@@ -4490,9 +4656,13 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, W
     checkGLcall("glViewport");
 }
 
     checkGLcall("glViewport");
 }
 
-static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
-    stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height;
+static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+    GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
+
+    stateblock->wineD3DDevice->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width;
+    stateblock->wineD3DDevice->posFixup[3] = stateblock->wineD3DDevice->posFixup[1] * yoffset;
+
     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
     }
     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
     }
@@ -4501,7 +4671,8 @@ static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     UINT Index = state - STATE_ACTIVELIGHT(0);
     const PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
 
     UINT Index = state - STATE_ACTIVELIGHT(0);
     const PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
 
@@ -4510,7 +4681,7 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
         checkGLcall("glDisable(GL_LIGHT0 + Index)");
     } else {
         float quad_att;
         checkGLcall("glDisable(GL_LIGHT0 + Index)");
     } else {
         float quad_att;
-        float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
+        float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
 
         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
         glMatrixMode(GL_MODELVIEW);
 
         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
         glMatrixMode(GL_MODELVIEW);
@@ -4542,9 +4713,9 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
         checkGLcall("glLightfv");
 
         if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
         checkGLcall("glLightfv");
 
         if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
-            quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
+            quad_att = 1.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
         } else {
         } else {
-            quad_att = 0; /*  0 or  MAX?  (0 seems to be ok) */
+            quad_att = 0.0f; /*  0 or  MAX?  (0 seems to be ok) */
         }
 
         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
         }
 
         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
@@ -4616,20 +4787,22 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContex
     return;
 }
 
     return;
 }
 
-static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     RECT *pRect = &stateblock->scissorRect;
     UINT height;
     UINT width;
     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
 
     RECT *pRect = &stateblock->scissorRect;
     UINT height;
     UINT width;
     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
 
-    target->get_drawable_size(target, &width, &height);
+    target->get_drawable_size(context, &width, &height);
     /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
      * Warning2: Even in windowed mode the coords are relative to the window, not the screen
      */
     TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
           pRect->right - pRect->left, pRect->bottom - pRect->top);
 
     /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
      * Warning2: Even in windowed mode the coords are relative to the window, not the screen
      */
     TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
           pRect->right - pRect->left, pRect->bottom - pRect->top);
 
-    if (stateblock->wineD3DDevice->render_offscreen) {
+    if (context->render_offscreen)
+    {
         glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
     } else {
         glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
         glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
     } else {
         glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
@@ -4637,7 +4810,8 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     checkGLcall("glScissor");
 }
 
     checkGLcall("glScissor");
 }
 
-static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
     } else {
     if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
     } else {
@@ -4646,8 +4820,10 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     }
 }
 
     }
 }
 
-static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    if(stateblock->wineD3DDevice->render_offscreen) {
+static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
+    if (context->render_offscreen)
+    {
         glFrontFace(GL_CCW);
         checkGLcall("glFrontFace(GL_CCW)");
     } else {
         glFrontFace(GL_CCW);
         checkGLcall("glFrontFace(GL_CCW)");
     } else {
@@ -4657,689 +4833,692 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo
 }
 
 const struct StateEntryTemplate misc_state_template[] = {
 }
 
 const struct StateEntryTemplate misc_state_template[] = {
-    { STATE_RENDER(WINED3DRS_SRCBLEND),                   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_DESTBLEND),                  { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_EDGEANTIALIAS),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE),      { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_SRCBLENDALPHA),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_RENDER(WINED3DRS_BLENDOPALPHA),               { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
-    { STATE_STREAMSRC,                                    { STATE_VDECL,                                        streamsrc           }, 0                               },
-    { STATE_VDECL,                                        { STATE_VDECL,                                        streamsrc           }, 0                               },
-    { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, 0                               },
-    { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, 0                               },
+    { STATE_RENDER(WINED3DRS_SRCBLEND),                   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DESTBLEND),                  { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_EDGEANTIALIAS),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE),      { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SRCBLENDALPHA),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_BLENDOPALPHA),               { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, WINED3D_GL_EXT_NONE             },
+    { STATE_STREAMSRC,                                    { STATE_VDECL,                                        streamsrc           }, WINED3D_GL_EXT_NONE             },
+    { STATE_VDECL,                                        { STATE_VDECL,                                        streamsrc           }, WINED3D_GL_EXT_NONE             },
+    { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, WINED3D_GL_EXT_NONE             },
+    { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, WINED3D_GL_EXT_NONE             },
     /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
      * vshader loadings are untied from each other
      */
     /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
      * vshader loadings are untied from each other
      */
-    { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, 0                               },
-    { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
-
-    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, 0                               },
+    { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, WINED3D_GL_EXT_NONE             },
+    { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
+
+    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, WINED3D_GL_EXT_NONE             },
     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
-    { STATE_RENDER(WINED3DRS_ANTIALIAS),                  { STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     }, 0                               },
-    { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   }, 0                               },
-    { STATE_RENDER(WINED3DRS_ZENABLE),                    { STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAPU),                      { STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAPV),                      { STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         }, 0                               },
-    { STATE_RENDER(WINED3DRS_FILLMODE),                   { STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      }, 0                               },
-    { STATE_RENDER(WINED3DRS_SHADEMODE),                  { STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     }, 0                               },
-    { STATE_RENDER(WINED3DRS_LINEPATTERN),                { STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   }, 0                               },
-    { STATE_RENDER(WINED3DRS_MONOENABLE),                 { STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    }, 0                               },
-    { STATE_RENDER(WINED3DRS_ROP2),                       { STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          }, 0                               },
-    { STATE_RENDER(WINED3DRS_PLANEMASK),                  { STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     }, 0                               },
-    { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   }, 0                               },
-    { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
-    { STATE_RENDER(WINED3DRS_ALPHAREF),                   { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
-    { STATE_RENDER(WINED3DRS_ALPHAFUNC),                  { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORKEYENABLE),             { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
-    { STATE_RENDER(WINED3DRS_LASTPIXEL),                  { STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     }, 0                               },
-    { STATE_RENDER(WINED3DRS_CULLMODE),                   { STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      }, 0                               },
-    { STATE_RENDER(WINED3DRS_ZFUNC),                      { STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         }, 0                               },
-    { STATE_RENDER(WINED3DRS_DITHERENABLE),               { STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  }, 0                               },
-    { STATE_RENDER(WINED3DRS_SUBPIXEL),                   { STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      }, 0                               },
-    { STATE_RENDER(WINED3DRS_SUBPIXELX),                  { STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     }, 0                               },
-    { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha }, 0                               },
-    { STATE_RENDER(WINED3DRS_ZBIAS),                      { STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         }, 0                               },
-    { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable }, 0                               },
-    { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias }, 0                               },
-    { STATE_RENDER(WINED3DRS_ANISOTROPY),                 { STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    }, 0                               },
-    { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    }, 0                               },
-    { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILENABLE),              { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILFAIL),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILZFAIL),               { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILPASS),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILFUNC),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILREF),                 { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_STENCILMASK),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
+    { STATE_RENDER(WINED3DRS_ANTIALIAS),                  { STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ZENABLE),                    { STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAPU),                      { STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAPV),                      { STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FILLMODE),                   { STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SHADEMODE),                  { STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_LINEPATTERN),                { STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_MONOENABLE),                 { STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ROP2),                       { STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_PLANEMASK),                  { STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ALPHAREF),                   { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ALPHAFUNC),                  { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORKEYENABLE),             { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_LASTPIXEL),                  { STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CULLMODE),                   { STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ZFUNC),                      { STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DITHERENABLE),               { STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SUBPIXEL),                   { STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SUBPIXELX),                  { STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ZBIAS),                      { STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ANISOTROPY),                 { STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILENABLE),              { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILFAIL),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILZFAIL),               { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILPASS),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILFUNC),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILREF),                 { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_STENCILMASK),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
     { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
-    { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  }, 0                               },
-    { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE),        { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL),           { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_CCW_STENCILPASS),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP0),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP1),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP2),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP3),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP4),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP5),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP6),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP7),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP8),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP9),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP10),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP11),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP12),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP13),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP14),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_WRAP15),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
-    { STATE_RENDER(WINED3DRS_EXTENTS),                    { STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     }, 0                               },
-    { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle}, 0                               },
-    { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments }, 0                               },
-    { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree}, 0                               },
-    { STATE_RENDER(WINED3DRS_NORMALDEGREE),               { STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  }, 0                               },
-    { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
-    { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
+    { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE),        { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL),           { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CCW_STENCILPASS),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP0),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP1),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP2),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP3),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP4),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP5),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP6),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP7),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP8),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP9),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP10),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP11),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP12),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP13),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP14),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_WRAP15),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_EXTENTS),                    { STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle}, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree}, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_NORMALDEGREE),               { STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa          }, ARB_MULTISAMPLE                 },
     { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa          }, ARB_MULTISAMPLE                 },
-    { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa_w        }, 0                               },
-    { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
+    { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa_w        }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN),          { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN),          state_debug_monitor }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       }, EXT_BLEND_MINMAX                },
     { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       }, EXT_BLEND_MINMAX                },
-    { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop_w     }, 0                               },
-    { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       }, 0                               },
-    { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS),        { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
+    { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop_w     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS),        { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   }, EXT_BLEND_COLOR                 },
     { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   }, EXT_BLEND_COLOR                 },
-    { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor_w }, 0                               },
-    { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, 0                               },
+    { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, WINED3D_GL_EXT_NONE             },
     /* Samplers */
     /* Samplers */
-    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, 0                               },
-    { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, 0                               },
-    { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
 const struct StateEntryTemplate ffp_vertexstate_template[] = {
 };
 
 const struct StateEntryTemplate ffp_vertexstate_template[] = {
-    { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, 0                               },
-    { STATE_VSHADER,                                      { STATE_VDECL,                                        vertexdeclaration   }, 0                               },
-    { STATE_MATERIAL,                                     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, 0                               },
-    { STATE_RENDER(WINED3DRS_SPECULARENABLE),             { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, 0                               },
+    { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
+    { STATE_VSHADER,                                      { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
+    { STATE_MATERIAL,                                     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SPECULARENABLE),             { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, WINED3D_GL_EXT_NONE             },
       /* Clip planes */
       /* Clip planes */
-    { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, 0                               },
-    { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, 0                               },
-    { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, 0                               },
+    { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, WINED3D_GL_EXT_NONE             },
+    { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, WINED3D_GL_EXT_NONE             },
       /* Lights */
       /* Lights */
-    { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, 0                               },
-    { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, 0                               },
+    { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, WINED3D_GL_EXT_NONE             },
+    { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, WINED3D_GL_EXT_NONE             },
     /* Viewport */
     /* Viewport */
-    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, 0                               },
+    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, WINED3D_GL_EXT_NONE             },
       /* Transform states follow                    */
       /* Transform states follow                    */
-    { STATE_TRANSFORM(WINED3DTS_VIEW),                    { STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_PROJECTION),              { STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection}, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        transform_world     }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_worldex   }, 0                               },
-    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_worldex   }, 0                               },
-    { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
+    { STATE_TRANSFORM(WINED3DTS_VIEW),                    { STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_PROJECTION),              { STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection}, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),  transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        transform_world     }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_worldex   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture   }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, WINED3D_GL_EXT_NONE             },
       /* Fog */
       /* Fog */
-    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
-    { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    }, 0                               },
-    { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
-    { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE),            { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
-    { STATE_RENDER(WINED3DRS_LIGHTING),                   { STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      }, 0                               },
-    { STATE_RENDER(WINED3DRS_AMBIENT),                    { STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       }, 0                               },
-    { STATE_RENDER(WINED3DRS_COLORVERTEX),                { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
-    { STATE_RENDER(WINED3DRS_LOCALVIEWER),                { STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   }, 0                               },
-    { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     }, 0                               },
-    { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
-    { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
-    { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
-    { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
+    { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE),            { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_LIGHTING),                   { STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_AMBIENT),                    { STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_COLORVERTEX),                { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_LOCALVIEWER),                { STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   }, ARB_VERTEX_BLEND                },
     { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   }, ARB_VERTEX_BLEND                },
-    { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend_w }, 0                               },
-    { STATE_RENDER(WINED3DRS_POINTSIZE),                  { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
+    { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend_w }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSIZE),                  { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
-    { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
+    { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   }, ARB_POINT_SPRITE                },
     { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   }, ARB_POINT_SPRITE                },
-    { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite_w }, 0                               },
-    { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
-    { STATE_RENDER(WINED3DRS_POINTSCALE_A),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
-    { STATE_RENDER(WINED3DRS_POINTSCALE_B),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
-    { STATE_RENDER(WINED3DRS_POINTSCALE_C),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
+    { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite_w }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSCALE_A),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSCALE_B),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSCALE_C),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
-    { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
+    { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, WINED3D_GL_EXT_NONE             },
     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
      */
     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
      */
     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, 0                               },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
-    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 
 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
 };
 
 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
-    { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
-    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
-    { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
-    { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }, 0                               },
-    { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
-    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, 0                               },
-    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, 0                               },
-    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, 0                               },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, WINED3D_GL_EXT_NONE             },
+    { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, WINED3D_GL_EXT_NONE             },
+    { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGSTART),                   state_fogstartend   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
 };
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION (*gl_info)
 };
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION (*gl_info)
+/* Context activation is done by the caller. */
 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
 
 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
 
-static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps)
+static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype,
+        const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
                             WINED3DTEXOPCAPS_ADDSIGNED   |
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
                             WINED3DTEXOPCAPS_ADDSIGNED   |
@@ -5414,19 +5593,21 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
     return i;
 }
 
     return i;
 }
 
-static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
 }
 
     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
 }
 
-static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
 }
 
 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
 }
 
 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
-        const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
+        const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
     unsigned int i, type, handlers;
         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
 {
     unsigned int i, type, handlers;
@@ -5468,7 +5649,7 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
              */
             if(set[cur[i].state]) continue;
             /* Skip state lines depending on unsupported extensions */
              */
             if(set[cur[i].state]) continue;
             /* Skip state lines depending on unsupported extensions */
-            if(cur[i].extension && !GL_SUPPORT(cur[i].extension)) continue;
+            if (!GL_SUPPORT(cur[i].extension)) continue;
             set[cur[i].state] = TRUE;
             /* In some cases having an extension means that nothing has to be
              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
             set[cur[i].state] = TRUE;
             /* In some cases having an extension means that nothing has to be
              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
index 1c9b5a8..239b777 100644 (file)
@@ -31,11 +31,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
  * Stateblock helper functions follow
  **************************************/
 
  * Stateblock helper functions follow
  **************************************/
 
-/** Allocates the correct amount of space for pixel and vertex shader constants, 
+/* Allocates the correct amount of space for pixel and vertex shader constants,
  * along with their set/changed flags on the given stateblock object
  */
  * along with their set/changed flags on the given stateblock object
  */
-HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) {
-    
+HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object)
+{
     IWineD3DStateBlockImpl *This = object;
 
     /* Allocate space for floating point constants */
     IWineD3DStateBlockImpl *This = object;
 
     /* Allocate space for floating point constants */
@@ -113,11 +113,8 @@ static inline void stateblock_set_bits(DWORD *map, UINT map_size)
 }
 
 /** Set all members of a stateblock savedstate to the given value */
 }
 
 /** Set all members of a stateblock savedstate to the given value */
-void stateblock_savedstates_set(
-    IWineD3DStateBlock* iface,
-    SAVEDSTATES* states,
-    BOOL value) {
-    
+void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states, BOOL value)
+{
     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
     unsigned bsize = sizeof(BOOL);
 
     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
     unsigned bsize = sizeof(BOOL);
 
@@ -228,7 +225,7 @@ void stateblock_copy(
     memcpy(Dest->vertexShaderConstantI, This->vertexShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
     memcpy(Dest->pixelShaderConstantB, This->pixelShaderConstantB, sizeof(BOOL) * MAX_CONST_B);
     memcpy(Dest->pixelShaderConstantI, This->pixelShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
     memcpy(Dest->vertexShaderConstantI, This->vertexShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
     memcpy(Dest->pixelShaderConstantB, This->pixelShaderConstantB, sizeof(BOOL) * MAX_CONST_B);
     memcpy(Dest->pixelShaderConstantI, This->pixelShaderConstantI, sizeof(INT) * MAX_CONST_I * 4);
-    
+
     memcpy(Dest->streamStride, This->streamStride, sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamOffset, This->streamOffset, sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DBuffer *) * MAX_STREAMS);
     memcpy(Dest->streamStride, This->streamStride, sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamOffset, This->streamOffset, sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DBuffer *) * MAX_STREAMS);
@@ -357,7 +354,7 @@ static inline void record_lights(IWineD3DStateBlockImpl *This, IWineD3DStateBloc
         LIST_FOR_EACH(e, &This->lightMap[i]) {
             BOOL updated = FALSE;
             PLIGHTINFOEL *src = LIST_ENTRY(e, PLIGHTINFOEL, entry), *realLight;
         LIST_FOR_EACH(e, &This->lightMap[i]) {
             BOOL updated = FALSE;
             PLIGHTINFOEL *src = LIST_ENTRY(e, PLIGHTINFOEL, entry), *realLight;
-            if(!src->changed || !src->enabledChanged) continue;
+            if (!src->changed && !src->enabledChanged) continue;
 
             /* Look up the light in the destination */
             LIST_FOR_EACH(f, &targetStateBlock->lightMap[i]) {
 
             /* Look up the light in the destination */
             LIST_FOR_EACH(f, &targetStateBlock->lightMap[i]) {
@@ -1087,9 +1084,6 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
     unsigned int i;
     IWineD3DSwapChain *swapchain;
     IWineD3DSurface *backbuffer;
     unsigned int i;
     IWineD3DSwapChain *swapchain;
     IWineD3DSurface *backbuffer;
-    WINED3DSURFACE_DESC desc = {0};
-    UINT width, height;
-    RECT scissorrect;
     HRESULT hr;
 
     /* Note this may have a large overhead but it should only be executed
     HRESULT hr;
 
     /* Note this may have a large overhead but it should only be executed
@@ -1292,28 +1286,27 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
         This->textures[i]         = NULL;
     }
 
         This->textures[i]         = NULL;
     }
 
-    /* Set the default scissor rect values */
-    desc.Width = &width;
-    desc.Height = &height;
-
     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
     hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
     if( hr == WINED3D_OK && swapchain != NULL) {
         WINED3DVIEWPORT vp;
 
         hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
     hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
     if( hr == WINED3D_OK && swapchain != NULL) {
         WINED3DVIEWPORT vp;
 
         hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
-        if( hr == WINED3D_OK && backbuffer != NULL) {
+        if (SUCCEEDED(hr) && backbuffer)
+        {
+            WINED3DSURFACE_DESC desc;
+            RECT scissorrect;
+
             IWineD3DSurface_GetDesc(backbuffer, &desc);
             IWineD3DSurface_Release(backbuffer);
 
             IWineD3DSurface_GetDesc(backbuffer, &desc);
             IWineD3DSurface_Release(backbuffer);
 
+            /* Set the default scissor rect values */
             scissorrect.left = 0;
             scissorrect.left = 0;
-            scissorrect.right = width;
+            scissorrect.right = desc.width;
             scissorrect.top = 0;
             scissorrect.top = 0;
-            scissorrect.bottom = height;
+            scissorrect.bottom = desc.height;
             hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
             hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
-            if( hr != WINED3D_OK ) {
-                ERR("This should never happen, expect rendering issues!\n");
-            }
+            if (FAILED(hr)) ERR("This should never happen, expect rendering issues!\n");
         }
 
         /* Set the default viewport */
         }
 
         /* Set the default viewport */
index 9e9d55c..cce613c 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 
-static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey);
-static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert);
-static void surface_remove_pbo(IWineD3DSurfaceImpl *This);
+#define GLINFO_LOCATION (*gl_info)
+
+static void surface_cleanup(IWineD3DSurfaceImpl *This)
+{
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    renderbuffer_entry_t *entry, *entry2;
+
+    TRACE("(%p) : Cleaning up.\n", This);
+
+    /* Need a context to destroy the texture. Use the currently active render
+     * target, but only if the primary render target exists. Otherwise
+     * lastActiveRenderTarget is garbage. When destroying the primary render
+     * target, Uninit3D() will activate a context before doing anything. */
+    if (device->render_targets && device->render_targets[0])
+    {
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    }
+
+    ENTER_GL();
+
+    if (This->texture_name)
+    {
+        /* Release the OpenGL texture. */
+        TRACE("Deleting texture %u.\n", This->texture_name);
+        glDeleteTextures(1, &This->texture_name);
+    }
+
+    if (This->Flags & SFLAG_PBO)
+    {
+        /* Delete the PBO. */
+        GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
+    }
+
+    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry)
+    {
+        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id));
+        HeapFree(GetProcessHeap(), 0, entry);
+    }
+
+    LEAVE_GL();
+
+    if (This->Flags & SFLAG_DIBSECTION)
+    {
+        /* Release the DC. */
+        SelectObject(This->hDC, This->dib.holdbitmap);
+        DeleteDC(This->hDC);
+        /* Release the DIB section. */
+        DeleteObject(This->dib.DIBsection);
+        This->dib.bitmap_data = NULL;
+        This->resource.allocatedMemory = NULL;
+    }
+
+    if (This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem((IWineD3DSurface *)This, NULL);
+    if (This->overlay_dest) list_remove(&This->overlay_entry);
+
+    HeapFree(GetProcessHeap(), 0, This->palette9);
+
+    resource_cleanup((IWineD3DResource *)This);
+}
+
+UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height)
+{
+    UINT size;
+
+    if (format_desc->format == WINED3DFMT_UNKNOWN)
+    {
+        size = 0;
+    }
+    else if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+    {
+        UINT row_block_count = (width + format_desc->block_width - 1) / format_desc->block_width;
+        UINT row_count = (height + format_desc->block_height - 1) / format_desc->block_height;
+        size = row_count * row_block_count * format_desc->block_byte_count;
+    }
+    else
+    {
+        /* The pitch is a multiple of 4 bytes. */
+        size = height * (((width * format_desc->byte_count) + alignment - 1) & ~(alignment - 1));
+    }
+
+    if (format_desc->heightscale != 0.0f) size *= format_desc->heightscale;
+
+    return size;
+}
+
+HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
+        UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
+        UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
+        WINED3DPOOL pool, IUnknown *parent)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &GLINFO_LOCATION);
+    void (*cleanup)(IWineD3DSurfaceImpl *This);
+    unsigned int resource_size;
+    HRESULT hr;
+
+    if (multisample_quality > 0)
+    {
+        FIXME("multisample_quality set to %u, substituting 0\n", multisample_quality);
+        multisample_quality = 0;
+    }
+
+    /* FIXME: Check that the format is supported by the device. */
+
+    resource_size = surface_calculate_size(format_desc, alignment, width, height);
+
+    /* Look at the implementation and set the correct Vtable. */
+    switch (surface_type)
+    {
+        case SURFACE_OPENGL:
+            surface->lpVtbl = &IWineD3DSurface_Vtbl;
+            cleanup = surface_cleanup;
+            break;
+
+        case SURFACE_GDI:
+            surface->lpVtbl = &IWineGDISurface_Vtbl;
+            cleanup = surface_gdi_cleanup;
+            break;
+
+        default:
+            ERR("Requested unknown surface implementation %#x.\n", surface_type);
+            return WINED3DERR_INVALIDCALL;
+    }
+
+    hr = resource_init((IWineD3DResource *)surface, WINED3DRTYPE_SURFACE,
+            device, resource_size, usage, format_desc, pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize resource, returning %#x.\n", hr);
+        return hr;
+    }
+
+    /* "Standalone" surface. */
+    IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);
+
+    surface->currentDesc.Width = width;
+    surface->currentDesc.Height = height;
+    surface->currentDesc.MultiSampleType = multisample_type;
+    surface->currentDesc.MultiSampleQuality = multisample_quality;
+    surface->texture_level = level;
+    list_init(&surface->overlays);
+
+    /* Flags */
+    surface->Flags = SFLAG_NORMCOORD; /* Default to normalized coords. */
+    if (discard) surface->Flags |= SFLAG_DISCARD;
+    if (lockable || format == WINED3DFMT_D16_LOCKABLE) surface->Flags |= SFLAG_LOCKABLE;
+
+    /* Quick lockable sanity check.
+     * TODO: remove this after surfaces, usage and lockability have been debugged properly
+     * this function is too deep to need to care about things like this.
+     * Levels need to be checked too, since they all affect what can be done. */
+    switch (pool)
+    {
+        case WINED3DPOOL_SCRATCH:
+            if(!lockable)
+            {
+                FIXME("Called with a pool of SCRATCH and a lockable of FALSE "
+                        "which are mutually exclusive, setting lockable to TRUE.\n");
+                lockable = TRUE;
+            }
+            break;
 
 
-void surface_force_reload(IWineD3DSurface *iface)
+        case WINED3DPOOL_SYSTEMMEM:
+            if (!lockable)
+                FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n");
+            break;
+
+        case WINED3DPOOL_MANAGED:
+            if (usage & WINED3DUSAGE_DYNAMIC)
+                FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n");
+            break;
+
+        case WINED3DPOOL_DEFAULT:
+            if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
+                WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n");
+            break;
+
+        default:
+            FIXME("Unknown pool %#x.\n", pool);
+            break;
+    };
+
+    if (usage & WINED3DUSAGE_RENDERTARGET && pool != WINED3DPOOL_DEFAULT)
+    {
+        FIXME("Trying to create a render target that isn't in the default pool.\n");
+    }
+
+    /* Mark the texture as dirty so that it gets loaded first time around. */
+    surface_add_dirty_rect((IWineD3DSurface *)surface, NULL);
+    list_init(&surface->renderbuffers);
+
+    TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size);
+
+    /* Call the private setup routine */
+    hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)surface);
+    if (FAILED(hr))
+    {
+        ERR("Private setup failed, returning %#x\n", hr);
+        cleanup(surface);
+        return hr;
+    }
+
+    return hr;
+}
+
+static void surface_force_reload(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
@@ -53,12 +254,12 @@ void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb
 
     if(srgb)
     {
 
     if(srgb)
     {
-        name = &This->glDescription.srgbTextureName;
+        name = &This->texture_name_srgb;
         flag = SFLAG_INSRGBTEX;
     }
     else
     {
         flag = SFLAG_INSRGBTEX;
     }
     else
     {
-        name = &This->glDescription.textureName;
+        name = &This->texture_name;
         flag = SFLAG_INTEXTURE;
     }
 
         flag = SFLAG_INTEXTURE;
     }
 
@@ -83,23 +284,24 @@ void surface_set_texture_target(IWineD3DSurface *iface, GLenum target)
 
     TRACE("(%p) : setting target %#x\n", This, target);
 
 
     TRACE("(%p) : setting target %#x\n", This, target);
 
-    if (This->glDescription.target != target)
+    if (This->texture_target != target)
     {
         if (target == GL_TEXTURE_RECTANGLE_ARB)
         {
             This->Flags &= ~SFLAG_NORMCOORD;
         }
     {
         if (target == GL_TEXTURE_RECTANGLE_ARB)
         {
             This->Flags &= ~SFLAG_NORMCOORD;
         }
-        else if (This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB)
+        else if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
         {
             This->Flags |= SFLAG_NORMCOORD;
         }
     }
         {
             This->Flags |= SFLAG_NORMCOORD;
         }
     }
-    This->glDescription.target = target;
+    This->texture_target = target;
     surface_force_reload(iface);
 }
 
     surface_force_reload(iface);
 }
 
+/* Context activation is done by the caller. */
 static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) {
 static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) {
-    int active_sampler;
+    DWORD active_sampler;
 
     /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
      * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
 
     /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
      * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
@@ -118,7 +320,8 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) {
     LEAVE_GL();
     active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
 
     LEAVE_GL();
     active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];
 
-    if (active_sampler != -1) {
+    if (active_sampler != WINED3D_UNMAPPED_STAGE)
+    {
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
     IWineD3DSurface_BindTexture((IWineD3DSurface *)This, srgb);
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
     IWineD3DSurface_BindTexture((IWineD3DSurface *)This, srgb);
@@ -136,8 +339,13 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
     return FALSE;
 }
 
     return FALSE;
 }
 
-/* This call just downloads data, the caller is responsible for activating the
- * right context and binding the correct texture. */
+#undef GLINFO_LOCATION
+
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
+/* This call just downloads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
 static void surface_download_data(IWineD3DSurfaceImpl *This) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
 
 static void surface_download_data(IWineD3DSurfaceImpl *This) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
 
@@ -150,29 +358,28 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
 
     ENTER_GL();
 
 
     ENTER_GL();
 
-    if (format_desc->format == WINED3DFMT_DXT1 || format_desc->format == WINED3DFMT_DXT2
-            || format_desc->format == WINED3DFMT_DXT3 || format_desc->format == WINED3DFMT_DXT4
-            || format_desc->format == WINED3DFMT_DXT5 || format_desc->format == WINED3DFMT_ATI2N)
+    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
     {
     {
-        if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can assume this as the texture would not have been created otherwise */
-            FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
-        } else {
-            TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p\n",
-                    This, This->glDescription.level, format_desc->glFormat, format_desc->glType,
-                    This->resource.allocatedMemory);
-
-            if(This->Flags & SFLAG_PBO) {
-                GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
-                checkGLcall("glBindBufferARB");
-                GL_EXTCALL(glGetCompressedTexImageARB(This->glDescription.target, This->glDescription.level, NULL));
-                checkGLcall("glGetCompressedTexImageARB()");
-                GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-                checkGLcall("glBindBufferARB");
-            } else {
-                GL_EXTCALL(glGetCompressedTexImageARB(This->glDescription.target, This->glDescription.level, This->resource.allocatedMemory));
-                checkGLcall("glGetCompressedTexImageARB()");
-            }
+        TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n",
+                This, This->texture_level, format_desc->glFormat, format_desc->glType,
+                This->resource.allocatedMemory);
+
+        if (This->Flags & SFLAG_PBO)
+        {
+            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
+            checkGLcall("glBindBufferARB");
+            GL_EXTCALL(glGetCompressedTexImageARB(This->texture_target, This->texture_level, NULL));
+            checkGLcall("glGetCompressedTexImageARB");
+            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+            checkGLcall("glBindBufferARB");
+        }
+        else
+        {
+            GL_EXTCALL(glGetCompressedTexImageARB(This->texture_target,
+                    This->texture_level, This->resource.allocatedMemory));
+            checkGLcall("glGetCompressedTexImageARB");
         }
         }
+
         LEAVE_GL();
     } else {
         void *mem;
         LEAVE_GL();
     } else {
         void *mem;
@@ -198,23 +405,21 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
             mem = This->resource.allocatedMemory;
         }
 
             mem = This->resource.allocatedMemory;
         }
 
-        TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level,
-                format, type, mem);
+        TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n",
+                This, This->texture_level, format, type, mem);
 
         if(This->Flags & SFLAG_PBO) {
             GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
             checkGLcall("glBindBufferARB");
 
 
         if(This->Flags & SFLAG_PBO) {
             GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
             checkGLcall("glBindBufferARB");
 
-            glGetTexImage(This->glDescription.target, This->glDescription.level, format,
-                          type, NULL);
-            checkGLcall("glGetTexImage()");
+            glGetTexImage(This->texture_target, This->texture_level, format, type, NULL);
+            checkGLcall("glGetTexImage");
 
             GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
             checkGLcall("glBindBufferARB");
         } else {
 
             GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
             checkGLcall("glBindBufferARB");
         } else {
-            glGetTexImage(This->glDescription.target, This->glDescription.level, format,
-                          type, mem);
-            checkGLcall("glGetTexImage()");
+            glGetTexImage(This->texture_target, This->texture_level, format, type, mem);
+            checkGLcall("glGetTexImage");
         }
         LEAVE_GL();
 
         }
         LEAVE_GL();
 
@@ -290,105 +495,70 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
     This->Flags |= SFLAG_INSYSMEM;
 }
 
     This->Flags |= SFLAG_INSYSMEM;
 }
 
-/* This call just uploads data, the caller is responsible for activating the
- * right context and binding the correct texture. */
+/* This call just uploads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
 static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
 
 static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
 
-    if (format_desc->heightscale != 1.0 && format_desc->heightscale != 0.0) height *= format_desc->heightscale;
+    TRACE("This %p, internal %#x, width %d, height %d, format %#x, type %#x, data %p.\n",
+            This, internal, width, height, format, type, data);
+    TRACE("target %#x, level %u, resource size %u.\n",
+            This->texture_target, This->texture_level, This->resource.size);
 
 
-    if (format_desc->format == WINED3DFMT_DXT1 || format_desc->format == WINED3DFMT_DXT2
-            || format_desc->format == WINED3DFMT_DXT3 || format_desc->format == WINED3DFMT_DXT4
-            || format_desc->format == WINED3DFMT_DXT5 || format_desc->format == WINED3DFMT_ATI2N)
-    {
-        if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
-            FIXME("Using DXT1/3/5 without advertized support\n");
-        } else {
-            /* glCompressedTexSubImage2D for uploading and glTexImage2D for allocating does not work well on some drivers(r200 dri, MacOS ATI driver)
-             * glCompressedTexImage2D does not accept NULL pointers. So for compressed textures surface_allocate_surface does nothing, and this
-             * function uses glCompressedTexImage2D instead of the SubImage call
-             */
-            TRACE("(%p) : Calling glCompressedTexSubImage2D w %d, h %d, data %p\n", This, width, height, data);
-            ENTER_GL();
+    if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
 
 
-            if(This->Flags & SFLAG_PBO) {
-                GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-                checkGLcall("glBindBufferARB");
-                TRACE("(%p) pbo: %#x, data: %p\n", This, This->pbo, data);
+    ENTER_GL();
 
 
-                GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
-                        width, height, 0 /* border */, This->resource.size, NULL));
-                checkGLcall("glCompressedTexSubImage2D");
+    if (This->Flags & SFLAG_PBO)
+    {
+        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
+        checkGLcall("glBindBufferARB");
 
 
-                GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-                checkGLcall("glBindBufferARB");
-            } else {
-                GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
-                        width, height, 0 /* border */, This->resource.size, data));
-                checkGLcall("glCompressedTexSubImage2D");
-            }
-            LEAVE_GL();
-        }
-    } else {
-        TRACE("(%p) : Calling glTexSubImage2D w %d,  h %d, data, %p\n", This, width, height, data);
-        ENTER_GL();
+        TRACE("(%p) pbo: %#x, data: %p.\n", This, This->pbo, data);
+        data = NULL;
+    }
 
 
-        if(This->Flags & SFLAG_PBO) {
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-            checkGLcall("glBindBufferARB");
-            TRACE("(%p) pbo: %#x, data: %p\n", This, This->pbo, data);
+    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+    {
+        TRACE("Calling glCompressedTexSubImage2DARB.\n");
 
 
-            glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, NULL);
-            checkGLcall("glTexSubImage2D");
+        GL_EXTCALL(glCompressedTexSubImage2DARB(This->texture_target, This->texture_level,
+                0, 0, width, height, internal, This->resource.size, data));
+        checkGLcall("glCompressedTexSubImage2DARB");
+    }
+    else
+    {
+        TRACE("Calling glTexSubImage2D.\n");
 
 
-            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-            checkGLcall("glBindBufferARB");
-        }
-        else {
-            glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, data);
-            checkGLcall("glTexSubImage2D");
-        }
+        glTexSubImage2D(This->texture_target, This->texture_level,
+                0, 0, width, height, format, type, data);
+        checkGLcall("glTexSubImage2D");
+    }
 
 
-        LEAVE_GL();
+    if (This->Flags & SFLAG_PBO)
+    {
+        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+        checkGLcall("glBindBufferARB");
     }
     }
+
+    LEAVE_GL();
 }
 
 }
 
-/* This call just allocates the texture, the caller is responsible for
- * activating the right context and binding the correct texture. */
+/* This call just allocates the texture, the caller is responsible for binding
+ * the correct texture. */
+/* Context activation is done by the caller. */
 static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
     BOOL enable_client_storage = FALSE;
     const BYTE *mem = NULL;
 
 static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) {
     const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
     BOOL enable_client_storage = FALSE;
     const BYTE *mem = NULL;
 
-    if (format_desc->heightscale != 1.0 && format_desc->heightscale != 0.0) height *= format_desc->heightscale;
+    if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
 
     TRACE("(%p) : Creating surface (target %#x)  level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
 
     TRACE("(%p) : Creating surface (target %#x)  level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
-            This, This->glDescription.target, This->glDescription.level, debug_d3dformat(format_desc->format),
+            This, This->texture_target, This->texture_level, debug_d3dformat(format_desc->format),
             internal, width, height, format, type);
 
             internal, width, height, format, type);
 
-    if (format_desc->format == WINED3DFMT_DXT1 || format_desc->format == WINED3DFMT_DXT2
-            || format_desc->format == WINED3DFMT_DXT3 || format_desc->format == WINED3DFMT_DXT4
-            || format_desc->format == WINED3DFMT_DXT5 || format_desc->format == WINED3DFMT_ATI2N)
-    {
-        /* glCompressedTexImage2D does not accept NULL pointers, so we cannot allocate a compressed texture without uploading data */
-        TRACE("Not allocating compressed surfaces, surface_upload_data will specify them\n");
-
-        /* We have to point GL to the client storage memory here, because upload_data might use a PBO. This means a double upload
-         * once, unfortunately
-         */
-        if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
-            /* Neither NONPOW2, DIBSECTION nor OVERSIZE flags can be set on compressed textures */
-            This->Flags |= SFLAG_CLIENT;
-            mem = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
-            ENTER_GL();
-            GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
-                       width, height, 0 /* border */, This->resource.size, mem));
-            LEAVE_GL();
-        }
-
-        return;
-    }
-
     ENTER_GL();
 
     if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
     ENTER_GL();
 
     if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
@@ -413,8 +583,18 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
             mem = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
         }
     }
             mem = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
         }
     }
-    glTexImage2D(This->glDescription.target, This->glDescription.level, internal, width, height, 0, format, type, mem);
-    checkGLcall("glTexImage2D");
+
+    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED && mem)
+    {
+        GL_EXTCALL(glCompressedTexImage2DARB(This->texture_target, This->texture_level,
+                internal, width, height, 0, This->resource.size, mem));
+    }
+    else
+    {
+        glTexImage2D(This->texture_target, This->texture_level,
+                internal, width, height, 0, format, type, mem);
+        checkGLcall("glTexImage2D");
+    }
 
     if(enable_client_storage) {
         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
 
     if(enable_client_storage) {
         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
@@ -426,6 +606,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
 /* In D3D the depth stencil dimensions have to be greater than or equal to the
  * render target dimensions. With FBOs, the dimensions have to be an exact match. */
 /* TODO: We should synchronize the renderbuffer's content with the texture's content. */
 /* In D3D the depth stencil dimensions have to be greater than or equal to the
  * render target dimensions. With FBOs, the dimensions have to be an exact match. */
 /* TODO: We should synchronize the renderbuffer's content with the texture's content. */
+/* GL locking is done by the caller */
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     renderbuffer_entry_t *entry;
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     renderbuffer_entry_t *entry;
@@ -526,64 +707,31 @@ void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect)
     }
 }
 
     }
 }
 
+static inline BOOL surface_can_stretch_rect(IWineD3DSurfaceImpl *src, IWineD3DSurfaceImpl *dst)
+{
+    return ((src->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+            || (src->resource.usage & WINED3DUSAGE_RENDERTARGET))
+            && ((dst->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+            || (dst->resource.usage & WINED3DUSAGE_RENDERTARGET))
+            && (src->resource.format_desc->format == dst->resource.format_desc->format
+            || (is_identity_fixup(src->resource.format_desc->color_fixup)
+            && is_identity_fixup(dst->resource.format_desc->color_fixup)));
+}
+
 static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->resource.ref);
     TRACE("(%p) : Releasing from %d\n", This, ref + 1);
 static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->resource.ref);
     TRACE("(%p) : Releasing from %d\n", This, ref + 1);
-    if (ref == 0) {
-        IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-        renderbuffer_entry_t *entry, *entry2;
-        TRACE("(%p) : cleaning up\n", This);
-
-        /* Need a context to destroy the texture. Use the currently active render target, but only if
-         * the primary render target exists. Otherwise lastActiveRenderTarget is garbage, see above.
-         * When destroying the primary rt, Uninit3D will activate a context before doing anything
-         */
-        if(device->render_targets && device->render_targets[0]) {
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        }
 
 
-        ENTER_GL();
-        if (This->glDescription.textureName != 0) { /* release the openGL texture.. */
-            TRACE("Deleting texture %d\n", This->glDescription.textureName);
-            glDeleteTextures(1, &This->glDescription.textureName);
-        }
-
-        if(This->Flags & SFLAG_PBO) {
-            /* Delete the PBO */
-            GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
-        }
-
-        LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) {
-            GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id));
-            HeapFree(GetProcessHeap(), 0, entry);
-        }
-        LEAVE_GL();
-
-        if(This->Flags & SFLAG_DIBSECTION) {
-            /* Release the DC */
-            SelectObject(This->hDC, This->dib.holdbitmap);
-            DeleteDC(This->hDC);
-            /* Release the DIB section */
-            DeleteObject(This->dib.DIBsection);
-            This->dib.bitmap_data = NULL;
-            This->resource.allocatedMemory = NULL;
-        }
-        if(This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem(iface, NULL);
-
-        HeapFree(GetProcessHeap(), 0, This->palette9);
-
-        resource_cleanup((IWineD3DResource *)iface);
-
-        if(This->overlay_dest) {
-            list_remove(&This->overlay_entry);
-        }
+    if (!ref)
+    {
+        surface_cleanup(This);
 
 
-        TRACE("(%p) Released\n", This);
+        TRACE("(%p) Released.\n", This);
         HeapFree(GetProcessHeap(), 0, This);
         HeapFree(GetProcessHeap(), 0, This);
-
     }
     }
+
     return ref;
 }
 
     return ref;
 }
 
@@ -602,13 +750,13 @@ void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb)
     if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
         IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture;
         TRACE("Passing to container\n");
     if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
         IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture;
         TRACE("Passing to container\n");
-        tex_impl->baseTexture.internal_preload(baseTexture, SRGB_RGB);
+        tex_impl->baseTexture.internal_preload(baseTexture, srgb);
         IWineD3DBaseTexture_Release(baseTexture);
     } else {
         TRACE("(%p) : About to load surface\n", This);
 
         if(!device->isInDraw) {
         IWineD3DBaseTexture_Release(baseTexture);
     } else {
         TRACE("(%p) : About to load surface\n", This);
 
         if(!device->isInDraw) {
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         }
 
         if (This->resource.format_desc->format == WINED3DFMT_P8
         }
 
         if (This->resource.format_desc->format == WINED3DFMT_P8
@@ -630,7 +778,7 @@ void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb)
             GLclampf tmp;
             tmp = 0.9f;
             ENTER_GL();
             GLclampf tmp;
             tmp = 0.9f;
             ENTER_GL();
-            glPrioritizeTextures(1, &This->glDescription.textureName, &tmp);
+            glPrioritizeTextures(1, &This->texture_name, &tmp);
             LEAVE_GL();
         }
     }
             LEAVE_GL();
         }
     }
@@ -641,6 +789,7 @@ static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
     surface_internal_preload(iface, SRGB_ANY);
 }
 
     surface_internal_preload(iface, SRGB_ANY);
 }
 
+/* Context activation is done by the caller. */
 static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
     This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
     This->resource.allocatedMemory =
 static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
     This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
     This->resource.allocatedMemory =
@@ -648,11 +797,11 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
 
     ENTER_GL();
     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
 
     ENTER_GL();
     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-    checkGLcall("glBindBuffer(GL_PIXEL_UNPACK_BUFFER, This->pbo)");
+    checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, This->pbo)");
     GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
     GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
-    checkGLcall("glGetBufferSubData");
+    checkGLcall("glGetBufferSubDataARB");
     GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
     GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
-    checkGLcall("glDeleteBuffers");
+    checkGLcall("glDeleteBuffersARB");
     LEAVE_GL();
 
     This->pbo = 0;
     LEAVE_GL();
 
     This->pbo = 0;
@@ -662,6 +811,7 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
 static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DBaseTexture *texture = NULL;
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DBaseTexture *texture = NULL;
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
     renderbuffer_entry_t *entry, *entry2;
     TRACE("(%p)\n", iface);
 
     renderbuffer_entry_t *entry, *entry2;
     TRACE("(%p)\n", iface);
 
@@ -689,8 +839,11 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
         IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
     }
     IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
         IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
     }
     IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
+    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
     This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
 
     This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
 
+    ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+
     /* Destroy PBOs, but load them into real sysmem before */
     if(This->Flags & SFLAG_PBO) {
         surface_remove_pbo(This);
     /* Destroy PBOs, but load them into real sysmem before */
     if(This->Flags & SFLAG_PBO) {
         surface_remove_pbo(This);
@@ -716,8 +869,10 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **) &texture);
     if(!texture) {
         ENTER_GL();
     IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **) &texture);
     if(!texture) {
         ENTER_GL();
-        glDeleteTextures(1, &This->glDescription.textureName);
-        This->glDescription.textureName = 0;
+        glDeleteTextures(1, &This->texture_name);
+        This->texture_name = 0;
+        glDeleteTextures(1, &This->texture_name_srgb);
+        This->texture_name_srgb = 0;
         LEAVE_GL();
     } else {
         IWineD3DBaseTexture_Release(texture);
         LEAVE_GL();
     } else {
         IWineD3DBaseTexture_Release(texture);
@@ -729,13 +884,6 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
    IWineD3DSurface IWineD3DSurface parts follow
    ****************************************************** */
 
    IWineD3DSurface IWineD3DSurface parts follow
    ****************************************************** */
 
-static void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription)
-{
-    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    TRACE("(%p) : returning %p\n", This, &This->glDescription);
-    *glDescription = &This->glDescription;
-}
-
 /* Read the framebuffer back into the surface */
 static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) {
     IWineD3DSwapChainImpl *swapchain;
 /* Read the framebuffer back into the surface */
 static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) {
     IWineD3DSwapChainImpl *swapchain;
@@ -854,11 +1002,11 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
 
     /* Save old pixel store pack state */
     glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
 
     /* Save old pixel store pack state */
     glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
-    checkGLcall("glIntegerv");
+    checkGLcall("glGetIntegerv");
     glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
     glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
-    checkGLcall("glIntegerv");
+    checkGLcall("glGetIntegerv");
     glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
     glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
-    checkGLcall("glIntegerv");
+    checkGLcall("glGetIntegerv");
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
     glPixelStorei(GL_PACK_ROW_LENGTH, This->currentDesc.Width);
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
     glPixelStorei(GL_PACK_ROW_LENGTH, This->currentDesc.Width);
@@ -1039,18 +1187,15 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb)
      * this code from getting called in such cases or perhaps
      * we can use FBOs */
 
      * this code from getting called in such cases or perhaps
      * we can use FBOs */
 
-    glCopyTexSubImage2D(This->glDescription.target,
-                        This->glDescription.level,
-                        0, 0, 0, 0,
-                        This->currentDesc.Width,
-                        This->currentDesc.Height);
+    glCopyTexSubImage2D(This->texture_target, This->texture_level,
+            0, 0, 0, 0, This->currentDesc.Width, This->currentDesc.Height);
     checkGLcall("glCopyTexSubImage2D");
 
     glReadBuffer(prevRead);
     checkGLcall("glReadBuffer");
 
     LEAVE_GL();
     checkGLcall("glCopyTexSubImage2D");
 
     glReadBuffer(prevRead);
     checkGLcall("glReadBuffer");
 
     LEAVE_GL();
-    TRACE("Updated target %d\n", This->glDescription.target);
+    TRACE("Updated target %d\n", This->texture_target);
 }
 
 static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
 }
 
 static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
@@ -1074,7 +1219,7 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
         GLenum error;
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
         GLenum error;
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
 
         GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
         ENTER_GL();
 
         GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
@@ -1120,6 +1265,7 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
 static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
 static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
+    const RECT *pass_rect = pRect;
 
     TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
 
 
     TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
 
@@ -1152,77 +1298,24 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
         goto lock_end;
     }
 
         goto lock_end;
     }
 
-    /* Now download the surface content from opengl
-     * Use the render target readback if the surface is on a swapchain(=onscreen render target) or the current primary target
-     * Offscreen targets which are not active at the moment or are higher targets(FBOs) can be locked with the texture path
-     */
-    if ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0])
+    /* IWineD3DSurface_LoadLocation() does not check if the rectangle specifies
+     * the full surface. Most callers don't need that, so do it here. */
+    if (pRect && pRect->top == 0 && pRect->left == 0
+            && pRect->right == This->currentDesc.Width
+            && pRect->bottom == This->currentDesc.Height)
     {
     {
-        const RECT *pass_rect = pRect;
-
-        /* IWineD3DSurface_LoadLocation does not check if the rectangle specifies the full surfaces
-         * because most caller functions do not need that. So do that here
-         */
-        if(pRect &&
-           pRect->top    == 0 &&
-           pRect->left   == 0 &&
-           pRect->right  == This->currentDesc.Width &&
-           pRect->bottom == This->currentDesc.Height) {
-            pass_rect = NULL;
-        }
-
-        switch(wined3d_settings.rendertargetlock_mode) {
-            case RTL_TEXDRAW:
-            case RTL_TEXTEX:
-                FIXME("Reading from render target with a texture isn't implemented yet, falling back to framebuffer reading\n");
-#if 0
-                /* Disabled for now. LoadLocation prefers the texture over the drawable as the source. So if we copy to the
-                 * texture first, then to sysmem, we'll avoid glReadPixels and use glCopyTexImage and glGetTexImage2D instead.
-                 * This may be faster on some cards
-                 */
-                IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* No partial texture copy yet */);
-#endif
-                /* drop through */
-
-            case RTL_AUTO:
-            case RTL_READDRAW:
-            case RTL_READTEX:
-                IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect);
-                break;
+        pass_rect = NULL;
+    }
 
 
-            case RTL_DISABLE:
-                break;
-        }
-    } else if(iface == myDevice->stencilBufferTarget) {
-        /** the depth stencil in openGL has a format of GL_FLOAT
-         * which should be good for WINED3DFMT_D16_LOCKABLE
-         * and WINED3DFMT_D16
-         * it is unclear what format the stencil buffer is in except.
-         * 'Each index is converted to fixed point...
-         * If GL_MAP_STENCIL is GL_TRUE, indices are replaced by their
-         * mappings in the table GL_PIXEL_MAP_S_TO_S.
-         * glReadPixels(This->lockedRect.left,
-         *             This->lockedRect.bottom - j - 1,
-         *             This->lockedRect.right - This->lockedRect.left,
-         *             1,
-         *             GL_DEPTH_COMPONENT,
-         *             type,
-         *             (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
-         *
-         * Depth Stencil surfaces which are not the current depth stencil target should have their data in a
-         * gl texture(next path), or in local memory(early return because of set SFLAG_INSYSMEM above). If
-         * none of that is the case the problem is not in this function :-)
-         ********************************************/
-        FIXME("Depth stencil locking not supported yet\n");
-    } else {
-        /* This path is for normal surfaces, offscreen render targets and everything else that is in a gl texture */
-        TRACE("locking an ordinary surface\n");
-        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);
+    if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE
+            && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0])))
+    {
+        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect);
     }
 
 lock_end:
     if(This->Flags & SFLAG_PBO) {
     }
 
 lock_end:
     if(This->Flags & SFLAG_PBO) {
-        ActivateContext(myDevice, myDevice->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
         checkGLcall("glBindBufferARB");
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
         checkGLcall("glBindBufferARB");
@@ -1292,10 +1385,10 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm
     }
 
     glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
     }
 
     glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
-    checkGLcall("glIntegerv");
+    checkGLcall("glGetIntegerv");
     glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
     glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
-    checkGLcall("glIntegerv");
-    glPixelZoom(1.0, -1.0);
+    checkGLcall("glGetIntegerv");
+    glPixelZoom(1.0f, -1.0f);
     checkGLcall("glPixelZoom");
 
     /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
     checkGLcall("glPixelZoom");
 
     /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
@@ -1303,7 +1396,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm
     glPixelStorei(GL_UNPACK_ROW_LENGTH, This->currentDesc.Width);
 
     glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, This->currentDesc.Width);
 
     glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
-    checkGLcall("glRasterPos2f");
+    checkGLcall("glRasterPos3i");
 
     /* Some drivers(radeon dri, others?) don't like exceptions during
      * glDrawPixels. If the surface is a DIB section, it might be in GDIMode
 
     /* Some drivers(radeon dri, others?) don't like exceptions during
      * glDrawPixels. If the surface is a DIB section, it might be in GDIMode
@@ -1345,7 +1438,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm
         checkGLcall("glBindBufferARB");
     }
 
         checkGLcall("glBindBufferARB");
     }
 
-    glPixelZoom(1.0,1.0);
+    glPixelZoom(1.0f, 1.0f);
     checkGLcall("glPixelZoom");
 
     glRasterPos3iv(&prev_rasterpos[0]);
     checkGLcall("glPixelZoom");
 
     glRasterPos3iv(&prev_rasterpos[0]);
@@ -1353,7 +1446,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm
 
     /* Reset to previous pack row length */
     glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
 
     /* Reset to previous pack row length */
     glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
-    checkGLcall("glPixelStorei GL_UNPACK_ROW_LENGTH");
+    checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH)");
 
     if(!swapchain) {
         glDrawBuffer(myDevice->offscreenBuffer);
 
     if(!swapchain) {
         glDrawBuffer(myDevice->offscreenBuffer);
@@ -1382,7 +1475,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
 
     if (This->Flags & SFLAG_PBO) {
         TRACE("Freeing PBO memory\n");
 
     if (This->Flags & SFLAG_PBO) {
         TRACE("Freeing PBO memory\n");
-        ActivateContext(myDevice, myDevice->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
         GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
         ENTER_GL();
         GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
         GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
@@ -1423,14 +1516,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
 
         switch(wined3d_settings.rendertargetlock_mode) {
             case RTL_READTEX:
 
         switch(wined3d_settings.rendertargetlock_mode) {
             case RTL_READTEX:
-            case RTL_TEXTEX:
-                ActivateContext(myDevice, iface, CTXUSAGE_BLIT);
                 IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */);
                 /* drop through */
 
                 IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */);
                 /* drop through */
 
-            case RTL_AUTO:
             case RTL_READDRAW:
             case RTL_READDRAW:
-            case RTL_TEXDRAW:
                 IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, fullsurface ? NULL : &This->dirtyRect);
                 break;
         }
                 IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, fullsurface ? NULL : &This->dirtyRect);
                 break;
         }
@@ -1662,7 +1751,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             }
             else if(!GL_SUPPORT(EXT_PALETTED_TEXTURE) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
                 *format = GL_ALPHA;
             }
             else if(!GL_SUPPORT(EXT_PALETTED_TEXTURE) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
                 *format = GL_ALPHA;
-                *internal = GL_RGBA;
                 *type = GL_UNSIGNED_BYTE;
                 *target_bpp = 1;
             }
                 *type = GL_UNSIGNED_BYTE;
                 *target_bpp = 1;
             }
@@ -1684,7 +1772,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             if (colorkey_active) {
                 *convert = CONVERT_CK_565;
                 *format = GL_RGBA;
             if (colorkey_active) {
                 *convert = CONVERT_CK_565;
                 *format = GL_RGBA;
-                *internal = GL_RGBA;
+                *internal = GL_RGB5_A1;
                 *type = GL_UNSIGNED_SHORT_5_5_5_1;
             }
             break;
                 *type = GL_UNSIGNED_SHORT_5_5_5_1;
             }
             break;
@@ -1693,7 +1781,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             if (colorkey_active) {
                 *convert = CONVERT_CK_5551;
                 *format = GL_BGRA;
             if (colorkey_active) {
                 *convert = CONVERT_CK_5551;
                 *format = GL_BGRA;
-                *internal = GL_RGBA;
+                *internal = GL_RGB5_A1;
                 *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
             }
             break;
                 *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
             }
             break;
@@ -1702,7 +1790,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             if (colorkey_active) {
                 *convert = CONVERT_CK_RGB24;
                 *format = GL_RGBA;
             if (colorkey_active) {
                 *convert = CONVERT_CK_RGB24;
                 *format = GL_RGBA;
-                *internal = GL_RGBA;
+                *internal = GL_RGBA8;
                 *type = GL_UNSIGNED_INT_8_8_8_8;
                 *target_bpp = 4;
             }
                 *type = GL_UNSIGNED_INT_8_8_8_8;
                 *target_bpp = 4;
             }
@@ -1712,16 +1800,15 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             if (colorkey_active) {
                 *convert = CONVERT_RGB32_888;
                 *format = GL_RGBA;
             if (colorkey_active) {
                 *convert = CONVERT_RGB32_888;
                 *format = GL_RGBA;
-                *internal = GL_RGBA;
+                *internal = GL_RGBA8;
                 *type = GL_UNSIGNED_INT_8_8_8_8;
             }
             break;
 
         case WINED3DFMT_R8G8_SNORM:
                 *type = GL_UNSIGNED_INT_8_8_8_8;
             }
             break;
 
         case WINED3DFMT_R8G8_SNORM:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
+            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
             *convert = CONVERT_V8U8;
             *format = GL_BGR;
             *convert = CONVERT_V8U8;
             *format = GL_BGR;
-            *internal = GL_RGB8;
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 3;
             break;
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 3;
             break;
@@ -1735,7 +1822,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
                 /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */
                 *target_bpp = 2;
                 *format = GL_RGB;
                 /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */
                 *target_bpp = 2;
                 *format = GL_RGB;
-                *internal = GL_RGB5;
                 *type = GL_UNSIGNED_SHORT_5_6_5;
             }
             break;
                 *type = GL_UNSIGNED_SHORT_5_6_5;
             }
             break;
@@ -1752,25 +1838,22 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
                  */
             } else {
                 *format = GL_BGRA;
                  */
             } else {
                 *format = GL_BGRA;
-                *internal = GL_RGB8;
                 *type = GL_UNSIGNED_INT_8_8_8_8_REV;
             }
             break;
 
         case WINED3DFMT_R8G8B8A8_SNORM:
                 *type = GL_UNSIGNED_INT_8_8_8_8_REV;
             }
             break;
 
         case WINED3DFMT_R8G8B8A8_SNORM:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
+            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
             *convert = CONVERT_Q8W8V8U8;
             *format = GL_BGRA;
             *convert = CONVERT_Q8W8V8U8;
             *format = GL_BGRA;
-            *internal = GL_RGBA8;
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 4;
             break;
 
         case WINED3DFMT_R16G16_SNORM:
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 4;
             break;
 
         case WINED3DFMT_R16G16_SNORM:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
+            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
             *convert = CONVERT_V16U16;
             *format = GL_BGR;
             *convert = CONVERT_V16U16;
             *format = GL_BGR;
-            *internal = GL_RGB16_EXT;
             *type = GL_UNSIGNED_SHORT;
             *target_bpp = 6;
             break;
             *type = GL_UNSIGNED_SHORT;
             *target_bpp = 6;
             break;
@@ -1782,7 +1865,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
              */
             *convert = CONVERT_A4L4;
             *format = GL_LUMINANCE_ALPHA;
              */
             *convert = CONVERT_A4L4;
             *format = GL_LUMINANCE_ALPHA;
-            *internal = GL_LUMINANCE4_ALPHA4;
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 2;
             break;
             *type = GL_UNSIGNED_BYTE;
             *target_bpp = 2;
             break;
@@ -1790,7 +1872,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
         case WINED3DFMT_R16G16_UNORM:
             *convert = CONVERT_G16R16;
             *format = GL_RGB;
         case WINED3DFMT_R16G16_UNORM:
             *convert = CONVERT_G16R16;
             *format = GL_RGB;
-            *internal = GL_RGB16_EXT;
             *type = GL_UNSIGNED_SHORT;
             *target_bpp = 6;
             break;
             *type = GL_UNSIGNED_SHORT;
             *target_bpp = 6;
             break;
@@ -1798,7 +1879,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
         case WINED3DFMT_R16G16_FLOAT:
             *convert = CONVERT_R16G16F;
             *format = GL_RGB;
         case WINED3DFMT_R16G16_FLOAT:
             *convert = CONVERT_R16G16F;
             *format = GL_RGB;
-            *internal = GL_RGB16F_ARB;
             *type = GL_HALF_FLOAT_ARB;
             *target_bpp = 6;
             break;
             *type = GL_HALF_FLOAT_ARB;
             *target_bpp = 6;
             break;
@@ -1806,11 +1886,33 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
         case WINED3DFMT_R32G32_FLOAT:
             *convert = CONVERT_R32G32F;
             *format = GL_RGB;
         case WINED3DFMT_R32G32_FLOAT:
             *convert = CONVERT_R32G32F;
             *format = GL_RGB;
-            *internal = GL_RGB32F_ARB;
             *type = GL_FLOAT;
             *target_bpp = 12;
             break;
 
             *type = GL_FLOAT;
             *target_bpp = 12;
             break;
 
+        case WINED3DFMT_D15S1:
+            if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+            {
+                *convert = CONVERT_D15S1;
+                *target_bpp = 4;
+            }
+            break;
+
+        case WINED3DFMT_D24X4S4:
+            if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+            {
+                *convert = CONVERT_D24X4S4;
+            }
+            break;
+
+        case WINED3DFMT_D24FS8:
+            if (GL_SUPPORT(ARB_DEPTH_BUFFER_FLOAT))
+            {
+                *convert = CONVERT_D24FS8;
+                *target_bpp = 8;
+            }
+            break;
+
         default:
             break;
     }
         default:
             break;
     }
@@ -1818,6 +1920,86 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey)
+{
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    IWineD3DPaletteImpl *pal = This->palette;
+    BOOL index_in_alpha = FALSE;
+    unsigned int i;
+
+    /* Old games like StarCraft, C&C, Red Alert and others use P8 render targets.
+     * Reading back the RGB output each lockrect (each frame as they lock the whole screen)
+     * is slow. Further RGB->P8 conversion is not possible because palettes can have
+     * duplicate entries. Store the color key in the unused alpha component to speed the
+     * download up and to make conversion unneeded. */
+    index_in_alpha = primary_render_target_is_p8(device);
+
+    if (!pal)
+    {
+        UINT dxVersion = ((IWineD3DImpl *)device->wineD3D)->dxVersion;
+
+        /* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
+        if (dxVersion <= 7)
+        {
+            ERR("This code should never get entered for DirectDraw!, expect problems\n");
+            if (index_in_alpha)
+            {
+                /* Guarantees that memory representation remains correct after sysmem<->texture transfers even if
+                 * there's no palette at this time. */
+                for (i = 0; i < 256; i++) table[i][3] = i;
+            }
+        }
+        else
+        {
+            /* Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
+             * alpha is stored in peFlags and may be used by the app if D3DPTEXTURECAPS_ALPHAPALETTE device
+             * capability flag is present (wine does advertise this capability) */
+            for (i = 0; i < 256; ++i)
+            {
+                table[i][0] = device->palettes[device->currentPalette][i].peRed;
+                table[i][1] = device->palettes[device->currentPalette][i].peGreen;
+                table[i][2] = device->palettes[device->currentPalette][i].peBlue;
+                table[i][3] = device->palettes[device->currentPalette][i].peFlags;
+            }
+        }
+    }
+    else
+    {
+        TRACE("Using surface palette %p\n", pal);
+        /* Get the surface's palette */
+        for (i = 0; i < 256; ++i)
+        {
+            table[i][0] = pal->palents[i].peRed;
+            table[i][1] = pal->palents[i].peGreen;
+            table[i][2] = pal->palents[i].peBlue;
+
+            /* When index_in_alpha is set the palette index is stored in the
+             * alpha component. In case of a readback we can then read
+             * GL_ALPHA. Color keying is handled in BltOverride using a
+             * GL_ALPHA_TEST using GL_NOT_EQUAL. In case of index_in_alpha the
+             * color key itself is passed to glAlphaFunc in other cases the
+             * alpha component of pixels that should be masked away is set to 0. */
+            if (index_in_alpha)
+            {
+                table[i][3] = i;
+            }
+            else if (colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue)
+                    && (i <= This->SrcBltCKey.dwColorSpaceHighValue))
+            {
+                table[i][3] = 0x00;
+            }
+            else if(pal->Flags & WINEDDPCAPS_ALPHA)
+            {
+                table[i][3] = pal->palents[i].peFlags;
+            }
+            else
+            {
+                table[i][3] = 0xFF;
+            }
+        }
+    }
+}
+
 static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width,
         UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This)
 {
 static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width,
         UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This)
 {
@@ -2176,82 +2358,83 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
                     float red = (*Source++);
                     Dest[0] = green;
                     Dest[1] = red;
                     float red = (*Source++);
                     Dest[0] = green;
                     Dest[1] = red;
-                    Dest[2] = 1.0;
+                    Dest[2] = 1.0f;
                     Dest += 3;
                 }
             }
             break;
         }
 
                     Dest += 3;
                 }
             }
             break;
         }
 
-        default:
-            ERR("Unsupported conversation type %d\n", convert);
-    }
-    return WINED3D_OK;
-}
-
-static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey) {
-    IWineD3DPaletteImpl* pal = This->palette;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BOOL index_in_alpha = FALSE;
-    int dxVersion = ( (IWineD3DImpl *) device->wineD3D)->dxVersion;
-    unsigned int i;
+        case CONVERT_D15S1:
+        {
+            unsigned int x, y;
 
 
-    /* Old games like StarCraft, C&C, Red Alert and others use P8 render targets.
-    * Reading back the RGB output each lockrect (each frame as they lock the whole screen)
-    * is slow. Further RGB->P8 conversion is not possible because palettes can have
-    * duplicate entries. Store the color key in the unused alpha component to speed the
-    * download up and to make conversion unneeded. */
-    index_in_alpha = primary_render_target_is_p8(device);
+            for (y = 0; y < height; ++y)
+            {
+                const WORD *source = (const WORD *)(src + y * pitch);
+                DWORD *dest = (DWORD *)(dst + y * outpitch);
 
 
-    if (pal == NULL) {
-        /* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
-        if(dxVersion <= 7) {
-            ERR("This code should never get entered for DirectDraw!, expect problems\n");
-            if(index_in_alpha) {
-                /* Guarantees that memory representation remains correct after sysmem<->texture transfers even if
-                   there's no palette at this time. */
-                for (i = 0; i < 256; i++) table[i][3] = i;
+                for (x = 0; x < width; ++x)
+                {
+                    /* The depth data is normalized, so needs to be scaled,
+                     * the stencil data isn't.  Scale depth data by
+                     *      (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
+                    WORD d15 = source[x] >> 1;
+                    DWORD d24 = (d15 << 9) + (d15 >> 6);
+                    dest[x] = (d24 << 8) | (source[x] & 0x1);
+                }
             }
             }
-        } else {
-            /*  Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
-                alpha is stored in peFlags and may be used by the app if D3DPTEXTURECAPS_ALPHAPALETTE device
-                capability flag is present (wine does advertise this capability) */
-            for (i = 0; i < 256; i++) {
-                table[i][0] = device->palettes[device->currentPalette][i].peRed;
-                table[i][1] = device->palettes[device->currentPalette][i].peGreen;
-                table[i][2] = device->palettes[device->currentPalette][i].peBlue;
-                table[i][3] = device->palettes[device->currentPalette][i].peFlags;
+            break;
+        }
+
+        case CONVERT_D24X4S4:
+        {
+            unsigned int x, y;
+
+            for (y = 0; y < height; ++y)
+            {
+                const DWORD *source = (const DWORD *)(src + y * pitch);
+                DWORD *dest = (DWORD *)(dst + y * outpitch);
+
+                for (x = 0; x < width; ++x)
+                {
+                    /* Just need to clear out the X4 part. */
+                    dest[x] = source[x] & ~0xf0;
+                }
             }
             }
+            break;
         }
         }
-    } else {
-        TRACE("Using surface palette %p\n", pal);
-        /* Get the surface's palette */
-        for (i = 0; i < 256; i++) {
-            table[i][0] = pal->palents[i].peRed;
-            table[i][1] = pal->palents[i].peGreen;
-            table[i][2] = pal->palents[i].peBlue;
 
 
-            /* When index_in_alpha is the palette index is stored in the alpha component. In case of a readback
-               we can then read GL_ALPHA. Color keying is handled in BltOverride using a GL_ALPHA_TEST using GL_NOT_EQUAL.
-               In case of index_in_alpha the color key itself is passed to glAlphaFunc in other cases the alpha component
-               of pixels that should be masked away is set to 0. */
-            if(index_in_alpha) {
-                table[i][3] = i;
-            } else if(colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue) &&  (i <= This->SrcBltCKey.dwColorSpaceHighValue)) {
-                table[i][3] = 0x00;
-            } else if(pal->Flags & WINEDDPCAPS_ALPHA) {
-                table[i][3] = pal->palents[i].peFlags;
-            } else {
-                table[i][3] = 0xFF;
+        case CONVERT_D24FS8:
+        {
+            unsigned int x, y;
+
+            for (y = 0; y < height; ++y)
+            {
+                const DWORD *source = (const DWORD *)(src + y * pitch);
+                float *dest_f = (float *)(dst + y * outpitch);
+                DWORD *dest_s = (DWORD *)(dst + y * outpitch);
+
+                for (x = 0; x < width; ++x)
+                {
+                    dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
+                    dest_s[x * 2 + 1] = source[x] & 0xff;
+                }
             }
             }
+            break;
         }
         }
+
+        default:
+            ERR("Unsupported conversion type %#x.\n", convert);
     }
     }
+    return WINED3D_OK;
 }
 
 /* This function is used in case of 8bit paletted textures to upload the palette.
    It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other
    extensions like ATI_fragment_shaders is possible.
 */
 }
 
 /* This function is used in case of 8bit paletted textures to upload the palette.
    It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other
    extensions like ATI_fragment_shaders is possible.
 */
+/* Context activation is done by the caller. */
 static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     BYTE table[256][4];
 static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     BYTE table[256][4];
@@ -2263,7 +2446,9 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
     if(GL_SUPPORT(EXT_PALETTED_TEXTURE))
     {
         TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
     if(GL_SUPPORT(EXT_PALETTED_TEXTURE))
     {
         TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
-        GL_EXTCALL(glColorTableEXT(This->glDescription.target,GL_RGBA,256,GL_RGBA,GL_UNSIGNED_BYTE, table));
+        ENTER_GL();
+        GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
+        LEAVE_GL();
     }
     else
     {
     }
     else
     {
@@ -2271,6 +2456,8 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
          * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
         TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");
 
          * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
         TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");
 
+        ENTER_GL();
+
         /* Create the fragment program if we don't have it */
         if(!device->paletteConversionShader)
         {
         /* Create the fragment program if we don't have it */
         if(!device->paletteConversionShader)
         {
@@ -2309,7 +2496,9 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0));
 
         /* Rebind the texture because it isn't bound anymore */
         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0));
 
         /* Rebind the texture because it isn't bound anymore */
-        glBindTexture(This->glDescription.target, This->glDescription.textureName);
+        glBindTexture(This->texture_target, This->texture_name);
+
+        LEAVE_GL();
     }
 }
 
     }
 }
 
@@ -2383,7 +2572,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
         char buffer[4096];
         ++gen;
         if ((gen % 10) == 0) {
         char buffer[4096];
         ++gen;
         if ((gen % 10) == 0) {
-            snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen);
+            snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm",
+                    This, This->texture_target, This->texture_level, gen);
             IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
         }
         /*
             IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
         }
         /*
@@ -2406,6 +2596,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+/* Context activation is done by the caller. */
 static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
     /* TODO: check for locks */
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
     /* TODO: check for locks */
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
@@ -2421,30 +2612,31 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL
         GLuint *name;
         TRACE("(%p) : Binding surface\n", This);
 
         GLuint *name;
         TRACE("(%p) : Binding surface\n", This);
 
-        name = srgb ? &This->glDescription.srgbTextureName : &This->glDescription.textureName;
+        name = srgb ? &This->texture_name_srgb : &This->texture_name;
         if(!device->isInDraw) {
         if(!device->isInDraw) {
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
         }
 
         ENTER_GL();
 
         }
 
         ENTER_GL();
 
-        if (!This->glDescription.level) {
+        if (!This->texture_level)
+        {
             if (!*name) {
                 glGenTextures(1, name);
                 checkGLcall("glGenTextures");
                 TRACE("Surface %p given name %d\n", This, *name);
 
             if (!*name) {
                 glGenTextures(1, name);
                 checkGLcall("glGenTextures");
                 TRACE("Surface %p given name %d\n", This, *name);
 
-                glBindTexture(This->glDescription.target, *name);
+                glBindTexture(This->texture_target, *name);
                 checkGLcall("glBindTexture");
                 checkGLcall("glBindTexture");
-                glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
-                glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
-                glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)");
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)");
-                glTexParameteri(This->glDescription.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+                glTexParameteri(This->texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
-                glTexParameteri(This->glDescription.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameteri(This->texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
             }
             /* This is where we should be reducing the amount of GLMemoryUsed */
                 checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
             }
             /* This is where we should be reducing the amount of GLMemoryUsed */
@@ -2453,7 +2645,7 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL
             ERR("Mipmap surface has a glTexture bound to it!\n");
         }
 
             ERR("Mipmap surface has a glTexture bound to it!\n");
         }
 
-        glBindTexture(This->glDescription.target, This->glDescription.textureName);
+        glBindTexture(This->texture_target, *name);
         checkGLcall("glBindTexture");
 
         LEAVE_GL();
         checkGLcall("glBindTexture");
 
         LEAVE_GL();
@@ -2536,13 +2728,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c
     }
     allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width  * height * 4);
     ENTER_GL();
     }
     allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width  * height * 4);
     ENTER_GL();
-    FIXME("Saving texture level %d width %d height %d\n", This->glDescription.level, width, height);
-    glGetTexImage(GL_TEXTURE_2D,
-                This->glDescription.level,
-                GL_RGBA,
-                GL_UNSIGNED_INT_8_8_8_8_REV,
-                allocatedMemory);
-    checkGLcall("glTexImage2D");
+    FIXME("Saving texture level %d width %d height %d\n", This->texture_level, width, height);
+    glGetTexImage(GL_TEXTURE_2D, This->texture_level, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, allocatedMemory);
+    checkGLcall("glGetTexImage");
     if (tmpTexture) {
         glBindTexture(GL_TEXTURE_2D, 0);
         glDeleteTextures(1, &tmpTexture);
     if (tmpTexture) {
         glBindTexture(GL_TEXTURE_2D, 0);
         glDeleteTextures(1, &tmpTexture);
@@ -2743,9 +2931,15 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) {
 
     /* Flip the opengl texture */
     {
 
     /* Flip the opengl texture */
     {
-        glDescriptor tmp_desc = back->glDescription;
-        back->glDescription = front->glDescription;
-        front->glDescription = tmp_desc;
+        GLuint tmp;
+
+        tmp = back->texture_name;
+        back->texture_name = front->texture_name;
+        front->texture_name = tmp;
+
+        tmp = back->texture_name_srgb;
+        back->texture_name_srgb = front->texture_name_srgb;
+        front->texture_name_srgb = tmp;
     }
 
     {
     }
 
     {
@@ -2779,7 +2973,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
     }
 
     if(override) {
     }
 
     if(override) {
-        /* DDraw sets this for the X11 surfaces, so don't confuse the user 
+        /* DDraw sets this for the X11 surfaces, so don't confuse the user
          * FIXME("(%p) Target override is not supported by now\n", This);
          * Additionally, it isn't really possible to support triple-buffering
          * properly on opengl at all
          * FIXME("(%p) Target override is not supported by now\n", This);
          * Additionally, it isn't really possible to support triple-buffering
          * properly on opengl at all
@@ -2832,7 +3026,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
     ENTER_GL();
 
     /* Bind the target texture */
     ENTER_GL();
 
     /* Bind the target texture */
-    glBindTexture(This->glDescription.target, This->glDescription.textureName);
+    glBindTexture(This->texture_target, This->texture_name);
     checkGLcall("glBindTexture");
     if(!swapchain) {
         TRACE("Reading from an offscreen target\n");
     checkGLcall("glBindTexture");
     if(!swapchain) {
         TRACE("Reading from an offscreen target\n");
@@ -2847,26 +3041,30 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
     xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1);
     yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1);
 
     xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1);
     yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1);
 
-    if( (xrel - 1.0 < -eps) || (xrel - 1.0 > eps)) {
+    if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+    {
         FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n");
 
         if(Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT) {
             ERR("Texture filtering not supported in direct blit\n");
         }
         FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n");
 
         if(Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT) {
             ERR("Texture filtering not supported in direct blit\n");
         }
-    } else if((Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT) && ((yrel - 1.0 < -eps) || (yrel - 1.0 > eps))) {
+    }
+    else if ((Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT)
+            && ((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
+    {
         ERR("Texture filtering not supported in direct blit\n");
     }
 
         ERR("Texture filtering not supported in direct blit\n");
     }
 
-    if(upsidedown &&
-       !((xrel - 1.0 < -eps) || (xrel - 1.0 > eps)) &&
-       !((yrel - 1.0 < -eps) || (yrel - 1.0 > eps))) {
+    if (upsidedown
+            && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+            && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
+    {
         /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */
 
         /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */
 
-        glCopyTexSubImage2D(This->glDescription.target,
-                            This->glDescription.level,
-                            drect->x1, drect->y1, /* xoffset, yoffset */
-                            srect->x1, Src->currentDesc.Height - srect->y2,
-                            drect->x2 - drect->x1, drect->y2 - drect->y1);
+        glCopyTexSubImage2D(This->texture_target, This->texture_level,
+                drect->x1 /*xoffset */, drect->y1 /* y offset */,
+                srect->x1, Src->currentDesc.Height - srect->y2,
+                drect->x2 - drect->x1, drect->y2 - drect->y1);
     } else {
         UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1;
         /* I have to process this row by row to swap the image,
     } else {
         UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1;
         /* I have to process this row by row to swap the image,
@@ -2876,25 +3074,22 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
          * However, stretching in x direction can be avoided if not necessary
          */
         for(row = drect->y1; row < drect->y2; row++) {
          * However, stretching in x direction can be avoided if not necessary
          */
         for(row = drect->y1; row < drect->y2; row++) {
-            if( (xrel - 1.0 < -eps) || (xrel - 1.0 > eps)) {
+            if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+            {
                 /* Well, that stuff works, but it's very slow.
                  * find a better way instead
                  */
                 UINT col;
 
                 for(col = drect->x1; col < drect->x2; col++) {
                 /* Well, that stuff works, but it's very slow.
                  * find a better way instead
                  */
                 UINT col;
 
                 for(col = drect->x1; col < drect->x2; col++) {
-                    glCopyTexSubImage2D(This->glDescription.target,
-                                        This->glDescription.level,
-                                        drect->x1 + col, row, /* xoffset, yoffset */
-                                        srect->x1 + col * xrel, yoffset - (int) (row * yrel),
-                                        1, 1);
+                    glCopyTexSubImage2D(This->texture_target, This->texture_level,
+                            drect->x1 + col /* x offset */, row /* y offset */,
+                            srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1);
                 }
             } else {
                 }
             } else {
-                glCopyTexSubImage2D(This->glDescription.target,
-                                    This->glDescription.level,
-                                    drect->x1, row, /* xoffset, yoffset */
-                                    srect->x1, yoffset - (int) (row * yrel),
-                                    drect->x2-drect->x1, 1);
+                glCopyTexSubImage2D(This->texture_target, This->texture_level,
+                        drect->x1 /* x offset */, row /* y offset */,
+                        srect->x1, yoffset - (int) (row * yrel), drect->x2-drect->x1, 1);
             }
         }
     }
             }
         }
     }
@@ -2914,17 +3109,19 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     float left, right, top, bottom; /* Texture coordinates */
     UINT fbwidth = Src->currentDesc.Width;
     UINT fbheight = Src->currentDesc.Height;
     float left, right, top, bottom; /* Texture coordinates */
     UINT fbwidth = Src->currentDesc.Width;
     UINT fbheight = Src->currentDesc.Height;
+    struct wined3d_context *context;
     GLenum drawBuffer = GL_BACK;
     GLenum texture_target;
     BOOL noBackBufferBackup;
 
     TRACE("Using hwstretch blit\n");
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
     GLenum drawBuffer = GL_BACK;
     GLenum texture_target;
     BOOL noBackBufferBackup;
 
     TRACE("Using hwstretch blit\n");
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
-    ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
+    context = ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
     surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
 
     noBackBufferBackup = !swapchain && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
     surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
 
     noBackBufferBackup = !swapchain && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
-    if(!noBackBufferBackup && Src->glDescription.textureName == 0) {
+    if (!noBackBufferBackup && !Src->texture_name)
+    {
         /* Get it a description */
         surface_internal_preload(SrcSurface, SRGB_RGB);
     }
         /* Get it a description */
         surface_internal_preload(SrcSurface, SRGB_RGB);
     }
@@ -2933,27 +3130,30 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring.
      * This way we don't have to wait for the 2nd readback to finish to leave this function.
      */
     /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring.
      * This way we don't have to wait for the 2nd readback to finish to leave this function.
      */
-    if(myDevice->activeContext->aux_buffers >= 2) {
+    if (context->aux_buffers >= 2)
+    {
         /* Got more than one aux buffer? Use the 2nd aux buffer */
         drawBuffer = GL_AUX1;
         /* Got more than one aux buffer? Use the 2nd aux buffer */
         drawBuffer = GL_AUX1;
-    } else if((swapchain || myDevice->offscreenBuffer == GL_BACK) && myDevice->activeContext->aux_buffers >= 1) {
+    }
+    else if ((swapchain || myDevice->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1)
+    {
         /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */
         drawBuffer = GL_AUX0;
     }
 
     if(noBackBufferBackup) {
         glGenTextures(1, &backup);
         /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */
         drawBuffer = GL_AUX0;
     }
 
     if(noBackBufferBackup) {
         glGenTextures(1, &backup);
-        checkGLcall("glGenTextures\n");
+        checkGLcall("glGenTextures");
         glBindTexture(GL_TEXTURE_2D, backup);
         glBindTexture(GL_TEXTURE_2D, backup);
-        checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
+        checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
         texture_target = GL_TEXTURE_2D;
     } else {
         /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
          * we are reading from the back buffer, the backup can be used as source texture
          */
         texture_target = GL_TEXTURE_2D;
     } else {
         /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
          * we are reading from the back buffer, the backup can be used as source texture
          */
-        texture_target = Src->glDescription.target;
-        glBindTexture(texture_target, Src->glDescription.textureName);
-        checkGLcall("glBindTexture(texture_target, Src->glDescription.textureName)");
+        texture_target = Src->texture_target;
+        glBindTexture(texture_target, Src->texture_name);
+        checkGLcall("glBindTexture(texture_target, Src->texture_name)");
         glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
 
         glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
 
@@ -2980,14 +3180,14 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
 
     /* No issue with overriding these - the sampler is dirty due to blit usage */
     glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER,
 
     /* No issue with overriding these - the sampler is dirty due to blit usage */
     glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER,
-                    magLookup[Filter - WINED3DTEXF_NONE]);
+            wined3d_gl_mag_filter(magLookup, Filter));
     checkGLcall("glTexParameteri");
     glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
     checkGLcall("glTexParameteri");
     glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
-                    minMipLookup[Filter].mip[WINED3DTEXF_NONE]);
+            wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
     checkGLcall("glTexParameteri");
 
     if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
     checkGLcall("glTexParameteri");
 
     if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
-        src = backup ? backup : Src->glDescription.textureName;
+        src = backup ? backup : Src->texture_name;
     } else {
         glReadBuffer(GL_FRONT);
         checkGLcall("glReadBuffer(GL_FRONT)");
     } else {
         glReadBuffer(GL_FRONT);
         checkGLcall("glReadBuffer(GL_FRONT)");
@@ -3069,14 +3269,15 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     glEnd();
     checkGLcall("glEnd and previous");
 
     glEnd();
     checkGLcall("glEnd and previous");
 
-    if(texture_target != This->glDescription.target) {
+    if (texture_target != This->texture_target)
+    {
         glDisable(texture_target);
         glDisable(texture_target);
-        glEnable(This->glDescription.target);
-        texture_target = This->glDescription.target;
+        glEnable(This->texture_target);
+        texture_target = This->texture_target;
     }
 
     /* Now read the stretched and upside down image into the destination texture */
     }
 
     /* Now read the stretched and upside down image into the destination texture */
-    glBindTexture(texture_target, This->glDescription.textureName);
+    glBindTexture(texture_target, This->texture_name);
     checkGLcall("glBindTexture");
     glCopyTexSubImage2D(texture_target,
                         0,
     checkGLcall("glBindTexture");
     glCopyTexSubImage2D(texture_target,
                         0,
@@ -3096,26 +3297,27 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
             glBindTexture(GL_TEXTURE_2D, backup);
             checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
         } else {
             glBindTexture(GL_TEXTURE_2D, backup);
             checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
         } else {
-            if(texture_target != Src->glDescription.target) {
+            if (texture_target != Src->texture_target)
+            {
                 glDisable(texture_target);
                 glDisable(texture_target);
-                glEnable(Src->glDescription.target);
-                texture_target = Src->glDescription.target;
+                glEnable(Src->texture_target);
+                texture_target = Src->texture_target;
             }
             }
-            glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
-            checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
+            glBindTexture(Src->texture_target, Src->texture_name);
+            checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)");
         }
 
         glBegin(GL_QUADS);
             /* top left */
         }
 
         glBegin(GL_QUADS);
             /* top left */
-            glTexCoord2f(0.0, (float) fbheight / (float) Src->pow2Height);
+            glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height);
             glVertex2i(0, 0);
 
             /* bottom left */
             glVertex2i(0, 0);
 
             /* bottom left */
-            glTexCoord2f(0.0, 0.0);
+            glTexCoord2f(0.0f, 0.0f);
             glVertex2i(0, fbheight);
 
             /* bottom right */
             glVertex2i(0, fbheight);
 
             /* bottom right */
-            glTexCoord2f((float) fbwidth / (float) Src->pow2Width, 0.0);
+            glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f);
             glVertex2i(fbwidth, Src->currentDesc.Height);
 
             /* top right */
             glVertex2i(fbwidth, Src->currentDesc.Height);
 
             /* top right */
@@ -3130,7 +3332,8 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     checkGLcall("glDisable(texture_target)");
 
     /* Cleanup */
     checkGLcall("glDisable(texture_target)");
 
     /* Cleanup */
-    if(src != Src->glDescription.textureName && src != backup) {
+    if (src != Src->texture_name && src != backup)
+    {
         glDeleteTextures(1, &src);
         checkGLcall("glDeleteTextures(1, &src)");
     }
         glDeleteTextures(1, &src);
         checkGLcall("glDeleteTextures(1, &src)");
     }
@@ -3384,7 +3587,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
          * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
          * backends.
          */
          * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
          * backends.
          */
-        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)) {
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)
+                && surface_can_stretch_rect(Src, This))
+        {
             stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
                     (IWineD3DSurface *)This, &rect, Filter, upsideDown);
         } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width ||
             stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
                     (IWineD3DSurface *)This, &rect, Filter, upsideDown);
         } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width ||
@@ -3446,8 +3651,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             Src->palette = This->palette;
         }
 
             Src->palette = This->palette;
         }
 
-        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT) &&
-            (Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) == 0) {
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)
+                && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
+                && surface_can_stretch_rect(Src, This))
+        {
             TRACE("Using stretch_rect_fbo\n");
             /* The source is always a texture, but never the currently active render target, and the texture
              * contents are never upside down
             TRACE("Using stretch_rect_fbo\n");
             /* The source is always a texture, but never the currently active render target, and the texture
              * contents are never upside down
@@ -3511,67 +3718,76 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h;
         }
 
             rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h;
         }
 
+        if (!is_identity_fixup(This->resource.format_desc->color_fixup))
+        {
+            FIXME("Destination format %s has a fixup, this is not supported.\n",
+                    debug_d3dformat(This->resource.format_desc->format));
+            dump_color_fixup_desc(This->resource.format_desc->color_fixup);
+        }
+
+        if (!myDevice->blitter->color_fixup_supported(Src->resource.format_desc->color_fixup))
+        {
+            FIXME("Source format %s has an unsupported fixup:\n",
+                    debug_d3dformat(Src->resource.format_desc->format));
+            dump_color_fixup_desc(Src->resource.format_desc->color_fixup);
+        }
+
         myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc,
         myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc,
-                Src->glDescription.target, Src->pow2Width, Src->pow2Height);
+                Src->texture_target, Src->pow2Width, Src->pow2Height);
 
         ENTER_GL();
 
         /* Bind the texture */
 
         ENTER_GL();
 
         /* Bind the texture */
-        glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
+        glBindTexture(Src->texture_target, Src->texture_name);
         checkGLcall("glBindTexture");
 
         /* Filtering for StretchRect */
         checkGLcall("glBindTexture");
 
         /* Filtering for StretchRect */
-        glTexParameteri(Src->glDescription.target, GL_TEXTURE_MAG_FILTER,
-                        magLookup[Filter - WINED3DTEXF_NONE]);
+        glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER,
+                wined3d_gl_mag_filter(magLookup, Filter));
         checkGLcall("glTexParameteri");
         checkGLcall("glTexParameteri");
-        glTexParameteri(Src->glDescription.target, GL_TEXTURE_MIN_FILTER,
-                        minMipLookup[Filter].mip[WINED3DTEXF_NONE]);
+        glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER,
+                wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
         checkGLcall("glTexParameteri");
         checkGLcall("glTexParameteri");
-        glTexParameteri(Src->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP);
-        glTexParameteri(Src->glDescription.target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         checkGLcall("glTexEnvi");
 
         /* This is for color keying */
         if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
             glEnable(GL_ALPHA_TEST);
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         checkGLcall("glTexEnvi");
 
         /* This is for color keying */
         if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
             glEnable(GL_ALPHA_TEST);
-            checkGLcall("glEnable GL_ALPHA_TEST");
+            checkGLcall("glEnable(GL_ALPHA_TEST)");
 
             /* When the primary render target uses P8, the alpha component contains the palette index.
              * Which means that the colorkey is one of the palette entries. In other cases pixels that
              * should be masked away have alpha set to 0. */
             if(primary_render_target_is_p8(myDevice))
 
             /* When the primary render target uses P8, the alpha component contains the palette index.
              * Which means that the colorkey is one of the palette entries. In other cases pixels that
              * should be masked away have alpha set to 0. */
             if(primary_render_target_is_p8(myDevice))
-                glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0);
+                glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
             else
             else
-                glAlphaFunc(GL_NOTEQUAL, 0.0);
-            checkGLcall("glAlphaFunc\n");
+                glAlphaFunc(GL_NOTEQUAL, 0.0f);
+            checkGLcall("glAlphaFunc");
         } else {
             glDisable(GL_ALPHA_TEST);
         } else {
             glDisable(GL_ALPHA_TEST);
-            checkGLcall("glDisable GL_ALPHA_TEST");
+            checkGLcall("glDisable(GL_ALPHA_TEST)");
         }
 
         /* Draw a textured quad
          */
         glBegin(GL_QUADS);
 
         }
 
         /* Draw a textured quad
          */
         glBegin(GL_QUADS);
 
-        glColor3d(1.0f, 1.0f, 1.0f);
+        glColor3f(1.0f, 1.0f, 1.0f);
         glTexCoord2f(glTexCoord[0], glTexCoord[2]);
         glTexCoord2f(glTexCoord[0], glTexCoord[2]);
-        glVertex3f(rect.x1,
-                    rect.y1,
-                    0.0);
+        glVertex3f(rect.x1, rect.y1, 0.0f);
 
         glTexCoord2f(glTexCoord[0], glTexCoord[3]);
 
         glTexCoord2f(glTexCoord[0], glTexCoord[3]);
-        glVertex3f(rect.x1, rect.y2, 0.0);
+        glVertex3f(rect.x1, rect.y2, 0.0f);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[3]);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[3]);
-        glVertex3f(rect.x2,
-                    rect.y2,
-                    0.0);
+        glVertex3f(rect.x2, rect.y2, 0.0f);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[2]);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[2]);
-        glVertex3f(rect.x2,
-                    rect.y1,
-                    0.0);
+        glVertex3f(rect.x2, rect.y1, 0.0f);
+
         glEnd();
         checkGLcall("glEnd");
 
         glEnd();
         checkGLcall("glEnd");
 
@@ -3580,8 +3796,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             checkGLcall("glDisable(GL_ALPHA_TEST)");
         }
 
             checkGLcall("glDisable(GL_ALPHA_TEST)");
         }
 
-        glBindTexture(Src->glDescription.target, 0);
-        checkGLcall("glBindTexture(Src->glDescription.target, 0)");
+        glBindTexture(Src->texture_target, 0);
+        checkGLcall("glBindTexture(Src->texture_target, 0)");
 
         /* Restore the color key parameters */
         Src->CKeyFlags = oldCKeyFlags;
 
         /* Restore the color key parameters */
         Src->CKeyFlags = oldCKeyFlags;
@@ -3598,7 +3814,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
 
         /* Flush in case the drawable is used by multiple GL contexts */
         if(dstSwapchain && (This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer || dstSwapchain->num_contexts >= 2))
 
         /* Flush in case the drawable is used by multiple GL contexts */
         if(dstSwapchain && (This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer || dstSwapchain->num_contexts >= 2))
-            glFlush();
+            wglFlush();
 
         /* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
         /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
 
         /* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
         /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
@@ -3669,11 +3885,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             }
 
             TRACE("(%p) executing Render Target override, color = %x\n", This, color);
             }
 
             TRACE("(%p) executing Render Target override, color = %x\n", This, color);
-            IWineD3DDeviceImpl_ClearSurface(myDevice, This,
-                                            1, /* Number of rectangles */
-                                            &rect, WINED3DCLEAR_TARGET, color,
-                                            0.0 /* Z */,
-                                            0 /* Stencil */);
+            IWineD3DDeviceImpl_ClearSurface(myDevice, This, 1 /* Number of rectangles */,
+                    &rect, WINED3DCLEAR_TARGET, color, 0.0f /* Z */, 0 /* Stencil */);
             return WINED3D_OK;
         }
     }
             return WINED3D_OK;
         }
     }
@@ -3706,7 +3919,7 @@ static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *D
                 depth = (float) DDBltFx->u5.dwFillDepth / (float) 0xffffffff;
                 break;
             default:
                 depth = (float) DDBltFx->u5.dwFillDepth / (float) 0xffffffff;
                 break;
             default:
-                depth = 0.0;
+                depth = 0.0f;
                 ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format));
         }
 
                 ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format));
         }
 
@@ -3843,13 +4056,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface)
         CONVERT_TYPES convert;
 
         /* Check if we are using a RTL mode which uses texturing for uploads */
         CONVERT_TYPES convert;
 
         /* Check if we are using a RTL mode which uses texturing for uploads */
-        BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX);
+        BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX);
 
         /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */
         d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE);
 
         if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION))
         {
 
         /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */
         d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE);
 
         if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION))
         {
+            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
             /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
             IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL);
 
             /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
             IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL);
 
@@ -3857,6 +4072,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface)
             IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
 
             /* Re-upload the palette */
             IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
 
             /* Re-upload the palette */
+            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
             d3dfmt_p8_upload_palette(iface, convert);
         } else {
             if(!(This->Flags & SFLAG_INSYSMEM)) {
             d3dfmt_p8_upload_palette(iface, convert);
         } else {
             if(!(This->Flags & SFLAG_INSYSMEM)) {
@@ -3891,8 +4107,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
     unsigned int pow2Width, pow2Height;
 
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
     unsigned int pow2Width, pow2Height;
 
-    This->glDescription.textureName      = 0;
-    This->glDescription.target           = GL_TEXTURE_2D;
+    This->texture_name = 0;
+    This->texture_target = GL_TEXTURE_2D;
 
     /* Non-power2 support */
     if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || GL_SUPPORT(WINE_NORMALIZED_TEXRECT)) {
 
     /* Non-power2 support */
     if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || GL_SUPPORT(WINE_NORMALIZED_TEXRECT)) {
@@ -3908,11 +4124,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
     This->pow2Height = pow2Height;
 
     if (pow2Width > This->currentDesc.Width || pow2Height > This->currentDesc.Height) {
     This->pow2Height = pow2Height;
 
     if (pow2Width > This->currentDesc.Width || pow2Height > This->currentDesc.Height) {
-        WINED3DFORMAT Format = This->resource.format_desc->format;
         /** TODO: add support for non power two compressed textures **/
         /** TODO: add support for non power two compressed textures **/
-        if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3
-            || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5
-            || Format == WINED3DFMT_ATI2N)
+        if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
         {
             FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n",
                   This, This->currentDesc.Width, This->currentDesc.Height);
         {
             FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n",
                   This, This->currentDesc.Width, This->currentDesc.Height);
@@ -3950,10 +4163,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
         */
         if(This->Flags & SFLAG_NONPOW2 && GL_SUPPORT(ARB_TEXTURE_RECTANGLE)
                 && !((This->resource.format_desc->format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE)
         */
         if(This->Flags & SFLAG_NONPOW2 && GL_SUPPORT(ARB_TEXTURE_RECTANGLE)
                 && !((This->resource.format_desc->format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE)
-                && (wined3d_settings.rendertargetlock_mode == RTL_READTEX
-                || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
+                && (wined3d_settings.rendertargetlock_mode == RTL_READTEX)))
         {
         {
-            This->glDescription.target = GL_TEXTURE_RECTANGLE_ARB;
+            This->texture_target = GL_TEXTURE_RECTANGLE_ARB;
             This->pow2Width  = This->currentDesc.Width;
             This->pow2Height = This->currentDesc.Height;
             This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
             This->pow2Width  = This->currentDesc.Width;
             This->pow2Height = This->currentDesc.Height;
             This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
@@ -4073,6 +4285,7 @@ static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, stru
     }
 }
 
     }
 }
 
+/* GL locking is done by the caller */
 static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target)
 {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target)
 {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
@@ -4082,14 +4295,14 @@ static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei
     glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
 
     glDisable(GL_CULL_FACE);
     glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
 
     glDisable(GL_CULL_FACE);
-    glEnable(GL_BLEND);
+    glDisable(GL_BLEND);
     glDisable(GL_ALPHA_TEST);
     glDisable(GL_SCISSOR_TEST);
     glDisable(GL_STENCIL_TEST);
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_ALWAYS);
     glDepthMask(GL_TRUE);
     glDisable(GL_ALPHA_TEST);
     glDisable(GL_SCISSOR_TEST);
     glDisable(GL_STENCIL_TEST);
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_ALWAYS);
     glDepthMask(GL_TRUE);
-    glBlendFunc(GL_ZERO, GL_ONE);
+    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
     glViewport(0, 0, w, h);
 
     surface_get_depth_blt_info(target, w, h, &info);
     glViewport(0, 0, w, h);
 
     surface_get_depth_blt_info(target, w, h, &info);
@@ -4130,7 +4343,9 @@ void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) {
     This->Flags |= location;
 }
 
     This->Flags |= location;
 }
 
-void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
+/* Context activation is done by the caller. */
+void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location)
+{
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
@@ -4164,8 +4379,9 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
 
             /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
              * directly on the FBO texture. That's because we need to flip. */
 
             /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
              * directly on the FBO texture. That's because we need to flip. */
-            GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-            if (This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
+            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+            {
                 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
                 bind_target = GL_TEXTURE_RECTANGLE_ARB;
             } else {
                 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
                 bind_target = GL_TEXTURE_RECTANGLE_ARB;
             } else {
@@ -4173,16 +4389,13 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
                 bind_target = GL_TEXTURE_2D;
             }
             glBindTexture(bind_target, device->depth_blt_texture);
                 bind_target = GL_TEXTURE_2D;
             }
             glBindTexture(bind_target, device->depth_blt_texture);
-            glCopyTexImage2D(bind_target,
-                    This->glDescription.level,
-                    This->resource.format_desc->glInternal,
-                    0,
-                    0,
-                    This->currentDesc.Width,
-                    This->currentDesc.Height,
-                    0);
+            glCopyTexImage2D(bind_target, This->texture_level, This->resource.format_desc->glInternal,
+                    0, 0, This->currentDesc.Width, This->currentDesc.Height, 0);
             glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
             glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
             glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
             glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+            glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+            glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
             glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
             glBindTexture(bind_target, old_binding);
 
             glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
             glBindTexture(bind_target, old_binding);
 
@@ -4201,21 +4414,17 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
-            context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->dst_fbo);
+            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb));
             checkGLcall("glFramebufferRenderbufferEXT");
             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb));
             checkGLcall("glFramebufferRenderbufferEXT");
-            context_attach_depth_stencil_fbo(device, GL_FRAMEBUFFER_EXT, iface, FALSE);
+            context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, iface, FALSE);
 
             /* Do the actual blit */
             surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target);
             checkGLcall("depth_blt");
 
 
             /* Do the actual blit */
             surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target);
             checkGLcall("depth_blt");
 
-            if (device->activeContext->current_fbo) {
-                context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->current_fbo->id);
-            } else {
-                GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-                checkGLcall("glBindFramebuffer()");
-            }
+            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
+            else context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
 
             LEAVE_GL();
         } else {
 
             LEAVE_GL();
         } else {
@@ -4227,15 +4436,12 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
 
             ENTER_GL();
 
 
             ENTER_GL();
 
-            GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-            checkGLcall("glBindFramebuffer()");
-            surface_depth_blt(This, This->glDescription.textureName, This->currentDesc.Width, This->currentDesc.Height, This->glDescription.target);
+            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            surface_depth_blt(This, This->texture_name, This->currentDesc.Width,
+                    This->currentDesc.Height, This->texture_target);
             checkGLcall("depth_blt");
 
             checkGLcall("depth_blt");
 
-            if (device->activeContext->current_fbo) {
-                GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, device->activeContext->current_fbo->id));
-                checkGLcall("glBindFramebuffer()");
-            }
+            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
 
             LEAVE_GL();
         } else {
 
             LEAVE_GL();
         } else {
@@ -4320,7 +4526,9 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float
     f->b = ((r->bottom * 2.0f) / h) - 1.0f;
 }
 
     f->b = ((r->bottom * 2.0f) / h) - 1.0f;
 }
 
-static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) {
+static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
+{
+    const struct wined3d_context *context;
     struct coords coords[4];
     RECT rect;
     IWineD3DSwapChain *swapchain;
     struct coords coords[4];
     RECT rect;
     IWineD3DSwapChain *swapchain;
@@ -4338,7 +4546,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
         rect.bottom = This->currentDesc.Height;
     }
 
         rect.bottom = This->currentDesc.Height;
     }
 
-    switch(This->glDescription.target)
+    switch (This->texture_target)
     {
         case GL_TEXTURE_2D:
             bind_target = GL_TEXTURE_2D;
     {
         case GL_TEXTURE_2D:
             bind_target = GL_TEXTURE_2D;
@@ -4423,23 +4631,24 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
             break;
 
         default:
             break;
 
         default:
-            ERR("Unexpected texture target %#x\n", This->glDescription.target);
+            ERR("Unexpected texture target %#x\n", This->texture_target);
             return;
     }
 
             return;
     }
 
-    ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
+    context = ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
+
     ENTER_GL();
 
     glEnable(bind_target);
     checkGLcall("glEnable(bind_target)");
     ENTER_GL();
 
     glEnable(bind_target);
     checkGLcall("glEnable(bind_target)");
-    glBindTexture(bind_target, This->glDescription.textureName);
-    checkGLcall("bind_target, This->glDescription.textureName)");
+    glBindTexture(bind_target, This->texture_name);
+    checkGLcall("glBindTexture(bind_target, This->texture_name)");
     glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
     glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
 
     glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
     glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     checkGLcall("glTexParameteri");
 
-    if (device->render_offscreen)
+    if (context->render_offscreen)
     {
         LONG tmp = rect.top;
         rect.top = rect.bottom;
     {
         LONG tmp = rect.top;
         rect.top = rect.bottom;
@@ -4471,7 +4680,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
         /* Make sure to flush the buffers. This is needed in apps like Red Alert II and Tiberian SUN that use multiple WGL contexts. */
         if(((IWineD3DSwapChainImpl*)swapchain)->frontBuffer == (IWineD3DSurface*)This ||
            ((IWineD3DSwapChainImpl*)swapchain)->num_contexts >= 2)
         /* Make sure to flush the buffers. This is needed in apps like Red Alert II and Tiberian SUN that use multiple WGL contexts. */
         if(((IWineD3DSwapChainImpl*)swapchain)->frontBuffer == (IWineD3DSurface*)This ||
            ((IWineD3DSwapChainImpl*)swapchain)->num_contexts >= 2)
-            glFlush();
+            wglFlush();
 
         IWineD3DSwapChain_Release(swapchain);
     } else {
 
         IWineD3DSwapChain_Release(swapchain);
     } else {
@@ -4552,11 +4761,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
 
         /* Download the surface to system memory */
         if(This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) {
 
         /* Download the surface to system memory */
         if(This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) {
-            if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
             surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));
 
             surface_download_data(This);
         } else {
             surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));
 
             surface_download_data(This);
         } else {
+            /* Note: It might be faster to download into a texture first. */
             read_from_framebuffer(This, rect,
                                   This->resource.allocatedMemory,
                                   IWineD3DSurface_GetPitch(iface));
             read_from_framebuffer(This, rect,
                                   This->resource.allocatedMemory,
                                   IWineD3DSurface_GetPitch(iface));
@@ -4583,6 +4793,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
              * but it isn't set (yet) in all cases it is getting called. */
             if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) {
                 TRACE("Removing the pbo attached to surface %p\n", This);
              * but it isn't set (yet) in all cases it is getting called. */
             if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) {
                 TRACE("Removing the pbo attached to surface %p\n", This);
+                if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
                 surface_remove_pbo(This);
             }
 
                 surface_remove_pbo(This);
             }
 
@@ -4634,7 +4845,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
                 }
             }
 
                 }
             }
 
-            if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+            if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
             surface_bind_and_dirtify(This, srgb);
 
             if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
             surface_bind_and_dirtify(This, srgb);
 
             if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
@@ -4829,7 +5040,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
     IWineD3DSurfaceImpl_BindTexture,
     IWineD3DSurfaceImpl_SaveSnapshot,
     IWineD3DSurfaceImpl_SetContainer,
     IWineD3DSurfaceImpl_BindTexture,
     IWineD3DSurfaceImpl_SaveSnapshot,
     IWineD3DSurfaceImpl_SetContainer,
-    IWineD3DSurfaceImpl_GetGlDesc,
     IWineD3DBaseSurfaceImpl_GetData,
     IWineD3DSurfaceImpl_SetFormat,
     IWineD3DSurfaceImpl_PrivateSetup,
     IWineD3DBaseSurfaceImpl_GetData,
     IWineD3DSurfaceImpl_SetFormat,
     IWineD3DSurfaceImpl_PrivateSetup,
@@ -4842,18 +5052,24 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
 
 #define GLINFO_LOCATION device->adapter->gl_info
 static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
 
 #define GLINFO_LOCATION device->adapter->gl_info
 static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
+/* Context activation is done by the caller. */
 static void ffp_blit_free(IWineD3DDevice *iface) { }
 
 static void ffp_blit_free(IWineD3DDevice *iface) { }
 
+/* Context activation is done by the caller. */
 static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
         GLenum textype, UINT width, UINT height)
 {
 static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
         GLenum textype, UINT width, UINT height)
 {
+    ENTER_GL();
     glEnable(textype);
     checkGLcall("glEnable(textype)");
     glEnable(textype);
     checkGLcall("glEnable(textype)");
+    LEAVE_GL();
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+/* Context activation is done by the caller. */
 static void ffp_blit_unset(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
 static void ffp_blit_unset(IWineD3DDevice *iface) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
+    ENTER_GL();
     glDisable(GL_TEXTURE_2D);
     checkGLcall("glDisable(GL_TEXTURE_2D)");
     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
     glDisable(GL_TEXTURE_2D);
     checkGLcall("glDisable(GL_TEXTURE_2D)");
     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
@@ -4864,6 +5080,7 @@ static void ffp_blit_unset(IWineD3DDevice *iface) {
         glDisable(GL_TEXTURE_RECTANGLE_ARB);
         checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
     }
         glDisable(GL_TEXTURE_RECTANGLE_ARB);
         checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
     }
+    LEAVE_GL();
 }
 
 static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup)
 }
 
 static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup)
index d487f80..5c00b2b 100644 (file)
@@ -30,8 +30,6 @@
 #include "wine/port.h"
 #include "wined3d_private.h"
 
 #include "wine/port.h"
 #include "wined3d_private.h"
 
-#include <assert.h>
-
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 
 /* See also float_16_to_32() in wined3d_private.h */
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 
 /* See also float_16_to_32() in wined3d_private.h */
@@ -43,26 +41,26 @@ static inline unsigned short float_32_to_16(const float *in)
     unsigned short ret;
 
     /* Deal with special numbers */
     unsigned short ret;
 
     /* Deal with special numbers */
-    if(*in == 0.0) return 0x0000;
+    if (*in == 0.0f) return 0x0000;
     if(isnan(*in)) return 0x7C01;
     if(isnan(*in)) return 0x7C01;
-    if(isinf(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);
+    if (isinf(*in)) return (*in < 0.0f ? 0xFC00 : 0x7c00);
 
     if(tmp < pow(2, 10)) {
         do
         {
 
     if(tmp < pow(2, 10)) {
         do
         {
-            tmp = tmp * 2.0;
+            tmp = tmp * 2.0f;
             exp--;
         }while(tmp < pow(2, 10));
     } else if(tmp >= pow(2, 11)) {
         do
         {
             exp--;
         }while(tmp < pow(2, 10));
     } else if(tmp >= pow(2, 11)) {
         do
         {
-            tmp /= 2.0;
+            tmp /= 2.0f;
             exp++;
         }while(tmp >= pow(2, 11));
     }
 
     mantissa = (unsigned int) tmp;
             exp++;
         }while(tmp >= pow(2, 11));
     }
 
     mantissa = (unsigned int) tmp;
-    if(tmp - mantissa >= 0.5) mantissa++; /* round to nearest, away from zero */
+    if(tmp - mantissa >= 0.5f) mantissa++; /* round to nearest, away from zero */
 
     exp += 10;  /* Normalize the mantissa */
     exp += 15;  /* Exponent is encoded with excess 15 */
 
     exp += 10;  /* Normalize the mantissa */
     exp += 15;  /* Exponent is encoded with excess 15 */
@@ -80,7 +78,7 @@ static inline unsigned short float_32_to_16(const float *in)
         ret = (exp << 10) | (mantissa & 0x3ff);
     }
 
         ret = (exp << 10) | (mantissa & 0x3ff);
     }
 
-    ret |= ((*in < 0.0 ? 1 : 0) << 15); /* Add the sign */
+    ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */
     return ret;
 }
 
     return ret;
 }
 
@@ -181,15 +179,17 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSU
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
     TRACE("(%p) : copying into %p\n", This, pDesc);
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
     TRACE("(%p) : copying into %p\n", This, pDesc);
-    if(pDesc->Format != NULL)             *(pDesc->Format) = This->resource.format_desc->format;
-    if(pDesc->Type != NULL)               *(pDesc->Type)   = This->resource.resourceType;
-    if(pDesc->Usage != NULL)              *(pDesc->Usage)              = This->resource.usage;
-    if(pDesc->Pool != NULL)               *(pDesc->Pool)               = This->resource.pool;
-    if(pDesc->Size != NULL)               *(pDesc->Size)               = This->resource.size;   /* dx8 only */
-    if(pDesc->MultiSampleType != NULL)    *(pDesc->MultiSampleType)    = This->currentDesc.MultiSampleType;
-    if(pDesc->MultiSampleQuality != NULL) *(pDesc->MultiSampleQuality) = This->currentDesc.MultiSampleQuality;
-    if(pDesc->Width != NULL)              *(pDesc->Width)              = This->currentDesc.Width;
-    if(pDesc->Height != NULL)             *(pDesc->Height)             = This->currentDesc.Height;
+
+    pDesc->format = This->resource.format_desc->format;
+    pDesc->resource_type = This->resource.resourceType;
+    pDesc->usage = This->resource.usage;
+    pDesc->pool = This->resource.pool;
+    pDesc->size = This->resource.size; /* dx8 only */
+    pDesc->multisample_type = This->currentDesc.MultiSampleType;
+    pDesc->multisample_quality = This->currentDesc.MultiSampleQuality;
+    pDesc->width = This->currentDesc.Width;
+    pDesc->height = This->currentDesc.Height;
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -332,19 +332,19 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD
 
 DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 
 DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
-    WINED3DFORMAT format = This->resource.format_desc->format;
+    const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
     DWORD ret;
     TRACE("(%p)\n", This);
 
     DWORD ret;
     TRACE("(%p)\n", This);
 
-    /* DXTn formats don't have exact pitches as they are to the new row of blocks,
-    where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5)
-    ie pitch = (width/4) * bytes per block                                  */
-    if (format == WINED3DFMT_DXT1) /* DXT1 is 8 bytes per block */
-        ret = ((This->currentDesc.Width + 3) >> 2) << 3;
-    else if (format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 ||
-             format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */
-        ret = ((This->currentDesc.Width + 3) >> 2) << 4;
-    else {
+    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+    {
+        /* Since compressed formats are block based, pitch means the amount of
+         * bytes to the next row of block rather than the next row of pixels. */
+        UINT row_block_count = (This->currentDesc.Width + format_desc->block_width - 1) / format_desc->block_width;
+        ret = row_block_count * format_desc->block_byte_count;
+    }
+    else
+    {
         unsigned char alignment = This->resource.wineD3DDevice->surface_alignment;
         ret = This->resource.format_desc->byte_count * This->currentDesc.Width;  /* Bytes / row */
         ret = (ret + alignment - 1) & ~(alignment - 1);
         unsigned char alignment = This->resource.wineD3DDevice->surface_alignment;
         ret = This->resource.format_desc->byte_count * This->currentDesc.Width;  /* Bytes / row */
         ret = (ret + alignment - 1) & ~(alignment - 1);
@@ -519,20 +519,9 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D
     }
 
     TRACE("(%p) : Setting texture format to (%d,%s)\n", This, format, debug_d3dformat(format));
     }
 
     TRACE("(%p) : Setting texture format to (%d,%s)\n", This, format, debug_d3dformat(format));
-    if (format == WINED3DFMT_UNKNOWN) {
-        This->resource.size = 0;
-    } else if (format == WINED3DFMT_DXT1) {
-        /* DXT1 is half byte per pixel */
-        This->resource.size = ((max(This->pow2Width, 4) * format_desc->byte_count) * max(This->pow2Height, 4)) >> 1;
-
-    } else if (format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 ||
-               format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) {
-        This->resource.size = ((max(This->pow2Width, 4) * format_desc->byte_count) * max(This->pow2Height, 4));
-    } else {
-        unsigned char alignment = This->resource.wineD3DDevice->surface_alignment;
-        This->resource.size = ((This->pow2Width * format_desc->byte_count) + alignment - 1) & ~(alignment - 1);
-        This->resource.size *= This->pow2Height;
-    }
+
+    This->resource.size = surface_calculate_size(format_desc, This->resource.wineD3DDevice->surface_alignment,
+            This->pow2Width, This->pow2Height);
 
     This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;
 
 
     This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;
 
@@ -735,6 +724,25 @@ static void convert_r5g6b5_x8r8g8b8(const BYTE *src, BYTE *dst,
     }
 }
 
     }
 }
 
+static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst,
+        DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+    unsigned int x, y;
+
+    TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+    for (y = 0; y < h; ++y)
+    {
+        const DWORD *src_line = (const DWORD *)(src + y * pitch_in);
+        DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+
+        for (x = 0; x < w; ++x)
+        {
+            dst_line[x] = 0xff000000 | (src_line[x] & 0xffffff);
+        }
+    }
+}
+
 struct d3dfmt_convertor_desc {
     WINED3DFORMAT from, to;
     void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
 struct d3dfmt_convertor_desc {
     WINED3DFORMAT from, to;
     void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
@@ -744,6 +752,7 @@ static const struct d3dfmt_convertor_desc convertors[] =
 {
     {WINED3DFMT_R32_FLOAT,  WINED3DFMT_R16_FLOAT,   convert_r32_float_r16_float},
     {WINED3DFMT_R5G6B5,     WINED3DFMT_X8R8G8B8,    convert_r5g6b5_x8r8g8b8},
 {
     {WINED3DFMT_R32_FLOAT,  WINED3DFMT_R16_FLOAT,   convert_r32_float_r16_float},
     {WINED3DFMT_R5G6B5,     WINED3DFMT_X8R8G8B8,    convert_r5g6b5_x8r8g8b8},
+    {WINED3DFMT_A8R8G8B8,   WINED3DFMT_X8R8G8B8,    convert_a8r8g8b8_x8r8g8b8},
 };
 
 static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
 };
 
 static inline const struct d3dfmt_convertor_desc *find_convertor(WINED3DFORMAT from, WINED3DFORMAT to)
@@ -781,10 +790,9 @@ static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source,
         return NULL;
     }
 
         return NULL;
     }
 
-    IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.wineD3DDevice,
-            source->currentDesc.Width, source->currentDesc.Height, to_fmt, TRUE /* lockable */,
-            TRUE /* discard  */, 0 /* level */, &ret, WINED3DRTYPE_SURFACE, 0 /* usage */,
-            WINED3DPOOL_SCRATCH, WINED3DMULTISAMPLE_NONE /* TODO: Multisampled conversion */,
+    IWineD3DDevice_CreateSurface((IWineD3DDevice *)source->resource.wineD3DDevice, source->currentDesc.Width,
+            source->currentDesc.Height, to_fmt, TRUE /* lockable */, TRUE /* discard  */, 0 /* level */, &ret,
+            0 /* usage */, WINED3DPOOL_SCRATCH, WINED3DMULTISAMPLE_NONE /* TODO: Multisampled conversion */,
             0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), NULL /* parent */);
     if(!ret) {
         ERR("Failed to create a destination surface for conversion\n");
             0 /* MultiSampleQuality */, IWineD3DSurface_GetImplType((IWineD3DSurface *) source), NULL /* parent */);
     if(!ret) {
         ERR("Failed to create a destination surface for conversion\n");
@@ -1127,8 +1135,6 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D
     dstwidth = xdst.right - xdst.left;
     width = (xdst.right - xdst.left) * bpp;
 
     dstwidth = xdst.right - xdst.left;
     width = (xdst.right - xdst.left) * bpp;
 
-    assert(width <= dlock.Pitch);
-
     if (DestRect && Src != This)
         dbuf = dlock.pBits;
     else
     if (DestRect && Src != This)
         dbuf = dlock.pBits;
     else
@@ -1629,7 +1635,6 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dst
         slock.Pitch = dlock.Pitch;
 
         /* Since slock was originally copied from this surface's description, we can just reuse it */
         slock.Pitch = dlock.Pitch;
 
         /* Since slock was originally copied from this surface's description, we can just reuse it */
-        assert(This->resource.allocatedMemory != NULL);
         sbuf = This->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp;
         dbuf = This->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp;
         sEntry = Src->resource.format_desc;
         sbuf = This->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp;
         dbuf = This->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp;
         sEntry = Src->resource.format_desc;
@@ -1650,63 +1655,39 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dst
         dEntry = This->resource.format_desc;
     }
 
         dEntry = This->resource.format_desc;
     }
 
-    /* Handle first the FOURCC surfaces... */
-    if (sEntry->Flags & dEntry->Flags & WINED3DFMT_FLAG_FOURCC)
+    /* Handle compressed surfaces first... */
+    if (sEntry->Flags & dEntry->Flags & WINED3DFMT_FLAG_COMPRESSED)
     {
     {
-        UINT block_width;
-        UINT block_height;
-        UINT block_byte_size;
+        UINT row_block_count;
 
 
-        TRACE("Fourcc -> Fourcc copy\n");
+        TRACE("compressed -> compressed copy\n");
         if (trans)
         if (trans)
-            FIXME("trans arg not supported when a FOURCC surface is involved\n");
+            FIXME("trans arg not supported when a compressed surface is involved\n");
         if (dstx || dsty)
             FIXME("offset for destination surface is not supported\n");
         if (Src->resource.format_desc->format != This->resource.format_desc->format)
         {
         if (dstx || dsty)
             FIXME("offset for destination surface is not supported\n");
         if (Src->resource.format_desc->format != This->resource.format_desc->format)
         {
-            FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
+            FIXME("compressed -> compressed copy only supported for the same type of surface\n");
             ret = WINED3DERR_WRONGTEXTUREFORMAT;
             goto error;
         }
 
             ret = WINED3DERR_WRONGTEXTUREFORMAT;
             goto error;
         }
 
-        if (This->resource.format_desc->format == WINED3DFMT_DXT1)
+        row_block_count = (w + dEntry->block_width - 1) / dEntry->block_width;
+        for (y = 0; y < h; y += dEntry->block_height)
         {
         {
-            block_width = 4;
-            block_height = 4;
-            block_byte_size = 8;
-        }
-        else if (This->resource.format_desc->format == WINED3DFMT_DXT2
-                || This->resource.format_desc->format == WINED3DFMT_DXT3
-                || This->resource.format_desc->format == WINED3DFMT_DXT4
-                || This->resource.format_desc->format == WINED3DFMT_DXT5)
-        {
-            block_width = 4;
-            block_height = 4;
-            block_byte_size = 16;
-        }
-        else
-        {
-            FIXME("Unsupported FourCC format %s.\n", debug_d3dformat(This->resource.format_desc->format));
-            block_width = 1;
-            block_height = 1;
-            block_byte_size = This->resource.format_desc->byte_count;
-        }
-
-        for (y = 0; y < h; y += block_height)
-        {
-            memcpy(dbuf, sbuf, (w / block_width) * block_byte_size);
+            memcpy(dbuf, sbuf, row_block_count * dEntry->block_byte_count);
             dbuf += dlock.Pitch;
             sbuf += slock.Pitch;
         }
 
         goto error;
     }
             dbuf += dlock.Pitch;
             sbuf += slock.Pitch;
         }
 
         goto error;
     }
-    if ((sEntry->Flags & WINED3DFMT_FLAG_FOURCC) && !(dEntry->Flags & WINED3DFMT_FLAG_FOURCC))
+    if ((sEntry->Flags & WINED3DFMT_FLAG_COMPRESSED) && !(dEntry->Flags & WINED3DFMT_FLAG_COMPRESSED))
     {
         /* TODO: Use the libtxc_dxtn.so shared library to do
          * software decompression
          */
     {
         /* TODO: Use the libtxc_dxtn.so shared library to do
          * software decompression
          */
-        ERR("DXTC decompression not supported by now\n");
+        ERR("Software decompression not supported.\n");
         goto error;
     }
 
         goto error;
     }
 
@@ -1844,32 +1825,24 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL
     }
     else
     {
     }
     else
     {
+        const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+
         TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
               pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
 
         TRACE("Lock Rect (%p) = l %d, t %d, r %d, b %d\n",
               pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
 
-        /* DXTn textures are based on compressed blocks of 4x4 pixels, each
-         * 16 bytes large (8 bytes in case of DXT1). Because of that Pitch has
-         * slightly different meaning compared to regular textures. For DXTn
-         * textures Pitch is the size of a row of blocks, 4 high and "width"
-         * long. The x offset is calculated differently as well, since moving 4
-         * pixels to the right actually moves an entire 4x4 block to right, ie
-         * 16 bytes (8 in case of DXT1). */
-        if (This->resource.format_desc->format == WINED3DFMT_DXT1)
-        {
-            pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 2);
-        }
-        else if (This->resource.format_desc->format == WINED3DFMT_DXT2
-                || This->resource.format_desc->format == WINED3DFMT_DXT3
-                || This->resource.format_desc->format == WINED3DFMT_DXT4
-                || This->resource.format_desc->format == WINED3DFMT_DXT5)
+        if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
         {
         {
-            pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
+            /* Compressed textures are block based, so calculate the offset of
+             * the block that contains the top-left pixel of the locked rectangle. */
+            pLockedRect->pBits = This->resource.allocatedMemory
+                    + ((pRect->top / format_desc->block_height) * pLockedRect->Pitch)
+                    + ((pRect->left / format_desc->block_width) * format_desc->block_byte_count);
         }
         else
         {
             pLockedRect->pBits = This->resource.allocatedMemory +
                     (pLockedRect->Pitch * pRect->top) +
         }
         else
         {
             pLockedRect->pBits = This->resource.allocatedMemory +
                     (pLockedRect->Pitch * pRect->top) +
-                    (pRect->left * This->resource.format_desc->byte_count);
+                    (pRect->left * format_desc->byte_count);
         }
         This->lockedRect.left   = pRect->left;
         This->lockedRect.top    = pRect->top;
         }
         This->lockedRect.left   = pRect->left;
         This->lockedRect.top    = pRect->top;
index 0ad65e0..0246782 100644 (file)
 #include "wine/port.h"
 #include "wined3d_private.h"
 
 #include "wine/port.h"
 #include "wined3d_private.h"
 
-#include <assert.h>
 #include <stdio.h>
 
 /* Use the d3d_surface debug channel to have one channel for all surfaces */
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 
 #include <stdio.h>
 
 /* Use the d3d_surface debug channel to have one channel for all surfaces */
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 
+void surface_gdi_cleanup(IWineD3DSurfaceImpl *This)
+{
+    TRACE("(%p) : Cleaning up.\n", This);
+
+    if (This->Flags & SFLAG_DIBSECTION)
+    {
+        /* Release the DC. */
+        SelectObject(This->hDC, This->dib.holdbitmap);
+        DeleteDC(This->hDC);
+        /* Release the DIB section. */
+        DeleteObject(This->dib.DIBsection);
+        This->dib.bitmap_data = NULL;
+        This->resource.allocatedMemory = NULL;
+    }
+
+    if (This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem((IWineD3DSurface *)This, NULL);
+    if (This->overlay_dest) list_remove(&This->overlay_entry);
+
+    HeapFree(GetProcessHeap(), 0, This->palette9);
+
+    resource_cleanup((IWineD3DResource *)This);
+}
+
 /*****************************************************************************
  * IWineD3DSurface::Release, GDI version
  *
 /*****************************************************************************
  * IWineD3DSurface::Release, GDI version
  *
@@ -46,32 +68,15 @@ static ULONG WINAPI IWineGDISurfaceImpl_Release(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->resource.ref);
     TRACE("(%p) : Releasing from %d\n", This, ref + 1);
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     ULONG ref = InterlockedDecrement(&This->resource.ref);
     TRACE("(%p) : Releasing from %d\n", This, ref + 1);
-    if (ref == 0) {
-        TRACE("(%p) : cleaning up\n", This);
-
-        if(This->Flags & SFLAG_DIBSECTION) {
-            /* Release the DC */
-            SelectObject(This->hDC, This->dib.holdbitmap);
-            DeleteDC(This->hDC);
-            /* Release the DIB section */
-            DeleteObject(This->dib.DIBsection);
-            This->dib.bitmap_data = NULL;
-            This->resource.allocatedMemory = NULL;
-        }
-        if(This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem(iface, NULL);
-
-        HeapFree(GetProcessHeap(), 0, This->palette9);
 
 
-        resource_cleanup((IWineD3DResource *)iface);
-
-        if(This->overlay_dest) {
-            list_remove(&This->overlay_entry);
-        }
+    if (!ref)
+    {
+        surface_gdi_cleanup(This);
 
 
-        TRACE("(%p) Released\n", This);
+        TRACE("(%p) Released.\n", This);
         HeapFree(GetProcessHeap(), 0, This);
         HeapFree(GetProcessHeap(), 0, This);
-
     }
     }
+
     return ref;
 }
 
     return ref;
 }
 
@@ -178,7 +183,8 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
             char buffer[4096];
             ++gen;
             if ((gen % 10) == 0) {
             char buffer[4096];
             ++gen;
             if ((gen % 10) == 0) {
-                snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen);
+                snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm",
+                        This, This->texture_target, This->texture_level, gen);
                 IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
             }
             /*
                 IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
             }
             /*
@@ -194,7 +200,10 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
     /* Tell the swapchain to update the screen */
     if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
     /* Tell the swapchain to update the screen */
     if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
-        x11_copy_to_screen(swapchain, &This->lockedRect);
+        if(iface == swapchain->frontBuffer)
+        {
+            x11_copy_to_screen(swapchain, &This->lockedRect);
+        }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
@@ -485,7 +494,10 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface)
     /* Tell the swapchain to update the screen */
     if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
     /* Tell the swapchain to update the screen */
     if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
-        x11_copy_to_screen(swapchain, NULL);
+        if(iface == swapchain->frontBuffer)
+        {
+            x11_copy_to_screen(swapchain, NULL);
+        }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
@@ -536,12 +548,6 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3DSurface *iface)
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static void WINAPI IWineGDISurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription) {
-    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    FIXME("(%p) : Should not be called on a GDI surface\n", This);
-    *glDescription = NULL;
-}
-
 static HRESULT WINAPI IWineGDISurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 
 static HRESULT WINAPI IWineGDISurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
 
@@ -671,7 +677,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
     IWineD3DBaseSurfaceImpl_BindTexture,
     IWineGDISurfaceImpl_SaveSnapshot,
     IWineD3DBaseSurfaceImpl_SetContainer,
     IWineD3DBaseSurfaceImpl_BindTexture,
     IWineGDISurfaceImpl_SaveSnapshot,
     IWineD3DBaseSurfaceImpl_SetContainer,
-    IWineGDISurfaceImpl_GetGlDesc,
     IWineD3DBaseSurfaceImpl_GetData,
     IWineD3DBaseSurfaceImpl_SetFormat,
     IWineGDISurfaceImpl_PrivateSetup,
     IWineD3DBaseSurfaceImpl_GetData,
     IWineD3DBaseSurfaceImpl_SetFormat,
     IWineGDISurfaceImpl_PrivateSetup,
index 12f812e..d8d3733 100644 (file)
@@ -45,26 +45,36 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
 
     IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
 
 
     IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
 
-    /* release the ref to the front and back buffer parents */
-    if(This->frontBuffer) {
+    /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
+     * the last buffer to be destroyed, FindContext() depends on that. */
+    if (This->frontBuffer)
+    {
         IWineD3DSurface_SetContainer(This->frontBuffer, 0);
         IWineD3DSurface_SetContainer(This->frontBuffer, 0);
-        if(D3DCB_DestroyRenderTarget(This->frontBuffer) > 0) {
-            FIXME("(%p) Something's still holding the front buffer\n",This);
+        if (D3DCB_DestroyRenderTarget(This->frontBuffer))
+        {
+            FIXME("(%p) Something's still holding the front buffer (%p).\n",
+                    This, This->frontBuffer);
         }
         }
+        This->frontBuffer = NULL;
     }
 
     }
 
-    if(This->backBuffer) {
-        UINT i;
-        for(i = 0; i < This->presentParms.BackBufferCount; i++) {
+    if (This->backBuffer)
+    {
+        UINT i = This->presentParms.BackBufferCount;
+
+        while (i--)
+        {
             IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
             IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
-            if(D3DCB_DestroyRenderTarget(This->backBuffer[i]) > 0) {
-                FIXME("(%p) Something's still holding the back buffer\n",This);
-            }
+            if (D3DCB_DestroyRenderTarget(This->backBuffer[i]))
+                FIXME("(%p) Something's still holding back buffer %u (%p).\n",
+                        This, i, This->backBuffer[i]);
         }
         HeapFree(GetProcessHeap(), 0, This->backBuffer);
         }
         HeapFree(GetProcessHeap(), 0, This->backBuffer);
+        This->backBuffer = NULL;
     }
 
     }
 
-    for(i = 0; i < This->num_contexts; i++) {
+    for (i = 0; i < This->num_contexts; ++i)
+    {
         DestroyContext(This->wineD3DDevice, This->context[i]);
     }
     /* Restore the screen resolution if we rendered in fullscreen
         DestroyContext(This->wineD3DDevice, This->context[i]);
     }
     /* Restore the screen resolution if we rendered in fullscreen
@@ -111,9 +121,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
         cursor.resource.pool = WINED3DPOOL_SCRATCH;
         cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &This->wineD3DDevice->adapter->gl_info);
         cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
         cursor.resource.pool = WINED3DPOOL_SCRATCH;
         cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_A8R8G8B8, &This->wineD3DDevice->adapter->gl_info);
         cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
-        cursor.glDescription.textureName = This->wineD3DDevice->cursorTexture;
-        cursor.glDescription.target = GL_TEXTURE_2D;
-        cursor.glDescription.level = 0;
+        cursor.texture_name = This->wineD3DDevice->cursorTexture;
+        cursor.texture_target = GL_TEXTURE_2D;
+        cursor.texture_level = 0;
         cursor.currentDesc.Width = This->wineD3DDevice->cursorWidth;
         cursor.currentDesc.Height = This->wineD3DDevice->cursorHeight;
         cursor.glRect.left = 0;
         cursor.currentDesc.Width = This->wineD3DDevice->cursorWidth;
         cursor.currentDesc.Height = This->wineD3DDevice->cursorHeight;
         cursor.glRect.left = 0;
@@ -131,7 +141,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
         if (This->presentParms.Windowed) {
             MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
         }
         if (This->presentParms.Windowed) {
             MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
         }
-        IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_NONE);
+        IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor,
+                NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
     }
     if(This->wineD3DDevice->logo_surface) {
         /* Blit the logo into the upper left corner of the drawable */
     }
     if(This->wineD3DDevice->logo_surface) {
         /* Blit the logo into the upper left corner of the drawable */
@@ -223,7 +234,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
         TRACE("Clearing the color buffer with cyan color\n");
 
         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL,
         TRACE("Clearing the color buffer with cyan color\n");
 
         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL,
-                              WINED3DCLEAR_TARGET, 0xff00ffff, 1.0, 0);
+                WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
     }
 
     if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags   & SFLAG_INSYSMEM ||
     }
 
     if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags   & SFLAG_INSYSMEM ||
@@ -371,10 +382,11 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
     IWineD3DBaseSwapChainImpl_GetGammaRamp
 };
 
     IWineD3DBaseSwapChainImpl_GetGammaRamp
 };
 
-WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface) {
-    WineD3DContext *ctx;
+struct wined3d_context *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface)
+{
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
-    WineD3DContext **newArray;
+    struct wined3d_context **newArray;
+    struct wined3d_context *ctx;
 
     TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
 
 
     TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
 
@@ -401,10 +413,11 @@ WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *
     return ctx;
 }
 
     return ctx;
 }
 
-void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
+void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height)
+{
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt;
     /* The drawable size of an onscreen drawable is the surface size.
     /* The drawable size of an onscreen drawable is the surface size.
-     * (Actually: The window size, but the surface is created in window size)
-     */
-    *width = This->currentDesc.Width;
-    *height = This->currentDesc.Height;
+     * (Actually: The window size, but the surface is created in window size) */
+    *width = surface->currentDesc.Width;
+    *height = surface->currentDesc.Height;
 }
 }
index dda4353..dd8f32e 100644 (file)
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
+#define GLINFO_LOCATION (*gl_info)
+
+static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb)
+{
+    /* Override the IWineD3DResource PreLoad method. */
+    IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    unsigned int i;
+    BOOL srgb_mode;
+    BOOL *dirty;
+
+    TRACE("(%p) : About to load texture.\n", This);
+
+    switch (srgb)
+    {
+        case SRGB_RGB:
+            srgb_mode = FALSE;
+            break;
+
+        case SRGB_BOTH:
+            texture_internal_preload(iface, SRGB_RGB);
+            /* Fallthrough */
+
+        case SRGB_SRGB:
+            srgb_mode = TRUE;
+            break;
+
+        default:
+            srgb_mode = This->baseTexture.is_srgb;
+            break;
+    }
+    dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
+
+    if (!device->isInDraw)
+    {
+        /* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture,
+         * thus no danger of recursive calls. */
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    }
+
+    if (This->resource.format_desc->format == WINED3DFMT_P8
+            || This->resource.format_desc->format == WINED3DFMT_A8P8)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            if (palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i]))
+            {
+                TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
+                /* TODO: This is not necessarily needed with hw palettized texture support. */
+                IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL);
+                /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
+                IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE);
+            }
+        }
+    }
+
+    /* If the texture is marked dirty or the srgb sampler setting has changed
+     * since the last load then reload the surfaces. */
+    if (*dirty)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
+        }
+    }
+    else
+    {
+        TRACE("(%p) Texture not dirty, nothing to do.\n", iface);
+    }
+
+    /* No longer dirty. */
+    *dirty = FALSE;
+}
+
+static void texture_cleanup(IWineD3DTextureImpl *This, D3DCB_DESTROYSURFACEFN surface_destroy_cb)
+{
+    unsigned int i;
+
+    TRACE("(%p) : Cleaning up\n", This);
+
+    for (i = 0; i < This->baseTexture.levels; ++i)
+    {
+        if (This->surfaces[i])
+        {
+            /* Clean out the texture name we gave to the surface so that the
+             * surface doesn't try and release it */
+            surface_set_texture_name(This->surfaces[i], 0, TRUE);
+            surface_set_texture_name(This->surfaces[i], 0, FALSE);
+            surface_set_texture_target(This->surfaces[i], 0);
+            IWineD3DSurface_SetContainer(This->surfaces[i], 0);
+            surface_destroy_cb(This->surfaces[i]);
+        }
+    }
+
+    TRACE("(%p) : Cleaning up base texture\n", This);
+    basetexture_cleanup((IWineD3DBaseTexture *)This);
+}
+
+HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+    UINT pow2_width, pow2_height;
+    UINT tmp_w, tmp_h;
+    unsigned int i;
+    HRESULT hr;
+
+    /* TODO: It should only be possible to create textures for formats
+     * that are reported as supported. */
+    if (WINED3DFMT_UNKNOWN >= format)
+    {
+        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    /* Non-power2 support. */
+    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO))
+    {
+        pow2_width = width;
+        pow2_height = height;
+    }
+    else
+    {
+        /* Find the nearest pow2 match. */
+        pow2_width = pow2_height = 1;
+        while (pow2_width < width) pow2_width <<= 1;
+        while (pow2_height < height) pow2_height <<= 1;
+
+        if (pow2_width != width || pow2_height != height)
+        {
+            if (levels > 1)
+            {
+                WARN("Attempted to create a mipmapped np2 texture without unconditional np2 support.\n");
+                return WINED3DERR_INVALIDCALL;
+            }
+            levels = 1;
+        }
+    }
+
+    /* Calculate levels for mip mapping. */
+    if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        levels = 1;
+    }
+    else if (!levels)
+    {
+        levels = wined3d_log2i(max(width, height)) + 1;
+        TRACE("Calculated levels = %u.\n", levels);
+    }
+
+    hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels,
+            WINED3DRTYPE_TEXTURE, device, 0, usage, format_desc, pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize basetexture, returning %#x.\n", hr);
+        return hr;
+    }
+
+    /* Precalculated scaling for 'faked' non power of two texture coords.
+     * Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
+     * is used in combination with texture uploads (RTL_READTEX). The reason is that EXT_PALETTED_TEXTURE
+     * doesn't work in combination with ARB_TEXTURE_RECTANGLE. */
+    if (GL_SUPPORT(WINE_NORMALIZED_TEXRECT) && (width != pow2_width || height != pow2_height))
+    {
+        texture->baseTexture.pow2Matrix[0] = 1.0f;
+        texture->baseTexture.pow2Matrix[5] = 1.0f;
+        texture->baseTexture.pow2Matrix[10] = 1.0f;
+        texture->baseTexture.pow2Matrix[15] = 1.0f;
+        texture->target = GL_TEXTURE_2D;
+        texture->cond_np2 = TRUE;
+        texture->baseTexture.minMipLookup = minMipLookup_noFilter;
+    }
+    else if (GL_SUPPORT(ARB_TEXTURE_RECTANGLE) && (width != pow2_width || height != pow2_height)
+            && !((format_desc->format == WINED3DFMT_P8) && GL_SUPPORT(EXT_PALETTED_TEXTURE)
+            && (wined3d_settings.rendertargetlock_mode == RTL_READTEX)))
+    {
+        if ((width != 1) || (height != 1)) texture->baseTexture.pow2Matrix_identity = FALSE;
+
+        texture->baseTexture.pow2Matrix[0] = (float)width;
+        texture->baseTexture.pow2Matrix[5] = (float)height;
+        texture->baseTexture.pow2Matrix[10] = 1.0f;
+        texture->baseTexture.pow2Matrix[15] = 1.0f;
+        texture->target = GL_TEXTURE_RECTANGLE_ARB;
+        texture->cond_np2 = TRUE;
+
+        if(texture->resource.format_desc->Flags & WINED3DFMT_FLAG_FILTERING)
+        {
+            texture->baseTexture.minMipLookup = minMipLookup_noMip;
+        }
+        else
+        {
+            texture->baseTexture.minMipLookup = minMipLookup_noFilter;
+        }
+    }
+    else
+    {
+        if ((width != pow2_width) || (height != pow2_height))
+        {
+            texture->baseTexture.pow2Matrix_identity = FALSE;
+            texture->baseTexture.pow2Matrix[0] = (((float)width) / ((float)pow2_width));
+            texture->baseTexture.pow2Matrix[5] = (((float)height) / ((float)pow2_height));
+        }
+        else
+        {
+            texture->baseTexture.pow2Matrix[0] = 1.0f;
+            texture->baseTexture.pow2Matrix[5] = 1.0f;
+        }
+
+        texture->baseTexture.pow2Matrix[10] = 1.0f;
+        texture->baseTexture.pow2Matrix[15] = 1.0f;
+        texture->target = GL_TEXTURE_2D;
+        texture->cond_np2 = FALSE;
+    }
+    TRACE("xf(%f) yf(%f)\n", texture->baseTexture.pow2Matrix[0], texture->baseTexture.pow2Matrix[5]);
+
+    /* Generate all the surfaces. */
+    tmp_w = width;
+    tmp_h = height;
+    for (i = 0; i < texture->baseTexture.levels; ++i)
+    {
+        /* Use the callback to create the texture surface. */
+        hr = IWineD3DDeviceParent_CreateSurface(device->device_parent, parent, tmp_w, tmp_h, format_desc->format,
+                usage, pool, i, WINED3DCUBEMAP_FACE_POSITIVE_X, &texture->surfaces[i]);
+        if (FAILED(hr) || ((IWineD3DSurfaceImpl *)texture->surfaces[i])->Flags & SFLAG_OVERSIZE)
+        {
+            FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
+            texture->surfaces[i] = NULL;
+            texture_cleanup(texture, D3DCB_DefaultDestroySurface);
+            return hr;
+        }
+
+        IWineD3DSurface_SetContainer(texture->surfaces[i], (IWineD3DBase *)texture);
+        TRACE("Created surface level %u @ %p.\n", i, texture->surfaces[i]);
+        surface_set_texture_target(texture->surfaces[i], texture->target);
+        /* Calculate the next mipmap level. */
+        tmp_w = max(1, tmp_w >> 1);
+        tmp_h = max(1, tmp_h >> 1);
+    }
+    texture->baseTexture.internal_preload = texture_internal_preload;
+
+    return WINED3D_OK;
+}
+
+#undef GLINFO_LOCATION
 
 /* *******************************************
    IWineD3DTexture IUnknown parts follow
    ******************************************* */
 
 /* *******************************************
    IWineD3DTexture IUnknown parts follow
    ******************************************* */
+
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
 static HRESULT WINAPI IWineD3DTextureImpl_QueryInterface(IWineD3DTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
 static HRESULT WINAPI IWineD3DTextureImpl_QueryInterface(IWineD3DTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
@@ -92,61 +352,6 @@ static DWORD WINAPI IWineD3DTextureImpl_GetPriority(IWineD3DTexture *iface) {
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
-void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
-
-    /* Override the IWineD3DResource PreLoad method */
-    unsigned int i;
-    IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BOOL srgb_mode;
-    BOOL *dirty;
-
-    TRACE("(%p) : About to load texture\n", This);
-
-    switch(srgb) {
-        case SRGB_RGB:      srgb_mode = FALSE; break;
-        case SRGB_BOTH:     texture_internal_preload(iface, SRGB_RGB);
-        case SRGB_SRGB:     srgb_mode = TRUE; break;
-        /* DONTKNOW, and shut up the compiler */
-        default:            srgb_mode = This->baseTexture.is_srgb; break;
-    }
-    dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
-
-    if(!device->isInDraw) {
-        /* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture, thus no danger of
-         * recursive calls
-         */
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-    }
-
-    if (This->resource.format_desc->format == WINED3DFMT_P8
-            || This->resource.format_desc->format == WINED3DFMT_A8P8)
-    {
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            if(palette9_changed((IWineD3DSurfaceImpl *)This->surfaces[i])) {
-                TRACE("Reloading surface because the d3d8/9 palette was changed\n");
-                /* TODO: This is not necessarily needed with hw palettized texture support */
-                IWineD3DSurface_LoadLocation(This->surfaces[i], SFLAG_INSYSMEM, NULL);
-                /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
-                IWineD3DSurface_ModifyLocation(This->surfaces[i], SFLAG_INTEXTURE, FALSE);
-            }
-        }
-    }
-    /* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
-    if (*dirty) {
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
-        }
-    } else {
-        TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
-    }
-
-    /* No longer dirty */
-    *dirty = FALSE;
-
-    return ;
-}
-
 static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
     texture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
 static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
     texture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
@@ -213,6 +418,7 @@ static BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) {
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
+/* Context activation is done by the caller. */
 static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
     BOOL set_gl_texture_desc;
 static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
     BOOL set_gl_texture_desc;
@@ -271,33 +477,13 @@ static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture *iface) {
     return This->cond_np2;
 }
 
     return This->cond_np2;
 }
 
-static void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface,
-                                                   const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
-                                                   const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
-    TRACE("(%p) : relay to BaseTexture\n", iface);
-    basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
-}
-
 /* *******************************************
    IWineD3DTexture IWineD3DTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
 /* *******************************************
    IWineD3DTexture IWineD3DTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
     IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
-    unsigned int i;
 
 
-    TRACE("(%p) : Cleaning up\n",This);
-    for (i = 0; i < This->baseTexture.levels; i++) {
-        if (This->surfaces[i] != NULL) {
-            /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
-            surface_set_texture_name(This->surfaces[i], 0, TRUE);
-            surface_set_texture_name(This->surfaces[i], 0, FALSE);
-            surface_set_texture_target(This->surfaces[i], 0);
-            IWineD3DSurface_SetContainer(This->surfaces[i], 0);
-            D3DCB_DestroySurface(This->surfaces[i]);
-        }
-    }
-    TRACE("(%p) : cleaning up base texture\n", This);
-    basetexture_cleanup((IWineD3DBaseTexture *)iface);
+    texture_cleanup(This, D3DCB_DestroySurface);
     /* free the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
     /* free the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -401,7 +587,6 @@ const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
     IWineD3DTextureImpl_BindTexture,
     IWineD3DTextureImpl_GetTextureDimensions,
     IWineD3DTextureImpl_IsCondNP2,
     IWineD3DTextureImpl_BindTexture,
     IWineD3DTextureImpl_GetTextureDimensions,
     IWineD3DTextureImpl_IsCondNP2,
-    IWineD3DTextureImpl_ApplyStateChanges,
     /* IWineD3DTexture */
     IWineD3DTextureImpl_Destroy,
     IWineD3DTextureImpl_GetLevelDesc,
     /* IWineD3DTexture */
     IWineD3DTextureImpl_Destroy,
     IWineD3DTextureImpl_GetLevelDesc,
index d697372..3c25ebe 100644 (file)
@@ -91,14 +91,14 @@ static const struct StaticPixelFormatDesc formats[] =
     {WINED3DFMT_A8_UNORM,           0x000000ff, 0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
     {WINED3DFMT_A8R3G3B2,           0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2,      0,      0,      FALSE},
     {WINED3DFMT_X4R4G4B4,           0x0,        0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0,      FALSE},
     {WINED3DFMT_A8_UNORM,           0x000000ff, 0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
     {WINED3DFMT_A8R3G3B2,           0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2,      0,      0,      FALSE},
     {WINED3DFMT_X4R4G4B4,           0x0,        0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0,      FALSE},
-    {WINED3DFMT_R10G10B10A2_UNORM,  0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
-    {WINED3DFMT_R10G10B10A2_UINT,   0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
-    {WINED3DFMT_R10G10B10A2_SNORM,  0xb0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
+    {WINED3DFMT_R10G10B10A2_UNORM,  0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
+    {WINED3DFMT_R10G10B10A2_UINT,   0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
+    {WINED3DFMT_R10G10B10A2_SNORM,  0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0,      FALSE},
     {WINED3DFMT_R8G8B8A8_UNORM,     0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_R8G8B8A8_UINT,      0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_X8B8G8R8,           0x0,        0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_R16G16_UNORM,       0x0,        0x0000ffff, 0xffff0000, 0x0,        4,      0,      0,      FALSE},
     {WINED3DFMT_R8G8B8A8_UNORM,     0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_R8G8B8A8_UINT,      0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_X8B8G8R8,           0x0,        0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0,      FALSE},
     {WINED3DFMT_R16G16_UNORM,       0x0,        0x0000ffff, 0xffff0000, 0x0,        4,      0,      0,      FALSE},
-    {WINED3DFMT_A2R10G10B10,        0xb0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4,      0,      0,      FALSE},
+    {WINED3DFMT_A2R10G10B10,        0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4,      0,      0,      FALSE},
     {WINED3DFMT_R16G16B16A16_UNORM, 0x1,        0x0000ffff, 0xffff0000, 0x0,        8,      0,      0,      FALSE},
     /* Luminance */
     {WINED3DFMT_L8,                 0x0,        0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
     {WINED3DFMT_R16G16B16A16_UNORM, 0x1,        0x0000ffff, 0xffff0000, 0x0,        8,      0,      0,      FALSE},
     /* Luminance */
     {WINED3DFMT_L8,                 0x0,        0x0,        0x0,        0x0,        1,      0,      0,      FALSE},
@@ -134,6 +134,24 @@ static const struct StaticPixelFormatDesc formats[] =
     {WINED3DFMT_NVHS,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
 };
 
     {WINED3DFMT_NVHS,               0x0,        0x0,        0x0,        0x0,        2,      0,      0,      TRUE },
 };
 
+struct wined3d_format_compression_info
+{
+    WINED3DFORMAT format;
+    UINT block_width;
+    UINT block_height;
+    UINT block_byte_count;
+};
+
+static const struct wined3d_format_compression_info format_compression_info[] =
+{
+    {WINED3DFMT_DXT1,   4,  4,  8},
+    {WINED3DFMT_DXT2,   4,  4,  16},
+    {WINED3DFMT_DXT3,   4,  4,  16},
+    {WINED3DFMT_DXT4,   4,  4,  16},
+    {WINED3DFMT_DXT5,   4,  4,  16},
+    {WINED3DFMT_ATI2N,  4,  4,  16},
+};
+
 struct wined3d_format_vertex_info
 {
     WINED3DFORMAT format;
 struct wined3d_format_vertex_info
 {
     WINED3DFORMAT format;
@@ -170,6 +188,7 @@ typedef struct {
     WINED3DFORMAT           fmt;
     GLint                   glInternal, glGammaInternal, rtInternal, glFormat, glType;
     unsigned int            Flags;
     WINED3DFORMAT           fmt;
     GLint                   glInternal, glGammaInternal, rtInternal, glFormat, glType;
     unsigned int            Flags;
+    GL_SupportedExt extension;
 } GlPixelFormatDescTemplate;
 
 /*****************************************************************************
 } GlPixelFormatDescTemplate;
 
 /*****************************************************************************
@@ -181,10 +200,8 @@ typedef struct {
 static const GlPixelFormatDescTemplate gl_formats_template[] = {
     /* WINED3DFORMAT                internal                          srgbInternal                            rtInternal
             format                  type
 static const GlPixelFormatDescTemplate gl_formats_template[] = {
     /* WINED3DFORMAT                internal                          srgbInternal                            rtInternal
             format                  type
-            flags */
-    {WINED3DFMT_UNKNOWN,            0,                                0,                                      0,
-            0,                      0,
-            0},
+            flags
+            extension */
     /* FourCC formats */
     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
     /* FourCC formats */
     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
@@ -192,208 +209,278 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
      * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
      * endian machine
      */
      * Macs, so probably the endianess differs. This could be tested as soon as we have a Windows and MacOS on a big
      * endian machine
      */
+    {WINED3DFMT_UYVY,               GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
+            GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
+            WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_UYVY,               GL_RGB,                           GL_RGB,                                 0,
             GL_YCBCR_422_APPLE,     UNSIGNED_SHORT_8_8_APPLE,
     {WINED3DFMT_UYVY,               GL_RGB,                           GL_RGB,                                 0,
             GL_YCBCR_422_APPLE,     UNSIGNED_SHORT_8_8_APPLE,
-            WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_FILTERING,
+            APPLE_YCBCR_422},
+    {WINED3DFMT_YUY2,               GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
+            GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
+            WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_YUY2,               GL_RGB,                           GL_RGB,                                 0,
             GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
     {WINED3DFMT_YUY2,               GL_RGB,                           GL_RGB,                                 0,
             GL_YCBCR_422_APPLE, UNSIGNED_SHORT_8_8_REV_APPLE,
-            WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_FILTERING,
+            APPLE_YCBCR_422},
     {WINED3DFMT_YV12,               GL_ALPHA,                         GL_ALPHA,                               0,
             GL_ALPHA,               GL_UNSIGNED_BYTE,
     {WINED3DFMT_YV12,               GL_ALPHA,                         GL_ALPHA,                               0,
             GL_ALPHA,               GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_DXT1,               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
     {WINED3DFMT_DXT1,               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            EXT_TEXTURE_COMPRESSION_S3TC},
     {WINED3DFMT_DXT2,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
     {WINED3DFMT_DXT2,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            EXT_TEXTURE_COMPRESSION_S3TC},
     {WINED3DFMT_DXT3,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
     {WINED3DFMT_DXT3,               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            EXT_TEXTURE_COMPRESSION_S3TC},
     {WINED3DFMT_DXT4,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
     {WINED3DFMT_DXT4,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            EXT_TEXTURE_COMPRESSION_S3TC},
     {WINED3DFMT_DXT5,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
     {WINED3DFMT_DXT5,               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
             GL_RGBA,                GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
-    {WINED3DFMT_MULTI2_ARGB8,       0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_G8R8_G8B8,          0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_R8G8_B8G8,          0,                                0,                                      0,
-            0,                      0,
-            0},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            EXT_TEXTURE_COMPRESSION_S3TC},
     /* IEEE formats */
     {WINED3DFMT_R32_FLOAT,          GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
             GL_RED,                 GL_FLOAT,
     /* IEEE formats */
     {WINED3DFMT_R32_FLOAT,          GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
             GL_RED,                 GL_FLOAT,
-            WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
+    {WINED3DFMT_R32_FLOAT,          GL_R32F,                          GL_R32F,                                0,
+            GL_RED,                 GL_FLOAT,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_RG},
+    {WINED3DFMT_R32G32_FLOAT,       GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
+            GL_RGB,                 GL_FLOAT,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
     {WINED3DFMT_R32G32_FLOAT,       GL_RG32F,                         GL_RG32F,                               0,
             GL_RG,                  GL_FLOAT,
     {WINED3DFMT_R32G32_FLOAT,       GL_RG32F,                         GL_RG32F,                               0,
             GL_RG,                  GL_FLOAT,
-            WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_RG},
     {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
             GL_RGBA,                GL_FLOAT,
     {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
             GL_RGBA,                GL_FLOAT,
-            WINED3DFMT_FLAG_RENDERTARGET},
-    /* Hmm? */
-    {WINED3DFMT_CxV8U8,             0,                                0,                                      0,
-            0,                      0,
-            0},
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
     /* Float */
     {WINED3DFMT_R16_FLOAT,          GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
     /* Float */
     {WINED3DFMT_R16_FLOAT,          GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
-            GL_RED,             GL_HALF_FLOAT_ARB,
-            WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            GL_RED,                 GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
+    {WINED3DFMT_R16_FLOAT,          GL_R16F,                          GL_R16F,                                0,
+            GL_RED,                 GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_RG},
+    {WINED3DFMT_R16G16_FLOAT,       GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
+            GL_RGB,                 GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
     {WINED3DFMT_R16G16_FLOAT,       GL_RG16F,                         GL_RG16F,                               0,
     {WINED3DFMT_R16G16_FLOAT,       GL_RG16F,                         GL_RG16F,                               0,
-            GL_RG,              GL_HALF_FLOAT_ARB,
-            WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            GL_RG,                  GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_RG},
     {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
     {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
-            GL_RGBA,            GL_HALF_FLOAT_ARB,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            GL_RGBA,                GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET,
+            ARB_TEXTURE_FLOAT},
     /* Palettized formats */
     /* Palettized formats */
-    {WINED3DFMT_A8P8,               0,                                0,                                      0,
-            0,                      0,
-            0},
+    {WINED3DFMT_P8,                 GL_RGBA,                          GL_RGBA,                                0,
+            GL_RGBA,                GL_UNSIGNED_BYTE,
+            0,
+            ARB_FRAGMENT_PROGRAM},
     {WINED3DFMT_P8,                 GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
             GL_COLOR_INDEX,         GL_UNSIGNED_BYTE,
     {WINED3DFMT_P8,                 GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
             GL_COLOR_INDEX,         GL_UNSIGNED_BYTE,
-            0},
+            0,
+            EXT_PALETTED_TEXTURE},
     /* Standard ARGB formats */
     {WINED3DFMT_R8G8B8,             GL_RGB8,                          GL_RGB8,                                0,
             GL_BGR,                 GL_UNSIGNED_BYTE,
     /* Standard ARGB formats */
     {WINED3DFMT_R8G8B8,             GL_RGB8,                          GL_RGB8,                                0,
             GL_BGR,                 GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A8R8G8B8,           GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
     {WINED3DFMT_A8R8G8B8,           GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_X8R8G8B8,           GL_RGB8,                          GL_SRGB8_EXT,                           0,
             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
     {WINED3DFMT_X8R8G8B8,           GL_RGB8,                          GL_SRGB8_EXT,                           0,
             GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R5G6B5,             GL_RGB5,                          GL_RGB5,                                GL_RGB8,
             GL_RGB,                 GL_UNSIGNED_SHORT_5_6_5,
     {WINED3DFMT_R5G6B5,             GL_RGB5,                          GL_RGB5,                                GL_RGB8,
             GL_RGB,                 GL_UNSIGNED_SHORT_5_6_5,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_X1R5G5B5,           GL_RGB5,                          GL_RGB5_A1,                             0,
             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
     {WINED3DFMT_X1R5G5B5,           GL_RGB5,                          GL_RGB5_A1,                             0,
             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A1R5G5B5,           GL_RGB5_A1,                       GL_RGB5_A1,                             0,
             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
     {WINED3DFMT_A1R5G5B5,           GL_RGB5_A1,                       GL_RGB5_A1,                             0,
             GL_BGRA,                GL_UNSIGNED_SHORT_1_5_5_5_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A4R4G4B4,           GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
     {WINED3DFMT_A4R4G4B4,           GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R3G3B2,             GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
             GL_RGB,                 GL_UNSIGNED_BYTE_3_3_2,
     {WINED3DFMT_R3G3B2,             GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
             GL_RGB,                 GL_UNSIGNED_BYTE_3_3_2,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A8_UNORM,           GL_ALPHA8,                        GL_ALPHA8,                              0,
             GL_ALPHA,               GL_UNSIGNED_BYTE,
     {WINED3DFMT_A8_UNORM,           GL_ALPHA8,                        GL_ALPHA8,                              0,
             GL_ALPHA,               GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
-    {WINED3DFMT_A8R3G3B2,           0,                                0,                                      0,
-            0,                      0,
-            0},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_X4R4G4B4,           GL_RGB4,                          GL_RGB4,                                0,
             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
     {WINED3DFMT_X4R4G4B4,           GL_RGB4,                          GL_RGB4,                                0,
             GL_BGRA,                GL_UNSIGNED_SHORT_4_4_4_4_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R10G10B10A2_UNORM,  GL_RGB10_A2,                      GL_RGB10_A2,                            0,
             GL_RGBA,                GL_UNSIGNED_INT_2_10_10_10_REV,
     {WINED3DFMT_R10G10B10A2_UNORM,  GL_RGB10_A2,                      GL_RGB10_A2,                            0,
             GL_RGBA,                GL_UNSIGNED_INT_2_10_10_10_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R8G8B8A8_UNORM,     GL_RGBA8,                         GL_RGBA8,                               0,
             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
     {WINED3DFMT_R8G8B8A8_UNORM,     GL_RGBA8,                         GL_RGBA8,                               0,
             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_X8B8G8R8,           GL_RGB8,                          GL_RGB8,                                0,
             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
     {WINED3DFMT_X8B8G8R8,           GL_RGB8,                          GL_RGB8,                                0,
             GL_RGBA,                GL_UNSIGNED_INT_8_8_8_8_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
-    {WINED3DFMT_R16G16_UNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           0,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
+    {WINED3DFMT_R16G16_UNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           GL_RGBA16_EXT,
             GL_RGB,                 GL_UNSIGNED_SHORT,
             GL_RGB,                 GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A2R10G10B10,        GL_RGB10_A2,                      GL_RGB10_A2,                            0,
             GL_BGRA,                GL_UNSIGNED_INT_2_10_10_10_REV,
     {WINED3DFMT_A2R10G10B10,        GL_RGB10_A2,                      GL_RGB10_A2,                            0,
             GL_BGRA,                GL_UNSIGNED_INT_2_10_10_10_REV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT,                    GL_RGBA16_EXT,                          0,
             GL_RGBA,                GL_UNSIGNED_SHORT,
     {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT,                    GL_RGBA16_EXT,                          0,
             GL_RGBA,                GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+            WINED3D_GL_EXT_NONE},
     /* Luminance */
     {WINED3DFMT_L8,                 GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
             GL_LUMINANCE,           GL_UNSIGNED_BYTE,
     /* Luminance */
     {WINED3DFMT_L8,                 GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
             GL_LUMINANCE,           GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A8L8,               GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
     {WINED3DFMT_A8L8,               GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_A4L4,               GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
     {WINED3DFMT_A4L4,               GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0},
+            0,
+            WINED3D_GL_EXT_NONE},
     /* Bump mapping stuff */
     /* Bump mapping stuff */
+    {WINED3DFMT_R8G8_SNORM,         GL_RGB8,                          GL_RGB8,                                0,
+            GL_BGR,                 GL_UNSIGNED_BYTE,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R8G8_SNORM,         GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
             GL_DSDT_NV,             GL_BYTE,
     {WINED3DFMT_R8G8_SNORM,         GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
             GL_DSDT_NV,             GL_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            NV_TEXTURE_SHADER},
+    {WINED3DFMT_L6V5U5,             GL_RGB5,                          GL_RGB5,                                0,
+            GL_RGB,                 GL_UNSIGNED_SHORT_5_6_5,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_L6V5U5,             GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
             GL_DSDT_MAG_NV,         GL_BYTE,
     {WINED3DFMT_L6V5U5,             GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
             GL_DSDT_MAG_NV,         GL_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            NV_TEXTURE_SHADER},
+    {WINED3DFMT_X8L8V8U8,           GL_RGB8,                          GL_RGB8,                                0,
+            GL_BGRA,                GL_UNSIGNED_INT_8_8_8_8_REV,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_X8L8V8U8,           GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
             GL_DSDT_MAG_VIB_NV,     GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
     {WINED3DFMT_X8L8V8U8,           GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
             GL_DSDT_MAG_VIB_NV,     GL_UNSIGNED_INT_8_8_S8_S8_REV_NV,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            NV_TEXTURE_SHADER},
+    {WINED3DFMT_R8G8B8A8_SNORM,     GL_RGBA8,                         GL_RGBA8,                               0,
+            GL_BGRA,                GL_UNSIGNED_BYTE,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R8G8B8A8_SNORM,     GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
             GL_RGBA,                GL_BYTE,
     {WINED3DFMT_R8G8B8A8_SNORM,     GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
             GL_RGBA,                GL_BYTE,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            NV_TEXTURE_SHADER},
+    {WINED3DFMT_R16G16_SNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           0,
+            GL_BGR,                 GL_UNSIGNED_SHORT,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
     {WINED3DFMT_R16G16_SNORM,       GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
             GL_HILO_NV,             GL_SHORT,
     {WINED3DFMT_R16G16_SNORM,       GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
             GL_HILO_NV,             GL_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
-    {WINED3DFMT_W11V11U10,          0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_A2W10V10U10,        0,                                0,                                      0,
-            0,                      0,
-            0},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            NV_TEXTURE_SHADER},
     /* Depth stencil formats */
     {WINED3DFMT_D16_LOCKABLE,       GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
     /* Depth stencil formats */
     {WINED3DFMT_D16_LOCKABLE,       GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_DEPTH},
+            WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
     {WINED3DFMT_D32,                GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
     {WINED3DFMT_D32,                GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
-            WINED3DFMT_FLAG_DEPTH},
+            WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
     {WINED3DFMT_D15S1,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
     {WINED3DFMT_D15S1,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
+            WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
+    {WINED3DFMT_D15S1,              GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
+            GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
+            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            EXT_PACKED_DEPTH_STENCIL},
     {WINED3DFMT_D24S8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
     {WINED3DFMT_D24S8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
+    {WINED3DFMT_D24S8,              GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
+            GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            EXT_PACKED_DEPTH_STENCIL},
     {WINED3DFMT_D24X8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
     {WINED3DFMT_D24X8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
     {WINED3DFMT_D24X4S4,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
     {WINED3DFMT_D24X4S4,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
-            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
+            WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
+    {WINED3DFMT_D24X4S4,            GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
+            GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
+            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            EXT_PACKED_DEPTH_STENCIL},
     {WINED3DFMT_D16_UNORM,          GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
     {WINED3DFMT_D16_UNORM,          GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_TEXTURE},
     {WINED3DFMT_L16,                GL_LUMINANCE16_EXT,               GL_LUMINANCE16_EXT,                     0,
             GL_LUMINANCE,           GL_UNSIGNED_SHORT,
     {WINED3DFMT_L16,                GL_LUMINANCE16_EXT,               GL_LUMINANCE16_EXT,                     0,
             GL_LUMINANCE,           GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
-    {WINED3DFMT_D32F_LOCKABLE,      GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
-            GL_DEPTH_COMPONENT,     GL_FLOAT,
-            WINED3DFMT_FLAG_DEPTH},
-    {WINED3DFMT_D24FS8,             GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE},
+    {WINED3DFMT_D32F_LOCKABLE,      GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
             GL_DEPTH_COMPONENT,     GL_FLOAT,
             GL_DEPTH_COMPONENT,     GL_FLOAT,
-            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL},
-    /* Is this a vertex buffer? */
-    {WINED3DFMT_VERTEXDATA,         0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_R16_UINT,           0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_R32_UINT,           0,                                0,                                      0,
-            0,                      0,
-            0},
-    {WINED3DFMT_R16G16B16A16_SNORM, GL_COLOR_INDEX,                   GL_COLOR_INDEX,                         0,
-            GL_COLOR_INDEX,         GL_UNSIGNED_SHORT,
-            0},
+            WINED3DFMT_FLAG_DEPTH,
+            ARB_DEPTH_BUFFER_FLOAT},
+    {WINED3DFMT_D24FS8,             GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
+            GL_DEPTH_STENCIL_EXT,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            ARB_DEPTH_BUFFER_FLOAT},
     /* Vendor-specific formats */
     /* Vendor-specific formats */
-    {WINED3DFMT_ATI2N,              0,                                0,                                      0,
-            GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0},
-    {WINED3DFMT_NVHU,               0,                                0,                                      0,
+    {WINED3DFMT_ATI2N,              GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0},
-    {WINED3DFMT_NVHS,               0,                                0,                                      0,
+            0,
+            ATI_TEXTURE_COMPRESSION_3DC},
+    {WINED3DFMT_ATI2N,              GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT,     0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0}
+            0,
+            EXT_TEXTURE_COMPRESSION_RGTC},
 };
 
 static inline int getFmtIdx(WINED3DFORMAT fmt) {
 };
 
 static inline int getFmtIdx(WINED3DFORMAT fmt) {
@@ -413,7 +500,7 @@ static inline int getFmtIdx(WINED3DFORMAT fmt) {
     return -1;
 }
 
     return -1;
 }
 
-static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
+static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
 {
     UINT format_count = sizeof(formats) / sizeof(*formats);
     UINT i;
 {
     UINT format_count = sizeof(formats) / sizeof(*formats);
     UINT i;
@@ -442,32 +529,216 @@ static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
     return TRUE;
 }
 
     return TRUE;
 }
 
+static BOOL init_format_compression_info(struct wined3d_gl_info *gl_info)
+{
+    unsigned int i;
+
+    for (i = 0; i < (sizeof(format_compression_info) / sizeof(*format_compression_info)); ++i)
+    {
+        struct GlPixelFormatDesc *format_desc;
+        int fmt_idx = getFmtIdx(format_compression_info[i].format);
+
+        if (fmt_idx == -1)
+        {
+            ERR("Format %s (%#x) not found.\n",
+                    debug_d3dformat(format_compression_info[i].format), format_compression_info[i].format);
+            return FALSE;
+        }
+
+        format_desc = &gl_info->gl_formats[fmt_idx];
+        format_desc->block_width = format_compression_info[i].block_width;
+        format_desc->block_height = format_compression_info[i].block_height;
+        format_desc->block_byte_count = format_compression_info[i].block_byte_count;
+        format_desc->Flags |= WINED3DFMT_FLAG_COMPRESSED;
+    }
+
+    return TRUE;
+}
+
 #define GLINFO_LOCATION (*gl_info)
 
 #define GLINFO_LOCATION (*gl_info)
 
-static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_format)
+/* Context activation is done by the caller. */
+static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
 {
 {
-    GLuint tex, fb;
+    /* Check if the default internal format is supported as a frame buffer
+     * target, otherwise fall back to the render target internal.
+     *
+     * Try to stick to the standard format if possible, this limits precision differences. */
     GLenum status;
     GLenum status;
+    GLuint tex;
+
+    ENTER_GL();
 
     while(glGetError());
 
     while(glGetError());
+    glDisable(GL_BLEND);
+
     glGenTextures(1, &tex);
     glBindTexture(GL_TEXTURE_2D, tex);
     glGenTextures(1, &tex);
     glBindTexture(GL_TEXTURE_2D, tex);
-    glTexImage2D(GL_TEXTURE_2D, 0, internal_format, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 
 
-    GL_EXTCALL(glGenFramebuffersEXT(1, &fb));
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
+    glTexImage2D(GL_TEXTURE_2D, 0, format_desc->glInternal, 16, 16, 0,
+            format_desc->glFormat, format_desc->glType, NULL);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
     GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-    GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
+    checkGLcall("Framebuffer format check");
+
+    if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+    {
+        TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
+        format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+        format_desc->rtInternal = format_desc->glInternal;
+    }
+    else
+    {
+        if (!format_desc->rtInternal)
+        {
+            if (format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)
+            {
+                FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
+                        " and no fallback specified.\n", debug_d3dformat(format_desc->format));
+                format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+            }
+            else
+            {
+                TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format_desc->format));
+            }
+            format_desc->rtInternal = format_desc->glInternal;
+        }
+        else
+        {
+            TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
+                    debug_d3dformat(format_desc->format));
+
+            while(glGetError());
+
+            GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
+
+            glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
+                    format_desc->glFormat, format_desc->glType, NULL);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+            GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
+
+            status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
+            checkGLcall("Framebuffer format check");
+
+            if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+            {
+                TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
+                        debug_d3dformat(format_desc->format));
+            }
+            else
+            {
+                FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
+                        debug_d3dformat(format_desc->format));
+                format_desc->Flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+            }
+        }
+    }
+
+    if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
+    {
+        GLuint rb;
+
+        if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+        {
+            GL_EXTCALL(glGenRenderbuffersEXT(1, &rb));
+            GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb));
+            GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16));
+            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+                    GL_RENDERBUFFER_EXT, rb));
+            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
+                    GL_RENDERBUFFER_EXT, rb));
+            checkGLcall("RB attachment");
+        }
+
+        glEnable(GL_BLEND);
+        glClear(GL_COLOR_BUFFER_BIT);
+        if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
+        {
+            while(glGetError());
+            TRACE("Format doesn't support post-pixelshader blending.\n");
+            format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+        }
+
+        if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+        {
+            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+                    GL_RENDERBUFFER_EXT, 0));
+            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
+                    GL_RENDERBUFFER_EXT, 0));
+            GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb));
+            checkGLcall("RB cleanup");
+        }
+    }
+
     glDeleteTextures(1, &tex);
 
     glDeleteTextures(1, &tex);
 
-    checkGLcall("Framebuffer format check");
+    LEAVE_GL();
+}
+
+/* Context activation is done by the caller. */
+static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
+{
+    unsigned int i;
+    GLuint fbo;
+
+    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+    {
+        ENTER_GL();
+
+        GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
+        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
+
+        LEAVE_GL();
+    }
+
+    for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
+    {
+        struct GlPixelFormatDesc *desc = &gl_info->gl_formats[i];
+
+        if (!desc->glInternal) continue;
+
+        if (desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+        {
+            TRACE("Skipping format %s because it's a depth/stencil format.\n",
+                    debug_d3dformat(desc->format));
+            continue;
+        }
+
+        if (desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+        {
+            TRACE("Skipping format %s because it's a compressed format.\n",
+                    debug_d3dformat(desc->format));
+            continue;
+        }
 
 
-    return status == GL_FRAMEBUFFER_COMPLETE_EXT;
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+        {
+            TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(desc->format));
+            check_fbo_compat(gl_info, desc);
+        }
+        else
+        {
+            desc->rtInternal = desc->glInternal;
+        }
+    }
+
+    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+    {
+        ENTER_GL();
+
+        GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
+
+        LEAVE_GL();
+    }
 }
 
 }
 
-static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
+static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
 {
     unsigned int i;
 
 {
     unsigned int i;
 
@@ -483,65 +754,203 @@ static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
             return FALSE;
         }
 
             return FALSE;
         }
 
+        if (!GL_SUPPORT(gl_formats_template[i].extension)) continue;
+
         desc = &gl_info->gl_formats[fmt_idx];
         desc->glInternal = gl_formats_template[i].glInternal;
         desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
         desc = &gl_info->gl_formats[fmt_idx];
         desc->glInternal = gl_formats_template[i].glInternal;
         desc->glGammaInternal = gl_formats_template[i].glGammaInternal;
+        desc->rtInternal = gl_formats_template[i].rtInternal;
         desc->glFormat = gl_formats_template[i].glFormat;
         desc->glType = gl_formats_template[i].glType;
         desc->color_fixup = COLOR_FIXUP_IDENTITY;
         desc->Flags |= gl_formats_template[i].Flags;
         desc->glFormat = gl_formats_template[i].glFormat;
         desc->glType = gl_formats_template[i].glType;
         desc->color_fixup = COLOR_FIXUP_IDENTITY;
         desc->Flags |= gl_formats_template[i].Flags;
-        desc->heightscale = 1.0;
+        desc->heightscale = 1.0f;
+    }
+
+    return TRUE;
+}
+
+static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
+{
+    if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+    c1 >>= 8; c2 >>= 8;
+    if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+    c1 >>= 8; c2 >>= 8;
+    if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+    c1 >>= 8; c2 >>= 8;
+    if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+    return TRUE;
+}
 
 
-        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && gl_formats_template[i].rtInternal)
+/* A context is provided by the caller */
+static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
+{
+    GLuint tex, fbo, buffer;
+    const DWORD data[] = {0x00000000, 0xffffffff};
+    DWORD readback[16 * 1];
+    BOOL ret = FALSE;
+
+    /* Render a filtered texture and see what happens. This is intended to detect the lack of
+     * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
+     * falling back to software. If this changes in the future this code will get fooled and
+     * apps might hit the software path due to incorrectly advertised caps.
+     *
+     * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
+     * disable fallback, if Apple or ATI ever change the driver behavior they will break more
+     * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
+     */
+
+    ENTER_GL();
+    while(glGetError());
+
+    glGenTextures(1, &buffer);
+    glBindTexture(GL_TEXTURE_2D, buffer);
+    memset(readback, 0x7e, sizeof(readback));
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+    glEnable(GL_TEXTURE_2D);
+
+    GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
+    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0));
+    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+    glViewport(0, 0, 16, 1);
+    glDisable(GL_LIGHTING);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+
+    glClearColor(0, 1, 0, 0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2f(0.0, 0.0);
+    glVertex2f(-1.0f, -1.0f);
+    glTexCoord2f(1.0, 0.0);
+    glVertex2f(1.0f, -1.0f);
+    glTexCoord2f(0.0, 1.0);
+    glVertex2f(-1.0f, 1.0f);
+    glTexCoord2f(1.0, 1.0);
+    glVertex2f(1.0f, 1.0f);
+    glEnd();
+
+    glBindTexture(GL_TEXTURE_2D, buffer);
+    memset(readback, 0x7f, sizeof(readback));
+    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
+    if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
+       color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
+    {
+        TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
+              readback[6], readback[9]);
+        ret = FALSE;
+    }
+    else
+    {
+        TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
+              readback[6], readback[9]);
+        ret = TRUE;
+    }
+
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+    GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
+    glDeleteTextures(1, &tex);
+    glDeleteTextures(1, &buffer);
+
+    if(glGetError())
+    {
+        FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
+        ret = FALSE;
+    }
+    LEAVE_GL();
+    return ret;
+}
+
+static void init_format_filter_info(struct wined3d_gl_info *gl_info)
+{
+    unsigned int fmt_idx, i;
+    WINED3DFORMAT fmts16[] = {
+        WINED3DFMT_R16_FLOAT,
+        WINED3DFMT_R16G16_FLOAT,
+        WINED3DFMT_R16G16B16A16_FLOAT,
+    };
+    BOOL filtered;
+    struct GlPixelFormatDesc *desc;
+
+    if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+    {
+        WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
+        if(gl_info->gl_vendor == VENDOR_NVIDIA && GL_SUPPORT(ARB_TEXTURE_FLOAT))
         {
         {
-            /* Check if the default internal format is supported as a frame buffer target, otherwise
-             * fall back to the render target internal.
-             *
-             * Try to stick to the standard format if possible, this limits precision differences */
-            if (!check_fbo_compat(gl_info, gl_formats_template[i].glInternal))
-            {
-                TRACE("Internal format of %s not supported as FBO target, using render target internal instead\n",
-                        debug_d3dformat(gl_formats_template[i].fmt));
-                desc->rtInternal = gl_formats_template[i].rtInternal;
-            }
-            else
+            TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
+            filtered = TRUE;
+        }
+        else if(GL_LIMITS(glsl_varyings > 44))
+        {
+            TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
+            filtered = TRUE;
+        }
+        else
+        {
+            TRACE("Assuming no float16 blending\n");
+            filtered = FALSE;
+        }
+
+        if(filtered)
+        {
+            for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
             {
             {
-                TRACE("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[i].fmt));
-                desc->rtInternal = gl_formats_template[i].glInternal;
+                fmt_idx = getFmtIdx(fmts16[i]);
+                gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
             }
         }
             }
         }
+        return;
+    }
+
+    for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
+    {
+        fmt_idx = getFmtIdx(fmts16[i]);
+        desc = &gl_info->gl_formats[fmt_idx];
+        if(!desc->glInternal) continue; /* Not supported by GL */
+
+        filtered = check_filter(gl_info, gl_info->gl_formats[fmt_idx].glInternal);
+        if(filtered)
+        {
+            TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
+            desc->Flags |= WINED3DFMT_FLAG_FILTERING;
+        }
         else
         {
         else
         {
-            desc->rtInternal = gl_formats_template[i].glInternal;
+            TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
         }
     }
         }
     }
-
-    return TRUE;
 }
 
 }
 
-static void apply_format_fixups(WineD3D_GL_Info *gl_info)
+static void apply_format_fixups(struct wined3d_gl_info *gl_info)
 {
     int idx;
 
     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
 {
     int idx;
 
     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
-    /* When ARB_texture_rg is supported we only require 16-bit for R16F instead of 64-bit RGBA16F */
-    if (GL_SUPPORT(ARB_TEXTURE_RG))
-    {
-        gl_info->gl_formats[idx].glInternal = GL_R16F;
-        gl_info->gl_formats[idx].glGammaInternal = GL_R16F;
-    }
 
     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
 
     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
-    /* When ARB_texture_rg is supported we only require 32-bit for R32F instead of 128-bit RGBA32F */
-    if (GL_SUPPORT(ARB_TEXTURE_RG))
-    {
-        gl_info->gl_formats[idx].glInternal = GL_R32F;
-        gl_info->gl_formats[idx].glGammaInternal = GL_R32F;
-    }
 
     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
 
     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
     gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
@@ -610,16 +1019,12 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info)
     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
     {
         idx = getFmtIdx(WINED3DFMT_ATI2N);
     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC))
     {
         idx = getFmtIdx(WINED3DFMT_ATI2N);
-        gl_info->gl_formats[idx].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
-        gl_info->gl_formats[idx].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
     }
     else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
     {
         idx = getFmtIdx(WINED3DFMT_ATI2N);
         gl_info->gl_formats[idx].color_fixup = create_color_fixup_desc(
                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
     }
     else if (GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC))
     {
         idx = getFmtIdx(WINED3DFMT_ATI2N);
-        gl_info->gl_formats[idx].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
-        gl_info->gl_formats[idx].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
         gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
     }
         gl_info->gl_formats[idx].color_fixup= create_color_fixup_desc(
                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
     }
@@ -627,22 +1032,14 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info)
     if (!GL_SUPPORT(APPLE_YCBCR_422))
     {
         idx = getFmtIdx(WINED3DFMT_YUY2);
     if (!GL_SUPPORT(APPLE_YCBCR_422))
     {
         idx = getFmtIdx(WINED3DFMT_YUY2);
-        gl_info->gl_formats[idx].glInternal = GL_LUMINANCE_ALPHA;
-        gl_info->gl_formats[idx].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
-        gl_info->gl_formats[idx].glFormat = GL_LUMINANCE_ALPHA;
-        gl_info->gl_formats[idx].glType = GL_UNSIGNED_BYTE;
         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
 
         idx = getFmtIdx(WINED3DFMT_UYVY);
         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
 
         idx = getFmtIdx(WINED3DFMT_UYVY);
-        gl_info->gl_formats[idx].glInternal = GL_LUMINANCE_ALPHA;
-        gl_info->gl_formats[idx].glGammaInternal = GL_LUMINANCE_ALPHA; /* not srgb */
-        gl_info->gl_formats[idx].glFormat = GL_LUMINANCE_ALPHA;
-        gl_info->gl_formats[idx].glType = GL_UNSIGNED_BYTE;
         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
     }
 
     idx = getFmtIdx(WINED3DFMT_YV12);
         gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
     }
 
     idx = getFmtIdx(WINED3DFMT_YV12);
-    gl_info->gl_formats[idx].heightscale = 1.5;
+    gl_info->gl_formats[idx].heightscale = 1.5f;
     gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
 
     if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
     gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
 
     if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
@@ -663,7 +1060,7 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info)
     }
 }
 
     }
 }
 
-static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
+static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
 {
     unsigned int i;
 
 {
     unsigned int i;
 
@@ -691,37 +1088,44 @@ static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
     return TRUE;
 }
 
     return TRUE;
 }
 
-BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
-{
-    return init_format_base_info(gl_info);
-}
-
-BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
+BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
 {
     if (!init_format_base_info(gl_info)) return FALSE;
 
 {
     if (!init_format_base_info(gl_info)) return FALSE;
 
-    if (!init_format_texture_info(gl_info))
+    if (!init_format_compression_info(gl_info))
     {
         HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
         return FALSE;
     }
 
     {
         HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
         return FALSE;
     }
 
-    if (!init_format_vertex_info(gl_info))
-    {
-        HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
-        return FALSE;
-    }
+    return TRUE;
+}
+
+/* Context activation is done by the caller. */
+BOOL initPixelFormats(struct wined3d_gl_info *gl_info)
+{
+    if (!init_format_base_info(gl_info)) return FALSE;
+
+    if (!init_format_compression_info(gl_info)) goto fail;
+    if (!init_format_texture_info(gl_info)) goto fail;
+    if (!init_format_vertex_info(gl_info)) goto fail;
 
     apply_format_fixups(gl_info);
 
     apply_format_fixups(gl_info);
+    init_format_fbo_compat_info(gl_info);
+    init_format_filter_info(gl_info);
 
     return TRUE;
 
     return TRUE;
+
+fail:
+    HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
+    return FALSE;
 }
 
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION This->adapter->gl_info
 
 }
 
 #undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION This->adapter->gl_info
 
-const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
+const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info)
 {
     int idx = getFmtIdx(fmt);
 
 {
     int idx = getFmtIdx(fmt);
 
@@ -907,9 +1311,12 @@ const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
   }
 }
 
   }
 }
 
-const char* debug_d3dusage(DWORD usage) {
-  switch (usage & WINED3DUSAGE_MASK) {
-#define WINED3DUSAGE_TO_STR(u) case u: return #u
+const char *debug_d3dusage(DWORD usage)
+{
+    char buf[284];
+
+    buf[0] = '\0';
+#define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
@@ -922,16 +1329,17 @@ const char* debug_d3dusage(DWORD usage) {
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
 #undef WINED3DUSAGE_TO_STR
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
 #undef WINED3DUSAGE_TO_STR
-  case 0: return "none";
-  default:
-    FIXME("Unrecognized %u Usage!\n", usage);
-    return "unrecognized";
-  }
+    if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
+
+    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
 }
 
 }
 
-const char* debug_d3dusagequery(DWORD usagequery) {
-  switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
-#define WINED3DUSAGEQUERY_TO_STR(u) case u: return #u
+const char *debug_d3dusagequery(DWORD usagequery)
+{
+    char buf[238];
+
+    buf[0] = '\0';
+#define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
@@ -940,11 +1348,9 @@ const char* debug_d3dusagequery(DWORD usagequery) {
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
 #undef WINED3DUSAGEQUERY_TO_STR
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
 #undef WINED3DUSAGEQUERY_TO_STR
-  case 0: return "none";
-  default:
-    FIXME("Unrecognized %u Usage Query!\n", usagequery);
-    return "unrecognized";
-  }
+    if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
+
+    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
 }
 
 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
 }
 
 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
@@ -1512,6 +1918,7 @@ BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWO
 }
 
 /* Setup this textures matrix according to the texture flags*/
 }
 
 /* Setup this textures matrix according to the texture flags*/
+/* GL locking is done by the caller (state handler) */
 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
         WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
 {
 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
         WINED3DFORMAT vtx_fmt, BOOL ffp_proj_control)
 {
@@ -1793,7 +2200,8 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
     /* No oversized texture? This is easy */
     if(!(This->Flags & SFLAG_OVERSIZE)) {
         /* Which rect from the texture do I need? */
     /* No oversized texture? This is easy */
     if(!(This->Flags & SFLAG_OVERSIZE)) {
         /* Which rect from the texture do I need? */
-        if(This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB) {
+        if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+        {
             glTexCoord[0] = (float) Rect->left;
             glTexCoord[2] = (float) Rect->top;
             glTexCoord[1] = (float) Rect->right;
             glTexCoord[0] = (float) Rect->left;
             glTexCoord[2] = (float) Rect->top;
             glTexCoord[1] = (float) Rect->right;
@@ -1894,238 +2302,6 @@ BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]
 }
 #undef GLINFO_LOCATION
 
 }
 #undef GLINFO_LOCATION
 
-/* Hash table functions */
-
-struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function)
-{
-    struct hash_table_t *table;
-    unsigned int initial_size = 8;
-
-    table = HeapAlloc(GetProcessHeap(), 0, sizeof(struct hash_table_t) + (initial_size * sizeof(struct list)));
-    if (!table)
-    {
-        ERR("Failed to allocate table, returning NULL.\n");
-        return NULL;
-    }
-
-    table->hash_function = hash_function;
-    table->compare_function = compare_function;
-
-    table->grow_size = initial_size - (initial_size >> 2);
-    table->shrink_size = 0;
-
-    table->buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, initial_size * sizeof(struct list));
-    if (!table->buckets)
-    {
-        ERR("Failed to allocate table buckets, returning NULL.\n");
-        HeapFree(GetProcessHeap(), 0, table);
-        return NULL;
-    }
-    table->bucket_count = initial_size;
-
-    table->entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, table->grow_size * sizeof(struct hash_table_entry_t));
-    if (!table->entries)
-    {
-        ERR("Failed to allocate table entries, returning NULL.\n");
-        HeapFree(GetProcessHeap(), 0, table->buckets);
-        HeapFree(GetProcessHeap(), 0, table);
-        return NULL;
-    }
-    table->entry_count = 0;
-
-    list_init(&table->free_entries);
-    table->count = 0;
-
-    return table;
-}
-
-void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb)
-{
-    unsigned int i = 0;
-
-    for (i = 0; i < table->entry_count; ++i)
-    {
-        if(free_value) {
-            free_value(table->entries[i].value, cb);
-        }
-        HeapFree(GetProcessHeap(), 0, table->entries[i].key);
-    }
-
-    HeapFree(GetProcessHeap(), 0, table->entries);
-    HeapFree(GetProcessHeap(), 0, table->buckets);
-    HeapFree(GetProcessHeap(), 0, table);
-}
-
-void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context)
-{
-    unsigned int i = 0;
-
-    for (i = 0; i < table->entry_count; ++i)
-    {
-        callback(table->entries[i].value, context);
-    }
-}
-
-static inline struct hash_table_entry_t *hash_table_get_by_idx(const struct hash_table_t *table, const void *key,
-        unsigned int idx)
-{
-    struct hash_table_entry_t *entry;
-
-    if (table->buckets[idx].next)
-        LIST_FOR_EACH_ENTRY(entry, &(table->buckets[idx]), struct hash_table_entry_t, entry)
-            if (table->compare_function(entry->key, key)) return entry;
-
-    return NULL;
-}
-
-static BOOL hash_table_resize(struct hash_table_t *table, unsigned int new_bucket_count)
-{
-    unsigned int new_entry_count = 0;
-    struct hash_table_entry_t *new_entries;
-    struct list *new_buckets;
-    unsigned int grow_size = new_bucket_count - (new_bucket_count >> 2);
-    unsigned int i;
-
-    new_buckets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_bucket_count * sizeof(struct list));
-    if (!new_buckets)
-    {
-        ERR("Failed to allocate new buckets, returning FALSE.\n");
-        return FALSE;
-    }
-
-    new_entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, grow_size * sizeof(struct hash_table_entry_t));
-    if (!new_entries)
-    {
-        ERR("Failed to allocate new entries, returning FALSE.\n");
-        HeapFree(GetProcessHeap(), 0, new_buckets);
-        return FALSE;
-    }
-
-    for (i = 0; i < table->bucket_count; ++i)
-    {
-        if (table->buckets[i].next)
-        {
-            struct hash_table_entry_t *entry, *entry2;
-
-            LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &table->buckets[i], struct hash_table_entry_t, entry)
-            {
-                int j;
-                struct hash_table_entry_t *new_entry = new_entries + (new_entry_count++);
-                *new_entry = *entry;
-
-                j = new_entry->hash & (new_bucket_count - 1);
-
-                if (!new_buckets[j].next) list_init(&new_buckets[j]);
-                list_add_head(&new_buckets[j], &new_entry->entry);
-            }
-        }
-    }
-
-    HeapFree(GetProcessHeap(), 0, table->buckets);
-    table->buckets = new_buckets;
-
-    HeapFree(GetProcessHeap(), 0, table->entries);
-    table->entries = new_entries;
-
-    table->entry_count = new_entry_count;
-    list_init(&table->free_entries);
-
-    table->bucket_count = new_bucket_count;
-    table->grow_size = grow_size;
-    table->shrink_size = new_bucket_count > 8 ? new_bucket_count >> 2 : 0;
-
-    return TRUE;
-}
-
-void hash_table_put(struct hash_table_t *table, void *key, void *value)
-{
-    unsigned int idx;
-    unsigned int hash;
-    struct hash_table_entry_t *entry;
-
-    hash = table->hash_function(key);
-    idx = hash & (table->bucket_count - 1);
-    entry = hash_table_get_by_idx(table, key, idx);
-
-    if (entry)
-    {
-        HeapFree(GetProcessHeap(), 0, key);
-        entry->value = value;
-
-        if (!value)
-        {
-            HeapFree(GetProcessHeap(), 0, entry->key);
-            entry->key = NULL;
-
-            /* Remove the entry */
-            list_remove(&entry->entry);
-            list_add_head(&table->free_entries, &entry->entry);
-
-            --table->count;
-
-            /* Shrink if necessary */
-            if (table->count < table->shrink_size) {
-                if (!hash_table_resize(table, table->bucket_count >> 1))
-                {
-                    ERR("Failed to shrink the table...\n");
-                }
-            }
-        }
-
-        return;
-    }
-
-    if (!value) return;
-
-    /* Grow if necessary */
-    if (table->count >= table->grow_size)
-    {
-        if (!hash_table_resize(table, table->bucket_count << 1))
-        {
-            ERR("Failed to grow the table, returning.\n");
-            return;
-        }
-
-        idx = hash & (table->bucket_count - 1);
-    }
-
-    /* Find an entry to insert */
-    if (!list_empty(&table->free_entries))
-    {
-        struct list *elem = list_head(&table->free_entries);
-
-        list_remove(elem);
-        entry = LIST_ENTRY(elem, struct hash_table_entry_t, entry);
-    } else {
-        entry = table->entries + (table->entry_count++);
-    }
-
-    /* Insert the entry */
-    entry->key = key;
-    entry->value = value;
-    entry->hash = hash;
-    if (!table->buckets[idx].next) list_init(&table->buckets[idx]);
-    list_add_head(&table->buckets[idx], &entry->entry);
-
-    ++table->count;
-}
-
-void hash_table_remove(struct hash_table_t *table, void *key)
-{
-    hash_table_put(table, key, NULL);
-}
-
-void *hash_table_get(const struct hash_table_t *table, const void *key)
-{
-    unsigned int idx;
-    struct hash_table_entry_t *entry;
-
-    idx = table->hash_function(key) & (table->bucket_count - 1);
-    entry = hash_table_get_by_idx(table, key, idx);
-
-    return entry ? entry->value : NULL;
-}
-
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
 #define ARG1 0x01
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype) {
 #define ARG1 0x01
@@ -2163,6 +2339,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
     unsigned int i;
     DWORD ttff;
     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
     unsigned int i;
     DWORD ttff;
     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
+    IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
         IWineD3DBaseTextureImpl *texture;
 
     for(i = 0; i < GL_LIMITS(texture_stages); i++) {
         IWineD3DBaseTextureImpl *texture;
@@ -2216,8 +2393,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
 
         carg2 = (args[cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : ARG_UNUSED;
         carg0 = (args[cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : ARG_UNUSED;
 
-        if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
-                         carg1, carg2, carg0)) {
+        if(is_invalid_op(device, i, cop, carg1, carg2, carg0)) {
             carg0 = ARG_UNUSED;
             carg2 = ARG_UNUSED;
             carg1 = WINED3DTA_CURRENT;
             carg0 = ARG_UNUSED;
             carg2 = ARG_UNUSED;
             carg1 = WINED3DTA_CURRENT;
@@ -2276,8 +2452,7 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
             }
         }
 
             }
         }
 
-        if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
-           aarg1, aarg2, aarg0)) {
+        if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
                aarg0 = ARG_UNUSED;
                aarg2 = ARG_UNUSED;
                aarg1 = WINED3DTA_CURRENT;
                aarg0 = ARG_UNUSED;
                aarg2 = ARG_UNUSED;
                aarg1 = WINED3DTA_CURRENT;
@@ -2356,23 +2531,32 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
     } else {
         settings->sRGB_write = 0;
     }
     } else {
         settings->sRGB_write = 0;
     }
+    if(device->vs_clipping || !use_vs(stateblock)) {
+        /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
+         * the fixed function vertex pipeline is used(which always supports clipplanes)
+         */
+        settings->emul_clipplanes = 0;
+    } else {
+        settings->emul_clipplanes = 1;
+    }
 }
 #undef GLINFO_LOCATION
 
 }
 #undef GLINFO_LOCATION
 
-const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
         const struct ffp_frag_settings *settings)
 {
         const struct ffp_frag_settings *settings)
 {
-    return hash_table_get(fragment_shaders, settings);
+    struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
+    return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
 }
 
 }
 
-void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc) {
-    struct ffp_frag_settings *key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key));
+void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
+{
     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
-     * whereas desc points to an extended structure with implementation specific parts.
-     * Make a copy of the key because hash_table_put takes ownership of it
-     */
-    *key = desc->settings;
-    hash_table_put(shaders, key, desc);
+     * whereas desc points to an extended structure with implementation specific parts. */
+    if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
+    {
+        ERR("Failed to insert ffp frag shader.\n");
+    }
 }
 
 /* Activates the texture dimension according to the bound D3D texture.
 }
 
 /* Activates the texture dimension according to the bound D3D texture.
@@ -2380,7 +2564,9 @@ void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *des
  * Requires the caller to activate the correct unit before
  */
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
  * Requires the caller to activate the correct unit before
  */
 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
-void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+/* GL locking is done by the caller (state handler) */
+void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     if(stateblock->textures[stage]) {
         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
             case GL_TEXTURE_2D:
     if(stateblock->textures[stage]) {
         switch (IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[stage])) {
             case GL_TEXTURE_2D:
@@ -2453,7 +2639,9 @@ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock
     }
 }
 
     }
 }
 
-void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+/* GL locking is done by the caller (state handler) */
+void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
+{
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
 
     DWORD sampler = state - STATE_SAMPLER(0);
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
 
@@ -2469,61 +2657,57 @@ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
 }
 #undef GLINFO_LOCATION
 
 }
 #undef GLINFO_LOCATION
 
-unsigned int ffp_frag_program_key_hash(const void *key)
+void *wined3d_rb_alloc(size_t size)
 {
 {
-    const struct ffp_frag_settings *k = key;
-    unsigned int hash = 0, i;
-    const DWORD *blob;
-
-    /* This takes the texture op settings of stage 0 and 1 into account.
-     * how exactly depends on the memory laybout of the compiler, but it
-     * should not matter too much. Stages > 1 are used rarely, so there's
-     * no need to process them. Even if they're used it is likely that
-     * the ffp setup has distinct stage 0 and 1 settings.
-     */
-    for(i = 0; i < 2; i++) {
-        blob = (const DWORD *)&k->op[i];
-        hash ^= blob[0] ^ blob[1];
-    }
+    return HeapAlloc(GetProcessHeap(), 0, size);
+}
 
 
-    hash += ~(hash << 15);
-    hash ^=  (hash >> 10);
-    hash +=  (hash << 3);
-    hash ^=  (hash >> 6);
-    hash += ~(hash << 11);
-    hash ^=  (hash >> 16);
+void *wined3d_rb_realloc(void *ptr, size_t size)
+{
+    return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
+}
 
 
-    return hash;
+void wined3d_rb_free(void *ptr)
+{
+    HeapFree(GetProcessHeap(), 0, ptr);
 }
 
 }
 
-BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb)
+static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
 {
 {
-    const struct ffp_frag_settings *ka = keya;
-    const struct ffp_frag_settings *kb = keyb;
+    const struct ffp_frag_settings *ka = key;
+    const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
 
 
-    return memcmp(ka, kb, sizeof(*ka)) == 0;
+    return memcmp(ka, kb, sizeof(*ka));
 }
 
 }
 
+const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
+{
+    wined3d_rb_alloc,
+    wined3d_rb_realloc,
+    wined3d_rb_free,
+    ffp_frag_program_key_compare,
+};
+
 UINT wined3d_log2i(UINT32 x)
 {
 UINT wined3d_log2i(UINT32 x)
 {
-    static const BYTE l[] =
+    static const UINT l[] =
     {
     {
-        0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
-        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     };
     UINT32 i;
 
     };
     UINT32 i;
 
index 7dba4e3..d24ecd6 100644 (file)
@@ -71,6 +71,10 @@ static void vshader_set_limits(IWineD3DVertexShaderImpl *This)
             This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
             break;
 
             This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
             break;
 
+        case WINED3D_SHADER_VERSION(4,0):
+            FIXME("Using 3.0 limits for 4.0 shader\n");
+            /* Fall through */
+
         case WINED3D_SHADER_VERSION(3,0):
             This->baseShader.limits.temporary = 32;
             This->baseShader.limits.constant_bool = 32;
         case WINED3D_SHADER_VERSION(3,0):
             This->baseShader.limits.temporary = 32;
             This->baseShader.limits.constant_bool = 32;
@@ -101,26 +105,6 @@ static void vshader_set_limits(IWineD3DVertexShaderImpl *This)
     }
 }
 
     }
 }
 
-/* This is an internal function,
- * used to create fake semantics for shaders
- * that don't have them - d3d8 shaders where the declaration
- * stores the register for each input
- */
-static void vshader_set_input(
-    IWineD3DVertexShaderImpl* This,
-    unsigned int regnum,
-    BYTE usage, BYTE usage_idx) {
-
-    This->semantics_in[regnum].usage = usage;
-    This->semantics_in[regnum].usage_idx = usage_idx;
-    This->semantics_in[regnum].reg.reg.type = WINED3DSPR_INPUT;
-    This->semantics_in[regnum].reg.reg.idx = regnum;
-    This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL;
-    This->semantics_in[regnum].reg.modifiers = 0;
-    This->semantics_in[regnum].reg.shift = 0;
-    This->semantics_in[regnum].reg.reg.rel_addr = NULL;
-}
-
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
     if (usage_idx1 != usage_idx2) return FALSE;
     if (usage1 == usage2) return TRUE;
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
     if (usage_idx1 != usage_idx2) return FALSE;
     if (usage1 == usage2) return TRUE;
@@ -130,19 +114,18 @@ static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_id
     return FALSE;
 }
 
     return FALSE;
 }
 
-BOOL vshader_get_input(
-    IWineD3DVertexShader* iface,
-    BYTE usage_req, BYTE usage_idx_req,
-    unsigned int* regnum) {
-
-    IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
-    int i;
+BOOL vshader_get_input(IWineD3DVertexShader* iface, BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum)
+{
+    IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
+    WORD map = This->baseShader.reg_maps.input_registers;
+    unsigned int i;
 
 
-    for (i = 0; i < MAX_ATTRIBS; i++) {
-        if (!This->baseShader.reg_maps.attributes[i]) continue;
+    for (i = 0; map; map >>= 1, ++i)
+    {
+        if (!(map & 1)) continue;
 
 
-        if (match_usage(This->semantics_in[i].usage,
-                This->semantics_in[i].usage_idx, usage_req, usage_idx_req))
+        if (match_usage(This->attributes[i].usage,
+                This->attributes[i].usage_idx, usage_req, usage_idx_req))
         {
             *regnum = i;
             return TRUE;
         {
             *regnum = i;
             return TRUE;
@@ -203,7 +186,7 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
 
 static HRESULT WINAPI IWineD3DVertexShaderImpl_GetParent(IWineD3DVertexShader *iface, IUnknown** parent){
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
 
 static HRESULT WINAPI IWineD3DVertexShaderImpl_GetParent(IWineD3DVertexShader *iface, IUnknown** parent){
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
-    
+
     *parent = This->parent;
     IUnknown_AddRef(*parent);
     TRACE("(%p) : returning %p\n", This, *parent);
     *parent = This->parent;
     IUnknown_AddRef(*parent);
     TRACE("(%p) : returning %p\n", This, *parent);
@@ -249,6 +232,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     const struct wined3d_shader_frontend *fe;
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     const struct wined3d_shader_frontend *fe;
+    unsigned int i;
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
@@ -280,16 +264,26 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
-            reg_maps, This->semantics_in, This->semantics_out, pFunction,
-            GL_LIMITS(vshader_constantsF));
+            reg_maps, This->attributes, NULL, This->output_signature,
+            pFunction, GL_LIMITS(vshader_constantsF));
     if (hr != WINED3D_OK) return hr;
 
     if (hr != WINED3D_OK) return hr;
 
-    vshader_set_limits(This);
+    if (output_signature)
+    {
+        for (i = 0; i < output_signature->element_count; ++i)
+        {
+            struct wined3d_shader_signature_element *e = &output_signature->elements[i];
+            reg_maps->output_registers |= 1 << e->register_idx;
+            This->output_signature[e->register_idx] = *e;
+        }
+    }
 
 
-    if(deviceImpl->vs_selected_mode == SHADER_ARB &&
-       (GLINFO_LOCATION).arb_vs_offset_limit      &&
-       This->min_rel_offset <= This->max_rel_offset) {
+    vshader_set_limits(This);
 
 
+    if (deviceImpl->vs_selected_mode == SHADER_ARB
+            && ((GLINFO_LOCATION).quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT)
+            && This->min_rel_offset <= This->max_rel_offset)
+    {
         if(This->max_rel_offset - This->min_rel_offset > 127) {
             FIXME("The difference between the minimum and maximum relative offset is > 127\n");
             FIXME("Which this OpenGL implementation does not support. Try using GLSL\n");
         if(This->max_rel_offset - This->min_rel_offset > 127) {
             FIXME("The difference between the minimum and maximum relative offset is > 127\n");
             FIXME("Which this OpenGL implementation does not support. Try using GLSL\n");
@@ -312,19 +306,6 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-/* Preload semantics for d3d8 shaders */
-static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader *iface, IWineD3DVertexDeclaration *vertex_declaration) {
-    IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
-    IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration;
-
-    unsigned int i;
-    for (i = 0; i < vdecl->element_count; ++i)
-    {
-        const struct wined3d_vertex_declaration_element *e = &vdecl->elements[i];
-        vshader_set_input(This, e->output_slot, e->usage, e->usage_idx);
-    }
-}
-
 /* Set local constants for d3d8 shaders */
 static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertexShader *iface,
         UINT start_idx, const float *src_data, UINT count) {
 /* Set local constants for d3d8 shaders */
 static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertexShader *iface,
         UINT start_idx, const float *src_data, UINT count) {
@@ -351,22 +332,6 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static GLuint vertexshader_compile(IWineD3DVertexShaderImpl *This, const struct vs_compile_args *args) {
-    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
-    SHADER_BUFFER buffer;
-    GLuint ret;
-
-    /* Generate the HW shader */
-    TRACE("(%p) : Generating hardware program\n", This);
-    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 ret;
-}
-
 const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
 {
     /*** IUnknown methods ***/
 const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
 {
     /*** IUnknown methods ***/
@@ -380,7 +345,6 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
     /*** IWineD3DVertexShader methods ***/
     IWineD3DVertexShaderImpl_GetDevice,
     IWineD3DVertexShaderImpl_GetFunction,
     /*** IWineD3DVertexShader methods ***/
     IWineD3DVertexShaderImpl_GetDevice,
     IWineD3DVertexShaderImpl_GetFunction,
-    IWineD3DVertexShaderImpl_FakeSemantics,
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
 
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
 
@@ -388,52 +352,3 @@ void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockIm
     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;
 }
     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->num_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 64d871b..85e8f3a 100644 (file)
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 #define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
+/* Context activation is done by the caller. */
 static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
     IWineD3DVolumeTexture *texture;
 static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
     IWineD3DVolumeTexture *texture;
-    int active_sampler;
+    DWORD active_sampler;
 
     /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
      * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
 
     /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
      * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
@@ -52,7 +53,8 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
         active_sampler = 0;
     }
 
         active_sampler = 0;
     }
 
-    if (active_sampler != -1) {
+    if (active_sampler != WINED3D_UNMAPPED_STAGE)
+    {
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
 
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
 
@@ -196,14 +198,15 @@ static HRESULT WINAPI IWineD3DVolumeImpl_GetDesc(IWineD3DVolume *iface, WINED3DV
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
     TRACE("(%p) : copying into %p\n", This, pDesc);
 
     IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
     TRACE("(%p) : copying into %p\n", This, pDesc);
 
-    *(pDesc->Format)  = This->resource.format_desc->format;
-    *(pDesc->Type)    = This->resource.resourceType;
-    *(pDesc->Usage)   = This->resource.usage;
-    *(pDesc->Pool)    = This->resource.pool;
-    *(pDesc->Size)    = This->resource.size; /* dx8 only */
-    *(pDesc->Width)   = This->currentDesc.Width;
-    *(pDesc->Height)  = This->currentDesc.Height;
-    *(pDesc->Depth)   = This->currentDesc.Depth;
+    pDesc->Format = This->resource.format_desc->format;
+    pDesc->Type = This->resource.resourceType;
+    pDesc->Usage = This->resource.usage;
+    pDesc->Pool = This->resource.pool;
+    pDesc->Size = This->resource.size; /* dx8 only */
+    pDesc->Width = This->currentDesc.Width;
+    pDesc->Height = This->currentDesc.Height;
+    pDesc->Depth = This->currentDesc.Depth;
+
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -300,6 +303,7 @@ static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWi
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
+/* Context activation is done by the caller. */
 static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) {
     IWineD3DVolumeImpl *This     = (IWineD3DVolumeImpl *)iface;
     const struct GlPixelFormatDesc *glDesc = This->resource.format_desc;
 static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) {
     IWineD3DVolumeImpl *This     = (IWineD3DVolumeImpl *)iface;
     const struct GlPixelFormatDesc *glDesc = This->resource.format_desc;
index 41a1160..134ff74 100644 (file)
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
+#define GLINFO_LOCATION (*gl_info)
+
+static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb)
+{
+    /* Override the IWineD3DResource Preload method. */
+    IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    BOOL srgb_mode = This->baseTexture.is_srgb;
+    BOOL srgb_was_toggled = FALSE;
+    unsigned int i;
+
+    TRACE("(%p) : About to load texture.\n", This);
+
+    if (!device->isInDraw)
+    {
+        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    }
+    else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0)
+    {
+        srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
+        srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
+        This->baseTexture.is_srgb = srgb_mode;
+    }
+
+    /* If the texture is marked dirty or the srgb sampler setting has changed
+     * since the last load then reload the volumes. */
+    if (This->baseTexture.dirty)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
+        }
+    }
+    else if (srgb_was_toggled)
+    {
+        for (i = 0; i < This->baseTexture.levels; ++i)
+        {
+            volume_add_dirty_box(This->volumes[i], NULL);
+            IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
+        }
+    }
+    else
+    {
+        TRACE("(%p) Texture not dirty, nothing to do.\n", iface);
+    }
+
+    /* No longer dirty */
+    This->baseTexture.dirty = FALSE;
+}
+
+static void volumetexture_cleanup(IWineD3DVolumeTextureImpl *This, D3DCB_DESTROYVOLUMEFN volume_destroy_cb)
+{
+    unsigned int i;
+
+    TRACE("(%p) : Cleaning up.\n", This);
+
+    for (i = 0; i < This->baseTexture.levels; ++i)
+    {
+        IWineD3DVolume *volume = This->volumes[i];
+
+        if (volume)
+        {
+            /* Cleanup the container. */
+            IWineD3DVolume_SetContainer(volume, NULL);
+            volume_destroy_cb(volume);
+        }
+    }
+    basetexture_cleanup((IWineD3DBaseTexture *)This);
+}
+
+HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height, UINT depth, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, gl_info);
+    UINT tmp_w, tmp_h, tmp_d;
+    unsigned int i;
+    HRESULT hr;
+
+    /* TODO: It should only be possible to create textures for formats
+     * that are reported as supported. */
+    if (WINED3DFMT_UNKNOWN >= format)
+    {
+        WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    if (!GL_SUPPORT(EXT_TEXTURE3D))
+    {
+        WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture);
+        return WINED3DERR_INVALIDCALL;
+    }
+
+    /* Calculate levels for mip mapping. */
+    if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
+    {
+        if (!GL_SUPPORT(SGIS_GENERATE_MIPMAP))
+        {
+            WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        if (levels > 1)
+        {
+            WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+            return WINED3DERR_INVALIDCALL;
+        }
+
+        levels = 1;
+    }
+    else if (!levels)
+    {
+        levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+        TRACE("Calculated levels = %u.\n", levels);
+    }
+
+    hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, levels,
+            WINED3DRTYPE_VOLUMETEXTURE, device, 0, usage, format_desc, pool, parent);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize basetexture, returning %#x.\n", hr);
+        return hr;
+    }
+
+    /* Is NP2 support for volumes needed? */
+    texture->baseTexture.pow2Matrix[0] = 1.0f;
+    texture->baseTexture.pow2Matrix[5] = 1.0f;
+    texture->baseTexture.pow2Matrix[10] = 1.0f;
+    texture->baseTexture.pow2Matrix[15] = 1.0f;
+
+    /* Generate all the surfaces. */
+    tmp_w = width;
+    tmp_h = height;
+    tmp_d = depth;
+
+    for (i = 0; i < texture->baseTexture.levels; ++i)
+    {
+        /* Create the volume. */
+        hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent,
+                tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i]);
+        if (FAILED(hr))
+        {
+            ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr);
+            texture->volumes[i] = NULL;
+            volumetexture_cleanup(texture, D3DCB_DefaultDestroyVolume);
+            return hr;
+        }
+
+        /* Set its container to this texture. */
+        IWineD3DVolume_SetContainer(texture->volumes[i], (IWineD3DBase *)texture);
+
+        /* Calculate the next mipmap level. */
+        tmp_w = max(1, tmp_w >> 1);
+        tmp_h = max(1, tmp_h >> 1);
+        tmp_d = max(1, tmp_d >> 1);
+    }
+    texture->baseTexture.internal_preload = volumetexture_internal_preload;
+
+    return WINED3D_OK;
+}
+
+#undef GLINFO_LOCATION
 
 /* *******************************************
    IWineD3DTexture IUnknown parts follow
    ******************************************* */
 
 /* *******************************************
    IWineD3DTexture IUnknown parts follow
    ******************************************* */
+
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
+
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_QueryInterface(IWineD3DVolumeTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_QueryInterface(IWineD3DVolumeTexture *iface, REFIID riid, LPVOID *ppobj)
 {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
@@ -90,43 +256,6 @@ static DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
     return resource_get_priority((IWineD3DResource *)iface);
 }
 
-void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
-    /* Overrider the IWineD3DResource Preload method */
-    unsigned int i;
-    IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BOOL srgb_mode = This->baseTexture.is_srgb;
-    BOOL srgb_was_toggled = FALSE;
-
-    TRACE("(%p) : About to load texture\n", This);
-
-    if(!device->isInDraw) {
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-    } else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
-        srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
-        srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
-        This->baseTexture.is_srgb = srgb_mode;
-    }
-
-    /* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
-    if (This->baseTexture.dirty) {
-        for (i = 0; i < This->baseTexture.levels; i++)
-            IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
-    } else if (srgb_was_toggled) {
-        for (i = 0; i < This->baseTexture.levels; i++) {
-            volume_add_dirty_box(This->volumes[i], NULL);
-            IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
-        }
-    } else {
-        TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
-    }
-
-    /* No longer dirty */
-    This->baseTexture.dirty = FALSE;
-
-    return ;
-}
-
 static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) {
     volumetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
 static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) {
     volumetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
 }
@@ -191,6 +320,7 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *ifa
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
     return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
 }
 
+/* Context activation is done by the caller. */
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface, BOOL srgb) {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
     BOOL dummy;
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface, BOOL srgb) {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
     BOOL dummy;
@@ -211,30 +341,14 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_IsCondNP2(IWineD3DVolumeTexture *if
     return FALSE;
 }
 
     return FALSE;
 }
 
-static void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface,
-                                                        const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
-                                                        const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
-    IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
-    TRACE("(%p) : nothing to do, passing to base texture\n", This);
-    basetexture_apply_state_changes((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
-}
-
-
 /* *******************************************
    IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DVolumeTextureImpl_Destroy(IWineD3DVolumeTexture *iface, D3DCB_DESTROYVOLUMEFN D3DCB_DestroyVolume) {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
 /* *******************************************
    IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow
    ******************************************* */
 static void WINAPI IWineD3DVolumeTextureImpl_Destroy(IWineD3DVolumeTexture *iface, D3DCB_DESTROYVOLUMEFN D3DCB_DestroyVolume) {
     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
-    unsigned int i;
-    TRACE("(%p) : Cleaning up\n",This);
-    for (i = 0; i < This->baseTexture.levels; i++) {
-        if (This->volumes[i] != NULL) {
-            /* Cleanup the container */
-            IWineD3DVolume_SetContainer(This->volumes[i], 0);
-            D3DCB_DestroyVolume(This->volumes[i]);
-        }
-    }
-    basetexture_cleanup((IWineD3DBaseTexture *)iface);
+
+    volumetexture_cleanup(This, D3DCB_DestroyVolume);
+
     HeapFree(GetProcessHeap(), 0, This);
 }
 
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -330,7 +444,6 @@ const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
     IWineD3DVolumeTextureImpl_BindTexture,
     IWineD3DVolumeTextureImpl_GetTextureDimensions,
     IWineD3DVolumeTextureImpl_IsCondNP2,
     IWineD3DVolumeTextureImpl_BindTexture,
     IWineD3DVolumeTextureImpl_GetTextureDimensions,
     IWineD3DVolumeTextureImpl_IsCondNP2,
-    IWineD3DVolumeTextureImpl_ApplyStateChanges,
     /* volume texture */
     IWineD3DVolumeTextureImpl_Destroy,
     IWineD3DVolumeTextureImpl_GetLevelDesc,
     /* volume texture */
     IWineD3DVolumeTextureImpl_Destroy,
     IWineD3DVolumeTextureImpl_GetLevelDesc,
index 2f2677c..f65ee31 100644 (file)
@@ -1,2 +1,4 @@
 @ stdcall WineDirect3DCreate(long ptr)
 @ stdcall WineDirect3DCreateClipper(ptr)
 @ stdcall WineDirect3DCreate(long ptr)
 @ stdcall WineDirect3DCreateClipper(ptr)
+@ stdcall wined3d_mutex_lock()
+@ stdcall wined3d_mutex_unlock()
index 1a9c925..9c85d57 100644 (file)
@@ -1141,10 +1141,13 @@ void (WINE_GLAPI *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
 void (WINE_GLAPI *glPointParameterfv) (GLenum pname, const GLfloat *params);
 
 /* glFinish and glFlush are always loaded from opengl32.dll, thus they always have
 void (WINE_GLAPI *glPointParameterfv) (GLenum pname, const GLfloat *params);
 
 /* glFinish and glFlush are always loaded from opengl32.dll, thus they always have
- * __stdcall calling convention
+ * __stdcall calling convention.
+ *
+ * They are wgl functions and must not be called inside the gl lock, give them a
+ * name that makes this clear
  */
  */
-void (__stdcall  *glFinish) ();
-void (__stdcall  *glFlush) ();
+void (__stdcall  *wglFinish) ();
+void (__stdcall  *wglFlush) ();
 
 /* WGL functions */
 HGLRC   (WINAPI *pwglCreateContext)(HDC);
 
 /* WGL functions */
 HGLRC   (WINAPI *pwglCreateContext)(HDC);
@@ -1517,6 +1520,20 @@ BOOL    (WINAPI *pwglShareLists)(HGLRC,HGLRC);
 #endif
 typedef void (WINE_GLAPI *PGLFNCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
 
 #endif
 typedef void (WINE_GLAPI *PGLFNCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
 
+/* GL_ARB_depth_buffer_float */
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+#define GL_DEPTH_COMPONENT32F             0x8cac
+#define GL_DEPTH32F_STENCIL8              0x8cad
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8dad
+#endif
+
+/* GL_ARB_depth_clamp */
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#define GL_DEPTH_CLAMP                    0x864f
+#endif
+
 /* GL_ARB_depth_texture */
 #ifndef GL_ARB_depth_texture
 #define GL_ARB_depth_texture 1
 /* GL_ARB_depth_texture */
 #ifndef GL_ARB_depth_texture
 #define GL_ARB_depth_texture 1
@@ -1897,6 +1914,15 @@ typedef void (WINE_GLAPI * PGLFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint sr
 #endif
 typedef void (WINE_GLAPI * PGLFNRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 
 #endif
 typedef void (WINE_GLAPI * PGLFNRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 
+/* GL_EXT_packed_depth_stencil */
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#define GL_DEPTH_STENCIL_EXT                0x84f9
+#define GL_UNSIGNED_INT_24_8_EXT            0x84fa
+#define GL_DEPTH24_STENCIL8_EXT             0x88f0
+#define GL_TEXTURE_STENCIL_SIZE_EXT         0x88f1
+#endif
+
 /* GL_EXT_secondary_color */
 #ifndef GL_EXT_secondary_color
 #define GL_EXT_secondary_color 1
 /* GL_EXT_secondary_color */
 #ifndef GL_EXT_secondary_color
 #define GL_EXT_secondary_color 1
@@ -1935,6 +1961,17 @@ typedef void (WINE_GLAPI * PGLFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum inte
 #endif
 typedef void (WINE_GLAPI * PGLFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
 typedef void (WINE_GLAPI * PGLFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
 #endif
 typedef void (WINE_GLAPI * PGLFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
 typedef void (WINE_GLAPI * PGLFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+
+/* GL_EXT_provoking_vertex */
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+#define GL_FIRST_VERTEX_CONVENTION_EXT                      0x8e4d
+#define GL_LAST_VERTEX_CONVENTION_EXT                       0x8e4e
+#define GL_PROVOKING_VERTEX_EXT                             0x8e4f
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTIONS_EXT    0x8e4c
+#endif
+typedef void (WINE_GLAPI * PGLFNGLPROVOKINGVERTEXEXTPROC)(GLenum mode);
+
 /* GL_EXT_texture3D */
 #ifndef GL_EXT_texture3D
 #define GL_EXT_texture3D 1
 /* GL_EXT_texture3D */
 #ifndef GL_EXT_texture3D
 #define GL_EXT_texture3D 1
@@ -3080,6 +3117,13 @@ typedef void (WINE_GLAPI *PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const
 #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT          0x8DBE
 #endif
 
 #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT          0x8DBE
 #endif
 
+/* GL_NV_vertex_program2_option */
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV               0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV                      0x88F5
+#endif
+
 /* GL_VERSION_2_0 */
 #ifndef GL_VERSION_2_0
 #define GL_VERSION_2_0 1
 /* GL_VERSION_2_0 */
 #ifndef GL_VERSION_2_0
 #define GL_VERSION_2_0 1
@@ -3302,6 +3346,18 @@ typedef enum _GL_Cards {
   CARD_ATI_RADEON_HD2600          = 0x9581,
   CARD_ATI_RADEON_HD2900          = 0x9400,
   CARD_ATI_RADEON_HD3200          = 0x9620,
   CARD_ATI_RADEON_HD2600          = 0x9581,
   CARD_ATI_RADEON_HD2900          = 0x9400,
   CARD_ATI_RADEON_HD3200          = 0x9620,
+  CARD_ATI_RADEON_HD4350          = 0x954f,
+  CARD_ATI_RADEON_HD4550          = 0x9540,
+  CARD_ATI_RADEON_HD4600          = 0x9495,
+  CARD_ATI_RADEON_HD4650          = 0x9498,
+  CARD_ATI_RADEON_HD4670          = 0x9490,
+  CARD_ATI_RADEON_HD4700          = 0x944e,
+  CARD_ATI_RADEON_HD4770          = 0x94b3,
+  CARD_ATI_RADEON_HD4800          = 0x944c, /* picked one value between 9440,944c,9442,9460 */
+  CARD_ATI_RADEON_HD4830          = 0x944c,
+  CARD_ATI_RADEON_HD4850          = 0x9442,
+  CARD_ATI_RADEON_HD4870          = 0x9440,
+  CARD_ATI_RADEON_HD4890          = 0x9460,
 
   CARD_NVIDIA_RIVA_128            = 0x0018,
   CARD_NVIDIA_RIVA_TNT            = 0x0020,
 
   CARD_NVIDIA_RIVA_128            = 0x0018,
   CARD_NVIDIA_RIVA_TNT            = 0x0020,
@@ -3342,39 +3398,21 @@ typedef enum _GL_Cards {
   CARD_INTEL_I915G                = 0x2582,
   CARD_INTEL_I915GM               = 0x2592,
   CARD_INTEL_I945GM               = 0x27a2, /* Same as GMA 950?? */
   CARD_INTEL_I915G                = 0x2582,
   CARD_INTEL_I915GM               = 0x2592,
   CARD_INTEL_I945GM               = 0x27a2, /* Same as GMA 950?? */
+  CARD_INTEL_X3100                = 0x2a02, /* found in macs. Same as GMA 965? */
 } GL_Cards;
 
 #define WINE_DEFAULT_VIDMEM 64*1024*1024
 
 } GL_Cards;
 
 #define WINE_DEFAULT_VIDMEM 64*1024*1024
 
-typedef enum _GL_VSVersion {
-  VS_VERSION_NOT_SUPPORTED = 0x0,
-  VS_VERSION_10 = 0x10,
-  VS_VERSION_11 = 0x11,
-  VS_VERSION_20 = 0x20,
-  VS_VERSION_30 = 0x30,
-  /*Force 32-bits*/
-  VS_VERSION_FORCE_DWORD = 0x7FFFFFFF
-} GL_VSVersion;
-
-typedef enum _GL_PSVersion {
-  PS_VERSION_NOT_SUPPORTED = 0x0,
-  PS_VERSION_10 = 0x10,
-  PS_VERSION_11 = 0x11,
-  PS_VERSION_12 = 0x12,
-  PS_VERSION_13 = 0x13,
-  PS_VERSION_14 = 0x14,
-  PS_VERSION_20 = 0x20,
-  PS_VERSION_30 = 0x30,
-  /*Force 32-bits*/
-  PS_VERSION_FORCE_DWORD = 0x7FFFFFFF
-} GL_PSVersion;
-
 #define MAKEDWORD_VERSION(maj, min)  ((maj & 0x0000FFFF) << 16) | (min & 0x0000FFFF)
 
 /* OpenGL Supported Extensions (ARB and EXT) */
 typedef enum _GL_SupportedExt {
 #define MAKEDWORD_VERSION(maj, min)  ((maj & 0x0000FFFF) << 16) | (min & 0x0000FFFF)
 
 /* OpenGL Supported Extensions (ARB and EXT) */
 typedef enum _GL_SupportedExt {
+  WINED3D_GL_EXT_NONE,
   /* ARB */
   ARB_COLOR_BUFFER_FLOAT,
   /* ARB */
   ARB_COLOR_BUFFER_FLOAT,
+  ARB_DEPTH_BUFFER_FLOAT,
+  ARB_DEPTH_CLAMP,
+  ARB_DEPTH_TEXTURE,
   ARB_DRAW_BUFFERS,
   ARB_FRAGMENT_PROGRAM,
   ARB_FRAGMENT_SHADER,
   ARB_DRAW_BUFFERS,
   ARB_FRAGMENT_PROGRAM,
   ARB_FRAGMENT_SHADER,
@@ -3414,9 +3452,11 @@ typedef enum _GL_SupportedExt {
   EXT_FRAMEBUFFER_OBJECT,
   EXT_FRAMEBUFFER_BLIT,
   EXT_FRAMEBUFFER_MULTISAMPLE,
   EXT_FRAMEBUFFER_OBJECT,
   EXT_FRAMEBUFFER_BLIT,
   EXT_FRAMEBUFFER_MULTISAMPLE,
+  EXT_PACKED_DEPTH_STENCIL,
   EXT_PALETTED_TEXTURE,
   EXT_PIXEL_BUFFER_OBJECT,
   EXT_POINT_PARAMETERS,
   EXT_PALETTED_TEXTURE,
   EXT_PIXEL_BUFFER_OBJECT,
   EXT_POINT_PARAMETERS,
+  EXT_PROVOKING_VERTEX,
   EXT_SECONDARY_COLOR,
   EXT_STENCIL_TWO_SIDE,
   EXT_STENCIL_WRAP,
   EXT_SECONDARY_COLOR,
   EXT_STENCIL_TWO_SIDE,
   EXT_STENCIL_WRAP,
@@ -3449,7 +3489,9 @@ typedef enum _GL_SupportedExt {
   NV_VERTEX_PROGRAM,
   NV_VERTEX_PROGRAM1_1,
   NV_VERTEX_PROGRAM2,
   NV_VERTEX_PROGRAM,
   NV_VERTEX_PROGRAM1_1,
   NV_VERTEX_PROGRAM2,
+  NV_VERTEX_PROGRAM2_OPTION,
   NV_VERTEX_PROGRAM3,
   NV_VERTEX_PROGRAM3,
+  NV_FRAGMENT_PROGRAM_OPTION,
   NV_FENCE,
   NV_DEPTH_CLAMP,
   NV_LIGHT_MAX_EXPONENT,
   NV_FENCE,
   NV_DEPTH_CLAMP,
   NV_LIGHT_MAX_EXPONENT,
@@ -3478,7 +3520,7 @@ typedef enum _GL_SupportedExt {
   WGL_ARB_PIXEL_FORMAT,
   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
 
   WGL_ARB_PIXEL_FORMAT,
   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
 
-  OPENGL_SUPPORTED_EXT_END
+  WINED3D_GL_EXT_COUNT,
 } GL_SupportedExt;
 
 
 } GL_SupportedExt;
 
 
@@ -3591,6 +3633,8 @@ typedef enum _GL_SupportedExt {
     /* GL_EXT_point_parameters */ \
     USE_GL_FUNC(PGLFNGLPOINTPARAMETERFEXTPROC,                      glPointParameterfEXT,                       EXT_POINT_PARAMETERS,   NULL )\
     USE_GL_FUNC(PGLFNGLPOINTPARAMETERFVEXTPROC,                     glPointParameterfvEXT,                      EXT_POINT_PARAMETERS,   NULL )\
     /* GL_EXT_point_parameters */ \
     USE_GL_FUNC(PGLFNGLPOINTPARAMETERFEXTPROC,                      glPointParameterfEXT,                       EXT_POINT_PARAMETERS,   NULL )\
     USE_GL_FUNC(PGLFNGLPOINTPARAMETERFVEXTPROC,                     glPointParameterfvEXT,                      EXT_POINT_PARAMETERS,   NULL )\
+    /* GL_EXT_provoking_vertex */ \
+    USE_GL_FUNC(PGLFNGLPROVOKINGVERTEXEXTPROC,                      glProvokingVertexEXT,                       EXT_PROVOKING_VERTEX,   NULL)\
     /* GL_EXT_secondary_color */ \
     USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3UBEXTPROC,                    glSecondaryColor3ubEXT,                     EXT_SECONDARY_COLOR,    NULL )\
     USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3UBVEXTPROC,                   glSecondaryColor3ubvEXT,                    EXT_SECONDARY_COLOR,    NULL )\
     /* GL_EXT_secondary_color */ \
     USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3UBEXTPROC,                    glSecondaryColor3ubEXT,                     EXT_SECONDARY_COLOR,    NULL )\
     USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3UBVEXTPROC,                   glSecondaryColor3ubvEXT,                    EXT_SECONDARY_COLOR,    NULL )\
@@ -3906,77 +3950,61 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFor
  ****************************************************/
 
 #define USE_GL_FUNC(type, pfn, ext, replace) type pfn;
  ****************************************************/
 
 #define USE_GL_FUNC(type, pfn, ext, replace) type pfn;
-typedef struct _WineD3D_GL_Info {
-
-  DWORD  glx_version;
-  DWORD  gl_version;
-
-  GL_Vendors gl_vendor;
-  GL_Cards   gl_card;
-  UINT   vidmem;
-  DWORD  driver_version;
-  DWORD  driver_version_hipart;
-  CHAR   driver_description[255];
-  CHAR   gl_renderer[255];
-  /**
-   * CAPS Constants
-   */
-  UINT   max_buffers;
-  UINT   max_lights;
-  UINT   max_textures;
-  UINT   max_texture_stages;
-  UINT   max_fragment_samplers;
-  UINT   max_vertex_samplers;
-  UINT   max_combined_samplers;
-  UINT   max_sampler_stages;
-  UINT   max_clipplanes;
-  UINT   max_texture_size;
-  UINT   max_texture3d_size;
-  float  max_pointsize, max_pointsizemin;
-  UINT   max_point_sprite_units;
-  UINT   max_blends;
-  UINT   max_anisotropy;
-  UINT   max_glsl_varyings;
-  float  max_shininess;
-
-  unsigned max_vshader_constantsF;
-  unsigned max_pshader_constantsF;
-
-  unsigned vs_arb_constantsF;
-  unsigned vs_arb_max_instructions;
-  unsigned vs_arb_max_temps;
-  unsigned ps_arb_constantsF;
-  unsigned ps_arb_max_instructions;
-  unsigned ps_arb_max_temps;
-  unsigned vs_glsl_constantsF;
-  unsigned ps_glsl_constantsF;
-
-  GL_PSVersion ps_arb_version;
-  GL_PSVersion ps_nv_version;
-
-  GL_VSVersion vs_arb_version;
-  GL_VSVersion vs_nv_version;
-  GL_VSVersion vs_ati_version;
-
-  BOOL arb_vs_offset_limit;
-  BOOL set_texcoord_w;
-  DWORD reserved_glsl_constants;
-
-  BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
-
-  /** OpenGL EXT and ARB functions ptr */
-  GL_EXT_FUNCS_GEN
-  /** OpenGL WGL functions ptr */
-  WGL_EXT_FUNCS_GEN
-
-  struct GlPixelFormatDesc *gl_formats;
-} WineD3D_GL_Info;
-#undef USE_GL_FUNC
 
 
-struct driver_quirk {
-    BOOL        (*match)(const WineD3D_GL_Info *gl_info);
-    void        (*apply)(WineD3D_GL_Info *gl_info);
-    const char  *description;
+struct wined3d_gl_info
+{
+    GL_Vendors gl_vendor;
+    GL_Cards gl_card;
+    UINT vidmem;
+    DWORD driver_version;
+    DWORD driver_version_hipart;
+    const char *driver_description;
+
+    UINT max_buffers;
+    UINT max_lights;
+    UINT max_textures;
+    UINT max_texture_stages;
+    UINT max_fragment_samplers;
+    UINT max_vertex_samplers;
+    UINT max_combined_samplers;
+    UINT max_sampler_stages;
+    UINT max_clipplanes;
+    UINT max_texture_size;
+    UINT max_texture3d_size;
+    float max_pointsize, max_pointsizemin;
+    UINT max_point_sprite_units;
+    UINT max_blends;
+    UINT max_anisotropy;
+    UINT max_glsl_varyings;
+    float max_shininess;
+
+    unsigned int max_vshader_constantsF;
+    unsigned int max_pshader_constantsF;
+
+    unsigned int vs_arb_constantsF;
+    unsigned int vs_arb_max_instructions;
+    unsigned int vs_arb_max_temps;
+    unsigned int ps_arb_constantsF;
+    unsigned int ps_arb_max_local_constants;
+    unsigned int ps_arb_max_instructions;
+    unsigned int ps_arb_max_temps;
+    unsigned int vs_glsl_constantsF;
+    unsigned int ps_glsl_constantsF;
+
+    DWORD reserved_glsl_constants;
+
+    DWORD quirks;
+
+    BOOL supported[WINED3D_GL_EXT_COUNT];
+
+    /* GL function pointers */
+    GL_EXT_FUNCS_GEN
+    /* WGL function pointers */
+    WGL_EXT_FUNCS_GEN
+
+    struct GlPixelFormatDesc *gl_formats;
 };
 
 };
 
+#undef USE_GL_FUNC
+
 #endif /* __WINE_WINED3D_GL */
 #endif /* __WINE_WINED3D_GL */
index 687fe89..bdb544a 100644 (file)
@@ -32,17 +32,25 @@ int num_lock = 0;
 void (*CDECL wine_tsx11_lock_ptr)(void) = NULL;
 void (*CDECL wine_tsx11_unlock_ptr)(void) = NULL;
 
 void (*CDECL wine_tsx11_lock_ptr)(void) = NULL;
 void (*CDECL wine_tsx11_unlock_ptr)(void) = NULL;
 
+CRITICAL_SECTION wined3d_cs;
+static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
+{
+    0, 0, &wined3d_cs,
+    {&wined3d_cs_debug.ProcessLocksList,
+    &wined3d_cs_debug.ProcessLocksList},
+    0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs")}
+};
+CRITICAL_SECTION wined3d_cs = {&wined3d_cs_debug, -1, 0, 0, 0, 0};
 
 /* When updating default value here, make sure to update winecfg as well,
  * where appropriate. */
 
 /* When updating default value here, make sure to update winecfg as well,
  * where appropriate. */
-wined3d_settings_t wined3d_settings = 
+wined3d_settings_t wined3d_settings =
 {
     VS_HW,          /* Hardware by default */
     PS_HW,          /* Hardware by default */
 {
     VS_HW,          /* Hardware by default */
     PS_HW,          /* Hardware by default */
-    VBO_HW,         /* Hardware by default */
     TRUE,           /* Use of GLSL enabled by default */
     TRUE,           /* Use of GLSL enabled by default */
-    ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
-    RTL_AUTO,       /* Automatically determine best locking method */
+    ORM_FBO,        /* Use FBOs to do offscreen rendering */
+    RTL_READTEX,    /* Default render target locking method */
     PCI_VENDOR_NONE,/* PCI Vendor ID */
     PCI_DEVICE_NONE,/* PCI Device ID */
     0,              /* The default of memory is set in FillGLCaps */
     PCI_VENDOR_NONE,/* PCI Vendor ID */
     PCI_DEVICE_NONE,/* PCI Device ID */
     0,              /* The default of memory is set in FillGLCaps */
@@ -97,6 +105,7 @@ static void CDECL wined3d_do_nothing(void)
 
 static BOOL wined3d_init(HINSTANCE hInstDLL)
 {
 
 static BOOL wined3d_init(HINSTANCE hInstDLL)
 {
+    DWORD wined3d_context_tls_idx;
     HMODULE mod;
     char buffer[MAX_PATH+10];
     DWORD size = sizeof(buffer);
     HMODULE mod;
     char buffer[MAX_PATH+10];
     DWORD size = sizeof(buffer);
@@ -105,6 +114,15 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
     DWORD len, tmpvalue;
     WNDCLASSA wc;
 
     DWORD len, tmpvalue;
     WNDCLASSA wc;
 
+    wined3d_context_tls_idx = TlsAlloc();
+    if (wined3d_context_tls_idx == TLS_OUT_OF_INDEXES)
+    {
+        DWORD err = GetLastError();
+        ERR("Failed to allocate context TLS index, err %#x.\n", err);
+        return FALSE;
+    }
+    context_set_tls_idx(wined3d_context_tls_idx);
+
     /* We need our own window class for a fake window which we use to retrieve GL capabilities */
     /* We might need CS_OWNDC in the future if we notice strange things on Windows.
      * Various articles/posts about OpenGL problems on Windows recommend this. */
     /* We need our own window class for a fake window which we use to retrieve GL capabilities */
     /* We might need CS_OWNDC in the future if we notice strange things on Windows.
      * Various articles/posts about OpenGL problems on Windows recommend this. */
@@ -117,11 +135,16 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
     wc.hCursor              = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
     wc.hbrBackground        = NULL;
     wc.lpszMenuName         = NULL;
     wc.hCursor              = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
     wc.hbrBackground        = NULL;
     wc.lpszMenuName         = NULL;
-    wc.lpszClassName        = "WineD3D_OpenGL";
+    wc.lpszClassName        = WINED3D_OPENGL_WINDOW_CLASS_NAME;
 
 
-    if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
+    if (!RegisterClassA(&wc))
     {
         ERR("Failed to register window class 'WineD3D_OpenGL'!\n");
     {
         ERR("Failed to register window class 'WineD3D_OpenGL'!\n");
+        if (!TlsFree(wined3d_context_tls_idx))
+        {
+            DWORD err = GetLastError();
+            ERR("Failed to free context TLS index, err %#x.\n", err);
+        }
         return FALSE;
     }
 
         return FALSE;
     }
 
@@ -181,19 +204,6 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
                 wined3d_settings.ps_mode = PS_NONE;
             }
         }
                 wined3d_settings.ps_mode = PS_NONE;
             }
         }
-        if ( !get_config_key( hkey, appkey, "VertexBufferMode", buffer, size) )
-        {
-            if (!strcmp(buffer,"none"))
-            {
-                TRACE("Disable Vertex Buffer Hardware support\n");
-                wined3d_settings.vbo_mode = VBO_NONE;
-            }
-            else if (!strcmp(buffer,"hardware"))
-            {
-                TRACE("Allow Vertex Buffer Hardware support\n");
-                wined3d_settings.vbo_mode = VBO_HW;
-            }
-        }
         if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
         {
             if (!strcmp(buffer,"disabled"))
         if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
         {
             if (!strcmp(buffer,"disabled"))
@@ -237,16 +247,6 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
                 TRACE("Using glReadPixels for render target reading and textures for writing\n");
                 wined3d_settings.rendertargetlock_mode = RTL_READTEX;
             }
                 TRACE("Using glReadPixels for render target reading and textures for writing\n");
                 wined3d_settings.rendertargetlock_mode = RTL_READTEX;
             }
-            else if (!strcmp(buffer,"texdraw"))
-            {
-                TRACE("Using textures for render target reading and glDrawPixels for writing\n");
-                wined3d_settings.rendertargetlock_mode = RTL_TEXDRAW;
-            }
-            else if (!strcmp(buffer,"textex"))
-            {
-                TRACE("Reading render targets via textures and writing via textures\n");
-                wined3d_settings.rendertargetlock_mode = RTL_TEXTEX;
-            }
         }
         if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) )
         {
         }
         if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) )
         {
@@ -309,8 +309,6 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
         TRACE("Allow HW vertex shaders\n");
     if (wined3d_settings.ps_mode == PS_NONE)
         TRACE("Disable pixel shaders\n");
         TRACE("Allow HW vertex shaders\n");
     if (wined3d_settings.ps_mode == PS_NONE)
         TRACE("Disable pixel shaders\n");
-    if (wined3d_settings.vbo_mode == VBO_NONE)
-        TRACE("Disable Vertex Buffer Hardware support\n");
     if (wined3d_settings.glslRequested)
         TRACE("If supported by your system, GL Shading Language will be used\n");
 
     if (wined3d_settings.glslRequested)
         TRACE("If supported by your system, GL Shading Language will be used\n");
 
@@ -320,13 +318,32 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
     return TRUE;
 }
 
     return TRUE;
 }
 
-static BOOL wined3d_destroy(void)
+static BOOL wined3d_destroy(HINSTANCE hInstDLL)
 {
 {
+    DWORD wined3d_context_tls_idx = context_get_tls_idx();
+
+    if (!TlsFree(wined3d_context_tls_idx))
+    {
+        DWORD err = GetLastError();
+        ERR("Failed to free context TLS index, err %#x.\n", err);
+    }
+
     HeapFree(GetProcessHeap(), 0, wined3d_settings.logo);
     HeapFree(GetProcessHeap(), 0, wined3d_settings.logo);
+    UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
 
     return TRUE;
 }
 
 
     return TRUE;
 }
 
+void WINAPI wined3d_mutex_lock(void)
+{
+    EnterCriticalSection(&wined3d_cs);
+}
+
+void WINAPI wined3d_mutex_unlock(void)
+{
+    LeaveCriticalSection(&wined3d_cs);
+}
+
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
 {
 /* At process attach */
 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
 {
@@ -338,7 +355,16 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
             return wined3d_init(hInstDLL);
 
         case DLL_PROCESS_DETACH:
             return wined3d_init(hInstDLL);
 
         case DLL_PROCESS_DETACH:
-            return wined3d_destroy();
+            return wined3d_destroy(hInstDLL);
+
+        case DLL_THREAD_DETACH:
+        {
+            if (!context_set_current(NULL))
+            {
+                ERR("Failed to clear current context.\n");
+            }
+            return TRUE;
+        }
 
         default:
             return TRUE;
 
         default:
             return TRUE;
index 303fb70..fefc540 100644 (file)
 #include "wine/wined3d.h"
 #include "wined3d_gl.h"
 #include "wine/list.h"
 #include "wine/wined3d.h"
 #include "wined3d_gl.h"
 #include "wine/list.h"
+#include "wine/rbtree.h"
+
+/* Driver quirks */
+#define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT       0x00000001
+#define WINED3D_QUIRK_SET_TEXCOORD_W            0x00000002
+#define WINED3D_QUIRK_GLSL_CLIP_VARYING         0x00000004
+#define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA     0x00000008
 
 /* Texture format fixups */
 
 
 /* Texture format fixups */
 
@@ -126,38 +133,9 @@ static inline enum yuv_fixup get_yuv_fixup(struct color_fixup_desc fixup)
     return yuv_fixup;
 }
 
     return yuv_fixup;
 }
 
-/* Hash table functions */
-typedef unsigned int (hash_function_t)(const void *key);
-typedef BOOL (compare_function_t)(const void *keya, const void *keyb);
-
-#define  ceilf(x) (float)ceil((double)x)
-
-struct hash_table_entry_t {
-    void *key;
-    void *value;
-    unsigned int hash;
-    struct list entry;
-};
-
-struct hash_table_t {
-    hash_function_t *hash_function;
-    compare_function_t *compare_function;
-    struct list *buckets;
-    unsigned int bucket_count;
-    struct hash_table_entry_t *entries;
-    unsigned int entry_count;
-    struct list free_entries;
-    unsigned int count;
-    unsigned int grow_size;
-    unsigned int shrink_size;
-};
-
-struct hash_table_t *hash_table_create(hash_function_t *hash_function, compare_function_t *compare_function);
-void hash_table_destroy(struct hash_table_t *table, void (*free_value)(void *value, void *cb), void *cb);
-void hash_table_for_each_entry(struct hash_table_t *table, void (*callback)(void *value, void *context), void *context);
-void *hash_table_get(const struct hash_table_t *table, const void *key);
-void hash_table_put(struct hash_table_t *table, void *key, void *value);
-void hash_table_remove(struct hash_table_t *table, void *key);
+void *wined3d_rb_alloc(size_t size);
+void *wined3d_rb_realloc(void *ptr, size_t size);
+void wined3d_rb_free(void *ptr);
 
 /* Device caps */
 #define MAX_PALETTES            65536
 
 /* Device caps */
 #define MAX_PALETTES            65536
@@ -198,13 +176,22 @@ struct min_lookup
     GLenum mip[WINED3DTEXF_LINEAR + 1];
 };
 
     GLenum mip[WINED3DTEXF_LINEAR + 1];
 };
 
-struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
-const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1];
-GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
-const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1];
+const struct min_lookup minMipLookup[WINED3DTEXF_LINEAR + 1];
+const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_LINEAR + 1];
+const struct min_lookup minMipLookup_noMip[WINED3DTEXF_LINEAR + 1];
+const GLenum magLookup[WINED3DTEXF_LINEAR + 1];
+const GLenum magLookup_noFilter[WINED3DTEXF_LINEAR + 1];
+
+static inline GLenum wined3d_gl_mag_filter(const GLenum mag_lookup[], WINED3DTEXTUREFILTERTYPE mag_filter)
+{
+    return mag_lookup[mag_filter];
+}
 
 
-extern const struct filter_lookup filter_lookup_nofilter;
-extern struct filter_lookup filter_lookup;
+static inline GLenum wined3d_gl_min_mip_filter(const struct min_lookup min_mip_lookup[],
+        WINED3DTEXTUREFILTERTYPE min_filter, WINED3DTEXTUREFILTERTYPE mip_filter)
+{
+    return min_mip_lookup[min_filter].mip[mip_filter];
+}
 
 /* float_16_to_32() and float_32_to_16() (see implementation in
  * surface_base.c) convert 16 bit floats in the FLOAT16 data type
 
 /* float_16_to_32() and float_32_to_16() (see implementation in
  * surface_base.c) convert 16 bit floats in the FLOAT16 data type
@@ -220,21 +207,43 @@ static inline float float_16_to_32(const unsigned short *in) {
     const unsigned short s = ((*in) & 0x8000);
     const unsigned short e = ((*in) & 0x7C00) >> 10;
     const unsigned short m = (*in) & 0x3FF;
     const unsigned short s = ((*in) & 0x8000);
     const unsigned short e = ((*in) & 0x7C00) >> 10;
     const unsigned short m = (*in) & 0x3FF;
-    const float sgn = (s ? -1.0 : 1.0);
+    const float sgn = (s ? -1.0f : 1.0f);
 
     if(e == 0) {
 
     if(e == 0) {
-        if(m == 0) return sgn * 0.0; /* +0.0 or -0.0 */
-        else return sgn * pow(2, -14.0) * ( (float) m / 1024.0);
+        if(m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
+        else return sgn * pow(2, -14.0f) * ((float)m / 1024.0f);
     } else if(e < 31) {
     } else if(e < 31) {
-        return sgn * pow(2, (float) e-15.0) * (1.0 + ((float) m / 1024.0));
+        return sgn * pow(2, (float)e - 15.0f) * (1.0f + ((float)m / 1024.0f));
     } else {
     } else {
-        if(m == 0) return sgn / 0.0; /* +INF / -INF */
-        else return 0.0 / 0.0; /* NAN */
+        if(m == 0) return sgn / 0.0f; /* +INF / -INF */
+        else return 0.0f / 0.0f; /* NAN */
+    }
+}
+
+static inline float float_24_to_32(DWORD in)
+{
+    const float sgn = in & 0x800000 ? -1.0f : 1.0f;
+    const unsigned short e = (in & 0x780000) >> 19;
+    const unsigned short m = in & 0x7ffff;
+
+    if (e == 0)
+    {
+        if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
+        else return sgn * pow(2, -6.0f) * ((float)m / 524288.0f);
+    }
+    else if (e < 15)
+    {
+        return sgn * pow(2, (float)e - 7.0f) * (1.0f + ((float)m / 524288.0f));
+    }
+    else
+    {
+        if (m == 0) return sgn / 0.0f; /* +INF / -INF */
+        else return 0.0f / 0.0f; /* NAN */
     }
 }
 
 /**
     }
 }
 
 /**
- * Settings 
+ * Settings
  */
 #define VS_NONE    0
 #define VS_HW      1
  */
 #define VS_NONE    0
 #define VS_HW      1
@@ -259,11 +268,8 @@ static inline float float_16_to_32(const unsigned short *in) {
 #define SHADER_NONE 4
 
 #define RTL_DISABLE   -1
 #define SHADER_NONE 4
 
 #define RTL_DISABLE   -1
-#define RTL_AUTO       0
 #define RTL_READDRAW   1
 #define RTL_READTEX    2
 #define RTL_READDRAW   1
 #define RTL_READTEX    2
-#define RTL_TEXDRAW    3
-#define RTL_TEXTEX     4
 
 #define PCI_VENDOR_NONE 0xffff /* e.g. 0x8086 for Intel and 0x10de for Nvidia */
 #define PCI_DEVICE_NONE 0xffff /* e.g. 0x14f for a Geforce6200 */
 
 #define PCI_VENDOR_NONE 0xffff /* e.g. 0x8086 for Intel and 0x10de for Nvidia */
 #define PCI_DEVICE_NONE 0xffff /* e.g. 0x14f for a Geforce6200 */
@@ -274,7 +280,6 @@ typedef struct wined3d_settings_s {
 /* vertex and pixel shader modes */
   int vs_mode;
   int ps_mode;
 /* vertex and pixel shader modes */
   int vs_mode;
   int ps_mode;
-  int vbo_mode;
 /* Ideally, we don't want the user to have to request GLSL.  If the hardware supports GLSL,
     we should use it.  However, until it's fully implemented, we'll leave it as a registry
     setting for developers. */
 /* Ideally, we don't want the user to have to request GLSL.  If the hardware supports GLSL,
     we should use it.  However, until it's fully implemented, we'll leave it as a registry
     setting for developers. */
@@ -325,6 +330,7 @@ typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE
     WINED3DSPR_LABEL = 18,
     WINED3DSPR_PREDICATE = 19,
     WINED3DSPR_IMMCONST,
     WINED3DSPR_LABEL = 18,
     WINED3DSPR_PREDICATE = 19,
     WINED3DSPR_IMMCONST,
+    WINED3DSPR_CONSTBUFFER,
 } WINED3DSHADER_PARAM_REGISTER_TYPE;
 
 enum wined3d_immconst_type
 } WINED3DSHADER_PARAM_REGISTER_TYPE;
 
 enum wined3d_immconst_type
@@ -506,12 +512,14 @@ typedef enum COMPARISON_TYPE
 #define MAX_LABELS 16
 
 #define SHADER_PGMSIZE 65535
 #define MAX_LABELS 16
 
 #define SHADER_PGMSIZE 65535
-typedef struct SHADER_BUFFER {
-    char* buffer;
+
+struct wined3d_shader_buffer
+{
+    char *buffer;
     unsigned int bsize;
     unsigned int lineNo;
     BOOL newline;
     unsigned int bsize;
     unsigned int lineNo;
     BOOL newline;
-} SHADER_BUFFER;
+};
 
 enum WINED3D_SHADER_INSTRUCTION_HANDLER
 {
 
 enum WINED3D_SHADER_INSTRUCTION_HANDLER
 {
@@ -620,28 +628,40 @@ struct wined3d_shader_version
 typedef struct shader_reg_maps
 {
     struct wined3d_shader_version shader_version;
 typedef struct shader_reg_maps
 {
     struct wined3d_shader_version shader_version;
-    char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
-    char temporary[MAX_REG_TEMP];           /* pixel, vertex */
-    char address[MAX_REG_ADDR];             /* vertex */
-    char packed_input[MAX_REG_INPUT];       /* pshader >= 3.0 */
-    char packed_output[MAX_REG_OUTPUT];     /* vertex >= 3.0 */
-    char attributes[MAX_ATTRIBS];           /* vertex */
-    char labels[MAX_LABELS];                /* pixel, vertex */
+    BYTE texcoord;                          /* MAX_REG_TEXCRD, 8 */
+    BYTE address;                           /* MAX_REG_ADDR, 1 */
+    WORD labels;                            /* MAX_LABELS, 16 */
+    DWORD temporary;                        /* MAX_REG_TEMP, 32 */
     DWORD *constf;                          /* pixel, vertex */
     DWORD texcoord_mask[MAX_REG_TEXCRD];    /* vertex < 3.0 */
     DWORD *constf;                          /* pixel, vertex */
     DWORD texcoord_mask[MAX_REG_TEXCRD];    /* vertex < 3.0 */
+    WORD input_registers;                   /* max(MAX_REG_INPUT, MAX_ATTRIBS), 16 */
+    WORD output_registers;                  /* MAX_REG_OUTPUT, 12 */
     WORD integer_constants;                 /* MAX_CONST_I, 16 */
     WORD boolean_constants;                 /* MAX_CONST_B, 16 */
     WORD integer_constants;                 /* MAX_CONST_I, 16 */
     WORD boolean_constants;                 /* MAX_CONST_B, 16 */
+    WORD local_int_consts;                  /* MAX_CONST_I, 16 */
+    WORD local_bool_consts;                 /* MAX_CONST_B, 16 */
 
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
 
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
-    BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
-    char usesnrm, vpos, usesdsy, usestexldd;
-    char usesrelconstF;
+    BYTE bumpmat;                           /* MAX_TEXTURES, 8 */
+    BYTE luminanceparams;                   /* MAX_TEXTURES, 8 */
+
+    WORD usesnrm        : 1;
+    WORD vpos           : 1;
+    WORD usesdsx        : 1;
+    WORD usesdsy        : 1;
+    WORD usestexldd     : 1;
+    WORD usesmova       : 1;
+    WORD usesfacing     : 1;
+    WORD usesrelconstF  : 1;
+    WORD fog            : 1;
+    WORD usestexldl     : 1;
+    WORD usesifc        : 1;
+    WORD usescall       : 1;
+    WORD padding        : 4;
 
     /* Whether or not loops are used in this shader, and nesting depth */
     unsigned loop_depth;
 
     /* Whether or not loops are used in this shader, and nesting depth */
     unsigned loop_depth;
-
-    /* Whether or not this shader uses fog */
-    char fog;
+    unsigned highest_render_target;
 
 } shader_reg_maps;
 
 
 } shader_reg_maps;
 
@@ -649,13 +669,15 @@ struct wined3d_shader_context
 {
     IWineD3DBaseShader *shader;
     const struct shader_reg_maps *reg_maps;
 {
     IWineD3DBaseShader *shader;
     const struct shader_reg_maps *reg_maps;
-    SHADER_BUFFER *buffer;
+    struct wined3d_shader_buffer *buffer;
+    void *backend_data;
 };
 
 struct wined3d_shader_register
 {
     WINED3DSHADER_PARAM_REGISTER_TYPE type;
     UINT idx;
 };
 
 struct wined3d_shader_register
 {
     WINED3DSHADER_PARAM_REGISTER_TYPE type;
     UINT idx;
+    UINT array_idx;
     const struct wined3d_shader_src_param *rel_addr;
     enum wined3d_immconst_type immconst_type;
     DWORD immconst_data[4];
     const struct wined3d_shader_src_param *rel_addr;
     enum wined3d_immconst_type immconst_type;
     DWORD immconst_data[4];
@@ -697,6 +719,19 @@ struct wined3d_shader_semantic
     struct wined3d_shader_dst_param reg;
 };
 
     struct wined3d_shader_dst_param reg;
 };
 
+struct wined3d_shader_attribute
+{
+    WINED3DDECLUSAGE usage;
+    UINT usage_idx;
+};
+
+struct wined3d_shader_loop_control
+{
+    unsigned int count;
+    unsigned int start;
+    int step;
+};
+
 struct wined3d_shader_frontend
 {
     void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
 struct wined3d_shader_frontend
 {
     void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
@@ -732,6 +767,8 @@ struct shader_caps {
     DWORD               MaxPShaderInstructionsExecuted;
     DWORD               MaxVertexShader30InstructionSlots;
     DWORD               MaxPixelShader30InstructionSlots;
     DWORD               MaxPShaderInstructionsExecuted;
     DWORD               MaxVertexShader30InstructionSlots;
     DWORD               MaxPixelShader30InstructionSlots;
+
+    BOOL                VSClipping;
 };
 
 enum tex_types
 };
 
 enum tex_types
@@ -752,11 +789,6 @@ enum vertexprocessing_mode {
 
 #define WINED3D_CONST_NUM_UNUSED ~0U
 
 
 #define WINED3D_CONST_NUM_UNUSED ~0U
 
-struct stb_const_desc {
-    unsigned char           texunit;
-    UINT                    const_num;
-};
-
 enum fogmode {
     FOG_OFF,
     FOG_LINEAR,
 enum fogmode {
     FOG_OFF,
     FOG_LINEAR,
@@ -790,24 +822,22 @@ struct vs_compile_args {
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
 };
 
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
 };
 
+struct wined3d_context;
+
 typedef struct {
 typedef struct {
-    const SHADER_HANDLER *shader_instruction_handler_table;
-    void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
+    void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
+    void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
     void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
     void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
-    void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
+    void (*shader_load_constants)(const struct wined3d_context *context, char usePS, char useVS);
     void (*shader_load_np2fixup_constants)(IWineD3DDevice *iface, char usePS, char useVS);
     void (*shader_destroy)(IWineD3DBaseShader *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
     void (*shader_load_np2fixup_constants)(IWineD3DDevice *iface, char usePS, char useVS);
     void (*shader_destroy)(IWineD3DBaseShader *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
-    GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface,
-            SHADER_BUFFER *buffer, const struct ps_compile_args *args);
-    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);
+    void (*shader_get_caps)(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
     void (*shader_add_instruction_modifiers)(const struct wined3d_shader_instruction *ins);
 } shader_backend_t;
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
     void (*shader_add_instruction_modifiers)(const struct wined3d_shader_instruction *ins);
 } shader_backend_t;
@@ -870,17 +900,19 @@ extern int num_lock;
 /* Checking of API calls */
 /* --------------------- */
 #ifndef WINE_NO_DEBUG_MSGS
 /* Checking of API calls */
 /* --------------------- */
 #ifndef WINE_NO_DEBUG_MSGS
-#define checkGLcall(A)                                          \
-do {                                                            \
-    GLint err = glGetError();                                   \
-    if (err == GL_NO_ERROR) {                                   \
-       TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__);    \
-                                                                \
-    } else do {                                                 \
-        FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
-            debug_glerror(err), err, A, __FILE__, __LINE__);    \
-       err = glGetError();                                      \
-    } while (err != GL_NO_ERROR);                               \
+#define checkGLcall(A)                                              \
+do {                                                                \
+    GLint err;                                                      \
+    if(!__WINE_IS_DEBUG_ON(_FIXME, __wine_dbch___default)) break;   \
+    err = glGetError();                                             \
+    if (err == GL_NO_ERROR) {                                       \
+       TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__);        \
+                                                                    \
+    } else do {                                                     \
+        FIXME(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n",     \
+            debug_glerror(err), err, A, __FILE__, __LINE__);        \
+       err = glGetError();                                          \
+    } while (err != GL_NO_ERROR);                                   \
 } while(0)
 #else
 #define checkGLcall(A) do {} while(0)
 } while(0)
 #else
 #define checkGLcall(A) do {} while(0)
@@ -910,10 +942,11 @@ do {                                          \
 } while(0)
 
 /* Trace vector and strided data information */
 } while(0)
 
 /* Trace vector and strided data information */
-#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
-#define TRACE_STRIDED(si, name) TRACE( #name "=(data:%p, stride:%d, format:%#x, vbo %d, stream %u)\n", \
+#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
+#define TRACE_STRIDED(si, name) do { if (si->use_map & (1 << name)) \
+        TRACE( #name "=(data:%p, stride:%d, format:%#x, vbo %d, stream %u)\n", \
         si->elements[name].data, si->elements[name].stride, si->elements[name].format_desc->format, \
         si->elements[name].data, si->elements[name].stride, si->elements[name].format_desc->format, \
-        si->elements[name].buffer_object, si->elements[name].stream_idx);
+        si->elements[name].buffer_object, si->elements[name].stream_idx); } while(0)
 
 /* Defines used for optimizations */
 
 
 /* Defines used for optimizations */
 
@@ -937,8 +970,8 @@ extern const float identity[16];
 /* Trace information per-vertex: (extremely high amount of trace) */
 #if 0 /* NOTE: Must be 0 in cvs */
 # define VTRACE(A) TRACE A
 /* Trace information per-vertex: (extremely high amount of trace) */
 #if 0 /* NOTE: Must be 0 in cvs */
 # define VTRACE(A) TRACE A
-#else 
-# define VTRACE(A) 
+#else
+# define VTRACE(A)
 #endif
 
 /* TODO: Confirm each of these works when wined3d move completed */
 #endif
 
 /* TODO: Confirm each of these works when wined3d move completed */
@@ -951,21 +984,21 @@ extern const float identity[16];
       the file is deleted                                                                            */
 # if 1 /* NOTE: Must be 1 in cvs, as this is mostly more useful than a trace from program start */
 #  define SINGLE_FRAME_DEBUGGING
       the file is deleted                                                                            */
 # if 1 /* NOTE: Must be 1 in cvs, as this is mostly more useful than a trace from program start */
 #  define SINGLE_FRAME_DEBUGGING
-# endif  
+# endif
   /* The following, when enabled, lets you see the makeup of the frame, by drawprimitive calls.
   /* The following, when enabled, lets you see the makeup of the frame, by drawprimitive calls.
-     It can only be enabled when FRAME_DEBUGGING is also enabled                               
-     The contents of the back buffer are written into /tmp/backbuffer_* after each primitive 
+     It can only be enabled when FRAME_DEBUGGING is also enabled
+     The contents of the back buffer are written into /tmp/backbuffer_* after each primitive
      array is drawn.                                                                            */
      array is drawn.                                                                            */
-# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */                                                                                       
+# if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */
 #  define SHOW_FRAME_MAKEUP 1
 #  define SHOW_FRAME_MAKEUP 1
-# endif  
+# endif
   /* The following, when enabled, lets you see the makeup of the all the textures used during each
      of the drawprimitive calls. It can only be enabled when SHOW_FRAME_MAKEUP is also enabled.
   /* The following, when enabled, lets you see the makeup of the all the textures used during each
      of the drawprimitive calls. It can only be enabled when SHOW_FRAME_MAKEUP is also enabled.
-     The contents of the textures assigned to each stage are written into 
+     The contents of the textures assigned to each stage are written into
      /tmp/texture_*_<Stage>.ppm after each primitive array is drawn.                            */
 # if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */
 #  define SHOW_TEXTURE_MAKEUP 0
      /tmp/texture_*_<Stage>.ppm after each primitive array is drawn.                            */
 # if 0 /* NOTE: Must be 0 in cvs, as this give a lot of ppm files when compiled in */
 #  define SHOW_TEXTURE_MAKEUP 0
-# endif  
+# endif
 extern BOOL isOn;
 extern BOOL isDumpingFrames;
 extern LONG primCounter;
 extern BOOL isOn;
 extern BOOL isDumpingFrames;
 extern LONG primCounter;
@@ -1053,8 +1086,6 @@ extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
     (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
 
 /* Routines and structures related to state management */
     (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
 
 /* Routines and structures related to state management */
-typedef struct WineD3DContext WineD3DContext;
-typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *ctx);
 
 #define STATE_RENDER(a) (a)
 #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
 
 #define STATE_RENDER(a) (a)
 #define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
@@ -1106,71 +1137,31 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock,
 
 #define STATE_HIGHEST (STATE_FRONTFACE)
 
 
 #define STATE_HIGHEST (STATE_FRONTFACE)
 
-struct StateEntry
-{
-    DWORD               representative;
-    APPLYSTATEFUNC      apply;
-};
-
-struct StateEntryTemplate
-{
-    DWORD               state;
-    struct StateEntry   content;
-    GL_SupportedExt     extension;
-};
-
-struct fragment_caps {
-    DWORD               PrimitiveMiscCaps;
-
-    DWORD               TextureOpCaps;
-    DWORD               MaxTextureBlendStages;
-    DWORD               MaxSimultaneousTextures;
-};
-
-struct fragment_pipeline {
-    void (*enable_extension)(IWineD3DDevice *iface, BOOL enable);
-    void (*get_caps)(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps);
-    HRESULT (*alloc_private)(IWineD3DDevice *iface);
-    void (*free_private)(IWineD3DDevice *iface);
-    BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
-    const struct StateEntryTemplate *states;
-    BOOL ffp_proj_control;
+enum fogsource {
+    FOGSOURCE_FFP,
+    FOGSOURCE_VS,
+    FOGSOURCE_COORD,
 };
 
 };
 
-extern const struct StateEntryTemplate misc_state_template[];
-extern const struct StateEntryTemplate ffp_vertexstate_template[];
-extern const struct fragment_pipeline ffp_fragment_pipeline;
-extern const struct fragment_pipeline atifs_fragment_pipeline;
-extern const struct fragment_pipeline arbfp_fragment_pipeline;
-extern const struct fragment_pipeline nvts_fragment_pipeline;
-extern const struct fragment_pipeline nvrc_fragment_pipeline;
-
-/* "Base" state table */
-HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
-        const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
-        const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
+#define WINED3D_MAX_FBO_ENTRIES 64
 
 
-/* Shaders for color conversions in blits */
-struct blit_shader {
-    HRESULT (*alloc_private)(IWineD3DDevice *iface);
-    void (*free_private)(IWineD3DDevice *iface);
-    HRESULT (*set_shader)(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
-            GLenum textype, UINT width, UINT height);
-    void (*unset_shader)(IWineD3DDevice *iface);
-    BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
+struct wined3d_occlusion_query
+{
+    struct list entry;
+    GLuint id;
+    struct wined3d_context *context;
 };
 
 };
 
-extern const struct blit_shader ffp_blit;
-extern const struct blit_shader arbfp_blit;
-
-enum fogsource {
-    FOGSOURCE_FFP,
-    FOGSOURCE_VS,
-    FOGSOURCE_COORD,
+struct wined3d_event_query
+{
+    struct list entry;
+    GLuint id;
+    struct wined3d_context *context;
 };
 
 };
 
-/* The new context manager that should deal with onscreen and offscreen rendering */
-struct WineD3DContext {
+struct wined3d_context
+{
+    const struct wined3d_gl_info *gl_info;
     /* State dirtification
      * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
      * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
     /* State dirtification
      * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
      * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
@@ -1182,9 +1173,11 @@ struct WineD3DContext {
     DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
 
     IWineD3DSurface         *surface;
     DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
 
     IWineD3DSurface         *surface;
+    IWineD3DSurface *current_rt;
     DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some information about the context state for optimization */
     DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some information about the context state for optimization */
+    WORD render_offscreen : 1;
     WORD draw_buffer_dirty : 1;
     WORD last_was_rhw : 1;              /* true iff last draw_primitive was in xyzrhw mode */
     WORD last_was_pshader : 1;
     WORD draw_buffer_dirty : 1;
     WORD last_was_rhw : 1;              /* true iff last draw_primitive was in xyzrhw mode */
     WORD last_was_pshader : 1;
@@ -1197,7 +1190,8 @@ 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 : 3;
+    WORD current : 1;
+    WORD destroyed : 1;
     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;
@@ -1216,17 +1210,93 @@ struct WineD3DContext {
     GLint                   aux_buffers;
 
     /* FBOs */
     GLint                   aux_buffers;
 
     /* FBOs */
+    UINT                    fbo_entry_count;
     struct list             fbo_list;
     struct fbo_entry        *current_fbo;
     GLuint                  src_fbo;
     GLuint                  dst_fbo;
     struct list             fbo_list;
     struct fbo_entry        *current_fbo;
     GLuint                  src_fbo;
     GLuint                  dst_fbo;
+    GLuint                  fbo_read_binding;
+    GLuint                  fbo_draw_binding;
+
+    /* Queries */
+    GLuint *free_occlusion_queries;
+    UINT free_occlusion_query_size;
+    UINT free_occlusion_query_count;
+    struct list occlusion_queries;
+
+    GLuint *free_event_queries;
+    UINT free_event_query_size;
+    UINT free_event_query_count;
+    struct list event_queries;
 
     /* Extension emulation */
     GLint                   gl_fog_source;
     GLfloat                 fog_coord_value;
     GLfloat                 color[4], fogstart, fogend, fogcolor[4];
 
     /* Extension emulation */
     GLint                   gl_fog_source;
     GLfloat                 fog_coord_value;
     GLfloat                 color[4], fogstart, fogend, fogcolor[4];
+    GLuint                  dummy_arbfp_prog;
+};
+
+typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *ctx);
+
+struct StateEntry
+{
+    DWORD representative;
+    APPLYSTATEFUNC apply;
+};
+
+struct StateEntryTemplate
+{
+    DWORD state;
+    struct StateEntry content;
+    GL_SupportedExt extension;
+};
+
+struct fragment_caps
+{
+    DWORD PrimitiveMiscCaps;
+    DWORD TextureOpCaps;
+    DWORD MaxTextureBlendStages;
+    DWORD MaxSimultaneousTextures;
+};
+
+struct fragment_pipeline
+{
+    void (*enable_extension)(IWineD3DDevice *iface, BOOL enable);
+    void (*get_caps)(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps);
+    HRESULT (*alloc_private)(IWineD3DDevice *iface);
+    void (*free_private)(IWineD3DDevice *iface);
+    BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
+    const struct StateEntryTemplate *states;
+    BOOL ffp_proj_control;
+};
+
+extern const struct StateEntryTemplate misc_state_template[];
+extern const struct StateEntryTemplate ffp_vertexstate_template[];
+extern const struct fragment_pipeline ffp_fragment_pipeline;
+extern const struct fragment_pipeline atifs_fragment_pipeline;
+extern const struct fragment_pipeline arbfp_fragment_pipeline;
+extern const struct fragment_pipeline nvts_fragment_pipeline;
+extern const struct fragment_pipeline nvrc_fragment_pipeline;
+
+/* "Base" state table */
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+        const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
+        const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
+
+/* Shaders for color conversions in blits */
+struct blit_shader
+{
+    HRESULT (*alloc_private)(IWineD3DDevice *iface);
+    void (*free_private)(IWineD3DDevice *iface);
+    HRESULT (*set_shader)(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
+            GLenum textype, UINT width, UINT height);
+    void (*unset_shader)(IWineD3DDevice *iface);
+    BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
 };
 
 };
 
+extern const struct blit_shader ffp_blit;
+extern const struct blit_shader arbfp_blit;
+
 typedef enum ContextUsage {
     CTXUSAGE_RESOURCELOAD       = 1,    /* Only loads textures: No State is applied */
     CTXUSAGE_DRAWPRIM           = 2,    /* OpenGL states are set up for blitting DirectDraw surfaces */
 typedef enum ContextUsage {
     CTXUSAGE_RESOURCELOAD       = 1,    /* Only loads textures: No State is applied */
     CTXUSAGE_DRAWPRIM           = 2,    /* OpenGL states are set up for blitting DirectDraw surfaces */
@@ -1234,14 +1304,24 @@ typedef enum ContextUsage {
     CTXUSAGE_CLEAR              = 4,    /* Drawable and states are set up for clearing */
 } ContextUsage;
 
     CTXUSAGE_CLEAR              = 4,    /* Drawable and states are set up for clearing */
 } ContextUsage;
 
-void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
-WineD3DContext *getActiveContext(void);
-WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
-void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
+struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage);
+struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win,
+        BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
+void DestroyContext(IWineD3DDeviceImpl *This, struct wined3d_context *context);
+void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query);
+void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
-void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
-void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
-void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
+void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo);
+void context_attach_depth_stencil_fbo(struct wined3d_context *context,
+        GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
+void context_attach_surface_fbo(const struct wined3d_context *context,
+        GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
+void context_free_event_query(struct wined3d_event_query *query);
+void context_free_occlusion_query(struct wined3d_occlusion_query *query);
+struct wined3d_context *context_get_current(void);
+DWORD context_get_tls_idx(void);
+BOOL context_set_current(struct wined3d_context *ctx);
+void context_set_tls_idx(DWORD idx);
 
 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
 HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
 
 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
 HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
@@ -1300,7 +1380,7 @@ struct WineD3DAdapter
     UINT                    num;
     BOOL                    opengl;
     POINT                   monitorPoint;
     UINT                    num;
     BOOL                    opengl;
     POINT                   monitorPoint;
-    WineD3D_GL_Info         gl_info;
+    struct wined3d_gl_info  gl_info;
     const char              *driver;
     const char              *description;
     WCHAR                   DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
     const char              *driver;
     const char              *description;
     WCHAR                   DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
@@ -1311,10 +1391,10 @@ struct WineD3DAdapter
     unsigned int            UsedTextureRam;
 };
 
     unsigned int            UsedTextureRam;
 };
 
-extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
-BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info);
+extern BOOL initPixelFormats(struct wined3d_gl_info *gl_info);
+BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info);
 extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
 extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram);
-extern void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info);
+extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info);
 
 /*****************************************************************************
  * High order patch management
 
 /*****************************************************************************
  * High order patch management
@@ -1371,21 +1451,23 @@ struct texture_stage_op
 struct ffp_frag_settings {
     struct texture_stage_op     op[MAX_TEXTURES];
     enum fogmode fog;
 struct ffp_frag_settings {
     struct texture_stage_op     op[MAX_TEXTURES];
     enum fogmode fog;
-    /* Use an int instead of a char to get dword alignment */
-    unsigned int sRGB_write;
+    /* Use shorts instead of chars to get dword alignment */
+    unsigned short sRGB_write;
+    unsigned short emul_clipplanes;
 };
 
 struct ffp_frag_desc
 {
 };
 
 struct ffp_frag_desc
 {
+    struct wine_rb_entry entry;
     struct ffp_frag_settings    settings;
 };
 
     struct ffp_frag_settings    settings;
 };
 
+extern const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions;
+
 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype);
 void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_settings *settings, BOOL ignore_textype);
-const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
         const struct ffp_frag_settings *settings);
         const struct ffp_frag_settings *settings);
-void add_ffp_frag_shader(struct hash_table_t *shaders, struct ffp_frag_desc *desc);
-BOOL ffp_frag_program_key_compare(const void *keya, const void *keyb);
-unsigned int ffp_frag_program_key_hash(const void *key);
+void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc);
 
 /*****************************************************************************
  * IWineD3D implementation structure
 
 /*****************************************************************************
  * IWineD3D implementation structure
@@ -1408,12 +1490,6 @@ extern const IWineD3DVtbl IWineD3D_Vtbl;
 
 BOOL InitAdapters(IWineD3DImpl *This);
 
 
 BOOL InitAdapters(IWineD3DImpl *This);
 
-/* TODO: setup some flags in the registry to enable, disable pbuffer support
-(since it will break quite a few things until contexts are managed properly!) */
-extern BOOL pbuffer_support;
-/* allocate one pbuffer per surface */
-extern BOOL pbuffer_per_surface;
-
 /* A helper function that dumps a resource list */
 void dumpResources(struct list *list);
 
 /* A helper function that dumps a resource list */
 void dumpResources(struct list *list);
 
@@ -1460,13 +1536,13 @@ struct IWineD3DDeviceImpl
 
     unsigned int max_ffp_textures, max_ffp_texture_stages;
     DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
 
     unsigned int max_ffp_textures, max_ffp_texture_stages;
     DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
+    DWORD vs_clipping;
 
     WORD view_ident : 1;                /* true iff view matrix is identity */
     WORD untransformed : 1;
     WORD vertexBlendUsed : 1;           /* To avoid needless setting of the blend matrices */
     WORD isRecordingState : 1;
     WORD isInDraw : 1;
 
     WORD view_ident : 1;                /* true iff view matrix is identity */
     WORD untransformed : 1;
     WORD vertexBlendUsed : 1;           /* To avoid needless setting of the blend matrices */
     WORD isRecordingState : 1;
     WORD isInDraw : 1;
-    WORD render_offscreen : 1;
     WORD bCursorVisible : 1;
     WORD haveHardwareCursor : 1;
     WORD d3d_initialized : 1;
     WORD bCursorVisible : 1;
     WORD haveHardwareCursor : 1;
     WORD d3d_initialized : 1;
@@ -1474,7 +1550,7 @@ struct IWineD3DDeviceImpl
     WORD softwareVertexProcessing : 1;  /* process vertex shaders using software or hardware */
     WORD useDrawStridedSlow : 1;
     WORD instancedDraw : 1;
     WORD softwareVertexProcessing : 1;  /* process vertex shaders using software or hardware */
     WORD useDrawStridedSlow : 1;
     WORD instancedDraw : 1;
-    WORD padding : 3;
+    WORD padding : 4;
 
     BYTE fixed_function_usage_map;      /* MAX_TEXTURES, 8 */
 
 
     BYTE fixed_function_usage_map;      /* MAX_TEXTURES, 8 */
 
@@ -1503,10 +1579,6 @@ struct IWineD3DDeviceImpl
     IWineD3DSurface        *auto_depth_stencil_buffer;
     IWineD3DSurface        *stencilBufferTarget;
 
     IWineD3DSurface        *auto_depth_stencil_buffer;
     IWineD3DSurface        *stencilBufferTarget;
 
-    /* Caches to avoid unneeded context changes */
-    IWineD3DSurface        *lastActiveRenderTarget;
-    IWineD3DSwapChain      *lastActiveSwapChain;
-
     /* palettes texture management */
     UINT                    NumberOfPalettes;
     PALETTEENTRY            **palettes;
     /* palettes texture management */
     UINT                    NumberOfPalettes;
     PALETTEENTRY            **palettes;
@@ -1554,11 +1626,9 @@ struct IWineD3DDeviceImpl
     const WineDirect3DVertexStridedData *up_strided;
 
     /* Context management */
     const WineDirect3DVertexStridedData *up_strided;
 
     /* Context management */
-    WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
-    WineD3DContext          *activeContext;
-    DWORD                   lastThread;
+    struct wined3d_context **contexts;
     UINT                    numContexts;
     UINT                    numContexts;
-    WineD3DContext          *pbufferContext;             /* The context that has a pbuffer as drawable */
+    struct wined3d_context *pbufferContext;              /* The context that has a pbuffer as drawable */
     DWORD                   pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
 
     /* High level patch management */
     DWORD                   pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
 
     /* High level patch management */
@@ -1570,6 +1640,8 @@ struct IWineD3DDeviceImpl
 
 extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
 
 
 extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
 
+void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource);
+void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource);
 void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
         BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup);
 void device_stream_info_from_strided(IWineD3DDeviceImpl *This,
 void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
         BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup);
 void device_stream_info_from_strided(IWineD3DDeviceImpl *This,
@@ -1579,7 +1651,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
                                         float Z, DWORD Stencil);
 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This);
 void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
                                         float Z, DWORD Stencil);
 void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This);
 void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state);
-static inline BOOL isStateDirty(WineD3DContext *context, DWORD state) {
+static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state)
+{
     DWORD idx = state >> 5;
     BYTE shift = state & 0x1f;
     return context->isStateDirty[idx] & (1 << shift);
     DWORD idx = state >> 5;
     BYTE shift = state & 0x1f;
     return context->isStateDirty[idx] & (1 << shift);
@@ -1640,7 +1713,7 @@ HRESULT resource_get_parent(IWineD3DResource *iface, IUnknown **parent);
 DWORD resource_get_priority(IWineD3DResource *iface);
 HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid,
         void *data, DWORD *data_size);
 DWORD resource_get_priority(IWineD3DResource *iface);
 HRESULT resource_get_private_data(IWineD3DResource *iface, REFGUID guid,
         void *data, DWORD *data_size);
-HRESULT resource_init(struct IWineD3DResourceClass *resource, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
         WINED3DPOOL pool, IUnknown *parent);
 WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface);
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
         WINED3DPOOL pool, IUnknown *parent);
 WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface);
@@ -1654,8 +1727,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
 /*****************************************************************************
  * IWineD3DBaseTexture D3D- > openGL state map lookups
  */
 /*****************************************************************************
  * IWineD3DBaseTexture D3D- > openGL state map lookups
  */
-#define WINED3DFUNC_NOTSUPPORTED  -2
-#define WINED3DFUNC_UNIMPLEMENTED -1
 
 typedef enum winetexturestates {
     WINED3DTEXSTA_ADDRESSU       = 0,
 
 typedef enum winetexturestates {
     WINED3DTEXSTA_ADDRESSU       = 0,
@@ -1704,9 +1775,6 @@ typedef struct IWineD3DBaseTextureClass
     void                    (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
 } IWineD3DBaseTextureClass;
 
     void                    (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
 } IWineD3DBaseTextureClass;
 
-void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
-void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
-void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
 void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb);
 
 typedef struct IWineD3DBaseTextureImpl
 void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb);
 
 typedef struct IWineD3DBaseTextureImpl
@@ -1728,15 +1796,13 @@ WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture
 BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface);
 BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface);
 DWORD basetexture_get_lod(IWineD3DBaseTexture *iface);
-void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage);
+HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type,
+        IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
+        WINED3DPOOL pool, IUnknown *parent);
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type);
 BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
 void basetexture_unload(IWineD3DBaseTexture *iface);
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type);
 BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
 void basetexture_unload(IWineD3DBaseTexture *iface);
-static inline void basetexture_setsrgbcache(IWineD3DBaseTexture *iface, BOOL srgb) {
-    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
-    This->baseTexture.is_srgb = srgb;
-}
 
 /*****************************************************************************
  * IWineD3DTexture implementation structure (extends IWineD3DBaseTextureImpl)
 
 /*****************************************************************************
  * IWineD3DTexture implementation structure (extends IWineD3DBaseTextureImpl)
@@ -1757,6 +1823,9 @@ typedef struct IWineD3DTextureImpl
 
 extern const IWineD3DTextureVtbl IWineD3DTexture_Vtbl;
 
 
 extern const IWineD3DTextureVtbl IWineD3DTexture_Vtbl;
 
+HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent);
+
 /*****************************************************************************
  * IWineD3DCubeTexture implementation structure (extends IWineD3DBaseTextureImpl)
  */
 /*****************************************************************************
  * IWineD3DCubeTexture implementation structure (extends IWineD3DBaseTextureImpl)
  */
@@ -1773,6 +1842,9 @@ typedef struct IWineD3DCubeTextureImpl
 
 extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
 
 
 extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
 
+HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent);
+
 typedef struct _WINED3DVOLUMET_DESC
 {
     UINT                    Width;
 typedef struct _WINED3DVOLUMET_DESC
 {
     UINT                    Width;
@@ -1819,6 +1891,9 @@ typedef struct IWineD3DVolumeTextureImpl
 
 extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
 
 
 extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
 
+HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height, UINT depth, UINT levels,
+        IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent);
+
 typedef struct _WINED3DSURFACET_DESC
 {
     WINED3DMULTISAMPLE_TYPE MultiSampleType;
 typedef struct _WINED3DSURFACET_DESC
 {
     WINED3DMULTISAMPLE_TYPE MultiSampleType;
@@ -1889,21 +1964,23 @@ struct IWineD3DSurfaceImpl
     UINT                      pow2Height;
 
     /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
     UINT                      pow2Height;
 
     /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
-    void (*get_drawable_size)(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
+    void (*get_drawable_size)(struct wined3d_context *context, UINT *width, UINT *height);
 
     /* Oversized texture */
     RECT                      glRect;
 
     /* PBO */
     GLuint                    pbo;
 
     /* Oversized texture */
     RECT                      glRect;
 
     /* PBO */
     GLuint                    pbo;
+    GLuint texture_name;
+    GLuint texture_name_srgb;
+    GLint texture_level;
+    GLenum texture_target;
 
     RECT                      lockedRect;
     RECT                      dirtyRect;
     int                       lockCount;
 #define MAXLOCKCOUNT          50 /* After this amount of locks do not free the sysmem copy */
 
 
     RECT                      lockedRect;
     RECT                      dirtyRect;
     int                       lockCount;
 #define MAXLOCKCOUNT          50 /* After this amount of locks do not free the sysmem copy */
 
-    glDescriptor              glDescription;
-
     /* For GetDC */
     wineD3DSurface_DIB        dib;
     HDC                       hDC;
     /* For GetDC */
     wineD3DSurface_DIB        dib;
     HDC                       hDC;
@@ -1934,6 +2011,13 @@ struct IWineD3DSurfaceImpl
 extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
 extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;
 
 extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
 extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl;
 
+UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height);
+void surface_gdi_cleanup(IWineD3DSurfaceImpl *This);
+HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
+        UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
+        UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
+        WINED3DPOOL pool, IUnknown *parent);
+
 /* Predeclare the shared Surface functions */
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
 ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
 /* Predeclare the shared Surface functions */
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj);
 ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface);
@@ -1974,10 +2058,10 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL
 void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb);
 const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface);
 
 void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb);
 const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface);
 
-void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
-void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
-void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
-void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
+void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height);
+void get_drawable_size_backbuffer(struct wined3d_context *context, UINT *width, UINT *height);
+void get_drawable_size_pbuffer(struct wined3d_context *context, UINT *width, UINT *height);
+void get_drawable_size_fbo(struct wined3d_context *context, UINT *width, UINT *height);
 
 void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
 
 
 void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
 
@@ -2060,6 +2144,9 @@ typedef enum {
     CONVERT_G16R16,
     CONVERT_R16G16F,
     CONVERT_R32G32F,
     CONVERT_G16R16,
     CONVERT_R16G16F,
     CONVERT_R32G32F,
+    CONVERT_D15S1,
+    CONVERT_D24X4S4,
+    CONVERT_D24FS8,
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);
@@ -2276,7 +2363,7 @@ typedef struct IWineD3DQueryImpl
 {
     const IWineD3DQueryVtbl  *lpVtbl;
     LONG                      ref;     /* Note: Ref counting not required */
 {
     const IWineD3DQueryVtbl  *lpVtbl;
     LONG                      ref;     /* Note: Ref counting not required */
-    
+
     IUnknown                 *parent;
     /*TODO: replace with iface usage */
 #if 0
     IUnknown                 *parent;
     /*TODO: replace with iface usage */
 #if 0
@@ -2290,25 +2377,12 @@ typedef struct IWineD3DQueryImpl
     WINED3DQUERYTYPE         type;
     /* TODO: Think about using a IUnknown instead of a void* */
     void                     *extendedData;
     WINED3DQUERYTYPE         type;
     /* TODO: Think about using a IUnknown instead of a void* */
     void                     *extendedData;
-    
-  
 } IWineD3DQueryImpl;
 
 extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
 extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
 extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl;
 
 } IWineD3DQueryImpl;
 
 extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl;
 extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl;
 extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl;
 
-/* Datastructures for IWineD3DQueryImpl.extendedData */
-typedef struct  WineQueryOcclusionData {
-    GLuint  queryId;
-    WineD3DContext *ctx;
-} WineQueryOcclusionData;
-
-typedef struct  WineQueryEventData {
-    GLuint  fenceId;
-    WineD3DContext *ctx;
-} WineQueryEventData;
-
 /* IWineD3DBuffer */
 
 /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
 /* IWineD3DBuffer */
 
 /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
@@ -2357,7 +2431,7 @@ struct wined3d_buffer
 
 extern const IWineD3DBufferVtbl wined3d_buffer_vtbl;
 const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object);
 
 extern const IWineD3DBufferVtbl wined3d_buffer_vtbl;
 const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object);
-const BYTE *buffer_get_sysmem(struct wined3d_buffer *This);
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This);
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
@@ -2395,7 +2469,7 @@ typedef struct IWineD3DSwapChainImpl
     long prev_time, frames;   /* Performance tracking */
     unsigned int vSyncCounter;
 
     long prev_time, frames;   /* Performance tracking */
     unsigned int vSyncCounter;
 
-    WineD3DContext        **context; /* Later a array for multithreading */
+    struct wined3d_context **context;
     unsigned int            num_contexts;
 
     HWND                    win_handle;
     unsigned int            num_contexts;
 
     HWND                    win_handle;
@@ -2418,10 +2492,12 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain
 HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp);
 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp);
 
 HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp);
 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp);
 
-WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);
+struct wined3d_context *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);
+
+#define DEFAULT_REFRESH_RATE 0
 
 /*****************************************************************************
 
 /*****************************************************************************
- * Utility function prototypes 
+ * Utility function prototypes
  */
 
 /* Trace routines */
  */
 
 /* Trace routines */
@@ -2453,19 +2529,18 @@ GLenum CompareFunc(DWORD func);
 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
 void   set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst);
 void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype, BOOL ffp_can_disable_proj);
 BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
 void   set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst);
 void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype, BOOL ffp_can_disable_proj);
-void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
-void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
+void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
 
 void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect);
 
 void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect);
-void surface_force_reload(IWineD3DSurface *iface);
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);
-void surface_load_ds_location(IWineD3DSurface *iface, DWORD location);
+void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location);
 void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location);
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
 void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name);
 void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location);
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
 void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name);
@@ -2500,8 +2575,8 @@ typedef struct SHADER_LIMITS {
     unsigned int label;
 } SHADER_LIMITS;
 
     unsigned int label;
 } SHADER_LIMITS;
 
-/** Keeps track of details for TEX_M#x# shader opcodes which need to 
   maintain state information between multiple codes */
+/* Keeps track of details for TEX_M#x# shader opcodes which need to
* maintain state information between multiple codes */
 typedef struct SHADER_PARSE_STATE {
     unsigned int current_row;
     DWORD texcoord_w[2];
 typedef struct SHADER_PARSE_STATE {
     unsigned int current_row;
     DWORD texcoord_w[2];
@@ -2513,12 +2588,9 @@ typedef struct SHADER_PARSE_STATE {
 #define PRINTF_ATTR(fmt,args)
 #endif
 
 #define PRINTF_ATTR(fmt,args)
 #endif
 
-/* Base Shader utility functions. 
- * (may move callers into the same file in the future) */
-extern int shader_addline(
-    SHADER_BUFFER* buffer,
-    const char* fmt, ...) PRINTF_ATTR(2,3);
-int shader_vaddline(SHADER_BUFFER *buffer, const char *fmt, va_list args);
+/* Base Shader utility functions. */
+int shader_addline(struct wined3d_shader_buffer *buffer, const char *fmt, ...) PRINTF_ATTR(2,3);
+int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *fmt, va_list args);
 
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
 
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
@@ -2566,19 +2638,23 @@ typedef struct IWineD3DBaseShaderImpl {
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
-void shader_buffer_init(struct SHADER_BUFFER *buffer);
-void shader_buffer_free(struct SHADER_BUFFER *buffer);
+void shader_buffer_clear(struct wined3d_shader_buffer *buffer);
+BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer);
+void shader_buffer_free(struct wined3d_shader_buffer *buffer);
 void shader_cleanup(IWineD3DBaseShader *iface);
 void shader_dump_src_param(const struct wined3d_shader_src_param *param,
         const struct wined3d_shader_version *shader_version);
 void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
         const struct wined3d_shader_version *shader_version);
 void shader_cleanup(IWineD3DBaseShader *iface);
 void shader_dump_src_param(const struct wined3d_shader_src_param *param,
         const struct wined3d_shader_version *shader_version);
 void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
         const struct wined3d_shader_version *shader_version);
-void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
-        const shader_reg_maps *reg_maps, const DWORD *pFunction);
+unsigned int shader_find_free_input_register(const struct shader_reg_maps *reg_maps, unsigned int max);
+void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffer *buffer,
+        const shader_reg_maps *reg_maps, const DWORD *pFunction, void *backend_ctx);
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
-        struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
-        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size);
+        struct shader_reg_maps *reg_maps, struct wined3d_shader_attribute *attributes,
+        struct wined3d_shader_signature_element *input_signature,
+        struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size);
 void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
 void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
+BOOL shader_match_semantic(const char *semantic_name, WINED3DDECLUSAGE usage);
 const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
 void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction);
 
 const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
 void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction);
 
@@ -2647,14 +2723,8 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD
 /*****************************************************************************
  * IDirect3DVertexShader implementation structures
  */
 /*****************************************************************************
  * IDirect3DVertexShader implementation structures
  */
-
-struct vs_compiled_shader {
-    struct vs_compile_args      args;
-    GLuint                      prgId;
-};
-
 typedef struct IWineD3DVertexShaderImpl {
 typedef struct IWineD3DVertexShaderImpl {
-    /* IUnknown parts*/   
+    /* IUnknown parts */
     const IWineD3DVertexShaderVtbl *lpVtbl;
 
     /* IWineD3DBaseShader */
     const IWineD3DVertexShaderVtbl *lpVtbl;
 
     /* IWineD3DBaseShader */
@@ -2666,31 +2736,40 @@ typedef struct IWineD3DVertexShaderImpl {
     DWORD                       usage;
 
     /* The GL shader */
     DWORD                       usage;
 
     /* The GL shader */
-    struct vs_compiled_shader   *gl_shaders;
-    UINT                        num_gl_shaders, shader_array_size;
+    void                        *backend_priv;
 
     /* Vertex shader input and output semantics */
 
     /* Vertex shader input and output semantics */
-    struct wined3d_shader_semantic semantics_in[MAX_ATTRIBS];
-    struct wined3d_shader_semantic semantics_out[MAX_REG_OUTPUT];
+    struct wined3d_shader_attribute attributes[MAX_ATTRIBS];
+    struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
 
     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 IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
 
 void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args);
 } IWineD3DVertexShaderImpl;
 extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
 
 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
  */
-struct ps_compiled_shader {
-    struct ps_compile_args      args;
-    GLuint                      prgId;
+
+/* Using additional shader constants (uniforms in GLSL / program environment
+ * or local parameters in ARB) is costly:
+ * ARB only knows float4 parameters and GLSL compiler are not really smart
+ * when it comes to efficiently pack float2 uniforms, so no space is wasted
+ * (in fact most compilers map a float2 to a full float4 uniform).
+ *
+ * For NP2 texcoord fixup we only need 2 floats (width and height) for each
+ * 2D texture used in the shader. We therefore pack fixup info for 2 textures
+ * into a single shader constant (uniform / program parameter).
+ *
+ * This structure is shared between the GLSL and the ARB backend.*/
+struct ps_np2fixup_info {
+    unsigned char     idx[MAX_FRAGMENT_SAMPLERS]; /* indices to the real constant */
+    WORD              active; /* bitfield indicating if we can apply the fixup */
+    WORD              num_consts;
 };
 
 typedef struct IWineD3DPixelShaderImpl {
 };
 
 typedef struct IWineD3DPixelShaderImpl {
@@ -2704,34 +2783,32 @@ typedef struct IWineD3DPixelShaderImpl {
     IUnknown                   *parent;
 
     /* Pixel shader input semantics */
     IUnknown                   *parent;
 
     /* Pixel shader input semantics */
-    struct wined3d_shader_semantic semantics_in[MAX_REG_INPUT];
+    struct wined3d_shader_signature_element input_signature[MAX_REG_INPUT];
     DWORD                 input_reg_map[MAX_REG_INPUT];
     BOOL                  input_reg_used[MAX_REG_INPUT];
     DWORD                 input_reg_map[MAX_REG_INPUT];
     BOOL                  input_reg_used[MAX_REG_INPUT];
-    int                         declared_in_count;
+    unsigned int declared_in_count;
 
     /* The GL shader */
 
     /* The GL shader */
-    struct ps_compiled_shader   *gl_shaders;
-    UINT                        num_gl_shaders, shader_array_size;
+    void                        *backend_priv;
 
     /* Some information about the shader behavior */
 
     /* Some information about the shader behavior */
-    struct stb_const_desc       bumpenvmatconst[MAX_TEXTURES];
-    unsigned char               numbumpenvmatconsts;
-    struct stb_const_desc       luminanceconst[MAX_TEXTURES];
     char                        vpos_uniform;
 
     char                        vpos_uniform;
 
-    const struct ps_compile_args *cur_args;
+    BOOL                        color0_mov;
+    DWORD                       color0_reg;
+
 } IWineD3DPixelShaderImpl;
 
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
 } IWineD3DPixelShaderImpl;
 
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
-GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args);
+void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures);
 void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
 
 /* sRGB correction constants */
 void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct ps_compile_args *args);
 
 /* sRGB correction constants */
-static const float srgb_cmp = 0.0031308;
-static const float srgb_mul_low = 12.92;
-static const float srgb_pow = 0.41666;
-static const float srgb_mul_high = 1.055;
-static const float srgb_sub_high = 0.055;
+static const float srgb_cmp = 0.0031308f;
+static const float srgb_mul_low = 12.92f;
+static const float srgb_pow = 0.41666f;
+static const float srgb_mul_high = 1.055f;
+static const float srgb_sub_high = 0.055f;
 
 /*****************************************************************************
  * IWineD3DPalette implementation structure
 
 /*****************************************************************************
  * IWineD3DPalette implementation structure
@@ -2771,6 +2848,8 @@ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth);
 #define WINED3DFMT_FLAG_STENCIL                  0x8
 #define WINED3DFMT_FLAG_RENDERTARGET             0x10
 #define WINED3DFMT_FLAG_FOURCC                   0x20
 #define WINED3DFMT_FLAG_STENCIL                  0x8
 #define WINED3DFMT_FLAG_RENDERTARGET             0x10
 #define WINED3DFMT_FLAG_FOURCC                   0x20
+#define WINED3DFMT_FLAG_FBO_ATTACHABLE           0x40
+#define WINED3DFMT_FLAG_COMPRESSED               0x80
 
 struct GlPixelFormatDesc
 {
 
 struct GlPixelFormatDesc
 {
@@ -2783,6 +2862,10 @@ struct GlPixelFormatDesc
     WORD depth_size;
     WORD stencil_size;
 
     WORD depth_size;
     WORD stencil_size;
 
+    UINT block_width;
+    UINT block_height;
+    UINT block_byte_count;
+
     enum wined3d_ffp_emit_idx emit_idx;
     GLint component_count;
     GLenum gl_vtx_type;
     enum wined3d_ffp_emit_idx emit_idx;
     GLint component_count;
     GLenum gl_vtx_type;
@@ -2800,12 +2883,16 @@ struct GlPixelFormatDesc
     struct color_fixup_desc color_fixup;
 };
 
     struct color_fixup_desc color_fixup;
 };
 
-const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info);
+const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info);
 
 static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock)
 {
 
 static inline BOOL use_vs(IWineD3DStateBlockImpl *stateblock)
 {
+    /* Check stateblock->vertexDecl to allow this to be used from
+     * IWineD3DDeviceImpl_FindTexUnitMap(). This is safe because
+     * stateblock->vertexShader implies a vertex declaration instead of ddraw
+     * style strided data. */
     return (stateblock->vertexShader
     return (stateblock->vertexShader
-            && !stateblock->wineD3DDevice->strided_streams.position_transformed
+            && !((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->position_transformed
             && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE);
 }
 
             && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE);
 }
 
@@ -2817,4 +2904,8 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock)
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
+
+/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
+#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
+
 #endif
 #endif
index 3845ded..ec20433 100644 (file)
@@ -1691,16 +1691,19 @@ typedef struct _WINED3DTRIPATCH_INFO
 
 typedef struct _WINED3DADAPTER_IDENTIFIER
 {
 
 typedef struct _WINED3DADAPTER_IDENTIFIER
 {
-    char *Driver;
-    char *Description;
-    char *DeviceName;
-    LARGE_INTEGER *DriverVersion;
-    DWORD *VendorId;
-    DWORD *DeviceId;
-    DWORD *SubSysId;
-    DWORD *Revision;
-    GUID *DeviceIdentifier;
-    DWORD *WHQLLevel;
+    char *driver;
+    UINT driver_size;
+    char *description;
+    UINT description_size;
+    char *device_name;
+    UINT device_name_size;
+    LARGE_INTEGER driver_version;
+    DWORD vendor_id;
+    DWORD device_id;
+    DWORD subsystem_id;
+    DWORD revision;
+    GUID device_identifier;
+    DWORD whql_level;
 } WINED3DADAPTER_IDENTIFIER;
 
 typedef struct _WINED3DPRESENT_PARAMETERS
 } WINED3DADAPTER_IDENTIFIER;
 
 typedef struct _WINED3DPRESENT_PARAMETERS
@@ -1724,27 +1727,27 @@ typedef struct _WINED3DPRESENT_PARAMETERS
 
 typedef struct _WINED3DSURFACE_DESC
 {
 
 typedef struct _WINED3DSURFACE_DESC
 {
-    WINED3DFORMAT *Format;
-    WINED3DRESOURCETYPE *Type;
-    DWORD *Usage;
-    WINED3DPOOL *Pool;
-    UINT *Size;
-    WINED3DMULTISAMPLE_TYPE *MultiSampleType;
-    DWORD *MultiSampleQuality;
-    UINT *Width;
-    UINT *Height;
+    WINED3DFORMAT format;
+    WINED3DRESOURCETYPE resource_type;
+    DWORD usage;
+    WINED3DPOOL pool;
+    UINT size;
+    WINED3DMULTISAMPLE_TYPE multisample_type;
+    DWORD multisample_quality;
+    UINT width;
+    UINT height;
 } WINED3DSURFACE_DESC;
 
 typedef struct _WINED3DVOLUME_DESC
 {
 } WINED3DSURFACE_DESC;
 
 typedef struct _WINED3DVOLUME_DESC
 {
-    WINED3DFORMAT *Format;
-    WINED3DRESOURCETYPE *Type;
-    DWORD *Usage;
-    WINED3DPOOL *Pool;
-    UINT *Size;
-    UINT *Width;
-    UINT *Height;
-    UINT *Depth;
+    WINED3DFORMAT Format;
+    WINED3DRESOURCETYPE Type;
+    DWORD Usage;
+    WINED3DPOOL Pool;
+    UINT Size;
+    UINT Width;
+    UINT Height;
+    UINT Depth;
 } WINED3DVOLUME_DESC;
 
 typedef struct _WINED3DCLIPSTATUS
 } WINED3DVOLUME_DESC;
 
 typedef struct _WINED3DCLIPSTATUS
@@ -1883,13 +1886,6 @@ typedef struct _WINED3DBUFFER_DESC
     UINT Size;
 } WINED3DBUFFER_DESC;
 
     UINT Size;
 } WINED3DBUFFER_DESC;
 
-typedef struct glDescriptor
-{
-    UINT textureName, srgbTextureName;
-    int level;
-    int /*GLenum*/ target;
-} glDescriptor;
-
 typedef struct WineDirect3DStridedData
 {
     WINED3DFORMAT format;   /* Format of the data */
 typedef struct WineDirect3DStridedData
 {
     WINED3DFORMAT format;   /* Format of the data */
@@ -2529,9 +2525,6 @@ interface IWineD3DSurface : IWineD3DResource
     HRESULT SetContainer(
         [in] IWineD3DBase *container
     );
     HRESULT SetContainer(
         [in] IWineD3DBase *container
     );
-    void GetGlDesc(
-        [out] glDescriptor **desc
-    );
     const void *GetData(
     );
     HRESULT SetFormat(
     const void *GetData(
     );
     HRESULT SetFormat(
@@ -2616,10 +2609,6 @@ interface IWineD3DBaseTexture : IWineD3DResource
     );
     BOOL IsCondNP2(
     );
     );
     BOOL IsCondNP2(
     );
-    void ApplyStateChanges(
-        const DWORD texture_states[WINED3D_HIGHEST_TEXTURE_STATE + 1],
-        const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1]
-    );
 }
 
 [
 }
 
 [
@@ -2872,9 +2861,6 @@ interface IWineD3DVertexShader : IWineD3DBaseShader
         [out] void *data,
         [in, out] UINT *data_size
     );
         [out] void *data,
         [in, out] UINT *data_size
     );
-    void FakeSemantics(
-        [in] IWineD3DVertexDeclaration *vertex_declaration
-    );
     HRESULT SetLocalConstantsF(
         [in] UINT start_idx,
         [in] const float *src_data,
     HRESULT SetLocalConstantsF(
         [in] UINT start_idx,
         [in] const float *src_data,
@@ -2939,7 +2925,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] BOOL discard,
         [in] UINT level,
         [out] IWineD3DSurface **surface,
         [in] BOOL discard,
         [in] UINT level,
         [out] IWineD3DSurface **surface,
-        [in] WINED3DRESOURCETYPE resource_type,
         [in] DWORD usage,
         [in] WINED3DPOOL pool,
         [in] WINED3DMULTISAMPLE_TYPE multisample_type,
         [in] DWORD usage,
         [in] WINED3DPOOL pool,
         [in] WINED3DMULTISAMPLE_TYPE multisample_type,
@@ -3015,8 +3000,8 @@ interface IWineD3DDevice : IWineD3DBase
         [in] DWORD fvf
     );
     HRESULT CreateVertexShader(
         [in] DWORD fvf
     );
     HRESULT CreateVertexShader(
-        [in] IWineD3DVertexDeclaration *declaration,
         [in] const DWORD *function,
         [in] const DWORD *function,
+        [in] const struct wined3d_shader_signature *output_signature,
         [out] IWineD3DVertexShader **shader,
         [in] IUnknown *parent
     );
         [out] IWineD3DVertexShader **shader,
         [in] IUnknown *parent
     );
@@ -3475,9 +3460,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] UINT swapchain_idx,
         [in] IWineD3DSurface *dst_surface
     );
         [in] UINT swapchain_idx,
         [in] IWineD3DSurface *dst_surface
     );
-    void ResourceReleased(
-        [in] IWineD3DResource *resource
-    );
     HRESULT EnumResources(
         [in] D3DCB_ENUMRESOURCES callback,
         [in] void *data
     HRESULT EnumResources(
         [in] D3DCB_ENUMRESOURCES callback,
         [in] void *data
@@ -3486,3 +3468,5 @@ interface IWineD3DDevice : IWineD3DBase
 
 IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent);
 IWineD3DClipper *WineDirect3DCreateClipper(IUnknown *parent);
 
 IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent);
 IWineD3DClipper *WineDirect3DCreateClipper(IUnknown *parent);
+void wined3d_mutex_lock(void);
+void wined3d_mutex_unlock(void);