OK, I give up. Pigglesworth, HAALP. What do I do wrong??!
authorDaniel Reimer <reimer.daniel@freenet.de>
Sun, 30 Aug 2009 11:35:28 +0000 (11:35 +0000)
committerDaniel Reimer <reimer.daniel@freenet.de>
Sun, 30 Aug 2009 11:35:28 +0000 (11:35 +0000)
svn path=/trunk/; revision=42967

68 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/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 d0b8f72..32511d6 100644 (file)
@@ -57,11 +57,9 @@ 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);
-
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,15 +73,14 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetDevice(LPDIRECT3DCUBETEXTURE8
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -92,10 +89,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_SetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -104,10 +100,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -116,10 +111,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_FreePrivateData(LPDIRECT3DCUBETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -128,10 +122,9 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_SetPriority(LPDIRECT3DCUBETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -140,10 +133,9 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetPriority(LPDIRECT3DCUBETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret =  IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
     ret =  IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -151,9 +143,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETEXTURE8 iface) {
@@ -161,10 +153,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETE
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     type = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
     type = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return type;
 }
 
     return type;
 }
 
@@ -174,10 +165,9 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_SetLOD(LPDIRECT3DCUBETEXTURE8 ifac
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     lod = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
     lod = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return lod;
 }
 
     return lod;
 }
 
@@ -186,10 +176,9 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLOD(LPDIRECT3DCUBETEXTURE8 ifac
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
     DWORD lod;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     lod = IWineD3DCubeTexture_GetLOD((LPDIRECT3DBASETEXTURE8) This);
     lod = IWineD3DCubeTexture_GetLOD((LPDIRECT3DBASETEXTURE8) This);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return lod;
 }
 
     return lod;
 }
 
@@ -198,10 +187,9 @@ static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLevelCount(LPDIRECT3DCUBETEXTUR
     DWORD cnt;
     TRACE("(%p) Relay\n", This);
 
     DWORD cnt;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     cnt = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
     cnt = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return cnt;
 }
 
     return cnt;
 }
 
@@ -213,21 +201,22 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetLevelDesc(LPDIRECT3DCUBETEXTU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
 
     return hr;
 }
 
     return hr;
 }
@@ -239,14 +228,13 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetCubeMapSurface(LPDIRECT3DCUBE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -255,10 +243,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_LockRect(LPDIRECT3DCUBETEXTURE8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -267,10 +254,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_UnlockRect(LPDIRECT3DCUBETEXTURE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -279,10 +265,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(LPDIRECT3DCUBETEXTU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
index 3a2eac2..8e32dc3 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) {
@@ -39,8 +48,7 @@ IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) {
     IDirect3D8Impl* object;
     TRACE("SDKVersion = %x\n", SDKVersion);
 
     IDirect3D8Impl* object;
     TRACE("SDKVersion = %x\n", SDKVersion);
 
-    wined3d_mutex_lock();
-
+    EnterCriticalSection(&d3d8_cs);
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl));
 
     object->lpVtbl = &Direct3D8_Vtbl;
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl));
 
     object->lpVtbl = &Direct3D8_Vtbl;
@@ -48,8 +56,7 @@ 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);
-
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (!object->WineD3D)
     {
 
     if (!object->WineD3D)
     {
@@ -70,7 +77,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
 }
 
 /***********************************************************************
 }
 
 /***********************************************************************
- *              ValidateVertexShader (D3D8.@)
+ *             ValidateVertexShader (D3D8.@)
  *
  * 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.... 
  *
  * 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.... 
@@ -101,7 +108,7 @@ HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD
 }
 
 /***********************************************************************
 }
 
 /***********************************************************************
- *              ValidatePixelShader (D3D8.@)
+ *             ValidatePixelShader (D3D8.@)
  *
  * PARAMS
  * toto       result?
  *
  * PARAMS
  * toto       result?
index e916f14..c38d8cc 100644 (file)
@@ -97,8 +97,6 @@
     _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;
@@ -122,6 +120,9 @@ 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
    =========================================================================== */
@@ -165,24 +166,10 @@ 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
 {
-    struct d3d8_handle_entry *entries;
-    struct d3d8_handle_entry *free_entries;
+    void **entries;
+    void **free_entries;
     UINT table_size;
     UINT entry_count;
 };
     UINT table_size;
     UINT entry_count;
 };
index a5658af..206697d 100644 (file)
@@ -69,7 +69,6 @@ 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;
@@ -120,7 +119,6 @@ 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;
@@ -165,23 +163,14 @@ 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, enum d3d8_handle_type type)
+static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object)
 {
 {
-    struct d3d8_handle_entry *entry;
-
     if (t->free_entries)
     {
         /* Use a free handle */
     if (t->free_entries)
     {
         /* Use a free handle */
-        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;
-
+        void **entry = t->free_entries;
+        t->free_entries = *entry;
+        *entry = object;
         return entry - t->entries;
     }
 
         return entry - t->entries;
     }
 
@@ -189,68 +178,34 @@ static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enu
     {
         /* 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);
-        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;
-        }
+        void **new_entries = HeapReAlloc(GetProcessHeap(), 0, t->entries, new_size * sizeof(void *));
+        if (!new_entries) return D3D8_INVALID_HANDLE;
         t->entries = new_entries;
         t->table_size = new_size;
     }
 
         t->entries = new_entries;
         t->table_size = new_size;
     }
 
-    entry = &t->entries[t->entry_count];
-    entry->object = object;
-    entry->type = type;
-
+    t->entries[t->entry_count] = object;
     return t->entry_count++;
 }
 
     return t->entry_count++;
 }
 
-static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
+static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle)
 {
 {
-    struct d3d8_handle_entry *entry;
-    void *object;
+    void **entry, *object;
 
 
-    if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
-    {
-        WARN("Invalid handle %u passed.\n", handle);
-        return NULL;
-    }
+    if (handle >= t->entry_count) return NULL;
 
     entry = &t->entries[handle];
 
     entry = &t->entries[handle];
-    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;
+    object = *entry;
+    *entry = t->free_entries;
     t->free_entries = entry;
 
     return object;
 }
 
     t->free_entries = entry;
 
     return object;
 }
 
-static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
+static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD 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;
+    if (handle >= t->entry_count) return NULL;
+    return t->entries[handle];
 }
 
 /* IDirect3D IUnknown parts follow: */
 }
 
 /* IDirect3D IUnknown parts follow: */
@@ -299,9 +254,7 @@ 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);
-
-        wined3d_mutex_lock();
-
+        EnterCriticalSection(&d3d8_cs);
         This->inDestruction = TRUE;
 
         for(i = 0; i < This->numConvertedDecls; i++) {
         This->inDestruction = TRUE;
 
         for(i = 0; i < This->numConvertedDecls; i++) {
@@ -313,8 +266,7 @@ 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);
-
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
     }
     return ref;
 }
     }
     return ref;
 }
@@ -325,11 +277,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE
     HRESULT hr;
 
     TRACE("(%p) : Relay\n", This);
     HRESULT hr;
 
     TRACE("(%p) : Relay\n", This);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -338,11 +288,9 @@ static UINT WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -351,11 +299,9 @@ 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);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -370,7 +316,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface,
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
@@ -380,9 +326,8 @@ 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;
 }
@@ -401,14 +346,21 @@ 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 */
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
-    wined3d_mutex_unlock();
-
-    fixup_caps(pWineCaps);
+    LeaveCriticalSection(&d3d8_cs);
     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;
 }
@@ -418,9 +370,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -432,10 +384,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVIC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -449,10 +400,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,pSurface->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -460,9 +410,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
 }
 
 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
@@ -470,10 +420,9 @@ static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -516,10 +465,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown *)object, SURFACE_OPENGL);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown *)object, SURFACE_OPENGL);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -571,9 +520,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;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -597,10 +546,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONS
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -611,14 +559,13 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return rc;
 }
 
     return rc;
 }
 
@@ -627,10 +574,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -639,9 +585,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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (CONST WINED3DGAMMARAMP *) pRamp);
     IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (CONST WINED3DGAMMARAMP *) pRamp);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
 }
 
 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
@@ -649,9 +595,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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
     IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 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,
@@ -673,11 +619,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
 
     object->lpVtbl = &Direct3DTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DTexture8_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (FAILED(hrc)) {
         /* free up object */ 
 
     if (FAILED(hrc)) {
         /* free up object */ 
@@ -714,12 +659,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8
 
     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (hrc != D3D_OK) {
 
 
     if (hrc != D3D_OK) {
 
@@ -756,11 +700,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 i
 
     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (hr != D3D_OK){
 
 
     if (hr != D3D_OK){
 
@@ -794,12 +737,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8
 
     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     object->fvf = FVF;
 
     if (D3D_OK != hrc) {
     object->fvf = FVF;
 
     if (D3D_OK != hrc) {
@@ -834,11 +775,10 @@ 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");
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (D3D_OK != hrc) {
 
 
     if (D3D_OK != hrc) {
 
@@ -854,10 +794,7 @@ 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,
-        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,D3DRESOURCETYPE Type, 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;
@@ -886,12 +823,11 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
-            MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
-    wined3d_mutex_unlock();
-
+            Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
+            (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
+    LeaveCriticalSection(&d3d8_cs);
     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);
@@ -909,9 +845,7 @@ 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, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
-
+    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
     return hr;
 }
 
     return hr;
 }
 
@@ -920,9 +854,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, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, 0);
-
+    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
+                                               ,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
+                                                D3DPOOL_DEFAULT, MultiSample, 0);
     return hr;
 }
 
     return hr;
 }
 
@@ -931,10 +865,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8
     HRESULT hr;
     TRACE("Relay\n");
 
     HRESULT hr;
     TRACE("Relay\n");
 
-    hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
-            0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE,
-            0 /* MultisampleQuality */);
-
+    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 */);
     return hr;
 }
 
     return hr;
 }
 
@@ -954,23 +886,25 @@ 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));
 
 
-    wined3d_mutex_lock();
+    winedesc.Format = &srcFormat;
+    winedesc.Width  = &srcWidth;
+    winedesc.Height = &srcHeight;
+    winedesc.Size   = &srcSize;
+    EnterCriticalSection(&d3d8_cs);
     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);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         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);
@@ -994,7 +928,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, ID
             }
         }
     }
             }
         }
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -1004,10 +938,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1023,10 +956,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1038,7 +970,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
 
     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)
@@ -1050,8 +982,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 ifa
     }
     if (original_ds) IWineD3DSurface_Release(original_ds);
 
     }
     if (original_ds) IWineD3DSurface_Release(original_ds);
 
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1065,8 +996,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 i
     if (ppRenderTarget == NULL) {
         return D3DERR_INVALIDCALL;
     }
     if (ppRenderTarget == NULL) {
         return D3DERR_INVALIDCALL;
     }
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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) {
@@ -1076,7 +1006,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;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -1091,7 +1021,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDE
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
@@ -1101,7 +1031,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;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -1111,10 +1041,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1123,10 +1052,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1136,10 +1064,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1149,10 +1076,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1162,10 +1088,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1175,10 +1100,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1188,10 +1112,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1201,10 +1124,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1214,10 +1136,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1227,10 +1148,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1240,10 +1160,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetLight(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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1253,10 +1172,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1265,10 +1183,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1277,10 +1194,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1289,10 +1205,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1301,10 +1216,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1313,10 +1227,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1325,10 +1238,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1337,10 +1249,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1355,11 +1266,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)
      */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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");
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         return hr;
     }
 
         return hr;
     }
 
@@ -1370,8 +1281,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
 
     object->wineD3DStateBlock = wineD3DStateBlock;
 
 
     object->wineD3DStateBlock = wineD3DStateBlock;
 
-    *pToken = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_SB);
-    wined3d_mutex_unlock();
+    *pToken = d3d8_allocate_handle(&This->handle_table, object);
+    LeaveCriticalSection(&d3d8_cs);
 
     if (*pToken == D3D8_INVALID_HANDLE)
     {
 
     if (*pToken == D3D8_INVALID_HANDLE)
     {
@@ -1393,17 +1304,16 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 ifa
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
-    wined3d_mutex_lock();
-    pSB = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
+    EnterCriticalSection(&d3d8_cs);
+    pSB = d3d8_get_object(&This->handle_table, Token - 1);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1414,17 +1324,16 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 i
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
 
     TRACE("(%p) %#x Relay\n", This, Token);
 
-    wined3d_mutex_lock();
-    pSB = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
+    EnterCriticalSection(&d3d8_cs);
+    pSB = d3d8_get_object(&This->handle_table, Token - 1);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
     if (!pSB)
     {
         WARN("Invalid handle (%#x) passed.\n", Token);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
         return D3DERR_INVALIDCALL;
     }
     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1434,9 +1343,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 if
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
-    pSB = d3d8_free_handle(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
-    wined3d_mutex_unlock();
+    EnterCriticalSection(&d3d8_cs);
+    pSB = d3d8_free_handle(&This->handle_table, Token - 1);
+    LeaveCriticalSection(&d3d8_cs);
 
     if (!pSB)
     {
 
     if (!pSB)
     {
@@ -1479,19 +1388,19 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(IDirect3DDevice8 *if
     object->lpVtbl = &Direct3DStateBlock8_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DStateBlock8_Vtbl;
     object->ref = 1;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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))
     {
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         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, D3D8_HANDLE_SB);
-    wined3d_mutex_unlock();
+    *handle = d3d8_allocate_handle(&This->handle_table, object);
+    LeaveCriticalSection(&d3d8_cs);
 
     if (*handle == D3D8_INVALID_HANDLE)
     {
 
     if (*handle == D3D8_INVALID_HANDLE)
     {
@@ -1511,11 +1420,9 @@ 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 */
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1524,10 +1431,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1542,7 +1448,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, D
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
@@ -1551,7 +1457,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;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return rc;
 }
 
     return rc;
 }
@@ -1561,11 +1467,10 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1613,11 +1518,12 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
+
     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;
 }
 
@@ -1627,11 +1533,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
+
     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;
 }
 
@@ -1640,10 +1547,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1658,10 +1564,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1670,10 +1575,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1682,10 +1586,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1694,10 +1597,9 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1706,12 +1608,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1721,12 +1622,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1735,13 +1635,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1753,13 +1652,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1769,10 +1667,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1807,11 +1704,10 @@ static HRESULT IDirect3DDevice8Impl_CreateVertexDeclaration(IDirect3DDevice8 *if
 
     CopyMemory(object->elements, declaration, object->elements_size);
 
 
     CopyMemory(object->elements, declaration, object->elements_size);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
     if (FAILED(hr)) {
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
     if (FAILED(hr)) {
@@ -1830,6 +1726,7 @@ 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;
 
@@ -1869,12 +1766,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
-    handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_VS);
+    EnterCriticalSection(&d3d8_cs);
+    handle = d3d8_allocate_handle(&This->handle_table, object);
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
         HeapFree(GetProcessHeap(), 0, object);
         *ppShader = 0;
         IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
         HeapFree(GetProcessHeap(), 0, object);
         *ppShader = 0;
@@ -1886,17 +1783,19 @@ 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, pFunction,
-                NULL /* output signature */, &object->wineD3DVertexShader, (IUnknown *)object);
+        hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration,
+                pFunction, &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_HANDLE_VS);
+            d3d8_free_handle(&This->handle_table, handle);
             IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
             HeapFree(GetProcessHeap(), 0, object);
             *ppShader = 0;
             IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
             HeapFree(GetProcessHeap(), 0, object);
             *ppShader = 0;
@@ -1908,7 +1807,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         }
     }
 
         }
     }
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return hrc;
 }
 
     return hrc;
 }
@@ -1992,31 +1891,29 @@ 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);
 
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         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);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         return D3D_OK;
     }
 
     TRACE("Setting shader\n");
 
         return D3D_OK;
     }
 
     TRACE("Setting shader\n");
 
-    wined3d_mutex_lock();
-    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
+    EnterCriticalSection(&d3d8_cs);
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     TRACE("Returning hr %#x\n", hr);
 
 
     TRACE("Returning hr %#x\n", hr);
 
@@ -2030,12 +1927,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))
     {
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         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;
@@ -2043,14 +1940,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 ifa
 
     if (!wined3d_declaration)
     {
 
     if (!wined3d_declaration)
     {
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         *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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
     if (SUCCEEDED(hrc))
     {
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
     if (SUCCEEDED(hrc))
     {
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
@@ -2069,13 +1966,13 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    wined3d_mutex_lock();
-    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
+    EnterCriticalSection(&d3d8_cs);
+
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
@@ -2087,7 +1984,7 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE
         IWineD3DVertexShader_Release(cur);
     }
 
         IWineD3DVertexShader_Release(cur);
     }
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (IUnknown_Release((IUnknown *)shader))
     {
 
     if (IUnknown_Release((IUnknown *)shader))
     {
@@ -2108,10 +2005,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2126,10 +2022,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2140,10 +2035,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);
 
-    wined3d_mutex_lock();
-    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
-    wined3d_mutex_unlock();
+    EnterCriticalSection(&d3d8_cs);
 
 
+    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);
@@ -2176,26 +2071,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);
 
-    wined3d_mutex_lock();
-    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
+    EnterCriticalSection(&d3d8_cs);
+
+    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
     if (!shader->wineD3DVertexShader)
     {
         return D3DERR_INVALIDCALL;
     }
 
     if (!shader->wineD3DVertexShader)
     {
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         *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;
 }
 
@@ -2205,19 +2100,18 @@ 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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2232,8 +2126,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) {
@@ -2243,7 +2137,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;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return rc;
 }
 
     return rc;
 }
@@ -2270,21 +2164,20 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader8_Vtbl;
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader8_Vtbl;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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))
     {
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         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, D3D8_HANDLE_PS);
-    wined3d_mutex_unlock();
-
+    handle = d3d8_allocate_handle(&This->handle_table, object);
+    LeaveCriticalSection(&d3d8_cs);
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
     if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
@@ -2305,27 +2198,26 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 ifac
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
 
     if (!pShader)
     {
         hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, NULL);
 
     if (!pShader)
     {
         hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, NULL);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         return hr;
     }
 
         return hr;
     }
 
-    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d8_cs);
         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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2340,7 +2232,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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;
@@ -2351,10 +2243,9 @@ 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;
 }
 
@@ -2365,14 +2256,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 i
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
 
 
-    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pShader);
-        wined3d_mutex_unlock();
-        return D3D_OK;
+        LeaveCriticalSection(&d3d8_cs);
+        return D3DERR_INVALIDCALL;
     }
 
     IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
     }
 
     IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
@@ -2383,7 +2274,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 i
         IWineD3DPixelShader_Release(cur);
     }
 
         IWineD3DPixelShader_Release(cur);
     }
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (IUnknown_Release((IUnknown *)shader))
     {
 
     if (IUnknown_Release((IUnknown *)shader))
     {
@@ -2398,10 +2289,9 @@ static HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2410,10 +2300,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2424,19 +2313,17 @@ 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);
 
-    wined3d_mutex_lock();
-    shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
+    EnterCriticalSection(&d3d8_cs);
+    shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1));
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pPixelShader);
     if (!shader)
     {
         WARN("Invalid handle (%#x) passed.\n", pPixelShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
         return D3DERR_INVALIDCALL;
     }
 
     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2445,10 +2332,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2457,10 +2343,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2469,10 +2354,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2481,12 +2365,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2501,7 +2384,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
@@ -2512,7 +2395,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa
         }
         *pStream = NULL;
     }
         }
         *pStream = NULL;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     return rc;
 }
 
     return rc;
 }
@@ -2681,7 +2564,8 @@ 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, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+            (IDirect3DSurface8 **)&d3d_surface, D3DRTYPE_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 3368794..d39d3d6 100644 (file)
@@ -71,11 +71,9 @@ 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);
-
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3D_Release(This->WineD3D);
         IWineD3D_Release(This->WineD3D);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -88,10 +86,9 @@ static HRESULT WINAPI IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -100,41 +97,36 @@ static UINT WINAPI IDirect3D8Impl_GetAdapterCount (LPDIRECT3D8 iface) {
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     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);
-    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;
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -143,10 +135,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -155,9 +146,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -169,9 +160,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -185,11 +176,10 @@ 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");
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -201,14 +191,6 @@ 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:
@@ -220,59 +202,42 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 i
             break;
     }
 
             break;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D8Impl_CheckDeviceMultiSampleType(IDirect3D8 *iface, UINT Adapter,
-        D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType)
-{
+static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D8Impl_CheckDepthStencilMatch(IDirect3D8 *iface, UINT Adapter, D3DDEVTYPE DeviceType,
-        D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
-{
+static HRESULT  WINAPI  IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     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;
@@ -287,15 +252,21 @@ 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*/
     }
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
-    wined3d_mutex_unlock();
-
-    fixup_caps(pWineCaps);
+    LeaveCriticalSection(&d3d8_cs);
     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;
 }
@@ -305,10 +276,9 @@ static HMONITOR WINAPI  IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT
     HMONITOR ret;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
     HMONITOR ret;
     TRACE("(%p)->(%d)\n", This, Adapter);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -374,15 +344,14 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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;
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         return hr;
     }
 
         return hr;
     }
 
@@ -409,7 +378,7 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     }
 
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
     }
 
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
@@ -435,11 +404,9 @@ 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");
-
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DDevice_Release(object->WineD3DDevice);
         IWineD3DDevice_Release(object->WineD3DDevice);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
         hr = E_OUTOFMEMORY;
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
         hr = E_OUTOFMEMORY;
index b59b1ab..a0de5c5 100644 (file)
@@ -56,10 +56,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,15 +72,14 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -90,10 +88,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -102,10 +99,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -114,10 +110,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXB
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -126,10 +121,9 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -138,10 +132,9 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -149,9 +142,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
@@ -167,10 +160,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -179,10 +171,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -192,9 +183,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 i
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
index 2f0fb1c..ae8d15f 100644 (file)
@@ -56,10 +56,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
index 04c4e48..ace9211 100644 (file)
@@ -58,10 +58,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -75,14 +74,16 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *i
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
+
     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);
     }
-    wined3d_mutex_unlock();
+
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -93,9 +94,11 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
+
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
-    wined3d_mutex_unlock();
+
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -106,9 +109,11 @@ static HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
+
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
-    wined3d_mutex_unlock();
+
+    LeaveCriticalSection(&d3d8_cs);
 
     return hr;
 }
 
     return hr;
 }
index 3185a1f..4b382ec 100644 (file)
@@ -76,10 +76,9 @@ 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) {
-                wined3d_mutex_lock();
+                EnterCriticalSection(&d3d8_cs);
                 IWineD3DSurface_Release(This->wineD3DSurface);
                 IWineD3DSurface_Release(This->wineD3DSurface);
-                wined3d_mutex_unlock();
-
+                LeaveCriticalSection(&d3d8_cs);
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
@@ -95,15 +94,14 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -112,10 +110,9 @@ static HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(LPDIRECT3DSURFACE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -124,10 +121,9 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(LPDIRECT3DSURFACE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -136,10 +132,9 @@ static HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -164,21 +159,22 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
 
     return hr;
 }
 
     return hr;
 }
@@ -189,7 +185,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     if (pRect) {
         D3DSURFACE_DESC desc;
         IDirect3DSurface8_GetDesc(iface, &desc);
     if (pRect) {
         D3DSURFACE_DESC desc;
         IDirect3DSurface8_GetDesc(iface, &desc);
@@ -201,15 +197,13 @@ 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");
-            wined3d_mutex_unlock();
-
+            LeaveCriticalSection(&d3d8_cs);
             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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -218,10 +212,9 @@ static HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
index 67f3429..25d2a0e 100644 (file)
@@ -56,10 +56,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
         IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         if (This->parentDevice) IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         if (This->parentDevice) IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -72,10 +71,9 @@ static HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -86,14 +84,13 @@ static HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hrc;
 }
 
     return hrc;
 }
 
index c22c491..c1bb91e 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,16 +72,14 @@ 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);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -91,10 +88,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_SetPrivateData(LPDIRECT3DTEXTURE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -103,10 +99,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetPrivateData(LPDIRECT3DTEXTURE8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -115,10 +110,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_FreePrivateData(LPDIRECT3DTEXTURE8 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -127,10 +121,9 @@ static DWORD WINAPI IDirect3DTexture8Impl_SetPriority(LPDIRECT3DTEXTURE8 iface,
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -139,10 +132,9 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetPriority(LPDIRECT3DTEXTURE8 iface)
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -150,9 +142,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) {
@@ -160,10 +152,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 i
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     type = IWineD3DTexture_GetType(This->wineD3DTexture);
     type = IWineD3DTexture_GetType(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return type;
 }
 
     return type;
 }
 
@@ -173,10 +164,9 @@ static DWORD WINAPI IDirect3DTexture8Impl_SetLOD(LPDIRECT3DTEXTURE8 iface, DWORD
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -185,10 +175,9 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetLOD(LPDIRECT3DTEXTURE8 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -197,10 +186,9 @@ static DWORD WINAPI IDirect3DTexture8Impl_GetLevelCount(LPDIRECT3DTEXTURE8 iface
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -212,21 +200,22 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetLevelDesc(LPDIRECT3DTEXTURE8 ifac
     WINED3DSURFACE_DESC    wined3ddesc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DSURFACE_DESC    wined3ddesc;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
 
     return hr;
 }
 
     return hr;
 }
@@ -237,15 +226,13 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE8 i
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -254,10 +241,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_LockRect(LPDIRECT3DTEXTURE8 iface, U
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -266,10 +252,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_UnlockRect(LPDIRECT3DTEXTURE8 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -278,10 +263,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_AddDirtyRect(LPDIRECT3DTEXTURE8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
index 617aff3..a282cda 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,15 +74,14 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -92,10 +90,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -104,10 +101,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -116,10 +112,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -128,10 +123,9 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -140,10 +134,9 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -151,9 +144,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
@@ -169,10 +162,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -181,10 +173,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -194,9 +185,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) {
         pDesc->Type = D3DRTYPE_VERTEXBUFFER;
 
     if (SUCCEEDED(hr)) {
         pDesc->Type = D3DRTYPE_VERTEXBUFFER;
index 2eea098..e9d56d0 100644 (file)
@@ -61,10 +61,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
         IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This->elements);
         HeapFree(GetProcessHeap(), 0, This);
     }
         HeapFree(GetProcessHeap(), 0, This->elements);
         HeapFree(GetProcessHeap(), 0, This);
     }
index 1a9b5ea..4ea8b52 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)
         {
-            wined3d_mutex_lock();
+            EnterCriticalSection(&d3d8_cs);
             IWineD3DVertexShader_Release(This->wineD3DVertexShader);
             IWineD3DVertexShader_Release(This->wineD3DVertexShader);
-            wined3d_mutex_unlock();
+            LeaveCriticalSection(&d3d8_cs);
         }
         HeapFree(GetProcessHeap(), 0, This);
     }
         }
         HeapFree(GetProcessHeap(), 0, This);
     }
index 968b534..474aad8 100644 (file)
@@ -72,10 +72,9 @@ 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) {
-            wined3d_mutex_lock();
+            EnterCriticalSection(&d3d8_cs);
             IWineD3DVolume_Release(This->wineD3DVolume);
             IWineD3DVolume_Release(This->wineD3DVolume);
-            wined3d_mutex_unlock();
-
+            LeaveCriticalSection(&d3d8_cs);
             HeapFree(GetProcessHeap(), 0, This);
         }
 
             HeapFree(GetProcessHeap(), 0, This);
         }
 
@@ -88,12 +87,11 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, ID
     IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
     IWineD3DDevice       *myDevice = NULL;
 
     IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
     IWineD3DDevice       *myDevice = NULL;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return D3D_OK;
 }
 
     return D3D_OK;
 }
 
@@ -102,10 +100,9 @@ static HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -114,10 +111,9 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetPrivateData(LPDIRECT3DVOLUME8 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -126,10 +122,9 @@ static HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -159,21 +154,21 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DV
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
-    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;
-    }
+    LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
 
     return hr;
 }
 
     return hr;
 }
@@ -183,10 +178,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -195,10 +189,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
index 1875081..098827a 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,15 +73,14 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetDevice(LPDIRECT3DVOLUMETEXT
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -91,10 +89,9 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_SetPrivateData(LPDIRECT3DVOLUM
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -103,10 +100,9 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetPrivateData(LPDIRECT3DVOLUM
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -115,10 +111,9 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_FreePrivateData(LPDIRECT3DVOLU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -127,10 +122,9 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetPriority(LPDIRECT3DVOLUMETEXT
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
     ret = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -139,10 +133,9 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetPriority(LPDIRECT3DVOLUMETEXT
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -150,9 +143,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTURE8 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTURE8 iface) {
@@ -160,10 +153,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLU
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE type;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return type;
 }
 
     return type;
 }
 
@@ -173,10 +165,9 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
     ret = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -185,10 +176,9 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE8
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -197,10 +187,9 @@ static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLevelCount(LPDIRECT3DVOLUMETE
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     ret = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
     ret = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -208,25 +197,26 @@ 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);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d8_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
 
     return hr;
 }
 
     return hr;
 }
@@ -238,14 +228,13 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetVolumeLevel(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -254,10 +243,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -266,10 +254,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -278,10 +265,9 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_AddDirtyBox(LPDIRECT3DVOLUMETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *) pDirtyBox);
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *) pDirtyBox);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
     return hr;
 }
 
index 8209d0b..bbd171e 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);
 
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D9CB_DestroySurface);
         IDirect3DDevice9Ex_Release(This->parentDevice);
-        wined3d_mutex_unlock();
+        LeaveCriticalSection(&d3d9_cs);
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -78,15 +78,14 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetDevice(LPDIRECT3DCUBETEXTURE9
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -95,10 +94,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_SetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
     hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -107,10 +105,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetPrivateData(LPDIRECT3DCUBETEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
     hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -119,10 +116,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_FreePrivateData(LPDIRECT3DCUBETE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
     hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -131,10 +127,9 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_SetPriority(LPDIRECT3DCUBETEXTURE9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
     ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -143,10 +138,9 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetPriority(LPDIRECT3DCUBETEXTURE9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -154,9 +148,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETEXTURE9 iface) {
@@ -164,10 +158,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture9Impl_GetType(LPDIRECT3DCUBETE
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -177,10 +170,9 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_SetLOD(LPDIRECT3DCUBETEXTURE9 ifac
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
     ret = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -189,10 +181,9 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetLOD(LPDIRECT3DCUBETEXTURE9 ifac
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_GetLOD(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetLOD(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -201,10 +192,9 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetLevelCount(LPDIRECT3DCUBETEXTUR
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
     ret = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -213,10 +203,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_SetAutoGenFilterType(LPDIRECT3DC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_SetAutoGenFilterType(This->wineD3DCubeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
     hr = IWineD3DCubeTexture_SetAutoGenFilterType(This->wineD3DCubeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -225,10 +214,9 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DCubeTexture9Impl_GetAutoGenFilterTyp
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DCubeTexture_GetAutoGenFilterType(This->wineD3DCubeTexture);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DCubeTexture_GetAutoGenFilterType(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -236,34 +224,37 @@ static void WINAPI IDirect3DCubeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DCUBE
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DCubeTexture_GenerateMipSubLevels(This->wineD3DCubeTexture);
     IWineD3DCubeTexture_GenerateMipSubLevels(This->wineD3DCubeTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 /* 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;
+    WINED3DSURFACE_DESC    wined3ddesc;
+    UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
 
     return hr;
 }
 
     return hr;
 }
@@ -275,14 +266,13 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetCubeMapSurface(LPDIRECT3DCUBE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -291,10 +281,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_LockRect(LPDIRECT3DCUBETEXTURE9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -303,10 +292,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_UnlockRect(LPDIRECT3DCUBETEXTURE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
     hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -315,10 +303,9 @@ static HRESULT  WINAPI IDirect3DCubeTexture9Impl_AddDirtyRect(LPDIRECT3DCUBETEXT
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
     hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -376,11 +363,10 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac
     }
     object->lpVtbl = &Direct3DCubeTexture9_Vtbl;
     object->ref = 1;
     }
     object->lpVtbl = &Direct3DCubeTexture9_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (hr != D3D_OK){
 
 
     if (hr != D3D_OK){
 
index f59fc46..40d73a5 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;
@@ -38,10 +47,9 @@ IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) {
 
     object->lpVtbl = &Direct3D9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3D9_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     object->WineD3D = WineDirect3DCreate(9, (IUnknown *)object);
     object->WineD3D = WineDirect3DCreate(9, (IUnknown *)object);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     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 b6ef7cf..7e43974 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,6 +44,7 @@
 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);
 
@@ -368,6 +369,7 @@ typedef struct IDirect3DBaseTexture9Impl
 
     /* IDirect3DResource9 fields */
     IWineD3DBaseTexture    *wineD3DBaseTexture;
 
     /* IDirect3DResource9 fields */
     IWineD3DBaseTexture    *wineD3DBaseTexture;
+    
 } IDirect3DBaseTexture9Impl;
 
 /* --------------------- */
 } IDirect3DBaseTexture9Impl;
 
 /* --------------------- */
index 5a87a8f..e5ca4c4 100644 (file)
@@ -248,7 +248,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
       unsigned i;
       This->inDestruction = TRUE;
 
       unsigned i;
       This->inDestruction = TRUE;
 
-      wined3d_mutex_lock();
+      EnterCriticalSection(&d3d9_cs);
       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,8 +259,7 @@ 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);
-      wined3d_mutex_unlock();
-
+      LeaveCriticalSection(&d3d9_cs);
       HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
       HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -272,10 +271,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_TestCooperativeLevel(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p)\n", This);
 
     HRESULT hr;
     TRACE("(%p)\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
     hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     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;
@@ -289,10 +287,9 @@ static UINT     WINAPI  IDirect3DDevice9Impl_GetAvailableTextureMem(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
     hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -301,10 +298,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_EvictManagedResources(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
     hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -319,7 +315,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9EX iface
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
     hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
     if (hr == D3D_OK && pWineD3D != NULL)
     {
@@ -330,8 +326,7 @@ 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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -350,11 +345,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9EX i
     }
 
     memset(pCaps, 0, sizeof(*pCaps));
     }
 
     memset(pCaps, 0, sizeof(*pCaps));
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
     hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
@@ -372,9 +365,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -386,10 +379,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCreationParameters(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
     hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -404,10 +396,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCursorProperties(LPDIRECT3DDEVIC
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -415,9 +406,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
     IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
 }
 
 static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
@@ -425,35 +416,53 @@ static BOOL     WINAPI  IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
     BOOL ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
     ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     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;
-    D3DRESOURCETYPE type;
+    WINED3DRESOURCETYPE 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;
-    WINED3DPOOL pool;
+    WINED3DFORMAT dummy_format;
+    WINED3DMULTISAMPLE_TYPE dummy_multisampletype;
+    DWORD dummy_dword;
+    WINED3DPOOL pool = WINED3DPOOL_SCRATCH; /* a harmless 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:
@@ -470,7 +479,6 @@ 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;
     }
 
@@ -507,7 +515,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
      */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -520,8 +528,7 @@ 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;
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
@@ -563,7 +570,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
         This->notreset = FALSE;
     }
 
         This->notreset = FALSE;
     }
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -574,10 +581,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
     hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
  }
 
     return hr;
  }
 
@@ -588,14 +594,13 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetBackBuffer(LPDIRECT3DDEVICE9EX i
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     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) {
@@ -603,10 +608,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -615,49 +619,48 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
     hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
-        DWORD Flags, const D3DGAMMARAMP *pRamp)
-{
+static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(LPDIRECT3DDEVICE9EX 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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 
 }
 
 
-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)
-{
+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 )  {
     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 = 0;
+    /*
+    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;
     }
     /*FIXME: Check MAX bounds of MultisampleQuality*/
 
     }
     /*FIXME: Check MAX bounds of MultisampleQuality*/
 
@@ -673,11 +676,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
-            MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
-    wined3d_mutex_unlock();
+            Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
+            (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
+    LeaveCriticalSection(&d3d9_cs);
 
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
 
 
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
 
@@ -693,17 +696,17 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
     return hrc;
 }
 
     return hrc;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width, UINT Height,
-        D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable,
-        IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
-{
+
+
+static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateRenderTarget(LPDIRECT3DDEVICE9EX 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, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
-
-    return hr;
+   hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,Lockable,FALSE/*Discard*/, 0/*Level*/, ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_RENDERTARGET,D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
+   return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
@@ -713,10 +716,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, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
-
-    return hr;
+     hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/* Lockable */,Discard, 0/* Level */
+                                               ,ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_DEPTHSTENCIL,
+                                                D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
+     return hr;
 }
 
 
 }
 
 
@@ -725,10 +728,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -737,10 +739,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -751,10 +752,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
     hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -764,10 +764,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
     hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -778,11 +777,9 @@ 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);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
     hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -796,18 +793,19 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    memset(&desc, 0, sizeof(desc));
+    desc.Usage = &usage;
+    desc.Pool = &pool;
+    desc.Type = &restype;
 
 
+    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 != WINED3DPOOL_DEFAULT || restype != WINED3DRTYPE_SURFACE)) {
-        wined3d_mutex_unlock();
+    if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != D3DPOOL_DEFAULT || restype != D3DRTYPE_SURFACE)) {
+        LeaveCriticalSection(&d3d9_cs);
         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;
     }
@@ -815,9 +813,7 @@ 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);
-
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -827,17 +823,15 @@ 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 /* Lockable */, FALSE /* Discard */,
-            0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, (WINED3DPOOL)Pool, D3DMULTISAMPLE_NONE,
-            0 /* MultisampleQuality */);
+    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);
 
     return hr;
 }
 
     return hr;
 }
@@ -849,17 +843,16 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL);
     hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     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);
 
@@ -867,25 +860,17 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
-
+    EnterCriticalSection(&d3d9_cs);
     hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
 
     hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
 
-    if (FAILED(hr))
-    {
-        FIXME("Call to IWineD3DDevice_GetRenderTarget failed, hr %#x\n", hr);
-    }
-    else if (!pRenderTarget)
-    {
-        *ppRenderTarget = NULL;
-    }
-    else
-    {
-        IWineD3DSurface_GetParent(pRenderTarget, (IUnknown **)ppRenderTarget);
+    if (hr == D3D_OK && pRenderTarget != NULL) {
+        IWineD3DSurface_GetParent(pRenderTarget,(IUnknown**)ppRenderTarget);
         IWineD3DSurface_Release(pRenderTarget);
         IWineD3DSurface_Release(pRenderTarget);
+    } else {
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+        *ppRenderTarget = NULL;
     }
     }
-
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -897,11 +882,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDE
     TRACE("(%p) Relay\n" , This);
 
     pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
     TRACE("(%p) Relay\n" , This);
 
     pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
     hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -915,7 +898,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -925,8 +908,7 @@ 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;
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -935,10 +917,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX ifac
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -947,10 +928,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface)
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
     hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -960,10 +940,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -973,10 +952,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
     hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -986,10 +964,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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -1000,10 +978,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
     hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1013,10 +990,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1026,10 +1002,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
     hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1039,10 +1014,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1052,10 +1026,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
     hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1065,10 +1038,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1078,10 +1050,9 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
     hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1090,10 +1061,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9EX ifa
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
     hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1102,10 +1072,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
     hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1114,10 +1083,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1126,10 +1094,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
     hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1138,10 +1105,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
     hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1150,10 +1116,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
     hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1162,10 +1127,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1174,10 +1138,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
     hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1192,7 +1155,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -1203,7 +1166,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX ifac
         }
         *ppTexture = NULL;
     }
         }
         *ppTexture = NULL;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return rc;
 }
 
     return rc;
 }
@@ -1213,11 +1176,10 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
     hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
                                    pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1263,10 +1225,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
     hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1275,24 +1236,20 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVI
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
     hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
-        D3DSAMPLERSTATETYPE Type, DWORD *pValue)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+static HRESULT  WINAPI  IDirect3DDevice9Impl_GetSamplerState(LPDIRECT3DDEVICE9EX 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
     hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1301,10 +1258,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
     hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1313,24 +1269,20 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
     hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface, UINT PaletteNumber,
-        const PALETTEENTRY *pEntries)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+static HRESULT  WINAPI  IDirect3DDevice9Impl_SetPaletteEntries(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1339,10 +1291,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
     hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1351,10 +1302,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1363,10 +1313,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3D
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
     hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1375,10 +1324,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
     hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1387,10 +1335,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
     hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1399,10 +1346,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIREC
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
     hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1411,10 +1357,9 @@ static BOOL     WINAPI  IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIREC
     BOOL ret;
     TRACE("(%p) Relay\n" , This);
 
     BOOL ret;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
     ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -1423,10 +1368,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
     hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1435,26 +1379,22 @@ static float    WINAPI  IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9EX i
     float ret;
     TRACE("(%p) Relay\n" , This);
 
     float ret;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
     ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
-        UINT StartVertex, UINT PrimitiveCount)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9EX 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1465,30 +1405,26 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
-        UINT PrimitiveCount, const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9EX 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1499,13 +1435,12 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1516,10 +1451,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX
     IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
     IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1593,9 +1527,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWO
         return D3D_OK;
     }
 
         return D3D_OK;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     decl = getConvertedDecl(This, FVF);
     decl = getConvertedDecl(This, FVF);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (!decl)
     {
 
     if (!decl)
     {
@@ -1644,12 +1578,11 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
     hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
-            pStreamData ? ((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer : NULL,
-            OffsetInBytes, Stride);
-    wined3d_mutex_unlock();
-
+                                          pStreamData==NULL ? NULL:((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer, 
+                                          OffsetInBytes, Stride);
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1664,7 +1597,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -1675,22 +1608,19 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i
         }
         *pStream = NULL;
     }
         }
         *pStream = NULL;
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return rc;
 }
 
 
     return rc;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT StreamNumber,
-        UINT Divider)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+static HRESULT  WINAPI  IDirect3DDevice9Impl_SetStreamSourceFreq(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, UINT Divider) {
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
     hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1699,10 +1629,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVIC
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
     hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1712,12 +1641,11 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1732,7 +1660,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX ifac
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -1741,8 +1669,7 @@ 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;
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return rc;
 }
 
     return rc;
 }
 
@@ -1751,10 +1678,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9EX i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
     hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1763,10 +1689,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9EX if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
     hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -1775,10 +1700,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX ifa
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
     hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -2071,12 +1995,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 == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
-        lockable = FALSE;
+    if (pool == D3DPOOL_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, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+            (IDirect3DSurface9 **)&d3d_surface, D3DRTYPE_SURFACE, usage, pool,
+            D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */, NULL);
     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 fe22916..e9547a7 100644 (file)
@@ -69,10 +69,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3D_Release(This->WineD3D);
         IWineD3D_Release(This->WineD3D);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -85,10 +84,9 @@ static HRESULT  WINAPI  IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9EX ifac
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, pInitializeFunction);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
     hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -97,10 +95,9 @@ static UINT     WINAPI  IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9EX iface) {
     HRESULT hr;
     TRACE("%p\n", This);
 
     HRESULT hr;
     TRACE("%p\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
     hr = IWineD3D_GetAdapterCount(This->WineD3D);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -109,25 +106,23 @@ static HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9EX iface, U
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
     WINED3DADAPTER_IDENTIFIER adapter_id;
     HRESULT hr;
 
-    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();
+    /* 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);
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
     hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
-    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;
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -141,10 +136,9 @@ static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9EX iface, UINT
         return 0;
     }
 
         return 0;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format));
     hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -157,10 +151,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;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -171,51 +165,38 @@ static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9EX iface,
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
 
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     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(IDirect3D9Ex *iface, UINT Adapter,
-        D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
-{
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9EX 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");
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(IDirect3D9Ex *iface, UINT Adapter, D3DDEVTYPE DeviceType,
-        D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
-{
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX 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:
@@ -227,43 +208,39 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(IDirect3D9Ex *iface, UINT
             break;
     }
 
             break;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(IDirect3D9Ex *iface, UINT Adapter,
-        D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType,
-        DWORD *pQualityLevels)
-{
+static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9EX 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(IDirect3D9Ex *iface, UINT Adapter,
-        D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
-{
+static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9EX 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -272,11 +249,10 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9EX i
     HRESULT hr;
     TRACE("%p\n", This);
 
     HRESULT hr;
     TRACE("%p\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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));
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -354,11 +330,9 @@ 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));
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
     hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
     HeapFree(GetProcessHeap(), 0, pWineCaps);
 
@@ -376,10 +350,9 @@ static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9EX iface, UIN
     HMONITOR ret;
     TRACE("%p\n", This);
 
     HMONITOR ret;
     TRACE("%p\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
     ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -445,14 +418,13 @@ 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 */
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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;
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         return hr;
     }
 
         return hr;
     }
 
@@ -520,7 +492,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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
index 49f6fc8..8802bd1 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,15 +73,14 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDevice(LPDIRECT3DINDEXBUFFER9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -91,10 +89,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_SetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -103,10 +100,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetPrivateData(LPDIRECT3DINDEXBU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -115,10 +111,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_FreePrivateData(LPDIRECT3DINDEXB
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -127,10 +122,9 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_SetPriority(LPDIRECT3DINDEXBUFFER9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -139,10 +133,9 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_GetPriority(LPDIRECT3DINDEXBUFFER9
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -150,9 +143,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) {
@@ -168,10 +161,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Lock(LPDIRECT3DINDEXBUFFER9 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -180,10 +172,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -193,9 +184,9 @@ static HRESULT  WINAPI        IDirect3DIndexBuffer9Impl_GetDesc(LPDIRECT3DINDEXB
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = d3dformat_from_wined3dformat(This->format);
@@ -232,13 +223,14 @@ static const IDirect3DIndexBuffer9Vtbl Direct3DIndexBuffer9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DIndexBuffer9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DIndexBuffer9 Methods follow: */
-HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT Length, DWORD Usage,
-        D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9 **ppIndexBuffer, HANDLE *pSharedHandle)
-{
+HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX 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));
@@ -251,12 +243,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *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");
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
         /* free up object */
     if (hrc != D3D_OK) {
 
         /* free up object */
index 3795045..3939f59 100644 (file)
@@ -56,10 +56,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,12 +72,11 @@ static HRESULT WINAPI IDirect3DPixelShader9Impl_GetDevice(LPDIRECT3DPIXELSHADER9
 
     TRACE("(%p) : Relay\n", This);
 
 
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return D3D_OK;
 }
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return D3D_OK;
 }
@@ -88,10 +86,9 @@ static HRESULT WINAPI IDirect3DPixelShader9Impl_GetFunction(LPDIRECT3DPIXELSHADE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData);
     hr = IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -130,14 +127,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(LPDIRECT3DDEVICE9EX iface,
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
 
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
             &object->wineD3DPixelShader, (IUnknown *)object);
     hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
             &object->wineD3DPixelShader, (IUnknown *)object);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
+    if (hrc != D3D_OK) {
 
 
-    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);
@@ -157,10 +152,9 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
     IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return D3D_OK;
 }
 
     return D3D_OK;
 }
 
@@ -175,7 +169,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(LPDIRECT3DDEVICE9EX iface, ID
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (SUCCEEDED(hrc))
     {
     hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
     if (SUCCEEDED(hrc))
     {
@@ -193,7 +187,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);
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
@@ -202,12 +196,11 @@ 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);   
 
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -217,9 +210,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantF(LPDIRECT3DDEVICE9EX
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -229,10 +222,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_SetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -241,10 +233,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_GetPixelShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -253,10 +244,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_SetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -265,9 +255,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_GetPixelShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
     return hr;
 }
index a17d2e8..6e4b20a 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DQuery_Release(This->wineD3DQuery);
         IWineD3DQuery_Release(This->wineD3DQuery);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,7 +74,7 @@ static HRESULT WINAPI IDirect3DQuery9Impl_GetDevice(LPDIRECT3DQUERY9 iface, IDir
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DQuery_GetDevice(This->wineD3DQuery, &pDevice);
     if(hr != D3D_OK){
         *ppDevice = NULL;
     hr = IWineD3DQuery_GetDevice(This->wineD3DQuery, &pDevice);
     if(hr != D3D_OK){
         *ppDevice = NULL;
@@ -83,8 +82,7 @@ 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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -93,10 +91,9 @@ static D3DQUERYTYPE WINAPI IDirect3DQuery9Impl_GetType(LPDIRECT3DQUERY9 iface) {
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DQuery_GetType(This->wineD3DQuery);
     hr = IWineD3DQuery_GetType(This->wineD3DQuery);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -105,10 +102,9 @@ static DWORD WINAPI IDirect3DQuery9Impl_GetDataSize(LPDIRECT3DQUERY9 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DQuery_GetDataSize(This->wineD3DQuery);
     ret = IWineD3DQuery_GetDataSize(This->wineD3DQuery);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -117,10 +113,9 @@ static HRESULT WINAPI IDirect3DQuery9Impl_Issue(LPDIRECT3DQUERY9 iface, DWORD dw
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DQuery_Issue(This->wineD3DQuery, dwIssueFlags);
     hr = IWineD3DQuery_Issue(This->wineD3DQuery, dwIssueFlags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -129,10 +124,9 @@ static HRESULT WINAPI IDirect3DQuery9Impl_GetData(LPDIRECT3DQUERY9 iface, void*
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DQuery_GetData(This->wineD3DQuery, pData, dwSize, dwGetDataFlags);
     hr = IWineD3DQuery_GetData(This->wineD3DQuery, pData, dwSize, dwGetDataFlags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -160,10 +154,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(LPDIRECT3DDEVICE9EX iface, D3DQU
 
     if (!ppQuery)
     {
 
     if (!ppQuery)
     {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, NULL, NULL);
         hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, NULL, NULL);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         return hr;
     }
 
         return hr;
     }
 
@@ -176,10 +169,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(LPDIRECT3DDEVICE9EX iface, D3DQU
 
     object->lpVtbl = &Direct3DQuery9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DQuery9_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, &object->wineD3DQuery, (IUnknown *)object);
     hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, &object->wineD3DQuery, (IUnknown *)object);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (FAILED(hr)) {
 
 
     if (FAILED(hr)) {
 
index 29ff5b3..d17233f 100644 (file)
@@ -57,10 +57,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -74,27 +73,25 @@ static HRESULT WINAPI IDirect3DStateBlock9Impl_GetDevice(LPDIRECT3DSTATEBLOCK9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     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); 
 
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -103,10 +100,9 @@ static HRESULT WINAPI IDirect3DStateBlock9Impl_Apply(LPDIRECT3DSTATEBLOCK9 iface
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
     hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -129,7 +125,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 &&
@@ -137,16 +133,15 @@ 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;
-
-   wined3d_mutex_lock();
+   
+   EnterCriticalSection(&d3d9_cs);
    hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown*)object);
    hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown*)object);
-   wined3d_mutex_unlock();
-
+   LeaveCriticalSection(&d3d9_cs);
    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);
@@ -160,41 +155,37 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(LPDIRECT3DDEVICE9EX iface,
    return hrc;
 }
 
    return hrc;
 }
 
-HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+HRESULT  WINAPI  IDirect3DDevice9Impl_BeginStateBlock(LPDIRECT3DDEVICE9EX iface) {
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;    
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
     hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
-HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **ppSB)
-{
-    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    IWineD3DStateBlock *wineD3DStateBlock;
-    IDirect3DStateBlock9Impl *object;
+HRESULT  WINAPI  IDirect3DDevice9Impl_EndStateBlock(LPDIRECT3DDEVICE9EX iface, IDirect3DStateBlock9** ppSB) {
+    IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;   
     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) */
-    wined3d_mutex_lock();
+     * of memory later and cause locking problems)
+     */
+    EnterCriticalSection(&d3d9_cs);
     hr=IWineD3DDevice_EndStateBlock(This->WineD3DDevice,&wineD3DStateBlock);
     hr=IWineD3DDevice_EndStateBlock(This->WineD3DDevice,&wineD3DStateBlock);
-    wined3d_mutex_unlock();
-
-    if (hr!= D3D_OK)
-    {
+    LeaveCriticalSection(&d3d9_cs);
+    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 b4defaf..f95c387 100644 (file)
@@ -78,10 +78,9 @@ 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) {
-                wined3d_mutex_lock();
+                EnterCriticalSection(&d3d9_cs);
                 IWineD3DSurface_Release(This->wineD3DSurface);
                 IWineD3DSurface_Release(This->wineD3DSurface);
-                wined3d_mutex_unlock();
-
+                LeaveCriticalSection(&d3d9_cs);
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
                 HeapFree(GetProcessHeap(), 0, This);
             }
         }
@@ -97,15 +96,14 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDevice(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -114,10 +112,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_SetPrivateData(LPDIRECT3DSURFACE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -126,10 +123,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetPrivateData(LPDIRECT3DSURFACE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
     hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -138,10 +134,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_FreePrivateData(LPDIRECT3DSURFACE9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
     hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -150,10 +145,9 @@ static DWORD WINAPI IDirect3DSurface9Impl_SetPriority(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_SetPriority(This->wineD3DSurface, PriorityNew);
     hr = IWineD3DSurface_SetPriority(This->wineD3DSurface, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -162,10 +156,9 @@ static DWORD WINAPI IDirect3DSurface9Impl_GetPriority(LPDIRECT3DSURFACE9 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_GetPriority(This->wineD3DSurface);
     hr = IWineD3DSurface_GetPriority(This->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -173,9 +166,10 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DSurface_PreLoad(This->wineD3DSurface);
     IWineD3DSurface_PreLoad(This->wineD3DSurface);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
+    return ;
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 iface) {
@@ -183,10 +177,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 i
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DRESOURCETYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DSurface_GetType(This->wineD3DSurface);
     ret = IWineD3DSurface_GetType(This->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -212,25 +205,28 @@ 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;
+    WINED3DSURFACE_DESC    wined3ddesc;
+    UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
 
     return hr;
 }
 
     return hr;
 }
@@ -240,11 +236,10 @@ static HRESULT WINAPI IDirect3DSurface9Impl_LockRect(LPDIRECT3DSURFACE9 iface, D
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -253,10 +248,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_UnlockRect(LPDIRECT3DSURFACE9 iface)
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
     hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
     switch(hr)
     {
         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
@@ -269,10 +263,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDC(LPDIRECT3DSURFACE9 iface, HDC*
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_GetDC(This->wineD3DSurface, phdc);
     hr = IWineD3DSurface_GetDC(This->wineD3DSurface, phdc);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -281,10 +274,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_ReleaseDC(LPDIRECT3DSURFACE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_ReleaseDC(This->wineD3DSurface, hdc);
     hr = IWineD3DSurface_ReleaseDC(This->wineD3DSurface, hdc);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     switch(hr) {
         case WINEDDERR_NODC:    return WINED3DERR_INVALIDCALL;
         default:                return hr;
     switch(hr) {
         case WINEDDERR_NODC:    return WINED3DERR_INVALIDCALL;
         default:                return hr;
index fb66807..4f639b1 100644 (file)
@@ -62,10 +62,9 @@ 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) {
-            wined3d_mutex_lock();
+            EnterCriticalSection(&d3d9_cs);
             IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D9CB_DestroyRenderTarget);
             IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D9CB_DestroyRenderTarget);
-            wined3d_mutex_unlock();
-
+            LeaveCriticalSection(&d3d9_cs);
             HeapFree(GetProcessHeap(), 0, This);
         }
     }
             HeapFree(GetProcessHeap(), 0, This);
         }
     }
@@ -79,9 +78,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
     hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -91,10 +90,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPC
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain,  ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
     hr = IWineD3DSwapChain_GetFrontBufferData(This->wineD3DSwapChain,  ((IDirect3DSurface9Impl *)pDestSurface)->wineD3DSurface);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -105,14 +103,13 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */
     return hrc;
 }
     /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */
     return hrc;
 }
@@ -122,10 +119,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetRasterStatus(LPDIRECT3DSWAPCHAI
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
     hr = IWineD3DSwapChain_GetRasterStatus(This->wineD3DSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -134,9 +130,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, (WINED3DDISPLAYMODE *) pMode);
     hr = IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, (WINED3DDISPLAYMODE *) pMode);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
 
     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
 
@@ -150,14 +146,13 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetDevice(LPDIRECT3DSWAPCHAIN9 ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -168,9 +163,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWA
 
     TRACE("(%p)->(%p): Relay\n", This, pPresentationParameters);
 
 
     TRACE("(%p)->(%p): Relay\n", This, pPresentationParameters);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, &winePresentParameters);
     hr = IWineD3DSwapChain_GetPresentParameters(This->wineD3DSwapChain, &winePresentParameters);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     pPresentationParameters->BackBufferWidth            = winePresentParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = winePresentParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth            = winePresentParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = winePresentParameters.BackBufferHeight;
@@ -245,10 +240,10 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
     localParameters.AutoRestoreDisplayMode              = TRUE;
 
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
     localParameters.AutoRestoreDisplayMode              = TRUE;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown*)object, SURFACE_OPENGL);
     hrc = IWineD3DDevice_CreateSwapChain(This->WineD3DDevice, &localParameters,
             &object->wineD3DSwapChain, (IUnknown*)object, SURFACE_OPENGL);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
@@ -285,7 +280,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UI
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -293,8 +288,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UI
     } else {
         *pSwapChain = NULL;
     }
     } else {
         *pSwapChain = NULL;
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -303,9 +297,8 @@ UINT     WINAPI  IDirect3DDevice9Impl_GetNumberOfSwapChains(LPDIRECT3DDEVICE9EX
     UINT ret;
     TRACE("(%p) Relay\n", This);
 
     UINT ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
     ret = IWineD3DDevice_GetNumberOfSwapChains(This->WineD3DDevice);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
     return ret;
 }
index 7db7037..f0a9c38 100644 (file)
@@ -59,10 +59,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
         IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -76,15 +75,14 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetDevice(LPDIRECT3DTEXTURE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -93,10 +91,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_SetPrivateData(LPDIRECT3DTEXTURE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -105,10 +102,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetPrivateData(LPDIRECT3DTEXTURE9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
     hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -117,10 +113,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_FreePrivateData(LPDIRECT3DTEXTURE9 i
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
     hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -129,10 +124,9 @@ static DWORD WINAPI IDirect3DTexture9Impl_SetPriority(LPDIRECT3DTEXTURE9 iface,
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
     ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -141,10 +135,9 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetPriority(LPDIRECT3DTEXTURE9 iface)
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
     ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -152,9 +145,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
     IWineD3DTexture_PreLoad(This->wineD3DTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 iface) {
@@ -162,10 +155,9 @@ static D3DRESOURCETYPE WINAPI IDirect3DTexture9Impl_GetType(LPDIRECT3DTEXTURE9 i
     HRESULT ret;
     TRACE("(%p) Relay\n", This);
 
     HRESULT ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_GetType(This->wineD3DTexture);
     ret = IWineD3DTexture_GetType(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -175,10 +167,9 @@ static DWORD WINAPI IDirect3DTexture9Impl_SetLOD(LPDIRECT3DTEXTURE9 iface, DWORD
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
     ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -187,10 +178,9 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetLOD(LPDIRECT3DTEXTURE9 iface) {
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -199,10 +189,9 @@ static DWORD WINAPI IDirect3DTexture9Impl_GetLevelCount(LPDIRECT3DTEXTURE9 iface
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
     DWORD ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
     ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -211,10 +200,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_SetAutoGenFilterType(LPDIRECT3DTEXTU
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_SetAutoGenFilterType(This->wineD3DTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
     hr = IWineD3DTexture_SetAutoGenFilterType(This->wineD3DTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -223,10 +211,9 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DTexture9Impl_GetAutoGenFilterType(LP
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
     D3DTEXTUREFILTERTYPE ret;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DTexture_GetAutoGenFilterType(This->wineD3DTexture);
     ret = (D3DTEXTUREFILTERTYPE) IWineD3DTexture_GetAutoGenFilterType(This->wineD3DTexture);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
 
     return ret;
 }
 
@@ -234,34 +221,38 @@ static void WINAPI IDirect3DTexture9Impl_GenerateMipSubLevels(LPDIRECT3DTEXTURE9
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DTexture_GenerateMipSubLevels(This->wineD3DTexture);
     IWineD3DTexture_GenerateMipSubLevels(This->wineD3DTexture);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 /* 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;
-    HRESULT hr;
+
+    WINED3DSURFACE_DESC    wined3ddesc;
+    UINT                   tmpInt = -1;
+    HRESULT                hr;
+    WINED3DFORMAT format;
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    /* 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);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
 
     return hr;
 }
 
     return hr;
 }
@@ -272,15 +263,13 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE9 i
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
     IWineD3DSurface *mySurface = NULL;
 
     TRACE("(%p) Relay\n", This);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hrc;
 }
 
     return hrc;
 }
 
@@ -289,10 +278,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_LockRect(LPDIRECT3DTEXTURE9 iface, U
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
     hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -301,10 +289,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_UnlockRect(LPDIRECT3DTEXTURE9 iface,
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
     hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -313,10 +300,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_AddDirtyRect(LPDIRECT3DTEXTURE9 ifac
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
     hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -357,7 +343,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 */
@@ -370,14 +356,12 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
 
     object->lpVtbl = &Direct3DTexture9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DTexture9_Vtbl;
     object->ref = 1;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
+    if (FAILED(hrc)) {
 
 
-    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 226e113..501db41 100644 (file)
@@ -58,10 +58,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -75,15 +74,14 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDevice(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -93,9 +91,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEX
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -105,10 +103,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEX
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -117,10 +114,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_FreePrivateData(LPDIRECT3DVERTE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -129,10 +125,9 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -141,10 +136,9 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -152,9 +146,10 @@ 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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
+    return ;
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
@@ -170,10 +165,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Lock(LPDIRECT3DVERTEXBUFFER9 if
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -182,10 +176,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -195,9 +188,9 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = D3DFMT_VERTEXDATA;
 
     if (SUCCEEDED(hr)) {
         pDesc->Format = D3DFMT_VERTEXDATA;
@@ -235,9 +228,10 @@ static const IDirect3DVertexBuffer9Vtbl Direct3DVertexBuffer9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DVertexBuffer9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DVertexBuffer9 Methods follow: */
-HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT Size, DWORD Usage,
-        DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle)
-{
+HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX 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;
@@ -252,12 +246,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface
     object->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
     object->ref = 1;
     object->fvf = FVF;
     object->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
     object->ref = 1;
     object->fvf = FVF;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
+    
     if (hrc != D3D_OK) {
 
         /* free up object */
     if (hrc != D3D_OK) {
 
         /* free up object */
index 4ae4751..38f0751 100644 (file)
@@ -87,7 +87,8 @@ 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;
@@ -229,11 +230,9 @@ 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");
     }
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration);
     IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     HeapFree(GetProcessHeap(), 0, This->elements);
     HeapFree(GetProcessHeap(), 0, This);
 }
     HeapFree(GetProcessHeap(), 0, This->elements);
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -263,14 +262,13 @@ static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDevice(LPDIRECT3DVERTEX
 
     TRACE("(%p) : Relay\n", iface);
 
 
     TRACE("(%p) : Relay\n", iface);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -350,9 +348,8 @@ static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elem
 }
 
 /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */
 }
 
 /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */
-HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
-        const D3DVERTEXELEMENT9 *pVertexElements, IDirect3DVertexDeclaration9 **ppDecl)
-{
+HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9EX 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;
@@ -395,10 +392,10 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *
     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;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
 
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
 
@@ -424,10 +421,9 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_SetVertexDeclaration(LPDIRECT3DDEVICE9EX i
 
     TRACE("(%p) : Relay\n", iface);
 
 
     TRACE("(%p) : Relay\n", iface);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration);
     hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -443,8 +439,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetVertexDeclaration(LPDIRECT3DDEVICE9EX i
     }
 
     *ppDecl = NULL;
     }
 
     *ppDecl = NULL;
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -452,8 +447,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_GetVertexDeclaration(LPDIRECT3DDEVICE9EX i
     } else {
         *ppDecl = NULL;
     }
     } else {
         *ppDecl = NULL;
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     TRACE("(%p) : returning %p\n", This, *ppDecl);
     return hr;
 }
     TRACE("(%p) : returning %p\n", This, *ppDecl);
     return hr;
 }
index 8a5d5bc..fd2837d 100644 (file)
@@ -56,10 +56,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DVertexShader_Release(This->wineD3DVertexShader);
         IWineD3DVertexShader_Release(This->wineD3DVertexShader);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -73,7 +72,7 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetDevice(LPDIRECT3DVERTEXSHADE
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
@@ -81,8 +80,7 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetDevice(LPDIRECT3DVERTEXSHADE
     } else {
         *ppDevice = NULL;
     }
     } else {
         *ppDevice = NULL;
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return hr;
 }
     TRACE("(%p) returning (%p)\n", This, *ppDevice);
     return hr;
 }
@@ -92,10 +90,9 @@ static HRESULT WINAPI IDirect3DVertexShader9Impl_GetFunction(LPDIRECT3DVERTEXSHA
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData);
     hr = IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -128,11 +125,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(LPDIRECT3DDEVICE9EX iface
 
     object->ref = 1;
     object->lpVtbl = &Direct3DVertexShader9_Vtbl;
 
     object->ref = 1;
     object->lpVtbl = &Direct3DVertexShader9_Vtbl;
-
-    wined3d_mutex_lock();
-    hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pFunction,
-            NULL /* output signature */, &object->wineD3DVertexShader, (IUnknown *)object);
-    wined3d_mutex_unlock();
+    EnterCriticalSection(&d3d9_cs);
+    hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, NULL /* declaration */, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
+    LeaveCriticalSection(&d3d9_cs);
 
     if (FAILED(hrc)) {
 
 
     if (FAILED(hrc)) {
 
@@ -155,10 +150,9 @@ 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);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, pShader==NULL?NULL:((IDirect3DVertexShader9Impl *)pShader)->wineD3DVertexShader);
     hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, pShader==NULL?NULL:((IDirect3DVertexShader9Impl *)pShader)->wineD3DVertexShader);
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
     return hrc;
 
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
     return hrc;
@@ -170,8 +164,7 @@ 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);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
     if (SUCCEEDED(hrc))
     {
     hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
     if (SUCCEEDED(hrc))
     {
@@ -189,8 +182,7 @@ 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);
     }
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 }
     TRACE("(%p) : returning %p\n", This, *ppShader);
     return hrc;
 }
@@ -206,10 +198,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
         return D3DERR_INVALIDCALL;
     }
 
         return D3DERR_INVALIDCALL;
     }
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -224,11 +215,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     }
 
     TRACE("(%p) : Relay\n", This);
     }
 
     TRACE("(%p) : Relay\n", This);
-
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -237,10 +226,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_SetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -249,10 +237,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantI(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
     hr = IWineD3DDevice_GetVertexShaderConstantI(This->WineD3DDevice, Register, pConstantData, Vector4iCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -261,10 +248,9 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_SetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
     return hr;
 }
 
@@ -273,9 +259,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantB(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
     hr = IWineD3DDevice_GetVertexShaderConstantB(This->WineD3DDevice, Register, pConstantData, BoolCount);
-    wined3d_mutex_unlock();
-
+    LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
     return hr;
 }
index 9f1252a..93b06b5 100644 (file)
@@ -72,10 +72,9 @@ 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) {
-            wined3d_mutex_lock();
+            EnterCriticalSection(&d3d9_cs);
             IWineD3DVolume_Release(This->wineD3DVolume);
             IWineD3DVolume_Release(This->wineD3DVolume);
-            wined3d_mutex_unlock();
-
+            LeaveCriticalSection(&d3d9_cs);
             HeapFree(GetProcessHeap(), 0, This);
         }
 
             HeapFree(GetProcessHeap(), 0, This);
         }
 
@@ -90,13 +89,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     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);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return D3D_OK;
 }
 
     return D3D_OK;
 }
@@ -107,11 +106,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_SetPrivateData(LPDIRECT3DVOLUME9 ifac
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
 
 
     hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -122,11 +121,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetPrivateData(LPDIRECT3DVOLUME9 ifac
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
 
 
     hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -137,11 +136,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_FreePrivateData(LPDIRECT3DVOLUME9 ifa
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
 
 
     hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -168,26 +167,29 @@ 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);
 
-    wined3d_mutex_lock();
+    /* 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);
 
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
 
 
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
 
-    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;
-    }
+    LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
 
     return hr;
 }
 
     return hr;
 }
@@ -198,12 +200,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
 
     hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
             (const WINED3DBOX *)pBox, Flags);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -214,11 +216,11 @@ static HRESULT WINAPI IDirect3DVolume9Impl_UnlockBox(LPDIRECT3DVOLUME9 iface) {
 
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
 
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
 
 
     hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
index 31b90bc..07b686f 100644 (file)
@@ -58,10 +58,9 @@ 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) {
-        wined3d_mutex_lock();
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
-        wined3d_mutex_unlock();
-
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -76,14 +75,14 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetDevice(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
     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);
     }
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -94,11 +93,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetPrivateData(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
 
 
     hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -109,11 +108,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetPrivateData(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
 
 
     hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -124,11 +123,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_FreePrivateData(LPDIRECT3DVOLU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
 
 
     hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -139,11 +138,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetPriority(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     priority = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
 
 
     priority = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return priority;
 }
 
     return priority;
 }
@@ -154,11 +153,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetPriority(LPDIRECT3DVOLUMETEXT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     priority = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
 
 
     priority = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return priority;
 }
 
     return priority;
 }
@@ -168,11 +167,11 @@ static void WINAPI IDirect3DVolumeTexture9Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
 
 
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
@@ -181,11 +180,11 @@ static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLU
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
 
 
     type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return type;
 }
 
     return type;
 }
@@ -197,11 +196,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     lod = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
 
 
     lod = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return lod;
 }
 
     return lod;
 }
@@ -212,11 +211,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE9
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     lod = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
 
 
     lod = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return lod;
 }
 
     return lod;
 }
@@ -227,11 +226,11 @@ static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLevelCount(LPDIRECT3DVOLUMETE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     level_count = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
 
 
     level_count = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return level_count;
 }
 
     return level_count;
 }
@@ -242,11 +241,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetAutoGenFilterType(LPDIRECT3
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
 
 
     hr = IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -257,11 +256,11 @@ static D3DTEXTUREFILTERTYPE WINAPI IDirect3DVolumeTexture9Impl_GetAutoGenFilterT
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     filter_type = (D3DTEXTUREFILTERTYPE)IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
 
 
     filter_type = (D3DTEXTUREFILTERTYPE)IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return filter_type;
 }
 
     return filter_type;
 }
@@ -271,37 +270,40 @@ static void WINAPI IDirect3DVolumeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DVO
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     IWineD3DVolumeTexture_GenerateMipSubLevels(This->wineD3DVolumeTexture);
 
 
     IWineD3DVolumeTexture_GenerateMipSubLevels(This->wineD3DVolumeTexture);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 /* 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);
 
-    wined3d_mutex_lock();
+    /* 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);
 
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
 
 
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
 
-    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;
-    }
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
 
     return hr;
 }
 
     return hr;
 }
@@ -313,7 +315,7 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     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) {
@@ -321,7 +323,7 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUM
        IWineD3DVolumeTexture_Release(myVolume);
     }
 
        IWineD3DVolumeTexture_Release(myVolume);
     }
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hrc;
 }
 
     return hrc;
 }
@@ -332,12 +334,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     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);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -348,11 +350,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);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
 
 
     hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -363,11 +365,11 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_AddDirtyBox(LPDIRECT3DVOLUMETE
 
     TRACE("(%p) Relay\n", This);
 
 
     TRACE("(%p) Relay\n", This);
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
 
 
     hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     return hr;
 }
 
     return hr;
 }
@@ -405,10 +407,11 @@ static const IDirect3DVolumeTexture9Vtbl Direct3DVolumeTexture9_Vtbl =
 
 
 /* IDirect3DDevice9 IDirect3DVolumeTexture9 Methods follow: */
 
 
 /* IDirect3DDevice9 IDirect3DVolumeTexture9 Methods follow: */
-HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
-        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format,
-        D3DPOOL Pool, IDirect3DVolumeTexture9 **ppVolumeTexture, HANDLE *pSharedHandle)
-{
+HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX 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;
@@ -425,13 +428,13 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *if
     object->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
     object->ref = 1;
 
     object->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
     object->ref = 1;
 
-    wined3d_mutex_lock();
+    EnterCriticalSection(&d3d9_cs);
 
     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);
 
-    wined3d_mutex_unlock();
+    LeaveCriticalSection(&d3d9_cs);
 
     if (hrc != D3D_OK) {
 
 
     if (hrc != D3D_OK) {
 
index dd35113..56ee162 100644 (file)
@@ -41,242 +41,48 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION      (*gl_info)
 
 
 #define GLINFO_LOCATION      (*gl_info)
 
-/* 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);
-}
-
-/* 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;
-}
+/* 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
 
 
-static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock)
-{
-    return stateblock->lowest_disabled_stage < 7;
-}
+/* 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
 
 /* 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) - 1)
+#define ARB_SHADER_PRIVCONST_BASE (GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS)
 #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 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
-{
+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 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;
+    struct hash_table_t     *fragment_shaders;
 };
 
 /********************************************************
  * 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)
  */
-/* GL locking is done by the caller */
-static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
+static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
     local_constant* lconst;
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
     local_constant* lconst;
-    DWORD i = 0, j;
+    DWORD i, j;
     unsigned int ret;
 
     if (TRACE_ON(d3d_shader)) {
     unsigned int ret;
 
     if (TRACE_ON(d3d_shader)) {
@@ -291,65 +97,54 @@ 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];
-        /* 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++) {
+        for(i = 0; i < 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.0f) lcl_const[0] = 1.0f;
-            else if (constants[j + 0] < -1.0f) lcl_const[0] = -1.0f;
+            if(constants[j + 0] > 1.0) lcl_const[0] = 1.0;
+            else if(constants[j + 0] < -1.0) lcl_const[0] = -1.0;
             else lcl_const[0] = constants[j + 0];
 
             else lcl_const[0] = constants[j + 0];
 
-            if (constants[j + 1] > 1.0f) lcl_const[1] = 1.0f;
-            else if (constants[j + 1] < -1.0f) lcl_const[1] = -1.0f;
+            if(constants[j + 1] > 1.0) lcl_const[1] = 1.0;
+            else if(constants[j + 1] < -1.0) lcl_const[1] = -1.0;
             else lcl_const[1] = constants[j + 1];
 
             else lcl_const[1] = constants[j + 1];
 
-            if (constants[j + 2] > 1.0f) lcl_const[2] = 1.0f;
-            else if (constants[j + 2] < -1.0f) lcl_const[2] = -1.0f;
+            if(constants[j + 2] > 1.0) lcl_const[2] = 1.0;
+            else if(constants[j + 2] < -1.0) lcl_const[2] = -1.0;
             else lcl_const[2] = constants[j + 2];
 
             else lcl_const[2] = constants[j + 2];
 
-            if (constants[j + 3] > 1.0f) lcl_const[3] = 1.0f;
-            else if (constants[j + 3] < -1.0f) lcl_const[3] = -1.0f;
+            if(constants[j + 3] > 1.0) lcl_const[3] = 1.0;
+            else if(constants[j + 3] < -1.0) lcl_const[3] = -1.0;
             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;
 
 
-        /* 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
-         */
-    }
-
-    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++) {
+                /* Find the next block of dirty constants */
                 dirty_consts[i] = 0;
                 dirty_consts[i] = 0;
-            }
+                j = i;
+                for(i++; (i < max_constants) && dirty_consts[i]; i++) {
+                    dirty_consts[i] = 0;
+                }
 
 
-            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)));
+                GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, constants + (j * 4)));
+            }
+        } 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)));
+                }
             }
         }
     }
             }
         }
     }
@@ -385,203 +180,93 @@ static void shader_arb_load_np2fixup_constants(
     IWineD3DDevice* device,
     char usePixelShader,
     char useVertexShader) {
     IWineD3DDevice* device,
     char usePixelShader,
     char useVertexShader) {
-
-    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");
+    /* not implemented */
 }
 
 /**
  * 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
  */
-/* 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;
+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;
 
     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 */
-        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);
+        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));
     }
 
     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 */
-        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);
+        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;
+            }
+        }
     }
 }
 
 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 */
-    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);
+    memset(This->activeContext->vshader_const_dirty + start, 1,
+            sizeof(*This->activeContext->vshader_const_dirty) * count);
+    This->highest_dirty_vs_const = max(This->highest_dirty_vs_const, start + count + 1);
 }
 
 static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 }
 
 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 */
-    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);
+    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);
 }
 
 static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
 }
 
 static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
@@ -592,7 +277,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.constant_float);
+    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.temporary);
     if(!ret) {
         ERR("Out of memory\n");
         return NULL;
     if(!ret) {
         ERR("Out of memory\n");
         return NULL;
@@ -605,75 +290,83 @@ 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 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)
+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)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
-    DWORD i, next_local = 0;
+    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
+    DWORD i, cur;
     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;
+    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;
     const local_constant *lconst;
     const local_constant *lconst;
-    DWORD map;
 
 
-    /* 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);
+    /* Temporary Output register */
+    shader_addline(buffer, "TEMP TMP_OUT;\n");
 
 
-            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.temporary; i++) {
+        if (reg_maps->temporary[i])
+            shader_addline(buffer, "TEMP R%u;\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.address; i++) {
+        if (reg_maps->address[i])
+            shader_addline(buffer, "ADDRESS A%d;\n", i);
     }
 
     }
 
-    for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
-    {
-        if (map & 1) shader_addline(buffer, "TEMP R%u;\n", i);
+    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->address; map; map >>= 1, ++i)
-    {
-        if (map & 1) shader_addline(buffer, "ADDRESS A%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);
     }
 
     }
 
-    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);
+    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");
         }
         }
+
+        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,
@@ -683,7 +376,6 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s
         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);
         }
     }
 
         }
     }
 
@@ -707,8 +399,6 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShader *iface, const s
             }
         }
     }
             }
         }
     }
-
-    return next_local;
 }
 
 static const char * const shift_tab[] = {
 }
 
 static const char * const shift_tab[] = {
@@ -734,8 +424,14 @@ 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 (dst->write_mask != WINED3DSP_WRITEMASK_ALL)
+    if (vshader && dst->reg.type == WINED3DSPR_ADDR)
+    {
+        *ptr++ = '.';
+        *ptr++ = 'x';
+    }
+    else 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';
@@ -780,207 +476,73 @@ static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param,
     *ptr = '\0';
 }
 
     *ptr = '\0';
 }
 
-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)
+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)
 {
     /* 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 *)ins->ctx->shader;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
     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 (reg->type)
+    switch (register_type)
     {
         case WINED3DSPR_TEMP:
     {
         case WINED3DSPR_TEMP:
-            sprintf(register_name, "R%u", reg->idx);
+            sprintf(register_name, "R%u", register_idx);
             break;
 
         case WINED3DSPR_INPUT:
             if (pshader)
             {
             break;
 
         case WINED3DSPR_INPUT:
             if (pshader)
             {
-                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);
-                        }
-                    }
-                }
+                if (register_idx == 0) strcpy(register_name, "fragment.color.primary");
+                else strcpy(register_name, "fragment.color.secondary");
             }
             else
             {
             }
             else
             {
-                if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx)) *is_color = TRUE;
-                sprintf(register_name, "vertex.attrib[%u]", reg->idx);
+                if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
+                sprintf(register_name, "vertex.attrib[%u]", register_idx);
             }
             break;
 
         case WINED3DSPR_CONST:
             }
             break;
 
         case WINED3DSPR_CONST:
-            if (!pshader && reg->rel_addr)
+            if (!pshader && rel_addr)
             {
             {
-                BOOL aL = FALSE;
-                char rel_reg[50];
                 UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset;
                 UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->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);
+                if (register_idx >= rel_offset)
+                    sprintf(register_name, "C[A0.x + %u]", register_idx - rel_offset);
                 else
                 else
-                    sprintf(register_name, "C[%s - %u]", rel_reg, -reg->idx + rel_offset);
+                    sprintf(register_name, "C[A0.x - %u]", -register_idx + rel_offset);
             }
             else
             {
                 if (This->baseShader.reg_maps.usesrelconstF)
             }
             else
             {
                 if (This->baseShader.reg_maps.usesrelconstF)
-                    sprintf(register_name, "C[%u]", reg->idx);
+                    sprintf(register_name, "C[%u]", register_idx);
                 else
                 else
-                    sprintf(register_name, "C%u", reg->idx);
+                    sprintf(register_name, "C%u", register_idx);
             }
             break;
 
         case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
             }
             break;
 
         case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
-            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);
-                }
-            }
+            if (pshader) sprintf(register_name, "T%u", register_idx);
+            else  sprintf(register_name, "A%u", register_idx);
             break;
 
         case WINED3DSPR_COLOROUT:
             break;
 
         case WINED3DSPR_COLOROUT:
-            if(ctx->cur_ps_args->super.srgb_correction && reg->idx == 0)
+            if (register_idx == 0)
             {
                 strcpy(register_name, "TMP_COLOR");
             }
             else
             {
             {
                 strcpy(register_name, "TMP_COLOR");
             }
             else
             {
-                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");
-                }
+                /* TODO: See GL_ARB_draw_buffers */
+                FIXME("Unsupported write to render target %u\n", register_idx);
+                sprintf(register_name, "unsupported_register");
             }
             break;
 
         case WINED3DSPR_RASTOUT:
             }
             break;
 
         case WINED3DSPR_RASTOUT:
-            if(reg->idx == 1) sprintf(register_name, "%s", ctx->fog_output);
-            else sprintf(register_name, "%s", rastout_reg_names[reg->idx]);
+            sprintf(register_name, "%s", rastout_reg_names[register_idx]);
             break;
 
         case WINED3DSPR_DEPTHOUT:
             break;
 
         case WINED3DSPR_DEPTHOUT:
@@ -988,71 +550,19 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
             break;
 
         case WINED3DSPR_ATTROUT:
             break;
 
         case WINED3DSPR_ATTROUT:
-        /* case WINED3DSPR_OUTPUT: */
-            if (pshader) sprintf(register_name, "oD[%u]", reg->idx);
-            else strcpy(register_name, ctx->color_output[reg->idx]);
+            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");
             break;
 
         case WINED3DSPR_TEXCRDOUT:
             break;
 
         case WINED3DSPR_TEXCRDOUT:
-            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);
-            }
+            if (pshader) sprintf(register_name, "oT[%u]", register_idx);
+            else sprintf(register_name, "result.texcoord[%u]", register_idx);
             break;
 
         default:
             break;
 
         default:
-            FIXME("Unhandled register type %#x[%u]\n", reg->type, reg->idx);
-            sprintf(register_name, "unrecognized_register[%u]", reg->idx);
+            FIXME("Unhandled register type %#x[%u]\n", register_type, register_idx);
+            sprintf(register_name, "unrecognized_register[%u]", register_idx);
             break;
     }
 }
             break;
     }
 }
@@ -1064,7 +574,8 @@ 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, &wined3d_dst->reg, register_name, &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);
     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);
@@ -1087,8 +598,8 @@ static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channe
     }
 }
 
     }
 }
 
-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)
+static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, DWORD dst_mask,
+                                 const char *one, const char *two, struct color_fixup_desc fixup)
 {
     DWORD mask;
 
 {
     DWORD mask;
 
@@ -1139,68 +650,19 @@ static void gen_color_correction(struct wined3d_shader_buffer *buffer, const cha
     }
 }
 
     }
 }
 
-static const char *shader_arb_get_modifier(const struct wined3d_shader_instruction *ins)
+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)
 {
 {
-    DWORD mod;
-    struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
-    if (!ins->dst_count) return "";
-
-    mod = ins->dst[0].modifiers;
+    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;
 
 
-    /* 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;
+    switch(sampler_type) {
+        case WINED3DSTT_1D:
+            tex_type = "1D";
+            break;
 
         case WINED3DSTT_2D:
             if(device->stateBlock->textures[sampler_idx] &&
 
         case WINED3DSTT_2D:
             if(device->stateBlock->textures[sampler_idx] &&
@@ -1211,11 +673,10 @@ 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))
             {
-                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;
-                }
+               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");
+               }
             }
             break;
 
             }
             break;
 
@@ -1232,61 +693,22 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             tex_type = "";
     }
 
             tex_type = "";
     }
 
-    /* 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)
-    {
+    if (bias) {
         /* Shouldn't be possible, but let's check for it */
         /* Shouldn't be possible, but let's check for it */
-        if(flags & TEX_PROJ) FIXME("Biased and Projected texture sampling\n");
+        if(projected) 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, %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);
+        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);
     }
 
     }
 
-    if (pshader)
+    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
     {
+        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", priv->cur_ps_args->super.color_fixup[sampler_idx]);
+                "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
     }
 }
 
     }
 }
 
@@ -1298,14 +720,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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
 
     /* 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, &src->reg, regstr, &is_color);
+    shader_arb_get_register_name(ins->ctx->shader, src->reg.type,
+            src->reg.idx, !!src->reg.rel_addr, 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)
@@ -1347,23 +769,6 @@ 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;
@@ -1376,116 +781,106 @@ 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
 
 
-    shader_arb_get_dst_param(ins, dst, dst_name);
+    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;
+        }
+    }
 
 
-    /* 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_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]);
+    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_src_param(ins, &ins->src[0], 0, src_name[0]);
 
     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_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
 
 
-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;
+    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_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]);
     }
     }
-    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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_wmask[20];
     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;
 
 
-    shader_arb_get_dst_param(ins, dst, dst_name);
+    /* 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_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;\n", shader_arb_get_modifier(ins), dst_name, src_name[1]);
+        shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
     } else {
     } else {
-        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);
-        }
+        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]);
     }
 }
 
 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_wmask[20];
     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;
 
-    shader_arb_get_dst_param(ins, dst, dst_name);
+    /* 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_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]);
 
-    /* No modifiers are supported on CMP */
-    shader_addline(buffer, "CMP %s, %s, %s, %s;\n", dst_name,
+    shader_addline(buffer, "CMP%s %s%s, %s, %s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
                    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.
@@ -1493,64 +888,37 @@ 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
     char dst_name[50];
     char src_name[3][50];
-    struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+    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);
 
 
-    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]);
 
-    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]);
-    }
+    /* 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]);
 }
 
 /* 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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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)
     {
@@ -1560,25 +928,31 @@ 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);
@@ -1589,67 +963,36 @@ 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, shader_arb_get_modifier(ins), dst_str, arguments);
+    shader_addline(buffer, "%s%s %s%s;\n", instruction, modifier, 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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
-
-    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->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];
 
 
-        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);
+        if (ins->handler_idx == WINED3DSIH_MOVA)
+            FIXME("mova should round\n");
 
 
-        ((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 TA.x, %s, helper_const.z;\n", src0_param);
-            shader_addline(buffer, "ARL A0.x, TA.x;\n");
+            shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
+            shader_addline(buffer, "ARL A0.x, TMP.x;\n");
         }
         else
         {
         }
         else
         {
@@ -1662,16 +1005,6 @@ 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);
@@ -1681,7 +1014,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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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,
@@ -1691,42 +1024,14 @@ 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)
     {
-        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);
+        /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
+        shader_addline(buffer, "KIL %s;\n", reg_dest);
     } else {
         /* 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)
          */
          */
-        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");
+        shader_addline(buffer, "SWZ TMP, %s, x, y, z, 1;\n", reg_dest);
+        shader_addline(buffer, "KIL TMP;\n");
     }
 }
 
     }
 }
 
@@ -1735,213 +1040,217 @@ 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);
-    struct wined3d_shader_src_param src;
+    BOOL projected = FALSE, bias = FALSE;
 
     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_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;
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+            dst->reg.idx, !!dst->reg.rel_addr, reg_dest, &is_color);
 
 
-    /* 1.0-1.3: Use the texcoord varying.
+    /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
        1.4+: Use provided coordinate source register. */
-    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);
+   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);
 }
 
 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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];
 
 
-    if (shader_version < WINED3D_SHADER_VERSION(1,4))
+    char tmp[20];
+    shader_arb_get_write_mask(ins, dst, tmp);
+    if (shader_version != WINED3D_SHADER_VERSION(1,4))
     {
         DWORD reg = dst->reg.idx;
     {
         DWORD reg = dst->reg.idx;
-
-        shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
-        shader_addline(buffer, "MOV_SAT %s, fragment.texcoord[%u];\n", dst_str, reg);
+        shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, 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_arb_get_dst_param(ins, &ins->dst[0], dst_str);
-        shader_addline(buffer, "MOV %s, %s;\n", dst_str, reg_src);
+        shader_addline(buffer, "MOV R%u%s, %s;\n", dst->reg.idx, tmp, reg_src);
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
-     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+     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[50];
+     char dst_str[8];
      char src_str[50];
 
      char src_str[50];
 
-     /* Note that texreg2ar treats Tx as a temporary register, not as a varying */
-     shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+     sprintf(dst_str, "T%u", reg1);
      shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
      shader_arb_get_src_param(ins, &ins->src[0], 0, 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);
+     shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str);
+     shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str);
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
-     shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+     shader_hw_sample(ins, reg1, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
-     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+     SHADER_BUFFER *buffer = ins->ctx->buffer;
 
      DWORD reg1 = ins->dst[0].reg.idx;
 
      DWORD reg1 = ins->dst[0].reg.idx;
-     char dst_str[50];
+     char dst_str[8];
      char src_str[50];
 
      char src_str[50];
 
-     /* Note that texreg2gb treats Tx as a temporary register, not as a varying */
-     shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+     sprintf(dst_str, "T%u", reg1);
      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 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);
+     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);
 }
 
 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[50];
+    char dst_str[8];
     char src_str[50];
 
     char src_str[50];
 
-    /* Note that texreg2rg treats Tx as a temporary register, not as a varying */
-    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    sprintf(dst_str, "T%u", reg1);
     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, 0, NULL, NULL);
+    shader_hw_sample(ins, reg1, dst_str, src_str, FALSE, FALSE);
 }
 
 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    char reg_coord[40], dst_reg[50], src_reg[50];
+    BOOL has_bumpmat = FALSE;
+    BOOL has_luminance = FALSE;
+    BOOL is_color;
+    int i;
+
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+
+    char reg_coord[40];
     DWORD reg_dest_code;
 
     DWORD reg_dest_code;
 
-    /* All versions have a destination register. The Tx where the texture coordinates come
-     * from is the varying incarnation of the texture register
-     */
+    /* All versions have a destination register */
     reg_dest_code = dst->reg.idx;
     reg_dest_code = dst->reg.idx;
-    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);
-
-    /* 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);
+    /* 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);
 
 
-    /* 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);
+    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;
+        }
     }
 
     }
 
-    shader_hw_sample(ins, reg_dest_code, dst_reg, "TA", 0, NULL, NULL);
+    if(has_bumpmat) {
+        DWORD src = ins->src[0].reg.idx;
 
 
-    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);
+        /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
+
+        shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
+        shader_addline(buffer, "DP3 TMP.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);
+        }
+
+        shader_hw_sample(ins, reg_dest_code, reg_coord, "TMP", FALSE, FALSE);
+
+        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);
+        }
+
+    } 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);
     }
 }
 
 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;
-    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_BUFFER *buffer = ins->ctx->buffer;
+    char src0_name[50];
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, 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);
+    shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", 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)
@@ -1950,42 +1259,27 @@ 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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    char dst_str[50];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_str[8];
     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);
 
 
-    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    sprintf(dst_str, "T%u", 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 %s.y, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
+    shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", 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, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
 }
 
 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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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], 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);
+    char src0_name[50];
 
     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 %s.%c, fragment.texcoord[%u], %s;\n",
-                   dst_name, 'x' + current_state->current_row, reg, src0_name);
+    shader_addline(buffer, "DP3 TMP.%c, T%u, %s;\n", '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;
 }
 
@@ -1995,20 +1289,18 @@ 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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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[50];
-    char src0_name[50], dst_name[50];
-    BOOL is_color;
+    char dst_str[8];
+    char src0_name[50];
 
 
-    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 %s.z, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
+    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    sprintf(dst_str, "T%u", reg);
     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, dst_name, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
@@ -2018,39 +1310,33 @@ 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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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[50];
+    char dst_str[8];
     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 %s.z, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
+    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Construct the eye-ray vector from w coordinates */
 
     /* Construct the eye-ray vector from w coordinates */
-    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);
+    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);
 
     /* Calculate reflection vector
      */
 
     /* Calculate reflection vector
      */
-    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);
+    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");
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    sprintf(dst_str, "T%u", reg);
     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, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
 
@@ -2061,53 +1347,51 @@ 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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    char dst_str[50];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_str[8];
     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_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);
+    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Calculate reflection vector.
      *
 
     /* Calculate reflection vector.
      *
-     *                   dot(N, E)
-     * dst_reg.xyz = 2 * --------- * N - E
-     *                   dot(N, N)
+     *               dot(N, E)
+     * TMP.xyz = 2 * --------- * N - E
+     *               dot(N, N)
      *
      * Which normalizes the normal vector
      */
      *
      * Which normalizes the normal vector
      */
-    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);
+    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);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Sample the texture using the calculated coordinates */
-    shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+    sprintf(dst_str, "T%u", reg);
     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, dst_reg, flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+    shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
     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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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(writemasks/swizzles are not valid on texdepth)
+     * here
      */
      */
-    shader_arb_get_dst_param(ins, dst, dst_name);
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+            dst->reg.idx, !!dst->reg.rel_addr, dst_name, &is_color);
 
     /* 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
@@ -2119,9 +1403,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 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");
+    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");
 }
 
 /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
@@ -2129,17 +1413,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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[50];
+    char dst_str[8];
 
     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 TB, 0.0;\n");
-    shader_addline(buffer, "DP3 TB.x, fragment.texcoord[%u], %s;\n", sampler_idx, src0);
+    shader_addline(buffer, "MOV TMP, 0.0;\n");
+    shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0);
 
 
-    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);
+    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);
 }
 
 /** Process the WINED3DSIO_TEXDP3 instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXDP3 instruction in ARB:
@@ -2149,12 +1433,19 @@ 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    char dst_mask[6];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    BOOL is_color;
 
     /* Handle output register */
 
     /* Handle output register */
-    shader_arb_get_dst_param(ins, dst, dst_str);
+    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_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx, src0);
+    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->reg.idx, src0);
+
+    /* TODO: Handle output modifiers */
 }
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
 }
 
 /** Process the WINED3DSIO_TEXM3X3 instruction in ARB
@@ -2162,16 +1453,21 @@ 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    char dst_str[50], dst_name[50];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char dst_str[50];
+    char dst_mask[6];
     char src0[50];
     BOOL is_color;
 
     char src0[50];
     BOOL is_color;
 
-    shader_arb_get_dst_param(ins, dst, dst_str);
+    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_src_param(ins, &ins->src[0], 0, src0);
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
-    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);
+    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 */
 }
 
 /** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB:
 }
 
 /** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB:
@@ -2181,23 +1477,21 @@ 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)
 {
-    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_BUFFER *buffer = ins->ctx->buffer;
+    DWORD dst_reg = ins->dst[0].reg.idx;
+    char src0[50];
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
 
     shader_arb_get_src_param(ins, &ins->src[0], 0, 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);
+    shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, 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 %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);
+    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");
 }
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for
 }
 
 /** Handles transforming all WINED3DSIO_M?x? opcodes for
@@ -2256,25 +1550,26 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins)
+static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
 {
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
-    const char *instruction;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    const char *instruction, *sat;
 
     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_EXP:  instruction = "EX2"; break;
-        case WINED3DSIH_EXPP: instruction = "EXP"; break;
+        case WINED3DSIH_RSQ: instruction = "RSQ"; break;
+        case WINED3DSIH_RCP: instruction = "RCP"; 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)
@@ -2285,54 +1580,29 @@ static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins)
         strcat(src, ".w");
     }
 
         strcat(src, ".w");
     }
 
-    shader_addline(buffer, "%s%s %s, %s;\n", instruction, shader_arb_get_modifier(ins), dst, src);
+    shader_addline(buffer, "%s%s %s, %s;\n", instruction, sat, dst, src);
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_name[50];
     char src_name[50];
-    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_dst_param(ins, &ins->dst[0], dst_name);
-    shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, 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;
-    }
+    char dst_wmask[20];
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    BOOL is_color;
 
 
-    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_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_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]);
+    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);
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
@@ -2341,657 +1611,24 @@ 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_name0[50], src_name1[50], src_name2[50];
+    char src_name[50];
+    char dst_wmask[20];
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     BOOL is_color;
 
-    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_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);
 
 
-        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);
-        }
-    }
+    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);
 }
 
 }
 
-static void shader_hw_sgn(const struct wined3d_shader_instruction *ins)
-{
-    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)
+static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
 {
     GLuint program_id = 0;
     const char *blt_vprogram =
 {
     GLuint program_id = 0;
     const char *blt_vprogram =
@@ -3016,8 +1653,7 @@ static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_inf
     return program_id;
 }
 
     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)
+static GLuint create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
 {
     GLuint program_id = 0;
     static const char * const blt_fprograms[tex_type_count] =
 {
     GLuint program_id = 0;
     static const char * const blt_fprograms[tex_type_count] =
@@ -3038,1171 +1674,66 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i
         "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
         "MOV result.depth.z, R0.x;\n"
         "END\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) {
-        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 ret;
-}
-
-/* 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)
-{
-    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))
-    {
-        ERR("Failed to initialize shader buffer.\n");
-        return 0;
-    }
-
-    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 */
-    }
+        /* 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",
+    };
 
 
-    /* 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++)
+    if (!blt_fprograms[tex_type])
     {
     {
-        if(stateblock->vertexShaderConstantB[i]) args->boolclip.bools |= ( 1 << i);
+        FIXME("tex_type %#x not supported\n", tex_type);
+        tex_type = tex_2d;
     }
 
     }
 
-    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;
+    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]));
 
 
-    /* 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;
+    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)));
     }
 
     }
 
-    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];
-        }
-    }
+    return program_id;
 }
 
 }
 
-/* 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;
+static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct shader_arb_priv *priv = This->shader_priv;
     struct shader_arb_priv *priv = This->shader_priv;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    int i;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
 
-    /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
-    if (usePS) {
-        struct arb_ps_compile_args compile_args;
-        struct arb_ps_compiled_shader *compiled;
-        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) This->stateBlock->pixelShader;
+    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)");
+    }
 
 
-        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;
+    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);
 
         /* 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));
@@ -4214,83 +1745,22 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
             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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
 
     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));
@@ -4301,16 +1771,18 @@ 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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
 
     if (priv->current_vprogram_id) {
         GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
         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);
@@ -4321,8 +1793,11 @@ 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 if(!priv->use_arbfp_fixed_func) {
+    } else {
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
         checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
     }
@@ -4330,116 +1805,303 @@ 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;
-    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)baseShader->baseShader.device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.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();
-
-        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))");
+        for(i = 0; i < This->num_gl_shaders; i++) {
+            GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId));
+            checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &This->gl_shaders[i].prgId))");
         }
         LEAVE_GL();
         }
         LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
-        This->backend_priv = NULL;
+        HeapFree(GetProcessHeap(), 0, This->gl_shaders);
+        This->gl_shaders = NULL;
+        This->num_gl_shaders = 0;
+        This->shader_array_size = 0;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
     } else {
         IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
-        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;
+}
 
 
-        if(shader_data->num_gl_shaders) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+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;
 
 
-        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))");
+    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]));
         }
         }
-        LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
-        This->backend_priv = NULL;
     }
     }
+
+    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 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);
-}
+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");
 
 
-struct wine_rb_functions sig_tree_functions =
-{
-    wined3d_rb_alloc,
-    wined3d_rb_realloc,
-    wined3d_rb_free,
-    sig_tree_compare
-};
+    shader_addline(buffer, "MOV result.position, TMP_OUT;\n");
 
 
-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;
-}
+    shader_addline(buffer, "END\n");
 
 
-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);
-}
+    /* TODO: change to resource.glObjectHandle or something like that */
+    GL_EXTCALL(glGenProgramsARB(1, &ret));
 
 
-/* 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;
+    TRACE("Creating a hw vertex shader, prg=%d\n", ret);
+    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ret));
 
 
-    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]));
+    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) {
+        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));
+            }
         }
     }
         }
     }
-    LEAVE_GL();
-
-    wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
-    HeapFree(GetProcessHeap(), 0, This->shader_priv);
-}
+    HeapFree(GetProcessHeap(), 0, lconst_map);
 
 
-static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) {
-    return TRUE;
+    return ret;
 }
 
 }
 
-static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info,
-        struct shader_caps *pCaps)
+static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
 {
     /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
      * then overwrite the shader specific ones
 {
     /* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
      * then overwrite the shader specific ones
@@ -4447,47 +2109,17 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_
     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)) {
-        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);
+        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(ARB_FRAGMENT_PROGRAM)) {
     }
 
     if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
-        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->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;
     }
     }
-
-    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)
@@ -4510,9 +2142,10 @@ 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];
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
 
@@ -4521,15 +2154,14 @@ 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, &dst->reg, regstr, &is_color);
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+                                 dst->reg.idx, !!dst->reg.rel_addr, regstr, &is_color);
 
 
-    /* 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),
+    /* Generate a line that does the output modifier computation */
+    shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
                    regstr, write_mask, regstr, shift_tab[shift]);
 }
 
                    regstr, write_mask, regstr, shift_tab[shift]);
 }
 
@@ -4538,10 +2170,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         */ shader_hw_break,
-    /* WINED3DSIH_BREAKC        */ shader_hw_breakc,
+    /* WINED3DSIH_BREAK         */ NULL,
+    /* WINED3DSIH_BREAKC        */ NULL,
     /* WINED3DSIH_BREAKP        */ NULL,
     /* WINED3DSIH_BREAKP        */ NULL,
-    /* WINED3DSIH_CALL          */ shader_hw_call,
+    /* WINED3DSIH_CALL          */ NULL,
     /* 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,
@@ -4554,23 +2186,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           */ 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_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_FRC           */ shader_hw_map2gl,
     /* WINED3DSIH_FRC           */ shader_hw_map2gl,
-    /* WINED3DSIH_IF            */ NULL /* Hardcoded into the shader */,
-    /* WINED3DSIH_IFC           */ shader_hw_ifc,
-    /* WINED3DSIH_LABEL         */ shader_hw_label,
+    /* WINED3DSIH_IF            */ NULL,
+    /* WINED3DSIH_IFC           */ NULL,
+    /* WINED3DSIH_LABEL         */ NULL,
     /* WINED3DSIH_LIT           */ shader_hw_map2gl,
     /* WINED3DSIH_LIT           */ 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_LOG           */ shader_hw_map2gl,
+    /* WINED3DSIH_LOGP          */ shader_hw_map2gl,
+    /* WINED3DSIH_LOOP          */ NULL,
+    /* WINED3DSIH_LRP           */ shader_hw_map2gl,
     /* 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,
@@ -4585,14 +2217,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_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_POW           */ shader_hw_map2gl,
+    /* WINED3DSIH_RCP           */ shader_hw_rsq_rcp,
+    /* WINED3DSIH_REP           */ NULL,
+    /* WINED3DSIH_RET           */ NULL,
+    /* WINED3DSIH_RSQ           */ shader_hw_rsq_rcp,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
-    /* WINED3DSIH_SGN           */ shader_hw_sgn,
+    /* WINED3DSIH_SGN           */ NULL,
     /* 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,
@@ -4604,8 +2236,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        */ shader_hw_texldd,
-    /* WINED3DSIH_TEXLDL        */ shader_hw_texldl,
+    /* WINED3DSIH_TEXLDD        */ NULL,
+    /* WINED3DSIH_TEXLDL        */ NULL,
     /* 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,
@@ -4620,391 +2252,8 @@ 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_handle_instruction,
+    shader_arb_instruction_handler_table,
     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,
@@ -5016,8 +2265,11 @@ 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 */
@@ -5034,9 +2286,7 @@ 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)");
@@ -5044,7 +2294,6 @@ 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) {
@@ -5061,21 +2310,14 @@ 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;
-    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->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
 }
 
     priv->use_arbfp_fixed_func = TRUE;
     return WINED3D_OK;
 }
 
-/* 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);
+static void arbfp_free_ffpshader(void *value, void *gli) {
+    const WineD3D_GL_Info *gl_info = gli;
+    struct arbfp_ffp_desc *entry_arb = value;
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
 
     ENTER_GL();
     GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
@@ -5084,12 +2326,11 @@ static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *context)
     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;
 
-    wine_rb_destroy(&priv->fragment_shaders, arbfp_free_ffpshader, &This->adapter->gl_info);
+    hash_table_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) {
@@ -5097,7 +2338,7 @@ static void arbfp_free(IWineD3DDevice *iface) {
     }
 }
 
     }
 }
 
-static void arbfp_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+static void arbfp_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
@@ -5135,8 +2376,7 @@ static void arbfp_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info
 #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, struct wined3d_context *context)
-{
+static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
@@ -5147,7 +2387,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;
-        context->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
+        device->activeContext->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);
     }
 
@@ -5157,8 +2397,7 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
 
 }
 
 
 }
 
-static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
     float col[4];
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
 
@@ -5169,33 +2408,31 @@ 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;
-        context->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
+        device->activeContext->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.0f; col[1] = 1.0f;
-        col[2] = 1.0f; col[3] = 0.0f;
+        col[0] = 1.0; col[1] = 1.0;
+        col[2] = 1.0; col[3] = 0.0;
     } else {
     } else {
-        col[0] = 0.0f; col[1] = 0.0f;
-        col[2] = 0.0f; col[3] = 0.0f;
+        col[0] = 0.0; col[1] = 0.0;
+        col[2] = 0.0; col[3] = 0.0;
     }
     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, struct wined3d_context *context)
-{
+static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 & (1 << stage)))
-        {
+        if(stage != 0 &&
+           ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
              * anyway
              */
             /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
              * anyway
              */
@@ -5209,7 +2446,7 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
             return;
         }
     } else if(device->shader_backend == &arb_program_shader_backend) {
-        context->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
+        device->activeContext->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);
     }
 
@@ -5222,17 +2459,15 @@ static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     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, struct wined3d_context *context)
-{
+static void tex_bumpenvlum_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 & (1 << stage)))
-        {
+        if(stage != 0 &&
+           ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
             /* The pixel shader has to know the luminance offset. Do a constants update if it
              * isn't scheduled anyway
              */
             /* The pixel shader has to know the luminance offset. Do a constants update if it
              * isn't scheduled anyway
              */
@@ -5246,21 +2481,20 @@ 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) {
-        context->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
+        device->activeContext->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.0f;
-    param[3] = 0.0f;
+    param[2] = 0.0;
+    param[3] = 0.0;
 
     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(struct wined3d_shader_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg)
-{
+static const char *get_argreg(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 */
@@ -5331,9 +2565,8 @@ static const char *get_argreg(struct wined3d_shader_buffer *buffer, DWORD argnum
     return ret;
 }
 
     return ret;
 }
 
-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)
-{
+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) {
     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;
@@ -5474,7 +2707,7 @@ static void gen_ffp_instr(struct wined3d_shader_buffer *buffer, unsigned int sta
 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;
-    struct wined3d_shader_buffer buffer;
+    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};
@@ -5537,11 +2770,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
     }
 
     /* Shader header */
     }
 
     /* Shader header */
-    if (!shader_buffer_init(&buffer))
-    {
-        ERR("Failed to initialize shader buffer.\n");
-        return 0;
-    }
+    shader_buffer_init(&buffer);
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
 
     shader_addline(&buffer, "!!ARBfp1.0\n");
 
@@ -5580,8 +2809,6 @@ 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;
@@ -5708,7 +2935,8 @@ 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", FALSE);
+        arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
+        shader_addline(&buffer, "MOV result.color.w, ret.w;\n");
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
     } else {
         shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
     }
@@ -5731,8 +2959,7 @@ 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, struct wined3d_context *context)
-{
+static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -5752,7 +2979,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(context, use_pshader, use_vshader);
+            device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
         }
         return;
     }
         }
         return;
     }
@@ -5760,7 +2987,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)
@@ -5776,7 +3003,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;
         }
@@ -5812,7 +3039,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(context, use_pshader, use_vshader);
+        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, 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);
@@ -5829,8 +3056,7 @@ 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, struct wined3d_context *context)
-{
+static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -5860,8 +3086,7 @@ static void state_arbfp_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
     if(!isStateDirty(context, STATE_PIXELSHADER)) {
         fragment_prog_arbfp(state, stateblock, context);
     }
@@ -5870,154 +3095,154 @@ static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
 #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   }, 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             },
+    {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                               },
 };
 
 const struct fragment_pipeline arbfp_fragment_pipeline = {
 };
 
 const struct fragment_pipeline arbfp_fragment_pipeline = {
@@ -6047,8 +3272,6 @@ 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;
@@ -6060,12 +3283,11 @@ 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");
+    checkGLcall("Delete yuv programs\n");
     LEAVE_GL();
 }
 
     LEAVE_GL();
 }
 
-static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum yuv_fixup yuv_fixup,
-        GLenum textype, char *luminance)
+static BOOL gen_planar_yuv_read(SHADER_BUFFER *buffer, enum yuv_fixup yuv_fixup, GLenum textype, char *luminance)
 {
     char chroma;
     const char *tex, *texinstr;
 {
     char chroma;
     const char *tex, *texinstr;
@@ -6152,7 +3374,7 @@ static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum yuv_f
     return TRUE;
 }
 
     return TRUE;
 }
 
-static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance)
+static BOOL gen_yv12_read(SHADER_BUFFER *buffer, GLenum textype, char *luminance)
 {
     const char *tex;
 
 {
     const char *tex;
 
@@ -6203,7 +3425,7 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
      * 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.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f);
+                   2.0 / 3.0, 1.0 / 6.0, (2.0 / 3.0) + (1.0 / 6.0), 1.0 / 3.0);
 
     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 */
@@ -6298,20 +3520,15 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
     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;
-    struct wined3d_shader_buffer buffer;
+    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 */
-    if (!shader_buffer_init(&buffer))
-    {
-        ERR("Failed to initialize shader buffer.\n");
-        return 0;
-    }
+    shader_buffer_init(&buffer);
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
 
     ENTER_GL();
     GL_EXTCALL(glGenProgramsARB(1, &shader));
@@ -6439,7 +3656,6 @@ 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)
 {
@@ -6500,7 +3716,6 @@ 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 aea942c..a8c137f 100644 (file)
@@ -28,8 +28,6 @@
 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
@@ -53,7 +51,8 @@ struct atifs_ffp_desc
 
 struct atifs_private_data
 {
 
 struct atifs_private_data
 {
-    struct wine_rb_tree fragment_shaders; /* A rb-tree to track fragment pipeline replacement shaders */
+    struct hash_table_t *fragment_shaders; /* A hashtable to track fragment pipeline replacement shaders */
+
 };
 
 static const char *debug_dstmod(GLuint mod) {
 };
 
 static const char *debug_dstmod(GLuint mod) {
@@ -192,9 +191,8 @@ static const char *debug_mask(GLuint mask) {
 }
 #define GLINFO_LOCATION (*gl_info)
 
 }
 #define GLINFO_LOCATION (*gl_info)
 
-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)
-{
+static void wrap_op1(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod) {
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp1ATI(%s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
     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));
@@ -207,9 +205,9 @@ static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint ds
     }
 }
 
     }
 }
 
-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)
-{
+static void wrap_op2(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
+                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod) {
     if(dstMask == GL_ALPHA) {
         TRACE("glAlphaFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
               debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
     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),
@@ -224,10 +222,10 @@ static void wrap_op2(const struct wined3d_gl_info *gl_info, GLuint op, GLuint ds
     }
 }
 
     }
 }
 
-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)
-{
+static void wrap_op3(const WineD3D_GL_Info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+                     GLuint arg1, GLuint arg1Rep, GLuint arg1Mod,
+                     GLuint arg2, GLuint arg2Rep, GLuint arg2Mod,
+                     GLuint arg3, GLuint arg3Rep, GLuint arg3Mod) {
     if(dstMask == GL_ALPHA) {
         /* Leave some free space to fit "GL_NONE, " in to align most alpha and color op lines */
         TRACE("glAlphaFragmentOp3ATI(%s, %s,          %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
     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),
@@ -251,7 +249,7 @@ static void wrap_op3(const struct wined3d_gl_info *gl_info, GLuint op, GLuint ds
     }
 }
 
     }
 }
 
-static GLuint register_for_arg(DWORD arg, const struct wined3d_gl_info *gl_info,
+static GLuint register_for_arg(DWORD arg, const 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;
@@ -379,7 +377,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 struct wined3d_gl_info *gl_info)
+static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const WineD3D_GL_Info *gl_info)
 {
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
     unsigned int stage;
 {
     GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
     unsigned int stage;
@@ -424,6 +422,13 @@ 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 */
@@ -454,24 +459,22 @@ 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);
 
-        /* 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:
+        /* 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 :-(
          *
          *
-         * 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.
+         * 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.
          */
          */
-        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,
+        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_RED_BIT_ATI, GL_NONE,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_NONE);
+        wrap_op1(gl_info, GL_MOV_ATI, GL_REG_5_ATI, GL_GREEN_BIT_ATI, GL_NONE,
+                 ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_NONE);
+        wrap_op3(gl_info, GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
+                 GL_REG_0_ATI + stage, GL_NONE, argmodextra_y,
+                 GL_REG_5_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
                  GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE);
                  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 */
@@ -796,8 +799,7 @@ 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, struct wined3d_context *context)
-{
+static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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;
@@ -806,7 +808,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st
     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)
@@ -822,7 +824,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st
 
         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;
     }
@@ -843,8 +845,7 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, st
     GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
 }
 
     GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
 }
 
-static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_texfactor_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
 
@@ -852,8 +853,7 @@ 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, struct wined3d_context *context)
-{
+static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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,23 +868,21 @@ static void set_bumpmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
      * 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.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;
+    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;
     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, struct wined3d_context *context)
-{
+static void textransform(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void atifs_apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_vshader = use_vs(stateblock);
 
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
     BOOL use_vshader = use_vs(stateblock);
 
@@ -901,7 +899,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(context, FALSE, use_vshader);
+        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, use_vshader);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
 
         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader) {
             device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCONSTANT, stateblock, context);
@@ -912,141 +910,139 @@ 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   }, 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             },
+    {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                               },
 };
 
 };
 
-/* 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)");
@@ -1054,10 +1050,9 @@ 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 struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+static void atifs_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *caps)
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
 {
     caps->TextureOpCaps =  WINED3DTEXOPCAPS_DISABLE                     |
                            WINED3DTEXOPCAPS_SELECTARG1                  |
@@ -1115,21 +1110,14 @@ static HRESULT atifs_alloc(IWineD3DDevice *iface) {
         return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
         return E_OUTOFMEMORY;
     }
     priv = This->fragment_priv;
-    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->fragment_shaders = hash_table_create(ffp_frag_program_key_hash, ffp_frag_program_key_compare);
     return WINED3D_OK;
 }
 
 #define GLINFO_LOCATION This->adapter->gl_info
     return WINED3D_OK;
 }
 
 #define GLINFO_LOCATION This->adapter->gl_info
-/* 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);
+static void atifs_free_ffpshader(void *value, void *device) {
+    IWineD3DDeviceImpl *This = device;
+    struct atifs_ffp_desc *entry_ati = value;
 
     ENTER_GL();
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
 
     ENTER_GL();
     GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
@@ -1138,12 +1126,11 @@ static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *context)
     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;
 
-    wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, This);
+    hash_table_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 c983e80..8b8aef4 100644 (file)
@@ -138,41 +138,35 @@ const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token
     }
 }
 
     }
 }
 
-void shader_buffer_clear(struct wined3d_shader_buffer *buffer)
+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)
 {
 {
+    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;
 }
 
-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)
+void shader_buffer_free(struct SHADER_BUFFER *buffer)
 {
     HeapFree(GetProcessHeap(), 0, buffer->buffer);
 }
 
 {
     HeapFree(GetProcessHeap(), 0, buffer->buffer);
 }
 
-int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va_list args)
+int shader_vaddline(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 */ || (unsigned int)rc > SHADER_PGMSIZE - 1 - buffer->bsize /* C99 */)
-    {
+    if (rc < 0 ||                                   /* C89 */ 
+        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;
@@ -194,7 +188,7 @@ int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va
     return 0;
 }
 
     return 0;
 }
 
-int shader_addline(struct wined3d_shader_buffer *buffer, const char *format, ...)
+int shader_addline(SHADER_BUFFER* buffer, const char *format, ...)
 {
     int ret;
     va_list args;
 {
     int ret;
     va_list args;
@@ -252,23 +246,24 @@ 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,
-        const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
+        DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
 {
 {
-    switch (reg->type)
+    switch (register_type)
     {
         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
     {
         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
-            if (shader_type == WINED3D_SHADER_TYPE_PIXEL) reg_maps->texcoord |= 1 << reg->idx;
-            else reg_maps->address |= 1 << reg->idx;
+            if (pshader) reg_maps->texcoord[register_idx] = 1;
+            else reg_maps->address[register_idx] = 1;
             break;
 
         case WINED3DSPR_TEMP:
             break;
 
         case WINED3DSPR_TEMP:
-            reg_maps->temporary |= 1 << reg->idx;
+            reg_maps->temporary[register_idx] = 1;
             break;
 
         case WINED3DSPR_INPUT:
             break;
 
         case WINED3DSPR_INPUT:
-            if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+            if (!pshader) reg_maps->attributes[register_idx] = 1;
+            else
             {
             {
-                if (reg->rel_addr)
+                if (has_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
@@ -281,142 +276,84 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
                 }
                 else
                 {
                 }
                 else
                 {
-                    ((IWineD3DPixelShaderImpl *)This)->input_reg_used[reg->idx] = TRUE;
+                    ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE;
                 }
             }
                 }
             }
-            else reg_maps->input_registers |= 1 << reg->idx;
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
-            if (reg->idx == 1) reg_maps->fog = 1;
+            if (register_idx == 1) reg_maps->fog = 1;
             break;
 
         case WINED3DSPR_MISCTYPE:
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
-            {
-                if (reg->idx == 0) reg_maps->vpos = 1;
-                else if (reg->idx == 1) reg_maps->usesfacing = 1;
-            }
+            if (pshader && register_idx == 0) reg_maps->vpos = 1;
             break;
 
         case WINED3DSPR_CONST:
             break;
 
         case WINED3DSPR_CONST:
-            if (reg->rel_addr)
+            if (has_rel_addr)
             {
             {
-                if (shader_type != WINED3D_SHADER_TYPE_PIXEL)
+                if (!pshader)
                 {
                 {
-                    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;
-                    }
+                    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;
                 }
                 reg_maps->usesrelconstF = TRUE;
             }
             else
             {
                 }
                 reg_maps->usesrelconstF = TRUE;
             }
             else
             {
-                set_bitmap_bit(reg_maps->constf, reg->idx);
+                set_bitmap_bit(reg_maps->constf, register_idx);
             }
             break;
 
         case WINED3DSPR_CONSTINT:
             }
             break;
 
         case WINED3DSPR_CONSTINT:
-            reg_maps->integer_constants |= (1 << reg->idx);
+            reg_maps->integer_constants |= (1 << register_idx);
             break;
 
         case WINED3DSPR_CONSTBOOL:
             break;
 
         case WINED3DSPR_CONSTBOOL:
-            reg_maps->boolean_constants |= (1 << reg->idx);
-            break;
-
-        case WINED3DSPR_COLOROUT:
-            reg_maps->highest_render_target = max(reg_maps->highest_render_target, reg->idx);
+            reg_maps->boolean_constants |= (1 << register_idx);
             break;
 
         default:
             break;
 
         default:
-            TRACE("Not recording register of type %#x and idx %u\n", reg->type, reg->idx);
+            TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx);
             break;
     }
 }
 
             break;
     }
 }
 
-static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
+static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
 {
     switch(instr)
     {
         case WINED3DSIH_M4x4:
         case WINED3DSIH_M3x4:
 {
     switch(instr)
     {
         case WINED3DSIH_M4x4:
         case WINED3DSIH_M3x4:
-            return param == 1 ? 3 : 0;
+            return param == 1 ? 4 : 1;
 
         case WINED3DSIH_M4x3:
         case WINED3DSIH_M3x3:
 
         case WINED3DSIH_M4x3:
         case WINED3DSIH_M3x3:
-            return param == 1 ? 2 : 0;
+            return param == 1 ? 3 : 1;
 
         case WINED3DSIH_M3x2:
 
         case WINED3DSIH_M3x2:
-            return param == 1 ? 1 : 0;
+            return param == 1 ? 2 : 1;
 
         default:
 
         default:
-            return 0;
+            return 1;
     }
 }
 
     }
 }
 
-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_attribute *attributes,
-        struct wined3d_shader_signature_element *input_signature,
-        struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
+        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)
 {
     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 */
 
@@ -431,6 +368,7 @@ 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));
@@ -472,22 +410,15 @@ 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:
-                    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);
-                    }
+                    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;
                     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->output_registers |= 1 << semantic.reg.reg.idx;
-                    shader_signature_from_semantic(&output_signature[semantic.reg.reg.idx], &semantic);
+                    reg_maps->packed_output[semantic.reg.reg.idx] = 1;
+                    semantics_out[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;
 
@@ -516,17 +447,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 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+            if (shader_version.major == 1 && pshader)
             {
                 float *value = (float *) lconst->value;
             {
                 float *value = (float *) lconst->value;
-                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;
+                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;
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
@@ -546,7 +477,6 @@ 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)
         {
@@ -563,7 +493,6 @@ 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
@@ -599,13 +528,12 @@ 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 |= 1 << src.reg.idx;
+            reg_maps->labels[src.reg.idx] = 1;
         }
         /* 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.
@@ -621,49 +549,22 @@ 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 (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3
-                        && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
+                if (!pshader && shader_version.major < 3 && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
                 {
                 {
-                    reg_maps->texcoord_mask[dst_param.reg.idx] |= dst_param.write_mask;
+                    reg_maps->texcoord_mask[dst_param.reg.type] |= dst_param.write_mask;
                 }
                 }
-
-                if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+                else
                 {
                 {
-                    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;
-                    }
+                    shader_record_register_usage(This, reg_maps, dst_param.reg.type,
+                            dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader);
                 }
 
                 /* 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
@@ -686,16 +587,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 |= 1 << dst_param.reg.idx;
+                        reg_maps->bumpmat[sampler_code] = TRUE;
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
                         {
-                            reg_maps->luminanceparams |= 1 << dst_param.reg.idx;
+                            reg_maps->luminanceparams[sampler_code] = TRUE;
                         }
                     }
                 }
                         }
                     }
                 }
-                else if (ins.handler_idx == WINED3DSIH_BEM)
+                else if (pshader && ins.handler_idx == WINED3DSIH_BEM)
                 {
                 {
-                    reg_maps->bumpmat |= 1 << dst_param.reg.idx;
+                    reg_maps->bumpmat[dst_param.reg.idx] = TRUE;
                 }
             }
 
                 }
             }
 
@@ -707,77 +608,45 @@ 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);
-                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)
+                switch(get_instr_regcount(ins.handler_idx, i))
                 {
                 {
-                    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;
-                    }
+                    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);
                 }
             }
         }
     }
     reg_maps->loop_depth = max_loop_depth;
 
                 }
             }
         }
     }
     reg_maps->loop_depth = max_loop_depth;
 
-    This->baseShader.functionLength = ((const char *)pToken - (const char *)byte_code);
+    This->baseShader.functionLength = ((char *)pToken - (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)
 {
@@ -796,7 +665,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_version->major < 3 && shader_version->type == WINED3D_SHADER_TYPE_PIXEL)
+        if (shader_is_pshader_version(shader_version->type) && shader_version->major < 3)
             return;
         else
             TRACE("_");
             return;
         else
             TRACE("_");
@@ -852,14 +721,15 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
     }
 }
 
     }
 }
 
-static void shader_dump_register(const struct wined3d_shader_register *reg,
-        const struct wined3d_shader_version *shader_version)
+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 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 = reg->idx;
+    UINT offset = register_idx;
 
 
-    switch (reg->type)
+    switch (register_type)
     {
         case WINED3DSPR_TEMP:
             TRACE("r");
     {
         case WINED3DSPR_TEMP:
             TRACE("r");
@@ -874,15 +744,15 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
-            offset = shader_get_float_offset(reg->type, reg->idx);
+            offset = shader_get_float_offset(register_type, register_idx);
             break;
 
         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
             break;
 
         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
-            TRACE("%c", shader_version->type == WINED3D_SHADER_TYPE_PIXEL ? 't' : 'a');
+            TRACE("%c", shader_is_pshader_version(shader_version->type) ? 't' : 'a');
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
-            TRACE("%s", rastout_reg_names[reg->idx]);
+            TRACE("%s", rastout_reg_names[register_idx]);
             break;
 
         case WINED3DSPR_COLOROUT:
             break;
 
         case WINED3DSPR_COLOROUT:
@@ -925,8 +795,8 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
             break;
 
         case WINED3DSPR_MISCTYPE:
             break;
 
         case WINED3DSPR_MISCTYPE:
-            if (reg->idx > 1) FIXME("Unhandled misctype register %d\n", reg->idx);
-            else TRACE("%s", misctype_reg_names[reg->idx]);
+            if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx);
+            else TRACE("%s", misctype_reg_names[register_idx]);
             break;
 
         case WINED3DSPR_PREDICATE:
             break;
 
         case WINED3DSPR_PREDICATE:
@@ -937,59 +807,42 @@ static void shader_dump_register(const struct wined3d_shader_register *reg,
             TRACE("l");
             break;
 
             TRACE("l");
             break;
 
-        case WINED3DSPR_CONSTBUFFER:
-            TRACE("cb");
-            break;
-
         default:
         default:
-            TRACE("unhandled_rtype(%#x)", reg->type);
+            TRACE("unhandled_rtype(%#x)", register_type);
             break;
     }
 
             break;
     }
 
-    if (reg->type == WINED3DSPR_IMMCONST)
+    if (register_type == WINED3DSPR_IMMCONST)
     {
         TRACE("(");
     {
         TRACE("(");
-        switch (reg->immconst_type)
+        switch (immconst_type)
         {
             case WINED3D_IMMCONST_FLOAT:
         {
             case WINED3D_IMMCONST_FLOAT:
-                TRACE("%.8e", *(const float *)reg->immconst_data);
+                TRACE("%.8e", *(float *)immconst_data);
                 break;
 
             case WINED3D_IMMCONST_FLOAT4:
                 TRACE("%.8e, %.8e, %.8e, %.8e",
                 break;
 
             case WINED3D_IMMCONST_FLOAT4:
                 TRACE("%.8e, %.8e, %.8e, %.8e",
-                        *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
-                        *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
+                        *(float *)&immconst_data[0], *(float *)&immconst_data[1],
+                        *(float *)&immconst_data[2], *(float *)&immconst_data[3]);
                 break;
 
             default:
                 break;
 
             default:
-                TRACE("<unhandled immconst_type %#x>", reg->immconst_type);
+                TRACE("<unhandled immconst_type %#x>", immconst_type);
                 break;
         }
         TRACE(")");
     }
                 break;
         }
         TRACE(")");
     }
-    else if (reg->type != WINED3DSPR_RASTOUT && reg->type != WINED3DSPR_MISCTYPE)
+    else if (register_type != WINED3DSPR_RASTOUT && register_type != WINED3DSPR_MISCTYPE)
     {
     {
-        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
+        if (rel_addr)
         {
         {
-            if (reg->rel_addr)
-            {
-                TRACE("[");
-                shader_dump_src_param(reg->rel_addr, shader_version);
-                TRACE(" + ");
-            }
-            TRACE("%u", offset);
-            if (reg->rel_addr) TRACE("]");
+            TRACE("[");
+            shader_dump_src_param(rel_addr, shader_version);
+            TRACE(" + ");
         }
         }
+        TRACE("%u", offset);
+        if (rel_addr) TRACE("]");
     }
 }
 
     }
 }
 
@@ -998,7 +851,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, shader_version);
+    shader_dump_register(param->reg.type, param->reg.idx, 0, NULL, param->reg.rel_addr, shader_version);
 
     if (write_mask != WINED3DSP_WRITEMASK_ALL)
     {
 
     if (write_mask != WINED3DSP_WRITEMASK_ALL)
     {
@@ -1032,7 +885,8 @@ 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, shader_version);
+    shader_dump_register(param->reg.type, param->reg.idx, param->reg.immconst_type,
+            param->reg.immconst_data, param->reg.rel_addr, shader_version);
 
     if (src_modifier)
     {
 
     if (src_modifier)
     {
@@ -1081,11 +935,12 @@ 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, struct wined3d_shader_buffer *buffer,
-        const shader_reg_maps *reg_maps, const DWORD *pFunction, void *backend_ctx)
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+        const shader_reg_maps *reg_maps, const DWORD *pFunction)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device; /* To access shader backend callbacks */
 {
     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];
@@ -1096,13 +951,13 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe
     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;
@@ -1137,12 +992,24 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe
                 || 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_PHASE
+                || ins.handler_idx == WINED3DSIH_RET)
         {
             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);
 
@@ -1156,7 +1023,10 @@ void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffe
         }
 
         /* Call appropriate function for output target */
         }
 
         /* Call appropriate function for output target */
-        device->shader_backend->shader_handle_instruction(&ins);
+        hw_fct(&ins);
+
+        /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
+        device->shader_backend->shader_add_instruction_modifiers(&ins);
     }
 }
 
     }
 }
 
@@ -1189,34 +1059,14 @@ 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);
 
-    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);
+    TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version.type) ? "ps": "vs",
+            shader_version.major, shader_version.minor);
 
     while (!fe->shader_is_end(fe_data, &pToken))
     {
 
     while (!fe->shader_is_end(fe_data, &pToken))
     {
@@ -1374,27 +1224,39 @@ void shader_cleanup(IWineD3DBaseShader *iface)
     }
 }
 
     }
 }
 
-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 const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
+static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum tex_types tex_type) {}
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_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(const struct wined3d_context *context, char usePS, char useVS) {}
+static void shader_none_load_constants(IWineD3DDevice *iface, 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 struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
+static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
 {
     /* Set the shader caps to 0 for the none shader backend */
     pCaps->VertexShaderVersion  = 0;
     pCaps->PixelShaderVersion    = 0;
 {
     /* Set the shader caps to 0 for the none shader backend */
     pCaps->VertexShaderVersion  = 0;
     pCaps->PixelShaderVersion    = 0;
-    pCaps->PixelShader1xMaxValue = 0.0f;
+    pCaps->PixelShader1xMaxValue = 0.0;
 }
 #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)
@@ -1417,7 +1279,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_handle_instruction,
+    shader_none_instruction_handler_table,
     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,
@@ -1429,6 +1291,9 @@ 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 9633e01..caf2148 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
 
-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)
+void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage)
 {
 {
-    HRESULT hr;
-
-    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;
-    }
-
-    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;
+    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;
 }
 
 void basetexture_cleanup(IWineD3DBaseTexture *iface)
 {
 }
 
 void basetexture_cleanup(IWineD3DBaseTexture *iface)
 {
-    basetexture_unload(iface);
+    IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
+    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();
+    }
+
     resource_cleanup((IWineD3DResource *)iface);
 }
 
     resource_cleanup((IWineD3DResource *)iface);
 }
 
@@ -74,17 +62,11 @@ 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, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         glDeleteTextures(1, &This->baseTexture.textureName);
         ENTER_GL();
         glDeleteTextures(1, &This->baseTexture.textureName);
-        This->baseTexture.textureName = 0;
-        LEAVE_GL();
-    }
-
-    if(This->baseTexture.srgbTextureName) {
-        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
-        ENTER_GL();
         glDeleteTextures(1, &This->baseTexture.srgbTextureName);
         glDeleteTextures(1, &This->baseTexture.srgbTextureName);
+        This->baseTexture.textureName = 0;
         This->baseTexture.srgbTextureName = 0;
         LEAVE_GL();
     }
         This->baseTexture.srgbTextureName = 0;
         LEAVE_GL();
     }
@@ -146,7 +128,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, NULL, CTXUSAGE_RESOURCELOAD);
+      ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
       ENTER_GL();
       glBindTexture(textureDimensions, This->baseTexture.textureName);
       checkGLcall("glBindTexture");
       ENTER_GL();
       glBindTexture(textureDimensions, This->baseTexture.textureName);
       checkGLcall("glBindTexture");
@@ -176,11 +158,12 @@ 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);
-
-    return This->baseTexture.filterType;
+  IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
+  FIXME("(%p) : stub\n", This);
+  if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
+     return WINED3DTEXF_NONE;
+  }
+  return This->baseTexture.filterType;
 }
 
 void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface)
 }
 
 void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface)
@@ -207,7 +190,6 @@ 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;
@@ -252,7 +234,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] = 1;
+        states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
         states[WINED3DTEXSTA_SRGBTEXTURE]   = 0;
         states[WINED3DTEXSTA_ELEMENTINDEX]  = 0;
         states[WINED3DTEXSTA_DMAPOFFSET]    = 0;
         states[WINED3DTEXSTA_SRGBTEXTURE]   = 0;
         states[WINED3DTEXSTA_ELEMENTINDEX]  = 0;
         states[WINED3DTEXSTA_DMAPOFFSET]    = 0;
@@ -306,7 +288,6 @@ 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;
@@ -332,7 +313,6 @@ 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])
@@ -341,9 +321,6 @@ 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;
@@ -351,7 +328,7 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         states = This->baseTexture.states;
     }
 
         states = This->baseTexture.states;
     }
 
-    /* This function relies on the correct texture being bound and loaded. */
+    /* ApplyStateChanges 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];
@@ -387,14 +364,17 @@ 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] ||
@@ -406,17 +386,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_ANISOTROPIC)
+        if (states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
+            states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
         {
 
             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 = 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));
+        glValue = This->baseTexture.minMipLookup
+                [min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
+                .mip[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],
@@ -436,29 +416,13 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
         }
     }
 
         }
     }
 
-    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");
+    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");
         }
         }
-        states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
+        states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
     }
 }
     }
 }
index 104f572..666de8e 100644 (file)
@@ -34,14 +34,16 @@ 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
@@ -198,20 +200,17 @@ 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 *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)
+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)
 {
 {
-    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 (!(si->use_map & (1 << attrib_idx))
-            || attrib->buffer_object != This->buffer_object)
-        return FALSE;
+    if (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 */
@@ -258,7 +257,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This,
     {
         WINED3DFORMAT format;
 
     {
         WINED3DFORMAT format;
 
-        if (!(strided->use_map & (1 << i)) || strided->elements[i].buffer_object != This->buffer_object) continue;
+        if (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)
@@ -309,7 +308,6 @@ 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;
@@ -397,7 +395,8 @@ 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, si, i, FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
+            ret = buffer_check_attribute(This, &device->strided_streams.elements[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,
@@ -406,7 +405,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, si, This->stride);
+            This->conversion_shift = find_conversion_shift(This, &device->strided_streams, This->stride);
         }
     }
     else
         }
     }
     else
@@ -416,29 +415,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, si, WINED3D_FFP_POSITION,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_NORMAL,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_DIFFUSE,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_SPECULAR,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD0,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD1,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD2,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD3,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD4,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD5,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD6,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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, si, WINED3D_FFP_TEXCOORD7,
+        ret = buffer_check_attribute(This, &device->strided_streams.elements[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");
@@ -458,7 +457,6 @@ 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 ?
@@ -508,18 +506,29 @@ static inline void fixup_d3dcolor(DWORD *dst_color)
 
 static inline void fixup_transformed_pos(float *p)
 {
 
 static inline void fixup_transformed_pos(float *p)
 {
-    /* rhw conversion like in position_float4(). */
-    if (p[3] != 1.0f && p[3] != 0.0f)
+    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
     {
     {
-        float w = 1.0f / p[3];
-        p[0] *= w;
-        p[1] *= w;
-        p[2] *= w;
-        p[3] = w;
+        w = 1.0 / p[3];
+        x = p[0] * w;
+        y = p[1] * w;
+        z = p[2] * 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;
@@ -579,8 +588,7 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface)
     return refcount;
 }
 
     return refcount;
 }
 
-/* Context activation is done by the caller. */
-BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
+const 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;
@@ -606,7 +614,7 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
     {
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     {
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
-        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, device->lastActiveRenderTarget, 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))
@@ -693,8 +701,6 @@ 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 */
@@ -730,7 +736,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");
@@ -803,7 +809,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
 
         if (!device->isInDraw)
         {
 
         if (!device->isInDraw)
         {
-            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, device->lastActiveRenderTarget, 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));
@@ -953,7 +959,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, NULL, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, device->lastActiveRenderTarget, 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));
@@ -979,16 +985,6 @@ 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 */
@@ -1005,7 +1001,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
 
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
 
-        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, device->lastActiveRenderTarget, 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 c4cd436..2c6703f 100644 (file)
@@ -2,7 +2,6 @@
  * 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 (*gl_info)
+#define GLINFO_LOCATION This->adapter->gl_info
 
 
-static DWORD wined3d_context_tls_idx;
+/* 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;
 
 /* FBO helper functions */
 
 
 /* FBO helper functions */
 
-/* GL locking is done by the caller */
-void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo)
+void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo)
 {
 {
-    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;
-    }
+    const IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 
-    switch (target)
+    if (!*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(glGenFramebuffersEXT(1, fbo));
+        checkGLcall("glGenFramebuffersEXT()");
+        TRACE("Created FBO %d\n", *fbo);
     }
 
     }
 
-    GL_EXTCALL(glBindFramebufferEXT(target, f));
+    GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
     checkGLcall("glBindFramebuffer()");
 }
 
     checkGLcall("glBindFramebuffer()");
 }
 
-/* GL locking is done by the caller */
-static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info)
+static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
 {
     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));
@@ -95,29 +66,16 @@ static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info)
     }
     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(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(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+    checkGLcall("glBindFramebuffer()");
     GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
     checkGLcall("glDeleteFramebuffers()");
 }
 
     GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
     checkGLcall("glDeleteFramebuffers()");
 }
 
-/* GL locking is done by the caller */
-static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOOL force_preload)
+static void context_apply_attachment_filter_states(IWineD3DDevice *iface, 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;
@@ -142,7 +100,7 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
         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(device, STATE_SAMPLER(texture_impl->baseTexture.sampler));
+            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
         }
 
         IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
         }
 
         IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
@@ -153,7 +111,7 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
         GLenum target, bind_target;
         GLint old_binding;
 
         GLenum target, bind_target;
         GLint old_binding;
 
-        target = surface_impl->texture_target;
+        target = surface_impl->glDescription.target;
         if (target == GL_TEXTURE_2D)
         {
             bind_target = GL_TEXTURE_2D;
         if (target == GL_TEXTURE_2D)
         {
             bind_target = GL_TEXTURE_2D;
@@ -168,7 +126,7 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
 
         surface_internal_preload(surface, SRGB_RGB);
 
 
         surface_internal_preload(surface, SRGB_RGB);
 
-        glBindTexture(bind_target, surface_impl->texture_name);
+        glBindTexture(bind_target, surface_impl->glDescription.textureName);
         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);
@@ -177,93 +135,44 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
     checkGLcall("apply_attachment_filter_states()");
 }
 
     checkGLcall("apply_attachment_filter_states()");
 }
 
-/* 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)
+/* TODO: Handle stencil attachments */
+void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, 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)
         {
-            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()");
-            }
-        }
-
-        if (!(format_flags & WINED3DFMT_FLAG_DEPTH))
-        {
-            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-            checkGLcall("glFramebufferTexture2DEXT()");
-        }
+            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_STENCIL))
-        {
-            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, depth_stencil_impl->glDescription.target,
+                        depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
             checkGLcall("glFramebufferTexture2DEXT()");
         }
             checkGLcall("glFramebufferTexture2DEXT()");
         }
-    }
-    else
-    {
+    } 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()");
     }
 }
 
     }
 }
 
-/* GL locking is done by the caller */
-void context_attach_surface_fbo(const struct wined3d_context *context,
-        GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
+void context_attach_surface_fbo(IWineD3DDeviceImpl *This, 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(surface, TRUE);
+        context_apply_attachment_filter_states((IWineD3DDevice *)This, surface, TRUE);
 
 
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->texture_target,
-                surface_impl->texture_name, surface_impl->texture_level));
+        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->glDescription.target,
+                surface_impl->glDescription.textureName, surface_impl->glDescription.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));
@@ -271,10 +180,9 @@ void context_attach_surface_fbo(const struct wined3d_context *context,
     }
 }
 
     }
 }
 
-/* GL locking is done by the caller */
-static void context_check_fbo_status(struct wined3d_context *context)
+static void context_check_fbo_status(IWineD3DDevice *iface)
 {
 {
-    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLenum status;
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
     GLenum status;
 
     status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
@@ -289,7 +197,7 @@ static void context_check_fbo_status(struct wined3d_context *context)
         /* 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 *)context->current_fbo->render_targets[i];
+            attachment = (IWineD3DSurfaceImpl *)This->activeContext->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",
@@ -297,7 +205,7 @@ static void context_check_fbo_status(struct wined3d_context *context)
                         attachment->pow2Width, attachment->pow2Height);
             }
         }
                         attachment->pow2Width, attachment->pow2Height);
             }
         }
-        attachment = (IWineD3DSurfaceImpl *)context->current_fbo->depth_stencil;
+        attachment = (IWineD3DSurfaceImpl *)This->activeContext->current_fbo->depth_stencil;
         if (attachment)
         {
             FIXME("\tDepth attachment: (%p) %s %ux%u\n",
         if (attachment)
         {
             FIXME("\tDepth attachment: (%p) %s %ux%u\n",
@@ -307,270 +215,113 @@ static void context_check_fbo_status(struct wined3d_context *context)
     }
 }
 
     }
 }
 
-static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context)
+static struct fbo_entry *context_create_fbo_entry(IWineD3DDevice *iface)
 {
 {
-    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     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, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
-    entry->depth_stencil = device->stencilBufferTarget;
+    memcpy(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
+    entry->depth_stencil = This->stencilBufferTarget;
     entry->attached = FALSE;
     entry->id = 0;
 
     return entry;
 }
 
     entry->attached = FALSE;
     entry->id = 0;
 
     return 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)
+static void context_destroy_fbo_entry(IWineD3DDeviceImpl *This, 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(context, &entry->id);
+        context_destroy_fbo(This, &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);
 }
 
 
-/* GL locking is done by the caller */
-static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context)
+static struct fbo_entry *context_find_fbo_entry(IWineD3DDevice *iface, WineD3DContext *context)
 {
 {
-    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     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, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets))
-                && entry->depth_stencil == device->stencilBufferTarget)
+        if (!memcmp(entry->render_targets, This->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets))
+                && entry->depth_stencil == This->stencilBufferTarget)
         {
         {
-            list_remove(&entry->entry);
-            list_add_head(&context->fbo_list, &entry->entry);
             return entry;
         }
     }
 
             return 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);
-    }
-
+    entry = context_create_fbo_entry(iface);
+    list_add_head(&context->fbo_list, &entry->entry);
     return entry;
 }
 
     return entry;
 }
 
-/* GL locking is done by the caller */
-static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+static void context_apply_fbo_entry(IWineD3DDevice *iface, struct fbo_entry *entry)
 {
 {
-    IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     unsigned int i;
 
     unsigned int i;
 
-    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id);
+    context_bind_fbo(iface, 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 = device->render_targets[i];
-            context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, i, render_target);
+            IWineD3DSurface *render_target = This->render_targets[i];
+            context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, i, render_target);
         }
 
         /* Apply depth targets */
         }
 
         /* Apply depth targets */
-        if (device->stencilBufferTarget)
-        {
-            unsigned int w = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Width;
-            unsigned int h = ((IWineD3DSurfaceImpl *)device->render_targets[0])->pow2Height;
+        if (This->stencilBufferTarget) {
+            unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
+            unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
 
 
-            surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h);
+            surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
         }
         }
-        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, device->stencilBufferTarget, TRUE);
+        context_attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, This->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 (device->render_targets[i])
-                context_apply_attachment_filter_states(device->render_targets[i], FALSE);
+            if (This->render_targets[i])
+                context_apply_attachment_filter_states(iface, This->render_targets[i], FALSE);
         }
         }
-        if (device->stencilBufferTarget)
-            context_apply_attachment_filter_states(device->stencilBufferTarget, FALSE);
+        if (This->stencilBufferTarget)
+            context_apply_attachment_filter_states(iface, This->stencilBufferTarget, FALSE);
     }
 
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
     }
 
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
-        if (device->render_targets[i])
-            device->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
+        if (This->render_targets[i])
+            This->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
         else
         else
-            device->draw_buffers[i] = GL_NONE;
+            This->draw_buffers[i] = GL_NONE;
     }
 }
 
     }
 }
 
-/* GL locking is done by the caller */
-static void context_apply_fbo_state(struct wined3d_context *context)
+static void context_apply_fbo_state(IWineD3DDevice *iface)
 {
 {
-    if (context->render_offscreen)
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    WineD3DContext *context = This->activeContext;
+
+    if (This->render_offscreen)
     {
     {
-        context->current_fbo = context_find_fbo_entry(context);
-        context_apply_fbo_entry(context, context->current_fbo);
+        context->current_fbo = context_find_fbo_entry(iface, context);
+        context_apply_fbo_entry(iface, context->current_fbo);
     } else {
         context->current_fbo = NULL;
     } else {
         context->current_fbo = NULL;
-        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
     }
 
     }
 
-    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;
+    context_check_fbo_status(iface);
 }
 
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
 }
 
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
@@ -578,25 +329,15 @@ 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;
 
-                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)
+                LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->contexts[i]->fbo_list, struct fbo_entry, entry)
                 {
                     BOOL destroyed = FALSE;
                     UINT j;
                 {
                     BOOL destroyed = FALSE;
                     UINT j;
@@ -605,16 +346,14 @@ 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(context, entry);
+                            context_destroy_fbo_entry(This, entry);
                             destroyed = TRUE;
                         }
                     }
 
                     if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource)
                             destroyed = TRUE;
                         }
                     }
 
                     if (!destroyed && entry->depth_stencil == (IWineD3DSurface *)resource)
-                        context_destroy_fbo_entry(context, entry);
+                        context_destroy_fbo_entry(This, entry);
                 }
                 }
-
-                LEAVE_GL();
             }
 
             break;
             }
 
             break;
@@ -625,156 +364,6 @@ 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
  *
@@ -788,13 +377,12 @@ BOOL context_set_current(struct wined3d_context *ctx)
  *  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(struct wined3d_context *context, DWORD state, const struct StateEntry *StateTable)
-{
+static void Context_MarkStateDirty(WineD3DContext *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 (isStateDirty(context, rep)) return;
+    if(!rep || isStateDirty(context, rep)) return;
 
     context->dirtyArray[context->numDirtyEntries++] = rep;
     idx = rep >> 5;
 
     context->dirtyArray[context->numDirtyEntries++] = rep;
     idx = rep >> 5;
@@ -818,10 +406,8 @@ static void Context_MarkStateDirty(struct wined3d_context *context, DWORD state,
  *  pbuffer: optional pbuffer used with this context
  *
  *****************************************************************************/
  *  pbuffer: optional pbuffer used with this context
  *
  *****************************************************************************/
-static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This,
-        HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer)
-{
-    struct wined3d_context **oldArray = This->contexts;
+static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) {
+    WineD3DContext **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));
@@ -834,7 +420,7 @@ static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This,
         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(**This->contexts));
+    This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineD3DContext));
     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);
@@ -851,8 +437,7 @@ static struct wined3d_context *AddContextToArray(IWineD3DDeviceImpl *This,
     /* 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++) {
-        if (This->StateTable[state].representative)
-            Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
+        Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
     }
 
     This->numContexts++;
     }
 
     This->numContexts++;
@@ -1051,15 +636,12 @@ 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
  *
  *****************************************************************************/
-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;
+WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) {
+    HDC oldDrawable, hdc;
     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);
 
@@ -1175,7 +757,7 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
         /* 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 NULL;
+            return FALSE;
         }
 
         DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
         }
 
         DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
@@ -1194,7 +776,7 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
 
                 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 NULL;
+                    return FALSE;
                 }
             } 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.
@@ -1202,21 +784,13 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
                 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 NULL;
+                return FALSE;
             }
         }
     }
 
     ctx = pwglCreateContext(hdc);
             }
         }
     }
 
     ctx = pwglCreateContext(hdc);
-    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(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
 
     if(!ctx) {
         ERR("Failed to create a WGL context\n");
 
     if(!ctx) {
         ERR("Failed to create a WGL context\n");
@@ -1229,20 +803,14 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
     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");
-        if (!pwglDeleteContext(ctx))
-        {
-            DWORD err = GetLastError();
-            ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err);
-        }
+        pwglDeleteContext(ctx);
         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)) {
@@ -1257,27 +825,18 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
                 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 */
-    if (!context_set_current(ret))
-    {
+    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) {
         ERR("Cannot activate context to set up defaults\n");
         goto out;
     }
         ERR("Cannot activate context to set up defaults\n");
         goto out;
     }
@@ -1288,7 +847,7 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
 
     TRACE("Setting up the screen\n");
     /* Clear the screen */
 
     TRACE("Setting up the screen\n");
     /* Clear the screen */
-    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+    glClearColor(1.0, 0.0, 0.0, 0.0);
     checkGLcall("glClearColor");
     glClearIndex(0);
     glClearDepth(1);
     checkGLcall("glClearColor");
     glClearIndex(0);
     glClearDepth(1);
@@ -1332,54 +891,30 @@ struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceI
         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, ...");
+            checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...\n");
         }
     }
         }
     }
-    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)");
-    }
-
-    if (GL_SUPPORT(EXT_PROVOKING_VERTEX))
-    {
-        GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
+        checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
     }
     }
-
     LEAVE_GL();
 
     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;
+    }
     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;
 }
 
@@ -1397,9 +932,8 @@ out:
  *  context: Context to remove
  *
  *****************************************************************************/
  *  context: Context to remove
  *
  *****************************************************************************/
-static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_context *context)
-{
-    struct wined3d_context **new_array;
+static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *context) {
+    WineD3DContext **new_array;
     BOOL found = FALSE;
     UINT i;
 
     BOOL found = FALSE;
     UINT i;
 
@@ -1409,6 +943,7 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_cont
     {
         if (This->contexts[i] == context)
         {
     {
         if (This->contexts[i] == context)
         {
+            HeapFree(GetProcessHeap(), 0, context);
             found = TRUE;
             break;
         }
             found = TRUE;
             break;
         }
@@ -1454,35 +989,52 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, struct wined3d_cont
  *  context: Context to destroy
  *
  *****************************************************************************/
  *  context: Context to destroy
  *
  *****************************************************************************/
-void DestroyContext(IWineD3DDeviceImpl *This, struct wined3d_context *context)
-{
-    BOOL destroy;
+void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
+    struct fbo_entry *entry, *entry2;
 
     TRACE("Destroying ctx %p\n", context);
 
 
     TRACE("Destroying ctx %p\n", context);
 
-    if (context->tid == GetCurrentThreadId() || !context->current)
-    {
-        context_destroy_gl_resources(context);
-        destroy = TRUE;
+    /* 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;
+    }
 
 
-        if (!context_set_current(NULL))
-        {
-            ERR("Failed to clear current D3D context.\n");
-        }
+    ENTER_GL();
+
+    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) {
+        context_destroy_fbo_entry(This, entry);
     }
     }
-    else
+    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);
+    }
+
+    LEAVE_GL();
+
+    if (This->activeContext == context)
     {
     {
-        context->destroyed = 1;
-        destroy = FALSE;
+        This->activeContext = NULL;
+        TRACE("Destroying the active context.\n");
     }
 
     }
 
+    /* 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)");
@@ -1512,20 +1064,14 @@ static inline void set_blit_dimension(UINT width, UINT height) {
  *  height: render target height
  *
  *****************************************************************************/
  *  height: render target height
  *
  *****************************************************************************/
-/* Context activation is done by the caller. */
-static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *context, UINT width, UINT height)
-{
-    int i;
+static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
+    int i, sampler;
     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
@@ -1540,10 +1086,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
     /* TODO: Use a display list */
 
     /* Disable shaders */
     /* TODO: Use a display list */
 
     /* Disable shaders */
-    ENTER_GL();
-    This->shader_backend->shader_select(context, FALSE, FALSE);
-    LEAVE_GL();
-
+    This->shader_backend->shader_select((IWineD3DDevice *)This, FALSE, FALSE);
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
 
@@ -1581,8 +1124,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
         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 != WINED3D_UNMAPPED_STAGE)
-        {
+        if (sampler != -1) {
             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);
             }
@@ -1617,12 +1159,11 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
     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.0f);
+                  0.0);
         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
     }
 
         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
     }
 
-    if (sampler != WINED3D_UNMAPPED_STAGE)
-    {
+    if (sampler != -1) {
         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);
@@ -1662,7 +1203,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
     }
     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_COLORWRITEENABLE), StateTable);
+    Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), 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);
@@ -1686,11 +1227,9 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
     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);
-
-    set_blit_dimension(width, height);
-
     LEAVE_GL();
 
     LEAVE_GL();
 
+    set_blit_dimension(width, height);
     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);
@@ -1706,8 +1245,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context
  * 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 struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid)
-{
+static WineD3DContext *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++) {
@@ -1733,44 +1271,34 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *
  * Returns: The needed context
  *
  *****************************************************************************/
  * Returns: The needed context
  *
  *****************************************************************************/
-static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid)
-{
+static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid) {
     IWineD3DSwapChain *swapchain = NULL;
     IWineD3DSwapChain *swapchain = NULL;
-    struct wined3d_context *current_context = context_get_current();
+    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;
     const struct StateEntry *StateTable = This->StateTable;
     const struct StateEntry *StateTable = This->StateTable;
-    struct wined3d_context *context;
-    BOOL old_render_offscreen;
-
-    if (current_context && current_context->destroyed) current_context = NULL;
 
 
-    if (!target)
+    /* 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->current_rt
-                && ((IWineD3DSurfaceImpl *)current_context->surface)->resource.wineD3DDevice == This)
-        {
-            target = current_context->current_rt;
-        }
-        else
+        /* 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))
         {
         {
-            IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
-            if (swapchain->backBuffer) target = swapchain->backBuffer[0];
-            else target = swapchain->frontBuffer;
+            Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
         }
     }
 
         }
     }
 
-    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);
 
-        old_render_offscreen = context->render_offscreen;
-        context->render_offscreen = FALSE;
+        This->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
@@ -1782,161 +1310,157 @@ static inline struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWin
             }
         }
         IWineD3DSwapChain_Release(swapchain);
             }
         }
         IWineD3DSwapChain_Release(swapchain);
-    }
-    else
-    {
+
+        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 {
         TRACE("Rendering offscreen\n");
         TRACE("Rendering offscreen\n");
+        This->render_offscreen = TRUE;
 
 
-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)
+        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:
             {
             {
-                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;
+                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)
-            {
-                if (This->pbufferContext->tid && This->pbufferContext->tid != tid)
-                {
-                    FIXME("The PBuffer context is only supported for one thread for now!\n");
+            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);
                 }
                 }
-                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;
-            }
-        }
-        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);
-            }
+                break;
         }
 
         }
 
-        old_render_offscreen = context->render_offscreen;
-        context->render_offscreen = TRUE;
+        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);
+        }
     }
 
     }
 
-    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);
-    }
+    /* 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;
 
 
-    /* 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;
+        /* 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;
 
 
-        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);
-            }
+        /* 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);
         }
 
         }
 
-        /* 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);
-            }
+        /* Assume that the drawable will be modified by some other things now */
+        IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE);
 
 
-            IWineD3DSurface_ModifyLocation(context->current_rt, SFLAG_INDRAWABLE, FALSE);
-
-            This->isInDraw = oldInDraw;
-        }
+        This->isInDraw = oldInDraw;
     }
 
     }
 
-    context->draw_buffer_dirty = TRUE;
-    context->current_rt = target;
-
     return context;
 }
 
     return context;
 }
 
-/* Context activation is done by the caller. */
-static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit)
+static void apply_draw_buffer(IWineD3DDeviceImpl *This, IWineD3DSurface *target, BOOL blit)
 {
 {
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    IWineD3DSurface *rt = context->current_rt;
     IWineD3DSwapChain *swapchain;
     IWineD3DSwapChain *swapchain;
-    IWineD3DDeviceImpl *device;
 
 
-    device = ((IWineD3DSurfaceImpl *)rt)->resource.wineD3DDevice;
-    if (SUCCEEDED(IWineD3DSurface_GetContainer(rt, &IID_IWineD3DSwapChain, (void **)&swapchain)))
+    if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain)))
     {
         IWineD3DSwapChain_Release((IUnknown *)swapchain);
         ENTER_GL();
     {
         IWineD3DSwapChain_Release((IUnknown *)swapchain);
         ENTER_GL();
-        glDrawBuffer(surface_get_gl_buffer(rt, swapchain));
+        glDrawBuffer(surface_get_gl_buffer(target, swapchain));
         checkGLcall("glDrawBuffers()");
         LEAVE_GL();
     }
         checkGLcall("glDrawBuffers()");
         LEAVE_GL();
     }
@@ -1949,12 +1473,12 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
             {
                 if (GL_SUPPORT(ARB_DRAW_BUFFERS))
                 {
             {
                 if (GL_SUPPORT(ARB_DRAW_BUFFERS))
                 {
-                    GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), device->draw_buffers));
+                    GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), This->draw_buffers));
                     checkGLcall("glDrawBuffers()");
                 }
                 else
                 {
                     checkGLcall("glDrawBuffers()");
                 }
                 else
                 {
-                    glDrawBuffer(device->draw_buffers[0]);
+                    glDrawBuffer(This->draw_buffers[0]);
                     checkGLcall("glDrawBuffer()");
                 }
             } else {
                     checkGLcall("glDrawBuffer()");
                 }
             } else {
@@ -1964,7 +1488,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
         }
         else
         {
         }
         else
         {
-            glDrawBuffer(device->offscreenBuffer);
+            glDrawBuffer(This->offscreenBuffer);
             checkGLcall("glDrawBuffer()");
         }
         LEAVE_GL();
             checkGLcall("glDrawBuffer()");
         }
         LEAVE_GL();
@@ -1984,75 +1508,89 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
  *  usage: Prepares the context for blitting, drawing or other actions
  *
  *****************************************************************************/
  *  usage: Prepares the context for blitting, drawing or other actions
  *
  *****************************************************************************/
-struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
-{
-    struct wined3d_context *current_context = context_get_current();
+void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
     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);
-
-    context = FindContext(This, target, tid);
-
-    gl_info = context->gl_info;
+    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 */
 
     /* 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(last_device != This || context != This->activeContext) {
+        BOOL ret;
 
 
-        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);
+        /* Prevent an unneeded context switch as those are expensive */
+        if(context->glCtx && (context->glCtx == pwglGetCurrentContext())) {
+            TRACE("Already using gl context %p\n", context->glCtx);
         }
         }
-        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);
+        else {
+            TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
+
+            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));
+        }
+        if(This->activeContext->pshader_const_dirty) {
+            memset(This->activeContext->pshader_const_dirty, 1,
+                   sizeof(*This->activeContext->pshader_const_dirty) * 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) {
-                ENTER_GL();
-                context_apply_fbo_state(context);
-                LEAVE_GL();
+                context_apply_fbo_state((IWineD3DDevice *)This);
             }
             if (context->draw_buffer_dirty) {
             }
             if (context->draw_buffer_dirty) {
-                context_apply_draw_buffer(context, FALSE);
+                apply_draw_buffer(This, target, 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 (context->render_offscreen)
-                {
+                if (This->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();
-                    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);
+                    GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
+                    checkGLcall("glFramebufferRenderbufferEXT");
                     LEAVE_GL();
                 } else {
                     ENTER_GL();
                     LEAVE_GL();
                 } else {
                     ENTER_GL();
-                    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+                    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+                    checkGLcall("glFramebufferRenderbufferEXT");
                     LEAVE_GL();
                 }
                 context->draw_buffer_dirty = TRUE;
             }
             if (context->draw_buffer_dirty) {
                     LEAVE_GL();
                 }
                 context->draw_buffer_dirty = TRUE;
             }
             if (context->draw_buffer_dirty) {
-                context_apply_draw_buffer(context, TRUE);
+                apply_draw_buffer(This, target, 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;
                 }
@@ -2098,7 +1636,6 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
 
             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;
@@ -2106,7 +1643,6 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
                 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;
@@ -2120,6 +1656,8 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
         default:
             FIXME("Unexpected context usage requested\n");
     }
         default:
             FIXME("Unexpected context usage requested\n");
     }
+}
 
 
-    return context;
+WineD3DContext *getActiveContext(void) {
+    return last_device->activeContext;
 }
 }
index 4b6900a..ce5f6b6 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 (*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
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 /* *******************************************
    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;
@@ -321,6 +91,65 @@ 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);
 }
@@ -390,7 +219,6 @@ 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;
@@ -429,13 +257,36 @@ 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;
-
-    cubetexture_cleanup(This, D3DCB_DestroySurface);
+    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);
     /* finally delete the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
     /* finally delete the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -548,6 +399,7 @@ 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 58e3b69..ec6d3f0 100644 (file)
@@ -38,29 +38,26 @@ 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.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 */
+    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 */
 };
 
 };
 
+/* static function declarations */
+static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource);
+
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
 /**********************************************************
  * Global variable / Constants follow
  **********************************************************/
-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 */
+const float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};  /* 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. */
@@ -172,7 +169,6 @@ 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)
 {
@@ -182,8 +178,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
     const DWORD *streams = declaration->streams;
     unsigned int i;
 
     const DWORD *streams = declaration->streams;
     unsigned int i;
 
-    stream_info->use_map = 0;
-    stream_info->swizzle_map = 0;
+    memset(stream_info, 0, sizeof(*stream_info));
 
     /* 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;
@@ -445,7 +440,6 @@ 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;
 
@@ -463,8 +457,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
 
     FIXME("Ignoring access flags (pool)\n");
 
 
     FIXME("Ignoring access flags (pool)\n");
 
-    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, desc->byte_width,
-            desc->usage, format_desc, WINED3DPOOL_MANAGED, parent);
+    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, desc->byte_width,
+            desc->usage, WINED3DFMT_UNKNOWN, 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);
@@ -475,6 +469,8 @@ 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);
 
@@ -539,7 +535,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
-    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
+    hr = resource_init(&object->resource, 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);
@@ -551,6 +547,8 @@ 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;
 
@@ -604,7 +602,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
-    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
+    hr = resource_init(&object->resource, 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);
@@ -616,6 +614,8 @@ 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,45 +897,171 @@ 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,
-        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, WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool,
+        WINED3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, WINED3DSURFTYPE Impl, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DSurfaceImpl *object;
+    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;
     HRESULT hr;
 
     TRACE("(%p) Create surface\n",This);
 
     HRESULT hr;
 
     TRACE("(%p) Create surface\n",This);
 
-    if (Impl == SURFACE_OPENGL && !This->adapter)
-    {
-        ERR("OpenGL surfaces are not available without OpenGL.\n");
-        return WINED3DERR_NOTAVAILABLE;
+    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(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("Failed to allocate surface memory.\n");
+        ERR("Out of memory\n");
         *ppSurface = NULL;
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
         *ppSurface = NULL;
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
-    hr = surface_init(object, Impl, This->surface_alignment, Width, Height, Level, Lockable,
-            Discard, MultiSample, MultisampleQuality, This, Usage, Format, Pool, parent);
+    /* 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);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize surface, returning %#x.\n", hr);
+        WARN("Failed to initialize resource, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppSurface = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppSurface = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created surface %p\n", This, object);
+    TRACE("(%p) : Created resource %p\n", This, object);
+
+    IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)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;
 }
 
@@ -967,13 +1093,73 @@ 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)
     {
@@ -983,20 +1169,106 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
     }
 
     object->lpVtbl = &IWineD3DTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DTexture_Vtbl;
-
-    hr = texture_init(object, Width, Height, Levels, This, Usage, Format, Pool, parent);
+    hr = resource_init(&object->resource, WINED3DRTYPE_TEXTURE, This, 0, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize texture, returning %#x\n", hr);
+        WARN("Failed to initialize resource, 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;
 
-    TRACE("(%p) : Created texture %p\n", This, 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;
+        }
 
 
+        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;
 }
 
@@ -1005,11 +1277,47 @@ 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;
 
-    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));
+    /* 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);
+    }
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
@@ -1020,18 +1328,69 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
     }
 
     object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DVolumeTexture_Vtbl;
-    hr = volumetexture_init(object, Width, Height, Depth, Levels, This, Usage, Format, Pool, parent);
+    hr = resource_init(&object->resource, WINED3DRTYPE_VOLUMETEXTURE, This, 0, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize volumetexture, returning %#x\n", hr);
+        WARN("Failed to initialize resource, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppVolumeTexture = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppVolumeTexture = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created volume texture %p.\n", This, object);
-    *ppVolumeTexture = (IWineD3DVolumeTexture *)object;
+    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;
 
 
+    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;
 }
 
@@ -1058,7 +1417,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
     }
 
     object->lpVtbl = &IWineD3DVolume_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DVolume_Vtbl;
-    hr = resource_init((IWineD3DResource *)object, WINED3DRTYPE_VOLUME, This,
+    hr = resource_init(&object->resource, 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))
     {
@@ -1070,6 +1429,8 @@ 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,
@@ -1095,8 +1456,47 @@ 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)
@@ -1107,18 +1507,85 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
     }
 
     object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
     }
 
     object->lpVtbl = &IWineD3DCubeTexture_Vtbl;
-    hr = cubetexture_init(object, EdgeLength, Levels, This, Usage, Format, Pool, parent);
+    hr = resource_init(&object->resource, WINED3DRTYPE_CUBETEXTURE, This, 0, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
     if (FAILED(hr))
     {
-        WARN("Failed to initialize cubetexture, returning %#x\n", hr);
+        WARN("Failed to initialize resource, returning %#x\n", hr);
         HeapFree(GetProcessHeap(), 0, object);
         *ppCubeTexture = NULL;
         return hr;
     }
 
         HeapFree(GetProcessHeap(), 0, object);
         *ppCubeTexture = NULL;
         return hr;
     }
 
-    TRACE("(%p) : Created Cube Texture %p\n", This, object);
-    *ppCubeTexture = (IWineD3DCubeTexture *)object;
+    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);
+    *ppCubeTexture = (IWineD3DCubeTexture *) object;
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -1192,13 +1659,32 @@ 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(), 0, sizeof(struct wined3d_occlusion_query));
-        ((struct wined3d_occlusion_query *)object->extendedData)->context = NULL;
-        break;
+        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);
 
 
+            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(), 0, sizeof(struct wined3d_event_query));
-        ((struct wined3d_event_query *)object->extendedData)->context = NULL;
+        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();
         break;
 
     case WINED3DQUERYTYPE_VCACHE:
         break;
 
     case WINED3DQUERYTYPE_VCACHE:
@@ -1841,10 +2327,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3D
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
-        const DWORD *pFunction, const struct wined3d_shader_signature *output_signature,
-        IWineD3DVertexShader **ppVertexShader, IUnknown *parent)
-{
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, IWineD3DVertexDeclaration *vertex_declaration, CONST DWORD *pFunction, 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;
@@ -1867,7 +2350,11 @@ 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);
 
-    hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, output_signature);
+    if (vertex_declaration) {
+        IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
+    }
+
+    hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, NULL);
     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);
@@ -1981,8 +2468,9 @@ 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, 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, WINED3DRTYPE_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;
@@ -2012,7 +2500,6 @@ 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
@@ -2114,12 +2601,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] = WINED3D_UNMAPPED_STAGE;
-            This->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE;
+            This->texUnitMap[state] = -1;
+            This->rev_tex_unit_map[state] = -1;
         }
     }
 
         }
     }
 
-    /* Setup the implicit swapchain. This also initializes a context. */
+    /* Setup the implicit swapchain */
     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);
@@ -2140,12 +2627,16 @@ 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;
@@ -2191,8 +2682,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
 
         case ORM_BACKBUFFER:
         {
 
         case ORM_BACKBUFFER:
         {
-            if (context_get_current()->aux_buffers > 0)
-            {
+            if(This->activeContext->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 {
@@ -2208,7 +2698,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.0f, 0);
+                          0x00, 1.0, 0);
 
     This->d3d_initialized = TRUE;
 
 
     This->d3d_initialized = TRUE;
 
@@ -2297,7 +2787,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, NULL, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
 
     if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
 
 
     if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
 
@@ -2344,15 +2834,11 @@ 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;
@@ -2783,8 +3269,7 @@ 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.0f || pLight->Attenuation1 < 0.0f || pLight->Attenuation2 < 0.0f)
-            {
+            if(pLight->Attenuation0 < 0.0 || pLight->Attenuation1 < 0.0 || pLight->Attenuation2 < 0.0) {
                 WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
                 return WINED3DERR_INVALIDCALL;
             }
                 WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL\n");
                 return WINED3DERR_INVALIDCALL;
             }
@@ -2846,7 +3331,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.0f;
+        object->lightPosn[3] = 0.0;
         object->exponent     = 0.0f;
         object->cutoff       = 180.0f;
         break;
         object->exponent     = 0.0f;
         object->cutoff       = 180.0f;
         break;
@@ -2856,13 +3341,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.0f;
+        object->lightPosn[3] = 1.0;
 
         /* 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.0f;
+        object->lightDirn[3] = 1.0;
 
         /*
          * 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
@@ -2877,15 +3362,14 @@ 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.0f;
+            object->exponent = 0;
         } 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.0001f) rho = 0.0001f;
-            object->exponent = -0.3f/logf(cosf(rho/2));
+            if (rho < 0.0001) rho = 0.0001f;
+            object->exponent = -0.3/log(cos(rho/2));
         }
         }
-        if (object->exponent > 128.0f)
-        {
-            object->exponent = 128.0f;
+        if (object->exponent > 128.0) {
+            object->exponent = 128.0;
         }
         object->cutoff = pLight->Phi*90/M_PI;
 
         }
         object->cutoff = pLight->Phi*90/M_PI;
 
@@ -2936,6 +3420,9 @@ 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;
@@ -3636,21 +4123,18 @@ static inline void markTextureStagesDirty(IWineD3DDeviceImpl *This, DWORD 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];
+static void device_map_stage(IWineD3DDeviceImpl *This, int stage, int unit) {
+    int i = This->rev_tex_unit_map[unit];
+    int j = This->texUnitMap[stage];
 
     This->texUnitMap[stage] = unit;
 
     This->texUnitMap[stage] = unit;
-    if (i != WINED3D_UNMAPPED_STAGE && i != stage)
-    {
-        This->texUnitMap[i] = WINED3D_UNMAPPED_STAGE;
+    if (i != -1 && i != stage) {
+        This->texUnitMap[i] = -1;
     }
 
     This->rev_tex_unit_map[unit] = stage;
     }
 
     This->rev_tex_unit_map[unit] = stage;
-    if (j != WINED3D_UNMAPPED_STAGE && j != unit)
-    {
-        This->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
+    if (j != -1 && j != unit) {
+        This->rev_tex_unit_map[j] = -1;
     }
 }
 
     }
 }
 
@@ -3744,12 +4228,14 @@ 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, DWORD unit)
+        const DWORD *vshader_sampler_tokens, int unit)
 {
 {
-    DWORD current_mapping = This->rev_tex_unit_map[unit];
+    int current_mapping = This->rev_tex_unit_map[unit];
 
 
-    /* Not currently used */
-    if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE;
+    if (current_mapping == -1) {
+        /* Not currently used */
+        return TRUE;
+    }
 
     if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
         /* Used by a fragment sampler */
 
     if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
         /* Used by a fragment sampler */
@@ -3764,14 +4250,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 - MAX_FRAGMENT_SAMPLERS];
+    return !vshader_sampler_tokens[current_mapping];
 }
 
 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 = min(MAX_COMBINED_SAMPLERS, GL_LIMITS(combined_samplers)) - 1;
+    int start = GL_LIMITS(combined_samplers) - 1;
     int i;
 
     if (ps) {
     int i;
 
     if (ps) {
@@ -3783,7 +4269,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) {
-        DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
+        int 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)
@@ -4024,7 +4510,6 @@ 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,
@@ -4037,12 +4522,12 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
     BOOL doClip;
     DWORD numTextures;
 
     BOOL doClip;
     DWORD numTextures;
 
-    if (stream_info->use_map & (1 << WINED3D_FFP_NORMAL))
+    if (stream_info->elements[WINED3D_FFP_NORMAL].data)
     {
         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->use_map & (1 << WINED3D_FFP_POSITION)))
+    if (!stream_info->elements[WINED3D_FFP_POSITION].data)
     {
         ERR("Source has no position mask\n");
         return WINED3DERR_INVALIDCALL;
     {
         ERR("Source has no position mask\n");
         return WINED3DERR_INVALIDCALL;
@@ -4152,10 +4637,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.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);
+            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);
 
             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);
 
@@ -4178,7 +4663,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)
@@ -4275,8 +4760,7 @@ 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 (!(stream_info->use_map & (1 << WINED3D_FFP_DIFFUSE)))
-            {
+            if(!color_d) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
@@ -4303,13 +4787,11 @@ 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 (!(stream_info->use_map & (1 << WINED3D_FFP_SPECULAR)))
-            {
+            if(!color_s) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
                 static BOOL warned = FALSE;
 
                 if(!warned) {
@@ -4339,8 +4821,7 @@ 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 (!(stream_info->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + tex_index))))
-            {
+            if(!tex_coord) {
                 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);
@@ -4384,7 +4865,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, NULL, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, This->lastActiveRenderTarget, 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.
@@ -4402,11 +4883,7 @@ 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;
-
-            if (!(stream_info.use_map & (1 << i))) continue;
-
-            e = &stream_info.elements[i];
+            struct wined3d_stream_info_element *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];
@@ -4854,9 +5331,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) {
         return WINED3DERR_INVALIDCALL;
     }
 
         return WINED3DERR_INVALIDCALL;
     }
 
-    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, This->lastActiveRenderTarget, 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 */
-    wglFlush();
+    glFlush();
     /* 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
      */
@@ -4898,7 +5375,6 @@ 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
@@ -4934,10 +5410,9 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
         }
     }
 
         }
     }
 
-    context = ActivateContext(This, (IWineD3DSurface *)target, CTXUSAGE_CLEAR);
-
-    target->get_drawable_size(context, &drawable_width, &drawable_height);
+    target->get_drawable_size(target, &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 */
@@ -4949,7 +5424,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
     }
 
     if (Flags & WINED3DCLEAR_ZBUFFER) {
     }
 
     if (Flags & WINED3DCLEAR_ZBUFFER) {
-        DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
         glDepthMask(GL_TRUE);
         glClearDepth(Z);
         checkGLcall("glClearDepth");
         glDepthMask(GL_TRUE);
         glClearDepth(Z);
         checkGLcall("glClearDepth");
@@ -4958,19 +5433,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, context, location);
+            surface_load_ds_location(This->stencilBufferTarget, 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, context, location);
+            surface_load_ds_location(This->stencilBufferTarget, 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, context, location);
+            surface_load_ds_location(This->stencilBufferTarget, location);
         }
     }
 
         }
     }
 
@@ -4995,8 +5470,7 @@ 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 (context->render_offscreen)
-        {
+        if(This->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 {
@@ -5028,8 +5502,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This,  IWineD3DSurfa
                 continue;
             }
 
                 continue;
             }
 
-            if (context->render_offscreen)
-            {
+            if(This->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 {
@@ -5057,11 +5530,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((IWineD3DSurface *)target, SFLAG_INDRAWABLE, TRUE);
+        IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, 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 = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
+        DWORD location = This->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
         surface_modify_ds_location(This->stencilBufferTarget, location);
     }
 
         surface_modify_ds_location(This->stencilBufferTarget, location);
     }
 
@@ -5069,7 +5542,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) {
-            wglFlush();
+            glFlush();
         }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
         }
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
@@ -5730,7 +6203,6 @@ 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;
@@ -5739,28 +6211,31 @@ 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;
-    DWORD sampler;
+    int 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);
-    srcSurfaceWidth = winedesc.width;
-    srcSurfaceHeight = winedesc.height;
-    srcPool = winedesc.pool;
-    srcFormat = winedesc.format;
+
+    winedesc.Width  = &destSurfaceWidth;
+    winedesc.Height = &destSurfaceHeight;
+    winedesc.Pool   = &destPool;
+    winedesc.Format = &destFormat;
+    winedesc.Size   = &destSize;
 
     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);
@@ -5771,7 +6246,8 @@ 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(dst_impl, FALSE, TRUE, &dummy, &dummy, &dummy, &convert, &bpp, FALSE);
+    d3dfmt_get_conv((IWineD3DSurfaceImpl *) pDestinationSurface, 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,
@@ -5787,7 +6263,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
     }
 
         IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
     }
 
-    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
 
     ENTER_GL();
     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
 
     ENTER_GL();
     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
@@ -5798,8 +6274,10 @@ 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 = dst_impl->resource.format_desc;
+    dst_format_desc = ((IWineD3DSurfaceImpl *)pDestinationSurface)->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;
@@ -5822,7 +6300,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, dst_impl->texture_level, destLeft, destTop, srcWidth, srcHeight, dst_format_desc->glFormat,
+            This, glDescription->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 */
@@ -5844,7 +6322,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
 
         for (j = destTop; j < (srcHeight + destTop); ++j)
         {
 
         for (j = destTop; j < (srcHeight + destTop); ++j)
         {
-            glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, j,
+            glTexSubImage2D(glDescription->target, glDescription->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;
         }
@@ -5852,26 +6330,28 @@ 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 (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");
-            }
-            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));
+        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");
             }
             }
-        }
-        else
-        {
-            glTexSubImage2D(dst_impl->texture_target, dst_impl->texture_level, destLeft, destTop,
+
+
+        } else {
+            glTexSubImage2D(glDescription->target, glDescription->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);
         }
      }
@@ -5881,8 +6361,7 @@ 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 != WINED3D_UNMAPPED_STAGE)
-    {
+    if (sampler != -1) {
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
     }
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
     }
 
@@ -6024,7 +6503,6 @@ 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);
@@ -6033,20 +6511,21 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
         TRACE("Surface %p is onscreen\n", surface);
 
 
         TRACE("Surface %p is onscreen\n", surface);
 
-        context = ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
         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);
 
-        context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        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);
+        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");
     }
 
     if (rect) {
     }
 
     if (rect) {
@@ -6074,6 +6553,13 @@ 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);
@@ -6211,7 +6697,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_POINT);
+                WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
     }
 }
 
     }
 }
 
@@ -6249,16 +6735,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.0f));
-        c |= ((DWORD)(color[1] * 255.0f)) << 8;
-        c |= ((DWORD)(color[0] * 255.0f)) << 16;
-        c |= ((DWORD)(color[3] * 255.0f)) << 24;
+        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;
 
         /* 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_POINT);
+        hr = IWineD3DSurface_Blt(surface, NULL, NULL, NULL, WINEDDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE);
         if (FAILED(hr))
         {
             ERR("Blt failed, hr %#x\n", hr);
         if (FAILED(hr))
         {
             ERR("Blt failed, hr %#x\n", hr);
@@ -6343,8 +6829,6 @@ 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,
@@ -6403,7 +6887,6 @@ 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};
 
@@ -6427,16 +6910,11 @@ 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);
@@ -6456,25 +6934,28 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
         }
 
         ENTER_GL();
-        context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL);
+        GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
         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(context, GL_READ_FRAMEBUFFER_EXT, &context->src_fbo);
-        context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
+        context_bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
+        context_attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glReadBuffer()");
         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glReadBuffer()");
-        context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL, FALSE);
+        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
+        checkGLcall("glFramebufferRenderbufferEXT");
     }
     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);
@@ -6495,18 +6976,24 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
         }
 
         ENTER_GL();
-        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL);
+        GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
         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(context, GL_DRAW_FRAMEBUFFER_EXT, &context->dst_fbo);
-        context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
+        context_bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
+        context_attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glDrawBuffer()");
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glDrawBuffer()");
-        context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL, FALSE);
+        GL_EXTCALL(glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
+        checkGLcall("glFramebufferRenderbufferEXT");
     }
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
     }
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
@@ -6523,6 +7010,13 @@ 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) {
@@ -6576,6 +7070,10 @@ 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;
 }
@@ -6602,8 +7100,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 {
-                struct wined3d_context *context = ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
-                surface_load_ds_location(This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN);
+                ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
+                surface_load_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
             }
         }
                 surface_modify_ds_location(This->stencilBufferTarget, SFLAG_DS_OFFSCREEN);
             }
         }
@@ -6637,7 +7135,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
 
     /* some basic validation checks */
     if(This->cursorTexture) {
 
     /* some basic validation checks */
     if(This->cursorTexture) {
-        ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         glDeleteTextures(1, &This->cursorTexture);
         LEAVE_GL();
         ENTER_GL();
         glDeleteTextures(1, &This->cursorTexture);
         LEAVE_GL();
@@ -6687,8 +7185,7 @@ 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;
-                DWORD sampler;
-                INT i;
+                INT i, sampler;
 
                 /* Reformat the texture memory (pitch and width can be
                  * different) */
 
                 /* Reformat the texture memory (pitch and width can be
                  * different) */
@@ -6696,9 +7193,6 @@ 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)) {
@@ -6710,8 +7204,7 @@ 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 != WINED3D_UNMAPPED_STAGE)
-                {
+                if (sampler != -1) {
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
                 }
                 /* Create a new cursor texture */
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(sampler));
                 }
                 /* Create a new cursor texture */
@@ -6848,21 +7341,14 @@ 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;
-    TRACE("(%p)\n", This);
-
-    IWineD3DDevice_EnumResources(iface, evict_managed_resource, NULL);
+    /** 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);
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -6897,13 +7383,12 @@ 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->texture_name)
-    {
-        ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    if(surface->glDescription.textureName) {
+        ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
         ENTER_GL();
-        glDeleteTextures(1, &surface->texture_name);
+        glDeleteTextures(1, &surface->glDescription.textureName);
         LEAVE_GL();
         LEAVE_GL();
-        surface->texture_name = 0;
+        surface->glDescription.textureName = 0;
         surface->Flags &= ~SFLAG_CLIENT;
     }
     if(surface->pow2Width != pPresentationParameters->BackBufferWidth ||
         surface->Flags &= ~SFLAG_CLIENT;
     }
     if(surface->pow2Width != pPresentationParameters->BackBufferWidth ||
@@ -6964,8 +7449,6 @@ 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);
@@ -7000,6 +7483,7 @@ 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;
@@ -7021,6 +7505,7 @@ 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);
 
@@ -7290,36 +7775,69 @@ 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.)
  *****************************************************/
-void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
-{
-    TRACE("(%p) : Adding resource %p\n", This, resource);
+static void IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3DResource *resource){
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
 
+    TRACE("(%p) : Adding Resource %p\n", This, resource);
     list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
     list_add_head(&This->resources, &((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
 }
 
-static void device_resource_remove(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
-{
+static void IWineD3DDeviceImpl_RemoveResource(IWineD3DDevice *iface, IWineD3DResource *resource){
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
     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);
 }
 
-void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource)
-{
+
+static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DResource *resource){
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     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((IWineD3DDevice *)This, resource, type);
+    context_resource_released(iface, 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;
 
-            if (This->d3d_initialized)
-            {
+            /* 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;
+                    }
+                }
+
                 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;
@@ -7395,7 +7913,7 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour
 
 
     /* Remove the resource from the resourceStore */
 
 
     /* Remove the resource from the resourceStore */
-    device_resource_remove(This, resource);
+    IWineD3DDeviceImpl_RemoveResource(iface, resource);
 
     TRACE("Resource released\n");
 
 
     TRACE("Resource released\n");
 
@@ -7567,6 +8085,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_UpdateSurface,
     IWineD3DDeviceImpl_GetFrontBufferData,
     /*** object tracking ***/
     IWineD3DDeviceImpl_UpdateSurface,
     IWineD3DDeviceImpl_GetFrontBufferData,
     /*** object tracking ***/
+    IWineD3DDeviceImpl_ResourceReleased,
     IWineD3DDeviceImpl_EnumResources
 };
 
     IWineD3DDeviceImpl_EnumResources
 };
 
@@ -7690,11 +8209,12 @@ 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;
@@ -7706,29 +8226,28 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
     }
 }
 
     }
 }
 
-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_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_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_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_backbuffer(struct wined3d_context *context, UINT *width, UINT *height)
-{
-    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->surface;
+void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
+    IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice;
     /* 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 = surface->currentDesc.Width;
-    *height = surface->currentDesc.Height;
+     * surface the context belongs to.
+     */
+    *width = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Width;
+    *height = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Height;
 }
 }
index b971855..9a064bb 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);
@@ -55,8 +63,6 @@ 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_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                           },
@@ -97,10 +103,8 @@ 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                           },
@@ -136,9 +140,7 @@ 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                           },
 
@@ -169,32 +171,19 @@ const int maxLookup[MAX_LOOKUPS] =
 
 DWORD *stateLookup[MAX_LOOKUPS];
 
 
 DWORD *stateLookup[MAX_LOOKUPS];
 
-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 GLenum magLookup[] =
+struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
 {
 {
-    /* NONE     POINT       LINEAR */
-    GL_NEAREST, GL_NEAREST, GL_LINEAR,
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+    {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
 };
 
 };
 
-const GLenum magLookup_noFilter[] =
+GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
 {
 {
-    /* NONE     POINT       LINEAR */
-    GL_NEAREST, GL_NEAREST, GL_NEAREST,
+    GL_NEAREST, GL_NEAREST, GL_NEAREST, GL_NEAREST
 };
 
 /* drawStridedSlow attributes */
 };
 
 /* drawStridedSlow attributes */
@@ -211,104 +200,132 @@ glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
  * function query some info from GL.
  */
 
  * function query some info from GL.
  */
 
-struct wined3d_fake_gl_ctx
+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 =
 {
 {
-    HDC dc;
-    HWND wnd;
-    HGLRC 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") }
 };
 };
+static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };
 
 
-static void WineD3D_ReleaseFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
-{
-    TRACE_(d3d_caps)("Destroying fake GL context.\n");
+static void WineD3D_ReleaseFakeGLContext(void) {
+    HGLRC glCtx;
 
 
-    if (!pwglMakeCurrent(NULL, NULL))
-    {
-        ERR_(d3d_caps)("Failed to disable fake GL context.\n");
+    EnterCriticalSection(&wined3d_fake_gl_context_cs);
+
+    if(!wined3d_fake_gl_context_available) {
+        TRACE_(d3d_caps)("context not available\n");
+        LeaveCriticalSection(&wined3d_fake_gl_context_cs);
+        return;
     }
 
     }
 
-    if (!pwglDeleteContext(ctx->gl_ctx))
-    {
-        DWORD err = GetLastError();
-        ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
+    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;
     }
     }
+    assert(wined3d_fake_gl_context_ref >= 0);
 
 
-    ReleaseDC(ctx->wnd, ctx->dc);
-    DestroyWindow(ctx->wnd);
+    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
 }
 
 }
 
-static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
-{
-    PIXELFORMATDESCRIPTOR pfd;
-    int iPixelFormat;
+static BOOL WineD3D_CreateFakeGLContext(void) {
+    HGLRC glCtx = NULL;
+
+    EnterCriticalSection(&wined3d_fake_gl_context_cs);
 
     TRACE("getting context...\n");
 
     TRACE("getting context...\n");
+    if(wined3d_fake_gl_context_ref > 0) goto ret;
+    assert(0 == wined3d_fake_gl_context_ref);
 
 
-    /* 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;
-    }
+    wined3d_fake_gl_context_foreign = TRUE;
 
 
-    ctx->dc = GetDC(ctx->wnd);
-    if (!ctx->dc)
-    {
-        ERR_(d3d_caps)("Failed to get a DC.\n");
-        goto fail;
-    }
+    glCtx = pwglGetCurrentContext();
+    if (!glCtx) {
+        PIXELFORMATDESCRIPTOR pfd;
+        int iPixelFormat;
 
 
-    /* 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);
+        wined3d_fake_gl_context_foreign = FALSE;
 
 
-    /* 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;
-    }
+        /* 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;
+        }
 
 
-    /* Make it the current GL context. */
-    if (!context_set_current(NULL))
-    {
-        ERR_(d3d_caps)("Failed to clear current D3D context.\n");
-    }
+        /* 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;
+        }
 
 
-    if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
-    {
-        ERR_(d3d_caps)("Failed to make fake GL context current.\n");
-        goto fail;
+        /* 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;
+        }
     }
 
     }
 
+  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 (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;
-
+  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);
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -370,8 +387,7 @@ 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 struct wined3d_gl_info *gl_info,
-        WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
+static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
 {
     if (wined3d_settings.vs_mode == VS_NONE) {
         *vs_selected = SHADER_NONE;
 {
     if (wined3d_settings.vs_mode == VS_NONE) {
         *vs_selected = SHADER_NONE;
@@ -379,7 +395,7 @@ static void select_shader_mode(const struct wined3d_gl_info *gl_info,
         /* 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->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2])
+        if(gl_info->vs_nv_version && gl_info->vs_nv_version < VS_VERSION_20)
             *vs_selected = SHADER_ARB;
         else
             *vs_selected = SHADER_GLSL;
             *vs_selected = SHADER_ARB;
         else
             *vs_selected = SHADER_GLSL;
@@ -403,8 +419,11 @@ static void select_shader_mode(const struct wined3d_gl_info *gl_info,
 }
 
 /** 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, struct wined3d_gl_info *gl_info)
-{
+static void select_shader_max_constants(
+    int ps_selected_mode,
+    int vs_selected_mode,
+    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;
@@ -434,8 +453,7 @@ static void select_shader_max_constants(int ps_selected_mode, int vs_selected_mo
  * IWineD3D parts follows
  **********************************************************/
 
  * IWineD3D parts follows
  **********************************************************/
 
-/* GL locking is done by the caller */
-static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
+static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
 {
     GLuint prog;
     BOOL ret = FALSE;
 {
     GLuint prog;
     BOOL ret = FALSE;
@@ -464,7 +482,7 @@ static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_inf
 
     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");
+    checkGLcall("ARB vp offset limit test cleanup\n");
 
     return ret;
 }
 
     return ret;
 }
@@ -480,1377 +498,529 @@ static DWORD ver_for_ext(GL_SupportedExt ext)
     return 0;
 }
 
     return 0;
 }
 
-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;
-}
+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;
 
 
-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;
+    TRACE_(d3d_caps)("(%p)\n", gl_info);
+
+    ENTER_GL();
+
+    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;
         }
         }
+    } 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])
-    {
-        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;
-    }
-}
 
 
-/* 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])];
+    TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
 
 
-    /* No PBO -> No point in testing them. */
-    if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
+    /* Parse the GL_VERSION field into major and minor information */
+    gl_string = (const char *) glGetString(GL_VERSION);
+    if (gl_string != NULL) {
 
 
-    ENTER_GL();
+        /* 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);
 
 
-    while (glGetError());
-    glGenTextures(1, &texture);
-    glBindTexture(GL_TEXTURE_2D, texture);
+        /* 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;
+            }
 
 
-    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");
+            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;
+            }
 
 
-    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");
+            while (*gl_string_cursor == ' ') {
+                ++gl_string_cursor;
+            }
 
 
-    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");
+            if (!*gl_string_cursor) {
+                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
+                break;
+            }
 
 
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-    wglFinish(); /* just to be sure */
+            major = atoi(gl_string_cursor);
+            while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
+                ++gl_string_cursor;
+            }
 
 
-    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");
+            if (*gl_string_cursor++ != '.') {
+                ERR_(d3d_caps)("Invalid nVidia version string: %s\n", debugstr_a(gl_string));
+                break;
+            }
 
 
-    glDeleteTextures(1, &texture);
-    GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
-    checkGLcall("PBO test cleanup");
+            minor = atoi(gl_string_cursor);
+            minor = major*100+minor;
+            major = 10;
 
 
-    LEAVE_GL();
+            break;
 
 
-    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");
-    }
-}
+        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;
+            }
 
 
-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);
-}
+            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_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;
-}
+        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_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;
-}
+                if (*gl_string_cursor++ != '.') {
+                    ERR_(d3d_caps)("Invalid MacOS-Intel version string: %s\n", debugstr_a(gl_string));
+                    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;
-}
+                minor = atoi(gl_string_cursor);
+                break;
+            }
 
 
-/* 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];
+        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);
 
 
-    if(!GL_SUPPORT(EXT_SECONDARY_COLOR)) return FALSE;
+                if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
+                ++gl_string_cursor;
 
 
-    ENTER_GL();
-    while(glGetError());
-    GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
-    error = glGetError();
-    LEAVE_GL();
+                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;
 
 
-    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;
+        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);
     }
     }
-}
-
-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;
-}
 
 
-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);
-}
+    TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
 
 
-/* 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;
-    }
-}
+    /*
+     * 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_ati_dx9(struct wined3d_gl_info *gl_info)
-{
-    quirk_arb_constants(gl_info);
+    /* 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);
 
 
-    /* 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;
-    }
+    glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
+    gl_info->max_lights = gl_max;
+    TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
 
 
-    /* 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);
-}
+    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);
 
 
-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;
-}
-
-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;
-                }
+    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]);
 
 
-                /* 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;
-                }
+    /* 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");
 
 
-                /* Geforce6/7 lowend */
-                *vidmem = 64; /* */
-                return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
+    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++;
             }
 
             }
 
-            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;
-                }
-
-                /* 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;
-                }
+            len = GL_Extensions - Start;
+            if (len == 0 || len >= sizeof(ThisExtn))
+                continue;
 
 
-                /* 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 */
-            }
+            memcpy(ThisExtn, Start, len);
+            ThisExtn[len] = '\0';
+            TRACE_(d3d_caps)("- %s\n", ThisExtn);
 
 
-            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 */
+            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;
                 }
                 }
-
-                *vidmem = 64; /* Geforce3 cards have 64-128MB */
-                return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
             }
             }
+        }
 
 
-            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 */
-                }
-
-                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 */
-                }
+        LEAVE_GL();
 
 
-                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 */
-                }
+        /* 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
 
 
-                /* 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 */
-            }
+#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, "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 */
+        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;
             }
             }
+        }
 
 
-            *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
+        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
              *
              *
-             * 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 */
+             * 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 (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_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_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_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;
             }
             }
-
-            *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;
+        }
+        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);
             }
             }
+            TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
 
 
-            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;
+            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, "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 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;
             }
             }
+            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);
         }
         }
-    }
-
-    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_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[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_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[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[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_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 (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_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[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);
         }
         }
-        else
-        {
-            gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
+        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);
         }
         }
-        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[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);
         }
         }
-        else
-        {
-            gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
+        if (gl_info->supported[EXT_VERTEX_SHADER]) {
+            gl_info->vs_ati_version = VS_VERSION_11;
         }
         }
-        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[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;
         }
         }
-        else
-        {
-            gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
+        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[NV_LIGHT_MAX_EXPONENT]) {
+            glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->max_shininess);
+        } else {
+            gl_info->max_shininess = 128.0;
+        }
+        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;
         }
         }
-        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_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();
+    checkGLcall("extension detection\n");
 
     /* 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
@@ -1859,8 +1029,8 @@ static BOOL IWineD3DImpl_FillGLCaps(struct 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 backbuffer offscreen rendering mode.\n");
-        wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+        WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
+        wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
     }
 
     /* MRTs are currently only supported when FBOs are used. */
     }
 
     /* MRTs are currently only supported when FBOs are used. */
@@ -1868,7 +1038,357 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info)
         gl_info->max_buffers = 1;
     }
 
         gl_info->max_buffers = 1;
     }
 
-    gl_info->gl_card = wined3d_guess_card(gl_info, gl_renderer, &gl_info->gl_vendor, &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
+     * 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;
+    }
     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;  */
@@ -1893,6 +1413,31 @@ static BOOL IWineD3DImpl_FillGLCaps(struct 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) {
@@ -1907,6 +1452,7 @@ static BOOL IWineD3DImpl_FillGLCaps(struct 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;
@@ -1920,7 +1466,7 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info)
 
                 memcpy(ThisExtn, Start, len);
                 ThisExtn[len] = '\0';
 
                 memcpy(ThisExtn, Start, len);
                 ThisExtn[len] = '\0';
-                TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
+                TRACE_(d3d_caps)("- %s\n", 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;
@@ -1937,12 +1483,9 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info)
             }
         }
     }
             }
         }
     }
+    LEAVE_GL();
 
 
-    fixup_extensions(gl_info, gl_renderer);
-    add_gl_compat_wrappers(gl_info);
-
-    HeapFree(GetProcessHeap(), 0, gl_renderer);
-    return TRUE;
+    return return_value;
 }
 
 /**********************************************************
 }
 
 /**********************************************************
@@ -1989,39 +1532,40 @@ 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 */
-        unsigned int i = 0;
-        unsigned int j = 0;
-        DEVMODEW mode;
-
-        memset(&mode, 0, sizeof(mode));
-        mode.dmSize = sizeof(mode);
-
-        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;
+        int i = 0;
+        int j = 0;
 
 
-                case WINED3DFMT_P8:
-                    if (mode.dmBitsPerPel == 8) ++i;
-                    break;
+        if (!DEBUG_SINGLE_MODE) {
+            DEVMODEW DevModeW;
 
 
-                default:
-                    /* Skip other modes as they do not match the requested format */
-                    break;
+            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;
+                }
             }
             }
+        } 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);
@@ -2045,8 +1589,7 @@ 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)
-    {
+    if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
         DEVMODEW DevModeW;
         int ModeIdx = 0;
         UINT i = 0;
         DEVMODEW DevModeW;
         int ModeIdx = 0;
         UINT i = 0;
@@ -2092,7 +1635,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  = DEFAULT_REFRESH_RATE;
+            pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
 
             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
 
@@ -2110,9 +1653,14 @@ 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
-    {
+    } 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 {
         FIXME_(d3d_caps)("Adapter not primary display\n");
     }
 
         FIXME_(d3d_caps)("Adapter not primary display\n");
     }
 
@@ -2139,7 +1687,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  = DEFAULT_REFRESH_RATE;
+        pMode->RefreshRate  = WINED3DADAPTER_DEFAULT;
         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
         {
             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
         {
             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
@@ -2160,7 +1708,6 @@ 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);
 
@@ -2170,70 +1717,44 @@ 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");
-
-    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));
+    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(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->device_id = wined3d_settings.pci_device_id;
+        *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
     }
 
     if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
     {
         TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
     }
 
     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->vendor_id = wined3d_settings.pci_vendor_id;
+        *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
     }
 
     }
 
-    pIdentifier->whql_level = (Flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
+    if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
+        *(pIdentifier->WHQLLevel) = 0;
+    } else {
+        *(pIdentifier->WHQLLevel) = 1;
+    }
 
     return WINED3D_OK;
 }
 
 
     return WINED3D_OK;
 }
 
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined3d_gl_info *gl_info,
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const 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;
@@ -2282,7 +1803,7 @@ static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const struct wined
     return FALSE;
 }
 
     return FALSE;
 }
 
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const struct wined3d_gl_info *gl_info,
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const 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;
@@ -2358,9 +1879,10 @@ 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;
@@ -2380,11 +1902,8 @@ 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) {
-        if(pQualityLevels) *pQualityLevels = 1;
-        return WINED3D_OK;
-    }
-
+    if (WINED3DMULTISAMPLE_NONE == MultiSampleType) 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
      * with FBOs yet. */
     /* By default multisampling is disabled right now as it causes issues
      * on some Nvidia driver versions and it doesn't work well in combination
      * with FBOs yet. */
@@ -2573,7 +2092,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->depth_size || ds_format_desc->stencil_size)) return FALSE;
+    if (!(ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) 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)
@@ -2660,7 +2179,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const 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)) {
@@ -2740,7 +2259,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const 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;
 
@@ -3020,7 +2539,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const 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");
@@ -3044,13 +2563,12 @@ 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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const 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;
@@ -3529,6 +3047,18 @@ 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. */
@@ -3575,7 +3105,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
     int vs_selected_mode;
     int ps_selected_mode;
 
     int vs_selected_mode;
     int ps_selected_mode;
 
@@ -3595,7 +3125,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &adapter->gl_info;
     int vs_selected_mode;
     int ps_selected_mode;
 
     int vs_selected_mode;
     int ps_selected_mode;
 
@@ -3614,7 +3144,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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const 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;
@@ -3916,14 +3446,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.0f;
+    pCaps->MaxVertexW = 1.0;
 
 
-    pCaps->GuardBandLeft = 0.0f;
-    pCaps->GuardBandTop = 0.0f;
-    pCaps->GuardBandRight = 0.0f;
-    pCaps->GuardBandBottom = 0.0f;
+    pCaps->GuardBandLeft = 0;
+    pCaps->GuardBandTop = 0;
+    pCaps->GuardBandRight = 0;
+    pCaps->GuardBandBottom = 0;
 
 
-    pCaps->ExtentsAdjust = 0.0f;
+    pCaps->ExtentsAdjust = 0;
 
     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
                           WINED3DSTENCILCAPS_INCRSAT |
 
     pCaps->StencilCaps =  WINED3DSTENCILCAPS_DECRSAT |
                           WINED3DSTENCILCAPS_INCRSAT |
@@ -3935,7 +3465,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
                               WINED3DSTENCILCAPS_INCR;
     }
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
                               WINED3DSTENCILCAPS_INCR;
     }
-    if (GL_SUPPORT(EXT_STENCIL_TWO_SIDE) || GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
+    if ( This->dxVersion > 8 &&
+        ( GL_SUPPORT(EXT_STENCIL_TWO_SIDE) ||
+            GL_SUPPORT(ATI_SEPARATE_STENCIL) ) ) {
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
 
         pCaps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
     }
 
@@ -3951,13 +3483,14 @@ 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;
@@ -4006,7 +3539,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.0f;
+        pCaps->PixelShader1xMaxValue        = 0.0;
     } else {
         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
     } else {
         pCaps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
         pCaps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
@@ -4229,7 +3762,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.0f; /* This is needed to get the x coord unmodified through a MAD. */
+    object->posFixup[0] = 1.0; /* 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;
@@ -4255,7 +3788,6 @@ 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);
@@ -4321,6 +3853,366 @@ 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");
@@ -4351,16 +4243,13 @@ static void WINE_GLAPI position_float4(const void *data)
 {
     const GLfloat *pos = data;
 
 {
     const GLfloat *pos = data;
 
-    if (pos[3] != 0.0f && pos[3] != 1.0f)
-    {
-        float w = 1.0f / pos[3];
+    if (pos[3] < eps && pos[3] > -eps)
+        glVertex3fv(pos);
+    else {
+        float w = 1.0 / 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)
@@ -4388,7 +4277,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 struct wined3d_gl_info *gl_info)
+static void fillGLAttribFuncs(const 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;
@@ -4546,11 +4435,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
-    wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
-    wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
+    glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
+    glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
 #else
 #else
-    wglFinish = (void*)pwglGetProcAddress("wglFinish");
-    wglFlush = (void*)pwglGetProcAddress("wglFlush");
+    glFinish = (void*)pwglGetProcAddress("wglFinish");
+    glFlush = (void*)pwglGetProcAddress("wglFlush");
 #endif
 
     glEnableWINE = glEnable;
 #endif
 
     glEnableWINE = glEnable;
@@ -4559,8 +4448,7 @@ 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 struct wined3d_gl_info *gl_info = &adapter->gl_info;
-        struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
+        const WineD3D_GL_Info *gl_info = &adapter->gl_info;
         int iPixelFormat;
         int res;
         int i;
         int iPixelFormat;
         int res;
         int i;
@@ -4573,26 +4461,31 @@ BOOL InitAdapters(IWineD3DImpl *This)
         adapter->monitorPoint.x = -1;
         adapter->monitorPoint.y = -1;
 
         adapter->monitorPoint.x = -1;
         adapter->monitorPoint.y = -1;
 
-        if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
-        {
+        if (!WineD3D_CreateFakeGLContext()) {
             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(&fake_gl_ctx);
+            WineD3D_ReleaseFakeGLContext();
             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(&fake_gl_ctx);
+            WineD3D_ReleaseFakeGLContext();
             goto nogl_adapter;
         }
 
             goto nogl_adapter;
         }
 
-        hdc = fake_gl_ctx.dc;
+        hdc = pwglGetCurrentDC();
+        if(!hdc) {
+            ERR("Failed to get gl HDC\n");
+            WineD3D_ReleaseFakeGLContext();
+            goto nogl_adapter;
+        }
 
         adapter->driver = "Display";
         adapter->description = "Direct3D HAL";
 
         adapter->driver = "Display";
         adapter->description = "Direct3D HAL";
@@ -4729,7 +4622,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(&fake_gl_ctx);
+                WineD3D_ReleaseFakeGLContext();
                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
                 goto nogl_adapter;
             }
                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
                 goto nogl_adapter;
             }
@@ -4754,7 +4647,10 @@ BOOL InitAdapters(IWineD3DImpl *This)
             }
         }
 
             }
         }
 
-        WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
+        fixup_extensions(&adapter->gl_info);
+        add_gl_compat_wrappers(&adapter->gl_info);
+
+        WineD3D_ReleaseFakeGLContext();
 
         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 5a2c7e7..68821b4 100644 (file)
@@ -32,7 +32,6 @@ 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)
@@ -69,10 +68,8 @@ 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
  */
 
-/* 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)
+static void drawStridedSlow(IWineD3DDevice *iface, 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;
@@ -87,7 +84,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
     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");
@@ -113,38 +109,22 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
     VTRACE(("glBegin(%x)\n", glPrimType));
     glBegin(glPrimType);
 
     VTRACE(("glBegin(%x)\n", glPrimType));
     glBegin(glPrimType);
 
-    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_POSITION];
+    if (element->data) position = element->data + streamOffset[element->stream_idx];
 
 
-    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_NORMAL];
+    if (element->data) normal = element->data + streamOffset[element->stream_idx];
+    else glNormal3f(0, 0, 0);
 
 
-    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)
+    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)
         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));
 
-    if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+    element = &si->elements[WINED3D_FFP_SPECULAR];
+    if (element->data)
     {
     {
-        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 */
@@ -179,7 +159,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
     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];
-        DWORD texture_idx = This->texUnitMap[textureNo];
+        int texture_idx = This->texUnitMap[textureNo];
 
         if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
         {
 
         if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0)
         {
@@ -189,7 +169,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
 
         if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
 
 
         if (!pixelShader && !This->stateBlock->textures[textureNo]) continue;
 
-        if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;
+        if (texture_idx == -1) continue;
 
         if (coordIdx > 7)
         {
 
         if (coordIdx > 7)
         {
@@ -202,9 +182,9 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
             continue;
         }
 
             continue;
         }
 
-        if (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
+        element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+        if (element->data)
         {
         {
-            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);
         }
@@ -247,7 +227,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
         {
             int coord_idx;
             const void *ptr;
         {
             int coord_idx;
             const void *ptr;
-            DWORD texture_idx;
+            int texture_idx;
 
             if (!(tmp_tex_mask & 1)) continue;
 
 
             if (!(tmp_tex_mask & 1)) continue;
 
@@ -264,20 +244,18 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
             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 (num_untracked_materials)
-            {
+            if(This->activeContext->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.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;
+                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;
 
 
-                for (i = 0; i < num_untracked_materials; ++i)
-                {
-                    glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], color);
+                for(i = 0; i < This->activeContext->num_untracked_materials; i++) {
+                    glMaterialfv(GL_FRONT_AND_BACK, This->activeContext->untracked_materials[i], color);
                 }
             }
         }
                 }
             }
         }
@@ -317,7 +295,6 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
     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)
@@ -420,7 +397,6 @@ 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)
 {
@@ -466,9 +442,8 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream
             }
         }
 
             }
         }
 
-        for (i = MAX_ATTRIBS - 1; i >= 0; i--)
-        {
-            if (!(si->use_map & (1 << i))) continue;
+        for(i = MAX_ATTRIBS - 1; i >= 0; i--) {
+            if(!si->elements[i].data) continue;
 
             ptr = si->elements[i].data +
                   si->elements[i].stride * SkipnStrides +
 
             ptr = si->elements[i].data +
                   si->elements[i].stride * SkipnStrides +
@@ -482,7 +457,6 @@ 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)
@@ -522,8 +496,6 @@ 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;
@@ -560,11 +532,7 @@ 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;
-
-        if (!(s->use_map & (1 << i))) continue;
-
-        e = &s->elements[i];
+        struct wined3d_stream_info_element *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];
@@ -581,42 +549,30 @@ 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;
 
-    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);
-            }
+    /* 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;
 
-    context = ActivateContext(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
+    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. 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);
+         * 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);
     }
 
     /* 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 */
@@ -631,7 +587,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 && context->num_untracked_materials
+            if (!This->strided_streams.position_transformed && This->activeContext->num_untracked_materials
                     && This->stateBlock->renderState[WINED3DRS_LIGHTING])
             {
                 static BOOL warned;
                     && This->stateBlock->renderState[WINED3DRS_LIGHTING])
             {
                 static BOOL warned;
@@ -643,8 +599,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice
                 }
                 emulation = TRUE;
             }
                 }
                 emulation = TRUE;
             }
-            else if (context->fog_coord && This->stateBlock->renderState[WINED3DRS_FOGENABLE])
-            {
+            else if(This->activeContext->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
                  */
@@ -678,8 +633,7 @@ 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, context, stream_info, index_count,
-                        glPrimType, idxData, idxSize, minIndex, StartIdx);
+                drawStridedSlow(iface, 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 */
@@ -699,7 +653,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;
@@ -741,7 +695,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.0f) return;
+    if(length == 0.0) 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;
@@ -773,7 +727,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.0f, max_y = 0.0f, max_z = 0.0f, neg_z = 0.0f;
+    float max_x = 0.0, max_y = 0.0, max_z = 0.0, neg_z = 0.0;
     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;
@@ -782,11 +736,6 @@ 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
      */
@@ -837,14 +786,19 @@ 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.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);
+    glScalef(1 / (max_x) , 1 / (max_y), max_z == 0 ? 1 : 1 / ( 2 * max_z));
+    glTranslatef(0, 0, 0.5);
     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");
@@ -856,11 +810,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.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};
+        static const GLfloat black[] = {0, 0, 0, 0};
+        static const GLfloat red[]   = {1, 0, 0, 0};
+        static const GLfloat green[] = {0, 1, 0, 0};
+        static const GLfloat blue[]  = {0, 0, 1, 0};
+        static const GLfloat white[] = {1, 1, 1, 1};
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
         glEnable(GL_LIGHTING);
         checkGLcall("glEnable(GL_LIGHTING)");
         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
@@ -879,21 +833,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");
+        checkGLcall("Setting up light 1\n");
         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");
+        checkGLcall("Setting up light 2\n");
         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");
+        checkGLcall("Setting up light 3\n");
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_MATERIAL);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORVERTEX));
 
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_MATERIAL);
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORVERTEX));
@@ -901,7 +855,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");
+        checkGLcall("Setting up materials\n");
     }
 
     /* Enable the needed maps.
     }
 
     /* Enable the needed maps.
@@ -941,18 +895,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.0f, 1.0f, vtxStride / sizeof(float), info->Width,
-            0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
+            0, 1, vtxStride / sizeof(float), info->Width,
+            0, 1, 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.0f, 1.0f, vtxStride / sizeof(float), info->Width,
-                0.0f, 1.0f, info->Stride * vtxStride / sizeof(float), info->Height,
+                0, 1, vtxStride / sizeof(float), info->Width,
+                0, 1, info->Stride * vtxStride / sizeof(float), info->Height,
                 (const GLfloat *)data);
         checkGLcall("glMap2f");
     }
                 (const GLfloat *)data);
         checkGLcall("glMap2f");
     }
-    glMapGrid2f(ceilf(patch->numSegs[0]), 0.0f, 1.0f, ceilf(patch->numSegs[1]), 0.0f, 1.0f);
+    glMapGrid2f(ceilf(patch->numSegs[0]), 0.0, 1.0, ceilf(patch->numSegs[1]), 0.0, 1.0);
     checkGLcall("glMapGrid2f");
 
     glFeedbackBuffer(buffer_size * 2, feedback_type, feedbuffer);
     checkGLcall("glMapGrid2f");
 
     glFeedbackBuffer(buffer_size * 2, feedback_type, feedbuffer);
@@ -960,17 +914,19 @@ 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");
+    checkGLcall("glEvalMesh2\n");
 
     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 {
@@ -994,7 +950,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.5f) * 4.0f * max_z; /* z, triangle 3 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 2 + 4] - 0.5) * 4 * 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];
@@ -1004,7 +960,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.5f) * 4.0f * max_z; /* z, triangle 2 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 1 + 4] - 0.5) * 4 * 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];
@@ -1014,7 +970,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.5f) * 4.0f * max_z; /* z, triangle 1 */
+        patch->mem[i + 2] = (feedbuffer[j + out_vertex_size * 0 + 4] - 0.5) * 4 * 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];
@@ -1025,18 +981,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.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};
+        static const GLfloat x[] = {-1,  0,  0, 0};
+        static const GLfloat y[] = { 0, -1,  0, 0};
+        static const GLfloat z[] = { 0,  0, -1, 0};
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
         glLightfv(GL_LIGHT0, GL_POSITION, x);
         glLightfv(GL_LIGHT1, GL_POSITION, y);
         glLightfv(GL_LIGHT2, GL_POSITION, z);
-        checkGLcall("Setting up reverse light directions");
+        checkGLcall("Setting up reverse light directions\n");
 
         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");
+        checkGLcall("glEvalMesh2\n");
         i = glRenderMode(GL_RENDER);
         checkGLcall("glRenderMode(GL_RENDER)");
 
         i = glRenderMode(GL_RENDER);
         checkGLcall("glRenderMode(GL_RENDER)");
 
@@ -1050,29 +1006,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.0f)
+            if(patch->mem[i + 3] == 0.0)
                 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.0f)
+            if(patch->mem[i + 4] == 0.0)
                 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.0f)
+            if(patch->mem[i + 5] == 0.0)
                 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.0f)
+            if(patch->mem[i + 3] == 0.0)
                 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.0f)
+            if(patch->mem[i + 4] == 0.0)
                 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.0f)
+            if(patch->mem[i + 5] == 0.0)
                 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.0f)
+            if(patch->mem[i + 3] == 0.0)
                 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.0f)
+            if(patch->mem[i + 4] == 0.0)
                 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.0f)
+            if(patch->mem[i + 5] == 0.0)
                 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 9166041..1fc48cc 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.0f;
+    if(pname == GL_ACTIVE_TEXTURE) *params = 0.0;
     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) {
-        struct wined3d_context *ctx = context_get_current();
+        WineD3DContext *ctx = getActiveContext();
         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) {
-        struct wined3d_context *ctx = context_get_current();
+        WineD3DContext *ctx = getActiveContext();
         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,9 +166,8 @@ 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);
@@ -178,9 +177,9 @@ static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            ctx->fogstart = param;
+            getActiveContext()->fogstart = param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            ctx->fogend = param;
+            getActiveContext()->fogend = param;
         }
         old_fogcoord_glFogi(pname, param);
     }
         }
         old_fogcoord_glFogi(pname, param);
     }
@@ -188,8 +187,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);
@@ -199,9 +198,9 @@ static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            ctx->fogstart = *param;
+            getActiveContext()->fogstart = *param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            ctx->fogend = *param;
+            getActiveContext()->fogend = *param;
         }
         old_fogcoord_glFogiv(pname, param);
     }
         }
         old_fogcoord_glFogiv(pname, param);
     }
@@ -209,8 +208,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);
@@ -220,9 +219,9 @@ static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
         }
     } else {
         if(pname == GL_FOG_START) {
         }
     } else {
         if(pname == GL_FOG_START) {
-            ctx->fogstart = param;
+            getActiveContext()->fogstart = param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            ctx->fogend = param;
+            getActiveContext()->fogend = param;
         }
         old_fogcoord_glFogf(pname, param);
     }
         }
         old_fogcoord_glFogf(pname, param);
     }
@@ -230,8 +229,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);
@@ -241,14 +240,15 @@ 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) {
-            ctx->fogstart = *param;
+            getActiveContext()->fogstart = *param;
         } else if(pname == GL_FOG_END) {
         } else if(pname == GL_FOG_END) {
-            ctx->fogend = *param;
+            getActiveContext()->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) {
-    struct wined3d_context *ctx = context_get_current();
+    WineD3DContext *ctx = getActiveContext();
     if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
         GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
         GLfloat i;
 
         i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart);
     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.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];
+        c[0] = i * c[0] + (1.0 - i) * ctx->fogcolor[0];
+        c[1] = i * c[1] + (1.0 - i) * ctx->fogcolor[1];
+        c[2] = i * c[2] + (1.0 - i) * ctx->fogcolor[2];
 
         old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]);
         old_fogcoord_glVertex4f(x, y, z, w);
 
         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.0f);
+    wine_glVertex4f(x, y, z, 1.0);
 }
 
 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.0f);
+    wine_glVertex4f(pos[0], pos[1], pos[2], 1.0);
 }
 
 }
 
-static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-    struct wined3d_context *ctx = context_get_current();
+static void wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+    WineD3DContext *ctx = getActiveContext();
     ctx->color[0] = r;
     ctx->color[1] = g;
     ctx->color[2] = b;
     ctx->color[0] = r;
     ctx->color[1] = g;
     ctx->color[2] = b;
@@ -307,44 +307,43 @@ static void WINE_GLAPI 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_GLAPI wine_glColor4fv(const GLfloat *c) {
+static void 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_GLAPI wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
-    wine_glColor4f(r, g, b, 1.0f);
+static void wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
+    wine_glColor4f(r, g, b, 1.0);
 }
 
 }
 
-static void WINE_GLAPI wine_glColor3fv(const GLfloat *c) {
-    wine_glColor4f(c[0], c[1], c[2], 1.0f);
+static void wine_glColor3fv(const GLfloat *c) {
+    wine_glColor4f(c[0], c[1], c[2], 1.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);
+static void wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
+    wine_glColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
 }
 
 /* In D3D the fog coord is a UBYTE, so there's no problem with using the single
  * precision function
  */
 }
 
 /* In D3D the fog coord is a UBYTE, so there's no problem with using the single
  * precision function
  */
-static void WINE_GLAPI wine_glFogCoordfEXT(GLfloat f) {
-    struct wined3d_context *ctx = context_get_current();
+static void wine_glFogCoordfEXT(GLfloat f) {
+    WineD3DContext *ctx = getActiveContext();
     ctx->fog_coord_value = f;
 }
     ctx->fog_coord_value = f;
 }
-static void WINE_GLAPI wine_glFogCoorddEXT(GLdouble f) {
+static void wine_glFogCoorddEXT(GLdouble f) {
     wine_glFogCoordfEXT(f);
 }
     wine_glFogCoordfEXT(f);
 }
-static void WINE_GLAPI wine_glFogCoordfvEXT(const GLfloat *f) {
+static void wine_glFogCoordfvEXT(const GLfloat *f) {
     wine_glFogCoordfEXT(*f);
 }
     wine_glFogCoordfEXT(*f);
 }
-static void WINE_GLAPI wine_glFogCoorddvEXT(const GLdouble *f) {
+static void 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(struct wined3d_gl_info *gl_info)
-{
+void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info) {
     if(!GL_SUPPORT(ARB_MULTITEXTURE)) {
         TRACE("Applying GL_ARB_multitexture emulation hooks\n");
         gl_info->glActiveTextureARB         = wine_glActiveTextureARB;
     if(!GL_SUPPORT(ARB_MULTITEXTURE)) {
         TRACE("Applying GL_ARB_multitexture emulation hooks\n");
         gl_info->glActiveTextureARB         = wine_glActiveTextureARB;
index 8aae5f5..ca50305 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,8 +83,7 @@ struct constant_heap
 
 /* GLSL shader private data */
 struct shader_glsl_priv {
 
 /* GLSL shader private data */
 struct shader_glsl_priv {
-    struct wined3d_shader_buffer shader_buffer;
-    struct wine_rb_tree program_lookup;
+    struct hash_table_t *glsl_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;
@@ -95,7 +94,6 @@ 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;
@@ -104,7 +102,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;
+    GLint                       np2Fixup_location[MAX_FRAGMENT_SAMPLERS];
     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];
@@ -115,7 +113,6 @@ 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 {
@@ -125,59 +122,9 @@ 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 */
-/* GL locking is done by the caller */
-static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleARB obj)
+static void print_glsl_info_log(const WineD3D_GL_Info *gl_info, GLhandleARB obj)
 {
     int infologLength = 0;
     char *infoLog;
 {
     int infologLength = 0;
     char *infoLog;
@@ -193,8 +140,10 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA
         "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;
@@ -207,8 +156,6 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA
      * 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
          */
@@ -222,17 +169,10 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA
                 break;
             }
         }
                 break;
             }
         }
-
-        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);
+        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));
         }
         HeapFree(GetProcessHeap(), 0, infoLog);
     }
         }
         HeapFree(GetProcessHeap(), 0, infoLog);
     }
@@ -241,9 +181,7 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA
 /**
  * Loads (pixel shader) samplers
  */
 /**
  * Loads (pixel shader) samplers
  */
-/* 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)
+static void shader_glsl_load_psamplers(const WineD3D_GL_Info *gl_info, DWORD *tex_unit_map, GLhandleARB programId)
 {
     GLint name_loc;
     int i;
 {
     GLint name_loc;
     int i;
@@ -266,9 +204,7 @@ static void shader_glsl_load_psamplers(const struct wined3d_gl_info *gl_info,
     }
 }
 
     }
 }
 
-/* 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)
+static void shader_glsl_load_vsamplers(const 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];
@@ -291,8 +227,7 @@ static void shader_glsl_load_vsamplers(const struct wined3d_gl_info *gl_info,
     }
 }
 
     }
 }
 
-/* GL locking is done by the caller */
-static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants,
+static inline void walk_constant_heap(const 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;
@@ -353,23 +288,21 @@ static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, con
     checkGLcall("walk_constant_heap()");
 }
 
     checkGLcall("walk_constant_heap()");
 }
 
-/* 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)
+static inline void apply_clamped_constant(const WineD3D_GL_Info *gl_info, GLint location, const GLfloat *data)
 {
     GLfloat clamped_constant[4];
 
     if (location == -1) return;
 
 {
     GLfloat clamped_constant[4];
 
     if (location == -1) return;
 
-    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];
+    clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0 ? 1.0 : data[0];
+    clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0 ? 1.0 : data[1];
+    clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0 ? 1.0 : data[2];
+    clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0 ? 1.0 : data[3];
 
     GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
 }
 
 
     GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
 }
 
-/* GL locking is done by the caller */
-static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const float *constants,
+static inline void walk_constant_heap_clamped(const 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;
@@ -429,8 +362,7 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i
 }
 
 /* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
-/* GL locking is done by the caller */
-static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
+static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const 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)
 {
@@ -460,8 +392,7 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const stru
 }
 
 /* Loads integer constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads integer constants (aka uniforms) into the currently set GLSL program. */
-/* GL locking is done by the caller */
-static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
+static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const 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;
@@ -497,37 +428,16 @@ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const stru
 }
 
 /* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
 }
 
 /* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
-/* GL locking is done by the caller */
-static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
+static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const 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];
-    const char *prefix;
+    char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
+    const char* prefix = is_pshader? "PB":"VB";
     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)
@@ -568,15 +478,15 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const stru
     }
 }
 
     }
 }
 
-static void reset_program_constant_version(struct wine_rb_entry *entry, void *context)
+static void reset_program_constant_version(void *value, void *context)
 {
 {
-    WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0;
+    struct glsl_shader_prog_link *entry = value;
+    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,
@@ -595,45 +505,39 @@ static void shader_glsl_load_np2fixup_constants(
         return;
     }
 
         return;
     }
 
-    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;
+    if (prog->ps_args.np2_fixup) {
         UINT i;
         UINT fixup = prog->ps_args.np2_fixup;
         UINT i;
         UINT fixup = prog->ps_args.np2_fixup;
-        GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+        const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+        const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock;
 
         for (i = 0; fixup; fixup >>= 1, ++i) {
 
         for (i = 0; fixup; fixup >>= 1, ++i) {
-            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];
+            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));
+                }
             }
         }
             }
         }
-
-        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.
  */
-/* 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;
+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;
 
     GLhandleARB programId;
     struct glsl_shader_prog_link *prog = priv->glsl_program;
 
     GLhandleARB programId;
     struct glsl_shader_prog_link *prog = priv->glsl_program;
@@ -663,7 +567,7 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
                 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, &device->posFixup[0]));
+        GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
         checkGLcall("glUniform4fvARB");
     }
 
         checkGLcall("glUniform4fvARB");
     }
 
@@ -686,21 +590,20 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
         /* 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 < MAX_TEXTURES; i++) {
-            const float *data;
-
-            if(prog->bumpenvmat_location[i] == -1) continue;
+        for(i = 0; i < ((IWineD3DPixelShaderImpl *) pshader)->numbumpenvmatconsts; i++) {
+            IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pshader;
+            int stage = ps->luminanceconst[i].texunit;
 
 
-            data = (const float *)&stateBlock->textureState[i][WINED3DTSS_BUMPENVMAT00];
+            const float *data = (const float *)&stateBlock->textureState[(int)ps->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];
             GL_EXTCALL(glUniformMatrix2fvARB(prog->bumpenvmat_location[i], 1, 0, data));
             checkGLcall("glUniformMatrix2fvARB");
 
             /* 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(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];
+            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];
 
                 GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
                 checkGLcall("glUniform1fvARB");
 
                 GL_EXTCALL(glUniform1fvARB(prog->luminancescale_location[i], 1, scale));
                 checkGLcall("glUniform1fvARB");
@@ -711,15 +614,13 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
 
         if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
             float correction_params[4];
 
         if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
             float correction_params[4];
-
-            if (context->render_offscreen)
-            {
-                correction_params[0] = 0.0f;
-                correction_params[1] = 1.0f;
+            if(deviceImpl->render_offscreen) {
+                correction_params[0] = 0.0;
+                correction_params[1] = 1.0;
             } else {
                 /* position is window relative, not viewport relative */
             } else {
                 /* position is window relative, not viewport relative */
-                correction_params[0] = ((IWineD3DSurfaceImpl *)context->current_rt)->currentDesc.Height;
-                correction_params[1] = -1.0f;
+                correction_params[0] = ((IWineD3DSurfaceImpl *) deviceImpl->render_targets[0])->currentDesc.Height;
+                correction_params[1] = -1.0;
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
@@ -728,7 +629,7 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
     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");
-        wine_rb_for_each_entry(&priv->program_lookup, reset_program_constant_version, NULL);
+        hash_table_for_each_entry(priv->glsl_program_lookup, reset_program_constant_version, NULL);
         priv->next_constant_version = 1;
     }
     else
         priv->next_constant_version = 1;
     }
     else
@@ -792,38 +693,24 @@ 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(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)
+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)
 {
     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, map = reg_maps->labels; map; map >>= 1, ++i)
-    {
-        if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i);
+    for (i = 0; i < This->baseShader.limits.label; i++) {
+        if (reg_maps->labels[i])
+            shader_addline(buffer, "void subroutine%u();\n", i);
     }
 
     /* Declare the constants (aka uniforms) */
     }
 
     /* Declare the constants (aka uniforms) */
@@ -850,11 +737,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                 /* 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).
-                 *
-                 * Writing gl_ClipPos requires one uniform for each clipplane as well.
+                 * (Unfortunately the Nvidia driver doesn't store 128 and -128 in one float
                  */
                  */
-                max_constantsF = GL_LIMITS(vshader_constantsF) - 3 - GL_LIMITS(clipplanes);
+                max_constantsF = GL_LIMITS(vshader_constantsF) - 3;
                 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
@@ -899,28 +784,35 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
             shader_addline(buffer, "void order_ps_input();\n");
         }
     } else {
             shader_addline(buffer, "void order_ps_input();\n");
         }
     } else {
-        for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
-        {
-            if (!(map & 1)) continue;
+        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;
+            }
 
 
+            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 & (1 << i))
-            {
+            if(reg_maps->luminanceparams) {
+                ps_impl->luminanceconst[(int) ps_impl->numbumpenvmatconsts].texunit = 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_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(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(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)) {
@@ -933,14 +825,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                  */
                 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",
-                        context->render_offscreen ? 0.0f : ((IWineD3DSurfaceImpl *)device->render_targets[0])->currentDesc.Height,
-                        context->render_offscreen ? 1.0f : -1.0f);
+                               device->render_offscreen ? 0.0 : ((IWineD3DSurfaceImpl *) device->render_targets[0])->currentDesc.Height,
+                               device->render_offscreen ? 1.0 : -1.0);
             }
             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])
         {
@@ -956,6 +848,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                     } 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);
@@ -970,48 +871,17 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
             }
         }
     }
             }
         }
     }
-
-    /* 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, map = reg_maps->address; map; map >>= 1, ++i)
-    {
-        if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i);
+    for (i = 0; i < This->baseShader.limits.address; i++) {
+        if (reg_maps->address[i])
+            shader_addline(buffer, "ivec4 A%d;\n", i);
     }
 
     /* Declare texture coordinate temporaries and initialize them */
     }
 
     /* Declare texture coordinate temporaries and initialize them */
-    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);
+    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);
     }
 
     /* 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
@@ -1021,13 +891,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     {
         if (use_vs(device->stateBlock))
         {
     {
         if (use_vs(device->stateBlock))
         {
-            shader_addline(buffer, "varying vec4 IN[%u];\n", vec4_varyings(reg_maps->shader_version.major, gl_info));
+            shader_addline(buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
         } else {
             /* TODO: Write a replacement shader for the fixed function vertex pipeline, so this isn't needed.
              * 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", vec4_varyings(reg_maps->shader_version.major, gl_info));
+            shader_addline(buffer, "vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
         }
     }
 
         }
     }
 
@@ -1037,18 +907,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     }
 
     /* Declare temporary variables */
     }
 
     /* Declare temporary variables */
-    for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
-    {
-        if (map & 1) shader_addline(buffer, "vec4 R%u;\n", i);
+    for(i = 0; i < This->baseShader.limits.temporary; i++) {
+        if (reg_maps->temporary[i])
+            shader_addline(buffer, "vec4 R%u;\n", i);
     }
 
     /* Declare attributes */
     }
 
     /* Declare attributes */
-    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);
-        }
+    for (i = 0; i < This->baseShader.limits.attributes; i++) {
+        if (reg_maps->attributes[i])
+            shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
     }
 
     /* Declare loop registers aLx */
     }
 
     /* Declare loop registers aLx */
@@ -1104,22 +971,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 */
@@ -1183,7 +1050,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 struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+    const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
     char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
@@ -1198,8 +1065,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
             /* vertex shaders */
             if (!pshader)
             {
             /* vertex shaders */
             if (!pshader)
             {
-                struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
-                if (priv->cur_vs_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
+                if (((IWineD3DVertexShaderImpl *)This)->cur_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;
             }
@@ -1208,7 +1074,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];
-                unsigned int in_count = vec4_varyings(This->baseShader.reg_maps.shader_version.major, gl_info);
+                DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
                 if (reg->rel_addr)
                 {
 
                 if (reg->rel_addr)
                 {
@@ -1309,9 +1175,11 @@ 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, GL_LIMITS(buffers));
+                WARN("Write to render target %u, only %d supported\n", reg->idx, 4);
 
 
-            sprintf(register_name, "gl_FragData[%u]", reg->idx);
+            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");
             break;
 
         case WINED3DSPR_RASTOUT:
             break;
 
         case WINED3DSPR_RASTOUT:
@@ -1356,13 +1224,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", *(const float *)reg->immconst_data);
+                    sprintf(register_name, "%.8e", *(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)",
-                            *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
-                            *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
+                            *(float *)&reg->immconst_data[0], *(float *)&reg->immconst_data[1],
+                            *(float *)&reg->immconst_data[2], *(float *)&reg->immconst_data[3]);
                     break;
 
                 default:
                     break;
 
                 default:
@@ -1476,7 +1344,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(struct wined3d_shader_buffer *buffer,
+static DWORD shader_glsl_append_dst_ext(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;
@@ -1489,7 +1357,7 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_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(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins)
+static DWORD shader_glsl_append_dst(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]);
 }
@@ -1731,11 +1599,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))
     {
-        const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
-        fixup = priv->cur_ps_args->color_fixup[sampler];
+        IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+        fixup = This->cur_args->color_fixup[sampler];
         sampler_base = "Psampler";
 
         sampler_base = "Psampler";
 
-        if(priv->cur_ps_args->np2_fixup & (1 << sampler)) {
+        if(This->cur_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 {
@@ -1759,11 +1627,7 @@ 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) {
-            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);
+            shader_addline(ins->ctx->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, 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 {
@@ -1777,13 +1641,15 @@ 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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -1810,7 +1676,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
@@ -1848,7 +1714,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -1896,7 +1762,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -1920,7 +1786,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -1940,7 +1806,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -2044,7 +1910,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)
 {
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -2262,8 +2128,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;
@@ -2319,7 +2185,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);
@@ -2416,7 +2282,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
@@ -2480,33 +2346,22 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
         }
     }
 
         }
     }
 
-    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,
+    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],
                     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,
@@ -2633,17 +2488,10 @@ 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 shader_glsl_tex(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -2736,7 +2584,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 struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
+    const 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;
@@ -2746,7 +2594,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 shader_glsl_tex(ins);
+        return pshader_glsl_tex(ins);
     }
 
     sampler_idx = ins->src[1].reg.idx;
     }
 
     sampler_idx = ins->src[1].reg.idx;
@@ -2797,10 +2645,10 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
             "%s", coord_param.param_str);
 }
 
             "%s", coord_param.param_str);
 }
 
-static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
+static void pshader_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 */
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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))
@@ -2846,7 +2694,7 @@ static void shader_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 shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -2890,7 +2738,7 @@ static void shader_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 shader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -2911,7 +2759,7 @@ static void shader_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 shader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
+static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
 
 {
     glsl_dst_param_t dst_param;
 
@@ -2932,7 +2780,7 @@ static void shader_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 shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -2946,11 +2794,11 @@ static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *in
 
 /** 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 shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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);
@@ -2959,12 +2807,12 @@ static void shader_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 shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
 
@@ -2973,11 +2821,11 @@ static void shader_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 shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -2993,7 +2841,7 @@ static void shader_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 shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3017,7 +2865,7 @@ static void shader_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 shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3035,15 +2883,15 @@ static void shader_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 shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -3066,13 +2914,13 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
     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 shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
-    struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+    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;
@@ -3102,7 +2950,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
  * 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 shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3161,7 +3009,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3176,7 +3024,7 @@ static void shader_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 shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3192,7 +3040,7 @@ static void shader_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 shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3208,7 +3056,7 @@ static void shader_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 shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3225,7 +3073,7 @@ static void shader_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 shader_glsl_texkill(const struct wined3d_shader_instruction *ins)
+static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
 
 {
     glsl_dst_param_t dst_param;
 
@@ -3246,7 +3094,7 @@ static void shader_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 shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
+static void pshader_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;
@@ -3270,52 +3118,52 @@ static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
     }
 }
 
     }
 }
 
-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,
+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,
         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; map; map >>= 1, ++i)
+    for (i = 0; i < MAX_REG_INPUT; ++i)
     {
     {
-        const char *semantic_name;
-        UINT semantic_idx;
+        DWORD usage, usage_idx;
         char reg_mask[6];
 
         /* Unused */
         char reg_mask[6];
 
         /* Unused */
-        if (!(map & 1)) continue;
+        if (!reg_maps->packed_input[i]) continue;
 
 
-        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);
+        usage = semantics_in[i].usage;
+        usage_idx = semantics_in[i].usage_idx;
+        shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask);
 
 
-        if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
-        {
-            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);
-        }
-        else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
+        switch (usage)
         {
         {
-            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
+            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:
                 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);
-        }
-        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;
         }
     }
 }
         }
     }
 }
@@ -3325,23 +3173,20 @@ static void shader_glsl_input_pack(IWineD3DPixelShader *iface, struct wined3d_sh
  ********************************************/
 
 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.vshader = entry->vshader;
-    key.pshader = entry->pshader;
-    key.vs_args = entry->vs_args;
-    key.ps_args = entry->ps_args;
+    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;
 
 
-    if (wine_rb_put(&priv->program_lookup, &key, &entry->program_lookup_entry) == -1)
-    {
-        ERR("Failed to insert program entry.\n");
-    }
+    hash_table_put(priv->glsl_program_lookup, key, entry);
 }
 
 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;
@@ -3349,21 +3194,20 @@ 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;
 
-    entry = wine_rb_get(&priv->program_lookup, &key);
-    return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL;
+    return hash_table_get(priv->glsl_program_lookup, &key);
 }
 
 }
 
-/* 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,
+static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const 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.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);
+    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);
 
     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);
@@ -3373,33 +3217,28 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struc
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
-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)
+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)
 {
     unsigned int i, j;
 {
     unsigned int i, j;
-    const char *semantic_name_in, *semantic_name_out;
-    UINT semantic_idx_in, semantic_idx_out;
+    DWORD usage, usage_idx, usage_out, usage_idx_out;
     DWORD *set;
     DWORD in_idx;
     DWORD *set;
     DWORD in_idx;
-    unsigned int in_count = vec4_varyings(3, gl_info);
+    DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
     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 (!output_signature)
-    {
+    if (!semantics_out) {
         /* 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");
     }
 
-    input_map = reg_maps_in->input_registers;
-    for (i = 0; input_map; input_map >>= 1, ++i)
-    {
-        if (!(input_map & 1)) continue;
+    for(i = 0; i < MAX_REG_INPUT; i++) {
+        if (!reg_maps_in->packed_input[i]) continue;
 
         in_idx = map[i];
         if (in_idx >= (in_count + 2)) {
 
         in_idx = map[i];
         if (in_idx >= (in_count + 2)) {
@@ -3420,65 +3259,56 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, const struct
             sprintf(destination, "IN[%u]", in_idx);
         }
 
             sprintf(destination, "IN[%u]", in_idx);
         }
 
-        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);
+        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;
 
 
-        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
-                {
+                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;
+
+                default:
                     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);
-                }
-            }
-            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);
+                                   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;
 
 
-            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);
+                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);
 
 
-                if (semantic_idx_in == semantic_idx_out
-                        && !strcmp(semantic_name_in, semantic_name_out))
-                {
+                if(usage == usage_out &&
+                   usage_idx == usage_idx_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;
                 }
             }
@@ -3494,8 +3324,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, const struct
      * 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] && set[i] != WINED3DSP_WRITEMASK_ALL)
-        {
+        if(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)) {
@@ -3534,9 +3363,8 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer, const struct
     HeapFree(GetProcessHeap(), 0, set);
 }
 
     HeapFree(GetProcessHeap(), 0, set);
 }
 
-/* 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)
+static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexshader,
+        IWineD3DPixelShader *pixelshader, const WineD3D_GL_Info *gl_info)
 {
     GLhandleARB ret = 0;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
 {
     GLhandleARB ret = 0;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
@@ -3545,145 +3373,142 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
     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;
-    const char *semantic_name;
-    UINT semantic_idx;
+    SHADER_BUFFER buffer;
+    DWORD usage, usage_idx, writemask;
     char reg_mask[6];
     char reg_mask[6];
-    const struct wined3d_shader_signature_element *output_signature;
+    const struct wined3d_shader_semantic *semantics_out;
 
 
-    shader_buffer_clear(buffer);
+    shader_buffer_init(&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).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");
+        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");
             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) {
-        WORD map = vs->baseShader.reg_maps.output_registers;
-
         /* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */
         /* The vertex shader writes to its own varyings, the pixel shader needs them in the builtin ones */
-        output_signature = vs->output_signature;
+        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;
 
 
-        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;
+                case WINED3DDECLUSAGE_POSITION:
+                    shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+                    break;
 
 
-            if (!(map & 1)) continue;
+                case WINED3DDECLUSAGE_TEXCOORD:
+                    if (usage_idx < 8) {
+                        if(!(GLINFO_LOCATION).set_texcoord_w || ps_major > 0) writemask |= WINED3DSP_WRITEMASK_3;
 
 
-            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);
+                        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 (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;
+                case WINED3DDECLUSAGE_PSIZE:
+                    shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i);
+                    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]);
+                case WINED3DDECLUSAGE_FOG:
+                    shader_addline(&buffer, "gl_FogFragCoord = OUT[%u].%c;\n", i, reg_mask[1]);
+                    break;
+
+                default:
+                    break;
             }
         }
             }
         }
-        shader_addline(buffer, "}\n");
+        shader_addline(&buffer, "}\n");
 
     } else if(ps_major >= 3 && vs_major >= 3) {
 
     } else if(ps_major >= 3 && vs_major >= 3) {
-        WORD map = vs->baseShader.reg_maps.output_registers;
-
-        output_signature = vs->output_signature;
+        semantics_out = vs->semantics_out;
 
         /* 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", vec4_varyings(3, gl_info));
-        shader_addline(buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
+        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);
 
         /* 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; map; map >>= 1, ++i)
-        {
-            if (!(map & 1)) continue;
+        for(i = 0; i < MAX_REG_OUTPUT; i++) {
+            if (!vs->baseShader.reg_maps.packed_output[i]) continue;
 
 
-            semantic_name = output_signature[i].semantic_name;
-            shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask);
+            usage = semantics_out[i].usage;
+            usage_idx = semantics_out[i].usage_idx;
+            shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask);
 
 
-            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);
+            switch(usage) {
+                case WINED3DDECLUSAGE_POSITION:
+                    shader_addline(&buffer, "gl_Position%s = OUT[%u]%s;\n", reg_mask, i, reg_mask);
+                    break;
+
+                case WINED3DDECLUSAGE_PSIZE:
+                    shader_addline(&buffer, "gl_PointSize = OUT[%u].x;\n", i);
+                    break;
+
+                default:
+                    break;
             }
         }
 
         /* Then, fix the pixel shader input */
             }
         }
 
         /* Then, fix the pixel shader input */
-        handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->input_signature,
-                &ps->baseShader.reg_maps, output_signature, &vs->baseShader.reg_maps);
+        handle_ps3_input(&buffer, gl_info, ps->input_reg_map,
+                ps->semantics_in, &ps->baseShader.reg_maps, semantics_out, &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", vec4_varyings(3, gl_info));
-        shader_addline(buffer, "void order_ps_input() {\n");
+        shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
+        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->input_signature,
-                &ps->baseShader.reg_maps, NULL, NULL);
-        shader_addline(buffer, "}\n");
+        handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->semantics_in, &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;
 }
 
-/* GL locking is done by the caller */
-static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
+static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const WineD3D_GL_Info *gl_info,
         GLhandleARB programId, char prefix)
 {
     const local_constant *lconst;
         GLhandleARB programId, char prefix)
 {
     const local_constant *lconst;
@@ -3697,338 +3522,53 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struc
         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");
+    checkGLcall("Hardcoding local constants\n");
 }
 
 }
 
-/* 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;
-
-    /* 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");
+/** 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;
 
 
-    if(GL_SUPPORT(ARB_SHADER_TEXTURE_LOD) && reg_maps->usestexldd) {
-        shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
+    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));
     }
     }
-    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");
+    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));
     }
     }
-
-    /* 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);
+    entry = get_glsl_program_entry(priv, vshader, pshader, &vs_compile_args, &ps_compile_args);
+    if (entry) {
+        priv->glsl_program = entry;
+        return;
     }
 
     }
 
-    /* Base Shader Body */
-    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function, &priv_ctx);
-
-    /* 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);
+    /* 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));
 
     /* Create the entry */
     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
@@ -4038,22 +3578,24 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
     entry->vs_args = vs_compile_args;
     entry->ps_args = ps_compile_args;
     entry->constant_version = 0;
     entry->vs_args = vs_compile_args;
     entry->ps_args = ps_compile_args;
     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)
-    {
-        GLhandleARB vshader_id = find_glsl_vshader(context, &priv->shader_buffer,
-                (IWineD3DVertexShaderImpl *)vshader, &vs_compile_args);
-        WORD map = ((IWineD3DBaseShaderImpl *)vshader)->baseShader.reg_maps.input_registers;
+    if (vshader_id) {
+        const unsigned int max_attribs = 16;   /* TODO: Will this always be the case? It is at the moment... */
         char tmp_name[10];
 
         char tmp_name[10];
 
-        reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
+        reorder_shader_id = generate_param_reorder_function(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");
@@ -4075,23 +3617,25 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
          * 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; map; map >>= 1, ++i)
-        {
-            if (!(map & 1)) continue;
-
-            snprintf(tmp_name, sizeof(tmp_name), "attrib%u", i);
-            GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
+        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));
+            }
         }
         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)
-    {
-        GLhandleARB pshader_id = find_glsl_pshader(context, &priv->shader_buffer,
-                (IWineD3DPixelShaderImpl *)pshader, &ps_compile_args, &entry->np2Fixup_info);
+    if (pshader_id) {
         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");
@@ -4124,22 +3668,25 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
     }
 
     if(pshader) {
     }
 
     if(pshader) {
-        char name[32];
-
-        for(i = 0; i < MAX_TEXTURES; i++) {
-            sprintf(name, "bumpenvmat%u", i);
+        for(i = 0; i < ((IWineD3DPixelShaderImpl*)pshader)->numbumpenvmatconsts; i++) {
+            char name[32];
+            sprintf(name, "bumpenvmat%d", ((IWineD3DPixelShaderImpl*)pshader)->bumpenvmatconst[i].texunit);
             entry->bumpenvmat_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
             entry->bumpenvmat_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
-            sprintf(name, "luminancescale%u", i);
+            sprintf(name, "luminancescale%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
             entry->luminancescale_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
             entry->luminancescale_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
-            sprintf(name, "luminanceoffset%u", i);
+            sprintf(name, "luminanceoffset%d", ((IWineD3DPixelShaderImpl*)pshader)->luminanceconst[i].texunit);
             entry->luminanceoffset_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
         }
             entry->luminanceoffset_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"));
+    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));
             } else {
             } else {
-                FIXME("NP2 texcoord fixup needed for this pixelshader, but no fixup uniform found.\n");
+                entry->np2Fixup_location[i] = -1;
             }
         }
     }
             }
         }
     }
@@ -4150,7 +3697,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
 
     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 > vec4_varyings(3, gl_info))
+            && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
         entry->vertex_color_clamp = GL_FALSE;
@@ -4170,8 +3717,14 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
      * 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) shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
-    if (pshader) shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
+    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 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
@@ -4185,8 +3738,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
     }
 }
 
     }
 }
 
-/* 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)
+static GLhandleARB create_glsl_blt_shader(const WineD3D_GL_Info *gl_info, enum tex_types tex_type)
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
 {
     GLhandleARB program_id;
     GLhandleARB vshader_id, pshader_id;
@@ -4260,18 +3812,16 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
     return program_id;
 }
 
     return program_id;
 }
 
-/* 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;
+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;
     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(context, device, usePS, useVS);
+    if (useVS || usePS) set_glsl_shader_program(iface, 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;
@@ -4289,20 +3839,11 @@ static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS
     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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const 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];
 
@@ -4317,10 +3858,9 @@ 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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const 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;
 
@@ -4336,8 +3876,7 @@ 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 struct wined3d_context *context;
-    const struct wined3d_gl_info *gl_info;
+    const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
 
     IWineD3DPixelShaderImpl *ps = NULL;
     IWineD3DVertexShaderImpl *vs = NULL;
 
@@ -4347,45 +3886,15 @@ 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;
-        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(ps->num_gl_shaders == 0) return;
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
-        {
-            ENTER_GL();
-            shader_glsl_select(context, FALSE, FALSE);
-            LEAVE_GL();
-        }
+            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
     } else {
     } else {
-        struct glsl_vshader_private *shader_data;
         vs = (IWineD3DVertexShaderImpl *) This;
         vs = (IWineD3DVertexShaderImpl *) This;
-        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(vs->num_gl_shaders == 0) return;
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
         if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
-        {
-            ENTER_GL();
-            shader_glsl_select(context, FALSE, FALSE);
-            LEAVE_GL();
-        }
+            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
     }
 
     linked_programs = &This->baseShader.linked_programs;
     }
 
     linked_programs = &This->baseShader.linked_programs;
@@ -4394,7 +3903,6 @@ 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);
@@ -4404,57 +3912,62 @@ 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 < 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));
+        for(i = 0; i < ps->num_gl_shaders; i++) {
+            TRACE("deleting pshader %u\n", ps->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(ps->gl_shaders[i].prgId));
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
-        ps->backend_priv = NULL;
+        HeapFree(GetProcessHeap(), 0, ps->gl_shaders);
+        ps->gl_shaders = NULL;
+        ps->num_gl_shaders = 0;
+        ps->shader_array_size = 0;
     } else {
         UINT i;
     } else {
         UINT i;
-        struct glsl_vshader_private *shader_data = vs->backend_priv;
 
         ENTER_GL();
 
         ENTER_GL();
-        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));
+        for(i = 0; i < vs->num_gl_shaders; i++) {
+            TRACE("deleting vshader %u\n", vs->gl_shaders[i].prgId);
+            GL_EXTCALL(glDeleteObjectARB(vs->gl_shaders[i].prgId));
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
             checkGLcall("glDeleteObjectARB");
         }
         LEAVE_GL();
-        HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
-        HeapFree(GetProcessHeap(), 0, shader_data);
-        vs->backend_priv = NULL;
+        HeapFree(GetProcessHeap(), 0, vs->gl_shaders);
+        vs->gl_shaders = NULL;
+        vs->num_gl_shaders = 0;
+        vs->shader_array_size = 0;
     }
 }
 
     }
 }
 
-static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+static unsigned int glsl_program_key_hash(const void *key)
 {
     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;
 
 
-    if (k->vshader > prog->vshader) return 1;
-    else if (k->vshader < prog->vshader) return -1;
+    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->pshader > prog->pshader) return 1;
-    else if (k->pshader < prog->pshader) return -1;
+    return hash;
+}
 
 
-    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;
+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;
 
 
-    return 0;
+    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);
 }
 
 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)
@@ -4481,73 +3994,50 @@ 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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const WineD3D_GL_Info *gl_info = &This->adapter->gl_info;
     struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
     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");
-        goto fail;
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
     }
 
     if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
     {
         ERR("Failed to initialize vertex shader constant heap\n");
     }
 
     if (!constant_heap_init(&priv->vconst_heap, GL_LIMITS(vshader_constantsF)))
     {
         ERR("Failed to initialize vertex shader constant heap\n");
-        goto fail;
+        HeapFree(GetProcessHeap(), 0, priv->stack);
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
     }
 
     if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
     {
         ERR("Failed to initialize pixel shader constant heap\n");
     }
 
     if (!constant_heap_init(&priv->pconst_heap, GL_LIMITS(pshader_constantsF)))
     {
         ERR("Failed to initialize pixel shader constant heap\n");
-        goto fail;
-    }
-
-    if (wine_rb_init(&priv->program_lookup, &wined3d_glsl_program_rb_functions) == -1)
-    {
-        ERR("Failed to initialize rbtree.\n");
-        goto fail;
+        constant_heap_free(&priv->vconst_heap);
+        HeapFree(GetProcessHeap(), 0, priv->stack);
+        HeapFree(GetProcessHeap(), 0, priv);
+        return E_OUTOFMEMORY;
     }
 
     }
 
+    priv->glsl_program_lookup = hash_table_create(glsl_program_key_hash, glsl_program_key_compare);
     priv->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 struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
+    const 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])
@@ -4555,12 +4045,10 @@ 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();
 
 
-    wine_rb_destroy(&priv->program_lookup, NULL, NULL);
+    hash_table_destroy(priv->glsl_program_lookup, NULL, NULL);
     constant_heap_free(&priv->pconst_heap);
     constant_heap_free(&priv->vconst_heap);
     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;
@@ -4571,19 +4059,185 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
     return FALSE;
 }
 
     return FALSE;
 }
 
-static void shader_glsl_get_caps(WINED3DDEVTYPE devtype,
-        const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
+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)
 {
     /* 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 based
-     * on the version of NV_vertex_program.
+     * 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.
      * 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 ((gl_info->supported[NV_VERTEX_PROGRAM2] && !gl_info->supported[NV_VERTEX_PROGRAM3])
-            || gl_info->ps_arb_max_instructions <= 512)
+    if((GLINFO_LOCATION.vs_nv_version == VS_VERSION_20) || (GLINFO_LOCATION.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);
@@ -4601,8 +4255,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype,
      * 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 ((gl_info->supported[NV_FRAGMENT_PROGRAM] && !gl_info->supported[NV_FRAGMENT_PROGRAM2])
-            || (gl_info->ps_arb_max_instructions <= 512))
+    if((GLINFO_LOCATION.ps_nv_version == PS_VERSION_20) || (GLINFO_LOCATION.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);
@@ -4623,8 +4276,6 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype,
      */
     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)
@@ -4650,7 +4301,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           */ shader_glsl_bem,
+    /* WINED3DSIH_BEM           */ pshader_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,
@@ -4663,7 +4314,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        */ shader_glsl_dp2add,
+    /* WINED3DSIH_DP2ADD        */ pshader_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,
@@ -4701,7 +4352,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           */ shader_glsl_ret,
+    /* WINED3DSIH_RET           */ NULL,
     /* 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,
@@ -4709,49 +4360,32 @@ 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           */ 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_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_TEXLDD        */ shader_glsl_texldd,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
     /* WINED3DSIH_TEXLDD        */ shader_glsl_texldd,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
-    /* WINED3DSIH_TEXM3x2DEPTH  */ shader_glsl_texm3x2depth,
-    /* WINED3DSIH_TEXM3x2PAD    */ shader_glsl_texm3x2pad,
-    /* WINED3DSIH_TEXM3x2TEX    */ shader_glsl_texm3x2tex,
-    /* WINED3DSIH_TEXM3x3       */ shader_glsl_texm3x3,
+    /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_glsl_texm3x2depth,
+    /* WINED3DSIH_TEXM3x2PAD    */ pshader_glsl_texm3x2pad,
+    /* WINED3DSIH_TEXM3x2TEX    */ pshader_glsl_texm3x2tex,
+    /* WINED3DSIH_TEXM3x3       */ pshader_glsl_texm3x3,
     /* WINED3DSIH_TEXM3x3DIFF   */ NULL,
     /* WINED3DSIH_TEXM3x3DIFF   */ NULL,
-    /* 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,
+    /* 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,
 };
 
 };
 
-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_handle_instruction,
+    shader_glsl_instruction_handler_table,
     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,
@@ -4763,6 +4397,9 @@ 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 a0a576b..f7e331d 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
-
-/* GL locking for state handlers is done by the caller. */
-
-static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     BOOL bumpmap = FALSE;
 
     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
     BOOL bumpmap = FALSE;
 
     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
@@ -449,12 +445,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()");
+    checkGLcall("set_tex_op_nvrc()\n");
+
 }
 
 
 }
 
 
-static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -546,8 +542,7 @@ static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
 
@@ -562,8 +557,7 @@ static void nvts_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     nvts_activate_dimensions(sampler, stateblock, context);
 }
 
     nvts_activate_dimensions(sampler, stateblock, context);
 }
 
-static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
@@ -590,8 +584,7 @@ static void nvts_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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]));
@@ -599,12 +592,9 @@ static void nvrc_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
 #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)");
@@ -612,11 +602,9 @@ 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 struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
+static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps)
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD                        |
                             WINED3DTEXOPCAPS_ADDSIGNED                  |
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD                        |
                             WINED3DTEXOPCAPS_ADDSIGNED                  |
@@ -671,7 +659,6 @@ static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype,
 }
 
 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
@@ -700,137 +687,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        }, 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_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_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        }, 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(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(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        }, 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(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(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        }, 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(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(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        }, 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(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(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        }, 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(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(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        }, 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(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(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        }, 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(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(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        }, 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_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_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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, 0                               },
     { 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      }, WINED3D_GL_EXT_NONE             },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, 0                               },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
 };
 
 const struct fragment_pipeline nvts_fragment_pipeline = {
 };
 
 const struct fragment_pipeline nvts_fragment_pipeline = {
index a5447d0..338e66e 100644 (file)
@@ -22,6 +22,7 @@
 #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"
@@ -77,9 +78,7 @@ 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:
-            FIXME("Unhandled size bits %#x.\n", dwFlags & SIZE_BITS);
-            return 256;
+        default: assert(0); return 256;
     }
 }
 
     }
 }
 
index 6ac145c..33148c8 100644 (file)
@@ -178,10 +178,6 @@ 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;
@@ -242,9 +238,8 @@ 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, NULL, This->input_signature, NULL,
-            pFunction, GL_LIMITS(pshader_constantsF));
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction,
+                                    GL_LIMITS(pshader_constantsF));
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
@@ -299,7 +294,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures)
+static 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;
@@ -343,6 +338,29 @@ void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseT
     }
 }
 
     }
 }
 
+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 ***/
@@ -421,3 +439,44 @@ 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 2a2c1b1..481177f 100644 (file)
@@ -62,22 +62,38 @@ 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)
-        {
-            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);
+        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");
+            }
         }
         }
+        LEAVE_GL();
 
         HeapFree(GetProcessHeap(), 0, This->extendedData);
         HeapFree(GetProcessHeap(), 0, This);
 
         HeapFree(GetProcessHeap(), 0, This->extendedData);
         HeapFree(GetProcessHeap(), 0, This);
@@ -270,7 +286,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;
-    struct wined3d_occlusion_query *query = This->extendedData;
+    GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
     DWORD* data = pData;
     GLuint available;
     GLuint samples;
     DWORD* data = pData;
     GLuint available;
     GLuint samples;
@@ -278,8 +294,6 @@ 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 */
@@ -302,27 +316,26 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
         return S_OK;
     }
 
         return S_OK;
     }
 
-    if (query->context->tid != GetCurrentThreadId())
+    if (((WineQueryOcclusionData *)This->extendedData)->ctx != This->wineD3DDevice->activeContext
+            || This->wineD3DDevice->activeContext->tid != GetCurrentThreadId())
     {
     {
-        FIXME("%p Wrong thread, returning 1.\n", This);
+        FIXME("%p Wrong context, 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(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
-    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
+    GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
+    checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
     TRACE("(%p) : available %d.\n", This, available);
 
     if (available)
     {
         if (data)
         {
     TRACE("(%p) : available %d.\n", This, available);
 
     if (available)
     {
         if (data)
         {
-            GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples));
-            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
+            GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
+            checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
             TRACE("(%p) : Returning %d samples.\n", This, samples);
             *data = samples;
         }
             TRACE("(%p) : Returning %d samples.\n", This, samples);
             *data = samples;
         }
@@ -340,52 +353,32 @@ 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);
 
-    if (!pData || !dwSize) return S_OK;
-
-    if (!query->context)
-    {
-        ERR("Query not started, returning TRUE.\n");
-        *data = TRUE;
-
+    ctx = ((WineQueryEventData *)This->extendedData)->ctx;
+    if(pData == NULL || dwSize == 0) {
         return S_OK;
         return S_OK;
-    }
-
-    if (query->context->tid != GetCurrentThreadId())
-    {
+    } if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
         /* See comment in IWineD3DQuery::Issue, event query codeblock */
-        FIXME("Wrong thread, reporting GPU idle.\n");
+        FIXME("Query context not active, reporting GPU idle\n");
         *data = TRUE;
         *data = TRUE;
-
-        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));
+    } else if(GL_SUPPORT(APPLE_FENCE)) {
+        ENTER_GL();
+        *data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
         checkGLcall("glTestFenceAPPLE");
         checkGLcall("glTestFenceAPPLE");
-    }
-    else if (GL_SUPPORT(NV_FENCE))
-    {
-        *data = GL_EXTCALL(glTestFenceNV(query->id));
+        LEAVE_GL();
+    } else if(GL_SUPPORT(NV_FENCE)) {
+        ENTER_GL();
+        *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
         checkGLcall("glTestFenceNV");
         checkGLcall("glTestFenceNV");
-    }
-    else
-    {
+        LEAVE_GL();
+    } 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;
 }
 
@@ -462,47 +455,29 @@ 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)
-    {
-        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));
+    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));
             checkGLcall("glSetFenceAPPLE");
             checkGLcall("glSetFenceAPPLE");
-        }
-        else if (GL_SUPPORT(NV_FENCE))
-        {
-            GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
+            LEAVE_GL();
+        } else if (GL_SUPPORT(NV_FENCE)) {
+            ENTER_GL();
+            GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
             checkGLcall("glSetFenceNV");
             checkGLcall("glSetFenceNV");
+            LEAVE_GL();
         }
         }
-
-        LEAVE_GL();
-    }
-    else if(dwIssueFlags & WINED3DISSUE_BEGIN)
-    {
+    } 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");
     }
@@ -519,67 +494,34 @@ 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))
-    {
-        struct wined3d_occlusion_query *query = This->extendedData;
-        struct wined3d_context *context;
-
-        /* 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);
+    if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
+        WineD3DContext *ctx = ((WineQueryOcclusionData *)This->extendedData)->ctx;
 
 
-                    ENTER_GL();
+        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) {
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
                     checkGLcall("glEndQuery()");
-                    LEAVE_GL();
                 }
                 }
-            }
-            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(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) {
                     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 89ea7f3..807240b 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
-HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(struct IWineD3DResourceClass *resource, 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;
@@ -70,8 +68,6 @@ HRESULT resource_init(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type
         WineD3DAdapterChangeGLRam(device, size);
     }
 
         WineD3DAdapterChangeGLRam(device, size);
     }
 
-    device_resource_add(device, iface);
-
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
@@ -100,7 +96,10 @@ 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) device_resource_released(This->resource.wineD3DDevice, iface);
+    if (This->resource.wineD3DDevice != NULL) {
+        IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface);
+    }/* NOTE: this is not really an error for system memory resources */
+    return;
 }
 
 HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice** ppDevice)
 }
 
 HRESULT resource_get_device(IWineD3DResource *iface, IWineD3DDevice** ppDevice)
index ead2769..a626d52 100644 (file)
@@ -349,7 +349,6 @@ 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;
@@ -361,7 +360,6 @@ 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 91aa882..5cc445d 100644 (file)
@@ -28,9 +28,6 @@ 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)
 
@@ -49,26 +46,19 @@ 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_CONSTBUFFER  = 0x8,
+    WINED3D_SM4_RT_TEMP     = 0x0,
+    WINED3D_SM4_RT_INPUT    = 0x1,
+    WINED3D_SM4_RT_OUTPUT   = 0x2,
+    WINED3D_SM4_RT_IMMCONST = 0x4,
 };
 
 enum wined3d_sm4_immconst_type
 };
 
 enum wined3d_sm4_immconst_type
@@ -102,30 +92,20 @@ 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,
-    /* UNKNOWN */                       0,
-    /* UNKNOWN */                       0,
-    /* UNKNOWN */                       0,
-    /* WINED3D_SM4_RT_CONSTBUFFER */    WINED3DSPR_CONSTBUFFER,
+    /* 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,
 };
 
 static const struct sysval_map sysval_map[] =
 };
 
 static const struct sysval_map sysval_map[] =
@@ -285,7 +265,6 @@ 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))
@@ -298,16 +277,6 @@ 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 =
@@ -335,6 +304,7 @@ 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;
     }
 
@@ -349,8 +319,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))
@@ -363,16 +333,7 @@ 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];
     }
 
-    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->reg.idx = register_idx;
     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 8ddfd28..ad1593c 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 (*context->gl_info)
+#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
 
 
-/* GL locking for state handlers is done by the caller. */
+static void state_blendop(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)
-{
+static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
      */
@@ -54,13 +51,15 @@ static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
     }
 }
 
-static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
-    ERR("Undefined state.\n");
+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_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
 
     switch(Value) {
     WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
 
     switch(Value) {
@@ -81,8 +80,7 @@ static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -104,8 +102,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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");
@@ -133,8 +130,7 @@ static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
     }
 }
 
-static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
      */
@@ -160,8 +156,7 @@ static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -179,8 +174,7 @@ static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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");
@@ -190,8 +184,7 @@ static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
      */
@@ -204,8 +197,7 @@ static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
 
     if(glParm) {
     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
 
     if(glParm) {
@@ -228,8 +220,7 @@ static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
 
@@ -238,8 +229,7 @@ static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     checkGLcall("glLightModel for MODEL_AMBIENT");
 }
 
     checkGLcall("glLightModel for MODEL_AMBIENT");
 }
 
-static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
@@ -451,13 +441,11 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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]);
@@ -466,8 +454,7 @@ static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     checkGLcall("glBlendColor");
 }
 
     checkGLcall("glBlendColor");
 }
 
-static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     int glParm = 0;
     float ref;
     BOOL enable_ckey = FALSE;
     int glParm = 0;
     float ref;
     BOOL enable_ckey = FALSE;
@@ -521,7 +508,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
 
     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
         glParm = GL_NOTEQUAL;
 
     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
         glParm = GL_NOTEQUAL;
-        ref = 0.0f;
+        ref = 0.0;
     } 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]);
@@ -532,12 +519,11 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
     DWORD enable  = 0xFFFFFFFF;
     DWORD disable = 0x00000000;
 
-    if (!stateblock->wineD3DDevice->vs_clipping && use_vs(stateblock))
+    if (use_vs(stateblock))
     {
         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
     {
         /* 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
@@ -601,13 +587,11 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     int blendEquation = GL_FUNC_ADD;
     int blendEquationAlpha = GL_FUNC_ADD;
 
     int blendEquation = GL_FUNC_ADD;
     int blendEquationAlpha = GL_FUNC_ADD;
 
@@ -648,8 +632,8 @@ static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
     }
 }
 
-static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void
+state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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:
@@ -748,8 +732,7 @@ static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock
     checkGLcall("glMaterialfv(GL_EMISSION)");
 }
 
     checkGLcall("glMaterialfv(GL_EMISSION)");
 }
 
-static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -771,9 +754,8 @@ static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
-        GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
-{
+static void
+renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, 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));
@@ -784,8 +766,8 @@ static void renderstate_stencil_twosided(struct wined3d_context *context, GLint
     checkGLcall("glStencilOp(...)");
 }
 
     checkGLcall("glStencilOp(...)");
 }
 
-static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void
+state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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;
@@ -839,10 +821,10 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
              * 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(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);
+            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);
         } 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(...)");
@@ -874,8 +856,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
     }
 }
 
-static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
@@ -893,8 +874,7 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock
     glStencilMask(mask);
 }
 
     glStencilMask(mask);
 }
 
-static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
     DWORD mask;
 
     if(stateblock->wineD3DDevice->stencilBufferTarget) {
@@ -907,8 +887,7 @@ static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glStencilMask");
 }
 
     checkGLcall("glStencilMask");
 }
 
-static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
 
 
     TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
 
@@ -945,8 +924,7 @@ static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock
     }
 }
 
     }
 }
 
-void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float fogstart, fogend;
     union {
         DWORD d;
     float fogstart, fogend;
     union {
         DWORD d;
@@ -955,13 +933,13 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
 
     switch(context->fog_source) {
         case FOGSOURCE_VS:
 
     switch(context->fog_source) {
         case FOGSOURCE_VS:
-            fogstart = 1.0f;
-            fogend = 0.0f;
+            fogstart = 1.0;
+            fogend = 0.0;
             break;
 
         case FOGSOURCE_COORD:
             break;
 
         case FOGSOURCE_COORD:
-            fogstart = 255.0f;
-            fogend = 0.0f;
+            fogstart = 255.0;
+            fogend = 0.0;
             break;
 
         case FOGSOURCE_FFP:
             break;
 
         case FOGSOURCE_FFP:
@@ -971,8 +949,8 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
             fogend = tmpvalue.f;
             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
             if(fogstart == fogend) {
             fogend = tmpvalue.f;
             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
             if(fogstart == fogend) {
-                fogstart = -1.0f / 0.0f;
-                fogend = 0.0f;
+                fogstart = -1.0 / 0.0;
+                fogend = 0.0;
             }
             break;
 
             }
             break;
 
@@ -981,8 +959,8 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
              * 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.0f;
-            fogend = 0.0f;
+            fogstart = 0.0;
+            fogend = 0.0;
     }
 
     glFogf(GL_FOG_START, fogstart);
     }
 
     glFogf(GL_FOG_START, fogstart);
@@ -994,8 +972,7 @@ void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     TRACE("Fog End == %f\n", fogend);
 }
 
     TRACE("Fog End == %f\n", fogend);
 }
 
-void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -1136,15 +1113,13 @@ void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)");
@@ -1154,16 +1129,14 @@ static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
     float col[4];
     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
     glFogfv(GL_FOG_COLOR, &col[0]);
     checkGLcall("glFog GL_FOG_COLOR");
 }
 
-void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1173,10 +1146,11 @@ void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
 }
 
     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
 }
 
-static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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.
@@ -1186,10 +1160,10 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
         return;
     }
 
         return;
     }
 
+    isDiffuseSupplied = diffuse->data || diffuse->buffer_object;
+
     context->num_untracked_materials = 0;
     context->num_untracked_materials = 0;
-    if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
-            && stateblock->renderState[WINED3DRS_COLORVERTEX])
-    {
+    if (isDiffuseSupplied && 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],
@@ -1284,8 +1258,7 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     context->tracking_parm = Parm;
 }
 
     context->tracking_parm = Parm;
 }
 
-static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD                 d;
         WINED3DLINEPATTERN    lp;
     union {
         DWORD                 d;
         WINED3DLINEPATTERN    lp;
@@ -1305,8 +1278,7 @@ static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1334,8 +1306,7 @@ static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
 }
 
 
 }
 
 
-static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     if(isStateDirty(context, STATE_VDECL)) {
         return;
     }
     if(isStateDirty(context, STATE_VDECL)) {
         return;
     }
@@ -1344,7 +1315,8 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str
      * 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.use_map & (1 << WINED3D_FFP_NORMAL)))
+            && (stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].data
+            || stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].buffer_object))
     {
         glEnable(GL_NORMALIZE);
         checkGLcall("glEnable(GL_NORMALIZE);");
     {
         glEnable(GL_NORMALIZE);
         checkGLcall("glEnable(GL_NORMALIZE);");
@@ -1354,28 +1326,24 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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.0f)
-    {
+    if(tmpvalue.f != 1.0) {
         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.0f)
-    {
+    if(tmpvalue.f != 64.0) {
         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, struct wined3d_context *context)
-{
+static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1395,8 +1363,7 @@ static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfEXT(...)");
 }
 
     checkGLcall("glPointParameterfEXT(...)");
 }
 
-static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1416,8 +1383,7 @@ static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock,
     checkGLcall("glPointParameterfARB(...)");
 }
 
     checkGLcall("glPointParameterfARB(...)");
 }
 
-static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -1487,13 +1453,7 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     checkGLcall("glPointSize(...);");
 }
 
     checkGLcall("glPointSize(...);");
 }
 
-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)
-{
+static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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",
@@ -1518,8 +1478,7 @@ static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, st
     }
 }
 
     }
 }
 
-static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)");
@@ -1529,8 +1488,7 @@ static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 {
@@ -1544,8 +1502,7 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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]) {
@@ -1555,8 +1512,7 @@ static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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) {
@@ -1574,8 +1530,7 @@ static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -1605,15 +1560,13 @@ static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
     }
 }
 
-static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)");
@@ -1623,8 +1576,7 @@ static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
     }
 }
 
-static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)");
@@ -1634,8 +1586,7 @@ static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struc
     }
 }
 
     }
 }
 
-static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1654,8 +1605,7 @@ static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)");
@@ -1665,36 +1615,31 @@ static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
         float f;
     union {
         DWORD d;
         float f;
@@ -1714,127 +1659,109 @@ static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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");
     }
@@ -1888,8 +1815,7 @@ 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(const struct wined3d_context *context, IWineD3DDevice *iface,
-        BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+static void set_tex_op(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;
@@ -1900,6 +1826,7 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if
     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);
 
@@ -2913,8 +2840,7 @@ static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *if
 }
 
 
 }
 
 
-static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -2965,15 +2891,14 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
     }
 
         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
     }
 
-    set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
+    set_tex_op((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, struct wined3d_context *context)
-{
+void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -3067,13 +2992,12 @@ void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d
                          mapped_stage,
                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
     } else {
                          mapped_stage,
                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
     } else {
-        set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
+        set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
                     op, arg1, arg2, arg0);
     }
 }
 
                     op, arg1, arg2, arg0);
     }
 }
 
-static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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;
@@ -3098,7 +3022,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s
 
     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.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
+            stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].stride
             ? 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);
@@ -3109,8 +3033,8 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s
         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 so only enable the
-           fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
+        /* 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. */
         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);
@@ -3118,8 +3042,7 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void unloadTexCoords(const struct wined3d_context *context)
-{
+static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
     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) {
@@ -3128,8 +3051,7 @@ static void unloadTexCoords(const struct wined3d_context *context)
     }
 }
 
     }
 }
 
-static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
-        const struct wined3d_stream_info *si, GLuint *curVBO)
+static void loadTexCoords(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;
@@ -3137,14 +3059,14 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl
 
     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;
 
-        if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
+        e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+        if (coordIdx < MAX_TEXTURES && (e->data || e->buffer_object))
         {
         {
-            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);
 
@@ -3176,14 +3098,13 @@ static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBl
     checkGLcall("loadTexCoords");
 }
 
     checkGLcall("loadTexCoords");
 }
 
-static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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.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 };
+    static const GLfloat s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
+    static const GLfloat t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
+    static const GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
+    static const GLfloat q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
 
     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
     {
 
     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
     {
@@ -3345,13 +3266,12 @@ static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
          */
         GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
 
          */
         GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
 
-        unloadTexCoords(context);
-        loadTexCoords(context, stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
+        unloadTexCoords(stateblock);
+        loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
     }
 }
 
     }
 }
 
-static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -3362,16 +3282,14 @@ static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
        return;
     }
 
        return;
     }
 
-    device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock));
+    device->shader_backend->shader_load_constants((IWineD3DDevice *)device, use_ps(stateblock), use_vs(stateblock));
 }
 
 }
 
-static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 & (1 << stage)))
-    {
+    if(stateblock->pixelShader && stage != 0 &&
+       ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[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
          */
@@ -3382,8 +3300,7 @@ static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
 
@@ -3391,7 +3308,7 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s
 
     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
-     * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
+     * IWineD3DBaseTexture::ApplyStateChanges 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
@@ -3409,8 +3326,7 @@ static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 {
@@ -3440,8 +3356,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
         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);
-        basetexture_apply_state_changes(stateblock->textures[sampler],
-                stateblock->textureState[sampler], stateblock->samplerState[sampler]);
+        IWineD3DBaseTexture_ApplyStateChanges(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];
@@ -3461,7 +3376,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
             }
         }
 
             }
         }
 
-        /* Trigger shader constant reloading (for NP2 texcoord fixup) */
+        /* Trigger shader constant reloading (for NP2 texcoord fixup)
+         * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */
         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(
@@ -3482,8 +3398,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
     }
 }
 
     }
 }
 
-void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -3520,7 +3435,7 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
     }
 
     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
-        device->shader_backend->shader_select(context, use_pshader, use_vshader);
+        device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, 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);
@@ -3528,12 +3443,10 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
     }
 }
 
     }
 }
 
-static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 & (1 << stage)))
-    {
+    if(stateblock->pixelShader && stage != 0 &&
+       ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
          * anyway
          */
         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
          * anyway
          */
@@ -3544,8 +3457,7 @@ static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -3573,8 +3485,7 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
     }
 }
 
     }
 }
 
-static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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)) {
@@ -3582,20 +3493,9 @@ static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     }
 
     /* 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 */
-    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);
-    }
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
 
     TRACE("Clipplane [%f,%f,%f,%f]\n",
           stateblock->clipplane[index][0],
 
     TRACE("Clipplane [%f,%f,%f,%f]\n",
           stateblock->clipplane[index][0],
@@ -3608,8 +3508,7 @@ static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     glPopMatrix();
 }
 
     glPopMatrix();
 }
 
-static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -3648,8 +3547,7 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     static BOOL once = FALSE;
 
     switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
     static BOOL once = FALSE;
 
     switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
@@ -3668,8 +3566,7 @@ static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
 
     switch(val) {
     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
 
     switch(val) {
@@ -3711,8 +3608,7 @@ static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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
@@ -3769,8 +3665,7 @@ static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
     }
 }
 
     }
 }
 
-static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
     glMatrixMode(GL_PROJECTION);
     checkGLcall("glMatrixMode(GL_PROJECTION)");
     glLoadIdentity();
@@ -3809,8 +3704,7 @@ 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 (context->render_offscreen)
-            {
+            if(stateblock->wineD3DDevice->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);
@@ -3824,8 +3718,7 @@ 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 (context->render_offscreen)
-            {
+            if(stateblock->wineD3DDevice->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);
@@ -3834,14 +3727,12 @@ 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(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
-        checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
-
+        glTranslatef(0.5, 0.5, 0);
+        checkGLcall("glTranslatef(0.5, 0.5, 0)");
         /* 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 (context->render_offscreen)
-        {
-            glScalef(1.0f, -1.0f, 1.0f);
+        if (stateblock->wineD3DDevice->render_offscreen) {
+            glScalef(1.0, -1.0, 1.0);
             checkGLcall("glScalef");
         }
     } else {
             checkGLcall("glScalef");
         }
     } else {
@@ -3882,24 +3773,16 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
          * glScalef(1.0, flip, 2.0);
          */
 
          * glScalef(1.0, flip, 2.0);
          */
 
-        /* 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)
-        {
+        if (stateblock->wineD3DDevice->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(xoffset, -yoffset, -1.0f);
-            checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
-            glScalef(1.0f, -1.0f, 2.0f);
+            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);
         } else {
         } else {
-            glTranslatef(xoffset, yoffset, -1.0f);
-            checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
-            glScalef(1.0f, 1.0f, 2.0f);
+            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);
         }
         checkGLcall("glScalef");
 
         }
         checkGLcall("glScalef");
 
@@ -3912,8 +3795,7 @@ 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(const struct wined3d_context *context)
-{
+static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_NORMAL_ARRAY);
     glDisableClientState(GL_COLOR_ARRAY);
     glDisableClientState(GL_VERTEX_ARRAY);
     glDisableClientState(GL_NORMAL_ARRAY);
     glDisableClientState(GL_COLOR_ARRAY);
@@ -3923,13 +3805,21 @@ static inline void unloadVertexData(const struct wined3d_context *context)
     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
     }
     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
     }
-    unloadTexCoords(context);
+    unloadTexCoords(stateblock);
 }
 
 }
 
-static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i)
+static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
 }
@@ -3937,7 +3827,7 @@ static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, str
 /* 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, struct wined3d_context *context)
+static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineD3DContext *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;
@@ -3954,7 +3844,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, stru
 }
 
 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
 }
 
 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
-        const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
+        const struct wined3d_stream_info *stream_info, WineD3DContext *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;
@@ -4128,8 +4018,7 @@ 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(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
-        const struct wined3d_stream_info *si)
+static void loadVertexData(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;
@@ -4141,11 +4030,11 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     /* Blend Data ---------------------------------------------- */
     stateblock->wineD3DDevice->instancedDraw = FALSE;
 
     /* Blend Data ---------------------------------------------- */
-    if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
-            || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+    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)
     {
     {
-        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]);
@@ -4172,7 +4061,8 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
 
             checkGLcall("glWeightPointerARB");
 
 
             checkGLcall("glWeightPointerARB");
 
-            if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+            if (si->elements[WINED3D_FFP_BLENDINDICES].data
+                    || (si->elements[WINED3D_FFP_BLENDINDICES].buffer_object))
             {
                 static BOOL warned;
                 if (!warned)
             {
                 static BOOL warned;
                 if (!warned)
@@ -4196,7 +4086,8 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     }
 
     /* Point Size ----------------------------------------------*/
     }
 
     /* Point Size ----------------------------------------------*/
-    if (si->use_map & (1 << WINED3D_FFP_PSIZE))
+    e = &si->elements[WINED3D_FFP_PSIZE];
+    if (e->data || e->buffer_object)
     {
         /* 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");
@@ -4204,11 +4095,11 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     }
 
     /* Vertex Pointers -----------------------------------------*/
     }
 
     /* Vertex Pointers -----------------------------------------*/
-    if (si->use_map & (1 << WINED3D_FFP_POSITION))
+    e = &si->elements[WINED3D_FFP_POSITION];
+    if (e->data || e->buffer_object)
     {
         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));
@@ -4238,11 +4129,10 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     }
 
     /* Normals -------------------------------------------------*/
     }
 
     /* Normals -------------------------------------------------*/
-    if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+    e = &si->elements[WINED3D_FFP_NORMAL];
+    if (e->data || e->buffer_object)
     {
         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));
@@ -4269,11 +4159,11 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     /* 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   */
 
-    if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+    e = &si->elements[WINED3D_FFP_DIFFUSE];
+    if (e->data || e->buffer_object)
     {
         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));
@@ -4293,52 +4183,22 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     }
 
     /* Specular Colour ------------------------------------------*/
     }
 
     /* Specular Colour ------------------------------------------*/
-    if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+    e = &si->elements[WINED3D_FFP_SPECULAR];
+    if (e->data || e->buffer_object)
     {
         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;
             }
-
-            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, ...)");
-                }
-            }
+            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, ...)");
             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 {
@@ -4359,7 +4219,7 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
     }
 
     /* Texture coords -------------------------------------------*/
     }
 
     /* Texture coords -------------------------------------------*/
-    loadTexCoords(context, stateblock, si, &curVBO);
+    loadTexCoords(stateblock, si, &curVBO);
 }
 
 static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
 }
 
 static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
@@ -4385,8 +4245,7 @@ static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_i
     return;
 }
 
     return;
 }
 
-static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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;
@@ -4425,23 +4284,18 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
             device->useDrawStridedSlow = FALSE;
         }
     }
             device->useDrawStridedSlow = FALSE;
         }
     }
-    else
+    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))))
     {
     {
-        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;
-        }
+        /* 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)
@@ -4452,7 +4306,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     }
     else if (context->namedArraysLoaded)
     {
     }
     else if (context->namedArraysLoaded)
     {
-        unloadVertexData(context);
+        unloadVertexData(stateblock);
         context->namedArraysLoaded = FALSE;
     }
 
         context->namedArraysLoaded = FALSE;
     }
 
@@ -4465,13 +4319,12 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
     else if (load_named)
     {
         TRACE("Loading vertex data\n");
     else if (load_named)
     {
         TRACE("Loading vertex data\n");
-        loadVertexData(context, stateblock, dataLocations);
+        loadVertexData(stateblock, dataLocations);
         context->namedArraysLoaded = TRUE;
     }
 }
 
         context->namedArraysLoaded = TRUE;
     }
 }
 
-static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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);
@@ -4479,7 +4332,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     /* 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) {
@@ -4507,11 +4359,9 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
         /* 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)
-        {
-            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;
+        if (useVertexShaderFunction) {
+            device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
+            device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
         }
     }
 
         }
     }
 
@@ -4550,32 +4400,28 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
 
         if(context->last_was_vshader) {
             updateFog = TRUE;
 
         if(context->last_was_vshader) {
             updateFog = TRUE;
-            if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
+            if(!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;
-            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)");
-                }
+            /* 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
@@ -4591,14 +4437,6 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
                 }
             }
             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);
-            }
         }
     }
 
         }
     }
 
@@ -4606,7 +4444,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
      * application
      */
     if (!isStateDirty(context, STATE_PIXELSHADER)) {
      * application
      */
     if (!isStateDirty(context, STATE_PIXELSHADER)) {
-        device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
+        device->shader_backend->shader_select((IWineD3DDevice *)device, 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);
@@ -4628,8 +4466,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     }
 }
 
     }
 }
 
-static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     UINT width, height;
     IWineD3DSurfaceImpl *target;
 
     UINT width, height;
     IWineD3DSurfaceImpl *target;
 
@@ -4637,14 +4474,13 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     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 (context->render_offscreen)
-    {
+    if(stateblock->wineD3DDevice->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(context, &width, &height);
+        target->get_drawable_size(target, &width, &height);
 
         glViewport(stateblock->viewport.X,
                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
 
         glViewport(stateblock->viewport.X,
                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
@@ -4654,13 +4490,9 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, s
     checkGLcall("glViewport");
 }
 
     checkGLcall("glViewport");
 }
 
-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;
-
+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;
     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);
     }
@@ -4669,8 +4501,7 @@ static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock,
     }
 }
 
     }
 }
 
-static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
 
@@ -4679,7 +4510,7 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3
         checkGLcall("glDisable(GL_LIGHT0 + Index)");
     } else {
         float quad_att;
         checkGLcall("glDisable(GL_LIGHT0 + Index)");
     } else {
         float quad_att;
-        float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
+        float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
 
         /* 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);
@@ -4711,9 +4542,9 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3
         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.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
+            quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
         } else {
         } else {
-            quad_att = 0.0f; /*  0 or  MAX?  (0 seems to be ok) */
+            quad_att = 0; /*  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,
@@ -4785,22 +4616,20 @@ static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3
     return;
 }
 
     return;
 }
 
-static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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(context, &width, &height);
+    target->get_drawable_size(target, &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 (context->render_offscreen)
-    {
+    if (stateblock->wineD3DDevice->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);
@@ -4808,8 +4637,7 @@ static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     checkGLcall("glScissor");
 }
 
     checkGLcall("glScissor");
 }
 
-static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 {
@@ -4818,10 +4646,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct
     }
 }
 
     }
 }
 
-static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
-    if (context->render_offscreen)
-    {
+static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    if(stateblock->wineD3DDevice->render_offscreen) {
         glFrontFace(GL_CCW);
         checkGLcall("glFrontFace(GL_CCW)");
     } else {
         glFrontFace(GL_CCW);
         checkGLcall("glFrontFace(GL_CCW)");
     } else {
@@ -4831,692 +4657,689 @@ static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
 }
 
 const struct StateEntryTemplate misc_state_template[] = {
 }
 
 const struct StateEntryTemplate misc_state_template[] = {
-    { 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             },
+    { 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                               },
     /* 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      }, 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_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_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     }, 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_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_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  }, 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_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_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        }, 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_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_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     }, 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_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_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 }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor_w }, 0                               },
+    { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, 0                               },
     /* Samplers */
     /* Samplers */
-    { 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             },
+    { 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                               },
 };
 
 const struct StateEntryTemplate ffp_vertexstate_template[] = {
 };
 
 const struct StateEntryTemplate ffp_vertexstate_template[] = {
-    { 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             },
+    { 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                               },
       /* Clip planes */
       /* Clip planes */
-    { 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             },
+    { 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                               },
       /* Lights */
       /* Lights */
-    { 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             },
+    { 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                               },
     /* Viewport */
     /* Viewport */
-    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, WINED3D_GL_EXT_NONE             },
+    { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, 0                               },
       /* Transform states follow                    */
       /* Transform states follow                    */
-    { 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             },
+    { 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                               },
       /* Fog */
       /* Fog */
-    { 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_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
+    { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog_vertexpart}, 0                               },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
-    { 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_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_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 }, WINED3D_GL_EXT_NONE             },
-    { STATE_RENDER(WINED3DRS_POINTSIZE),                  { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, WINED3D_GL_EXT_NONE             },
+    { 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_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    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
     { 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 }, 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_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_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    }, WINED3D_GL_EXT_NONE             },
+    { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
      */
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, 0                               },
     { 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   }, WINED3D_GL_EXT_NONE             },
-    {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
+    { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, 0                               },
+    {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
 };
 
 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         }, 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             },
+    { 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                               },
 };
 #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 struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
+static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps)
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
                             WINED3DTEXOPCAPS_ADDSIGNED   |
 {
     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
                             WINED3DTEXOPCAPS_ADDSIGNED   |
@@ -5591,21 +5414,19 @@ static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
     return i;
 }
 
     return i;
 }
 
-static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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, struct wined3d_context *context)
-{
+static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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 struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
+        const 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;
@@ -5647,7 +5468,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 (!GL_SUPPORT(cur[i].extension)) continue;
+            if(cur[i].extension && !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 239b777..1c9b5a8 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,8 +113,11 @@ 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);
 
@@ -225,7 +228,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);
@@ -354,7 +357,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]) {
@@ -1084,6 +1087,9 @@ 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
@@ -1286,27 +1292,28 @@ 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 (SUCCEEDED(hr) && backbuffer)
-        {
-            WINED3DSURFACE_DESC desc;
-            RECT scissorrect;
-
+        if( hr == WINED3D_OK && backbuffer != NULL) {
             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 = desc.width;
+            scissorrect.right = width;
             scissorrect.top = 0;
             scissorrect.top = 0;
-            scissorrect.bottom = desc.height;
+            scissorrect.bottom = height;
             hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
             hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
-            if (FAILED(hr)) ERR("This should never happen, expect rendering issues!\n");
+            if( hr != WINED3D_OK ) {
+                ERR("This should never happen, expect rendering issues!\n");
+            }
         }
 
         /* Set the default viewport */
         }
 
         /* Set the default viewport */
index cce613c..9e9d55c 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
 
 
-#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;
-
-        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 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);
 
 
-static void surface_force_reload(IWineD3DSurface *iface)
+void surface_force_reload(IWineD3DSurface *iface)
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
 
@@ -254,12 +53,12 @@ void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb
 
     if(srgb)
     {
 
     if(srgb)
     {
-        name = &This->texture_name_srgb;
+        name = &This->glDescription.srgbTextureName;
         flag = SFLAG_INSRGBTEX;
     }
     else
     {
         flag = SFLAG_INSRGBTEX;
     }
     else
     {
-        name = &This->texture_name;
+        name = &This->glDescription.textureName;
         flag = SFLAG_INTEXTURE;
     }
 
         flag = SFLAG_INTEXTURE;
     }
 
@@ -284,24 +83,23 @@ 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->texture_target != target)
+    if (This->glDescription.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->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+        else if (This->glDescription.target == GL_TEXTURE_RECTANGLE_ARB)
         {
             This->Flags |= SFLAG_NORMCOORD;
         }
     }
         {
             This->Flags |= SFLAG_NORMCOORD;
         }
     }
-    This->texture_target = target;
+    This->glDescription.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) {
-    DWORD active_sampler;
+    int 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
@@ -320,8 +118,7 @@ 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 != WINED3D_UNMAPPED_STAGE)
-    {
+    if (active_sampler != -1) {
         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);
@@ -339,13 +136,8 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
     return FALSE;
 }
 
     return FALSE;
 }
 
-#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. */
+/* This call just downloads data, the caller is responsible for activating the
+ * right context and binding the correct texture. */
 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;
 
@@ -358,28 +150,29 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
 
     ENTER_GL();
 
 
     ENTER_GL();
 
-    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+    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)
     {
     {
-        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");
+        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()");
+            }
         }
         }
-
         LEAVE_GL();
     } else {
         void *mem;
         LEAVE_GL();
     } else {
         void *mem;
@@ -405,21 +198,23 @@ 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->texture_level, format, type, mem);
+        TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.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->texture_target, This->texture_level, format, type, NULL);
-            checkGLcall("glGetTexImage");
+            glGetTexImage(This->glDescription.target, This->glDescription.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->texture_target, This->texture_level, format, type, mem);
-            checkGLcall("glGetTexImage");
+            glGetTexImage(This->glDescription.target, This->glDescription.level, format,
+                          type, mem);
+            checkGLcall("glGetTexImage()");
         }
         LEAVE_GL();
 
         }
         LEAVE_GL();
 
@@ -495,70 +290,105 @@ 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 binding the
- * correct texture. */
-/* Context activation is done by the caller. */
+/* This call just uploads data, the caller is responsible for activating the
+ * right context and binding the correct texture. */
 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;
 
-    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->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;
+    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();
 
 
-    ENTER_GL();
+            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 (This->Flags & SFLAG_PBO)
-    {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-        checkGLcall("glBindBufferARB");
+                GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
+                        width, height, 0 /* border */, This->resource.size, NULL));
+                checkGLcall("glCompressedTexSubImage2D");
 
 
-        TRACE("(%p) pbo: %#x, data: %p.\n", This, This->pbo, data);
-        data = NULL;
-    }
+                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();
 
 
-    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
-    {
-        TRACE("Calling glCompressedTexSubImage2DARB.\n");
+        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);
 
 
-        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");
+            glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, NULL);
+            checkGLcall("glTexSubImage2D");
 
 
-        glTexSubImage2D(This->texture_target, This->texture_level,
-                0, 0, width, height, format, type, data);
-        checkGLcall("glTexSubImage2D");
-    }
+            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");
+        }
 
 
-    if (This->Flags & SFLAG_PBO)
-    {
-        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-        checkGLcall("glBindBufferARB");
+        LEAVE_GL();
     }
     }
-
-    LEAVE_GL();
 }
 
 }
 
-/* This call just allocates the texture, the caller is responsible for binding
- * the correct texture. */
-/* Context activation is done by the caller. */
+/* This call just allocates the texture, the caller is responsible for
+ * activating the right context and binding the correct texture. */
 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.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;
+    if (format_desc->heightscale != 1.0 && format_desc->heightscale != 0.0) 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->texture_target, This->texture_level, debug_d3dformat(format_desc->format),
+            This, This->glDescription.target, This->glDescription.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)) {
@@ -583,18 +413,8 @@ 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));
         }
     }
-
-    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");
-    }
+    glTexImage2D(This->glDescription.target, This->glDescription.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);
@@ -606,7 +426,6 @@ 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;
@@ -707,31 +526,64 @@ 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);
 
 
-    if (!ref)
-    {
-        surface_cleanup(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);
+        }
 
 
-        TRACE("(%p) Released.\n", This);
+        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);
+        }
+
+        TRACE("(%p) Released\n", This);
         HeapFree(GetProcessHeap(), 0, This);
         HeapFree(GetProcessHeap(), 0, This);
-    }
 
 
+    }
     return ref;
 }
 
     return ref;
 }
 
@@ -750,13 +602,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);
+        tex_impl->baseTexture.internal_preload(baseTexture, SRGB_RGB);
         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, NULL, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         }
 
         if (This->resource.format_desc->format == WINED3DFMT_P8
         }
 
         if (This->resource.format_desc->format == WINED3DFMT_P8
@@ -778,7 +630,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->texture_name, &tmp);
+            glPrioritizeTextures(1, &This->glDescription.textureName, &tmp);
             LEAVE_GL();
         }
     }
             LEAVE_GL();
         }
     }
@@ -789,7 +641,6 @@ 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 =
@@ -797,11 +648,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("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, This->pbo)");
+    checkGLcall("glBindBuffer(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("glGetBufferSubDataARB");
+    checkGLcall("glGetBufferSubData");
     GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
     GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
-    checkGLcall("glDeleteBuffersARB");
+    checkGLcall("glDeleteBuffers");
     LEAVE_GL();
 
     This->pbo = 0;
     LEAVE_GL();
 
     This->pbo = 0;
@@ -811,7 +662,6 @@ 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);
 
@@ -839,11 +689,8 @@ 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);
@@ -869,10 +716,8 @@ 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->texture_name);
-        This->texture_name = 0;
-        glDeleteTextures(1, &This->texture_name_srgb);
-        This->texture_name_srgb = 0;
+        glDeleteTextures(1, &This->glDescription.textureName);
+        This->glDescription.textureName = 0;
         LEAVE_GL();
     } else {
         IWineD3DBaseTexture_Release(texture);
         LEAVE_GL();
     } else {
         IWineD3DBaseTexture_Release(texture);
@@ -884,6 +729,13 @@ 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;
@@ -1002,11 +854,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("glGetIntegerv");
+    checkGLcall("glIntegerv");
     glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
     glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
-    checkGLcall("glGetIntegerv");
+    checkGLcall("glIntegerv");
     glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
     glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
-    checkGLcall("glGetIntegerv");
+    checkGLcall("glIntegerv");
 
     /* 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);
@@ -1187,15 +1039,18 @@ 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->texture_target, This->texture_level,
-            0, 0, 0, 0, This->currentDesc.Width, This->currentDesc.Height);
+    glCopyTexSubImage2D(This->glDescription.target,
+                        This->glDescription.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->texture_target);
+    TRACE("Updated target %d\n", This->glDescription.target);
 }
 
 static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
 }
 
 static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
@@ -1219,7 +1074,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, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
 
         GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
         ENTER_GL();
 
         GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
@@ -1265,7 +1120,6 @@ 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);
 
@@ -1298,24 +1152,77 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
         goto lock_end;
     }
 
         goto lock_end;
     }
 
-    /* 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)
+    /* 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])
     {
     {
-        pass_rect = NULL;
-    }
+        const RECT *pass_rect = pRect;
 
 
-    if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE
-            && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0])))
-    {
-        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect);
+        /* 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;
+
+            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 */);
     }
 
 lock_end:
     if(This->Flags & SFLAG_PBO) {
     }
 
 lock_end:
     if(This->Flags & SFLAG_PBO) {
-        ActivateContext(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(myDevice, myDevice->lastActiveRenderTarget, 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");
@@ -1385,10 +1292,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("glGetIntegerv");
+    checkGLcall("glIntegerv");
     glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
     glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
-    checkGLcall("glGetIntegerv");
-    glPixelZoom(1.0f, -1.0f);
+    checkGLcall("glIntegerv");
+    glPixelZoom(1.0, -1.0);
     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 */
@@ -1396,7 +1303,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("glRasterPos3i");
+    checkGLcall("glRasterPos2f");
 
     /* 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
@@ -1438,7 +1345,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm
         checkGLcall("glBindBufferARB");
     }
 
         checkGLcall("glBindBufferARB");
     }
 
-    glPixelZoom(1.0f, 1.0f);
+    glPixelZoom(1.0,1.0);
     checkGLcall("glPixelZoom");
 
     glRasterPos3iv(&prev_rasterpos[0]);
     checkGLcall("glPixelZoom");
 
     glRasterPos3iv(&prev_rasterpos[0]);
@@ -1446,7 +1353,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);
@@ -1475,7 +1382,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, NULL, CTXUSAGE_RESOURCELOAD);
+        ActivateContext(myDevice, myDevice->lastActiveRenderTarget, 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));
@@ -1516,10 +1423,14 @@ 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;
         }
@@ -1751,6 +1662,7 @@ 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;
             }
@@ -1772,7 +1684,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_RGB5_A1;
+                *internal = GL_RGBA;
                 *type = GL_UNSIGNED_SHORT_5_5_5_1;
             }
             break;
                 *type = GL_UNSIGNED_SHORT_5_5_5_1;
             }
             break;
@@ -1781,7 +1693,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_RGB5_A1;
+                *internal = GL_RGBA;
                 *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
             }
             break;
                 *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
             }
             break;
@@ -1790,7 +1702,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_RGBA8;
+                *internal = GL_RGBA;
                 *type = GL_UNSIGNED_INT_8_8_8_8;
                 *target_bpp = 4;
             }
                 *type = GL_UNSIGNED_INT_8_8_8_8;
                 *target_bpp = 4;
             }
@@ -1800,15 +1712,16 @@ 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_RGBA8;
+                *internal = GL_RGBA;
                 *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_SHADER)) break;
+            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) 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;
@@ -1822,6 +1735,7 @@ 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;
@@ -1838,22 +1752,25 @@ 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_SHADER)) break;
+            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) 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_SHADER)) break;
+            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) 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;
@@ -1865,6 +1782,7 @@ 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;
@@ -1872,6 +1790,7 @@ 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;
@@ -1879,6 +1798,7 @@ 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;
@@ -1886,33 +1806,11 @@ 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;
     }
@@ -1920,86 +1818,6 @@ 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)
 {
@@ -2358,83 +2176,82 @@ 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.0f;
+                    Dest[2] = 1.0;
                     Dest += 3;
                 }
             }
             break;
         }
 
                     Dest += 3;
                 }
             }
             break;
         }
 
-        case CONVERT_D15S1:
-        {
-            unsigned int x, y;
-
-            for (y = 0; y < height; ++y)
-            {
-                const WORD *source = (const WORD *)(src + y * pitch);
-                DWORD *dest = (DWORD *)(dst + y * outpitch);
-
-                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);
-                }
-            }
-            break;
-        }
+        default:
+            ERR("Unsupported conversation type %d\n", convert);
+    }
+    return WINED3D_OK;
+}
 
 
-        case CONVERT_D24X4S4:
-        {
-            unsigned int x, y;
+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;
 
 
-            for (y = 0; y < height; ++y)
-            {
-                const DWORD *source = (const DWORD *)(src + y * pitch);
-                DWORD *dest = (DWORD *)(dst + y * outpitch);
+    /* 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 (x = 0; x < width; ++x)
-                {
-                    /* Just need to clear out the X4 part. */
-                    dest[x] = source[x] & ~0xf0;
-                }
+    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;
+            }
+        } 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;
         }
         }
+    } 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;
 
 
-        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;
-                }
+            /* 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;
             }
             }
-            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];
@@ -2446,9 +2263,7 @@ 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");
-        ENTER_GL();
-        GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
-        LEAVE_GL();
+        GL_EXTCALL(glColorTableEXT(This->glDescription.target,GL_RGBA,256,GL_RGBA,GL_UNSIGNED_BYTE, table));
     }
     else
     {
     }
     else
     {
@@ -2456,8 +2271,6 @@ 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)
         {
@@ -2496,9 +2309,7 @@ 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->texture_target, This->texture_name);
-
-        LEAVE_GL();
+        glBindTexture(This->glDescription.target, This->glDescription.textureName);
     }
 }
 
     }
 }
 
@@ -2572,8 +2383,7 @@ 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->texture_target, This->texture_level, gen);
+            snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen);
             IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
         }
         /*
             IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
         }
         /*
@@ -2596,7 +2406,6 @@ 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;
@@ -2612,31 +2421,30 @@ 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->texture_name_srgb : &This->texture_name;
+        name = srgb ? &This->glDescription.srgbTextureName : &This->glDescription.textureName;
         if(!device->isInDraw) {
         if(!device->isInDraw) {
-            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         }
 
         ENTER_GL();
 
         }
 
         ENTER_GL();
 
-        if (!This->texture_level)
-        {
+        if (!This->glDescription.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->texture_target, *name);
+                glBindTexture(This->glDescription.target, *name);
                 checkGLcall("glBindTexture");
                 checkGLcall("glBindTexture");
-                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->glDescription.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->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->glDescription.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->texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+                glTexParameteri(This->glDescription.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->texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+                glTexParameteri(This->glDescription.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->texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameteri(This->glDescription.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 */
@@ -2645,7 +2453,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->texture_target, *name);
+        glBindTexture(This->glDescription.target, This->glDescription.textureName);
         checkGLcall("glBindTexture");
 
         LEAVE_GL();
         checkGLcall("glBindTexture");
 
         LEAVE_GL();
@@ -2728,9 +2536,13 @@ 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->texture_level, width, height);
-    glGetTexImage(GL_TEXTURE_2D, This->texture_level, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, allocatedMemory);
-    checkGLcall("glGetTexImage");
+    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");
     if (tmpTexture) {
         glBindTexture(GL_TEXTURE_2D, 0);
         glDeleteTextures(1, &tmpTexture);
     if (tmpTexture) {
         glBindTexture(GL_TEXTURE_2D, 0);
         glDeleteTextures(1, &tmpTexture);
@@ -2931,15 +2743,9 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) {
 
     /* Flip the opengl texture */
     {
 
     /* Flip the opengl texture */
     {
-        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;
+        glDescriptor tmp_desc = back->glDescription;
+        back->glDescription = front->glDescription;
+        front->glDescription = tmp_desc;
     }
 
     {
     }
 
     {
@@ -2973,7 +2779,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
@@ -3026,7 +2832,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->texture_target, This->texture_name);
+    glBindTexture(This->glDescription.target, This->glDescription.textureName);
     checkGLcall("glBindTexture");
     if(!swapchain) {
         TRACE("Reading from an offscreen target\n");
     checkGLcall("glBindTexture");
     if(!swapchain) {
         TRACE("Reading from an offscreen target\n");
@@ -3041,30 +2847,26 @@ 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.0f < -eps) || (xrel - 1.0f > eps))
-    {
+    if( (xrel - 1.0 < -eps) || (xrel - 1.0 > 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.0f < -eps) || (yrel - 1.0f > eps)))
-    {
+    } else if((Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT) && ((yrel - 1.0 < -eps) || (yrel - 1.0 > eps))) {
         ERR("Texture filtering not supported in direct blit\n");
     }
 
         ERR("Texture filtering not supported in direct blit\n");
     }
 
-    if (upsidedown
-            && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
-            && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
-    {
+    if(upsidedown &&
+       !((xrel - 1.0 < -eps) || (xrel - 1.0 > eps)) &&
+       !((yrel - 1.0 < -eps) || (yrel - 1.0 > 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->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);
+        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);
     } 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,
@@ -3074,22 +2876,25 @@ 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.0f < -eps) || (xrel - 1.0f > eps))
-            {
+            if( (xrel - 1.0 < -eps) || (xrel - 1.0 > 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->texture_target, This->texture_level,
-                            drect->x1 + col /* x offset */, row /* y offset */,
-                            srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1);
+                    glCopyTexSubImage2D(This->glDescription.target,
+                                        This->glDescription.level,
+                                        drect->x1 + col, row, /* xoffset, yoffset */
+                                        srect->x1 + col * xrel, yoffset - (int) (row * yrel),
+                                        1, 1);
                 }
             } else {
                 }
             } else {
-                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);
+                glCopyTexSubImage2D(This->glDescription.target,
+                                    This->glDescription.level,
+                                    drect->x1, row, /* xoffset, yoffset */
+                                    srect->x1, yoffset - (int) (row * yrel),
+                                    drect->x2-drect->x1, 1);
             }
         }
     }
             }
         }
     }
@@ -3109,19 +2914,17 @@ 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 */
-    context = ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
+    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->texture_name)
-    {
+    if(!noBackBufferBackup && Src->glDescription.textureName == 0) {
         /* Get it a description */
         surface_internal_preload(SrcSurface, SRGB_RGB);
     }
         /* Get it a description */
         surface_internal_preload(SrcSurface, SRGB_RGB);
     }
@@ -3130,30 +2933,27 @@ 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 (context->aux_buffers >= 2)
-    {
+    if(myDevice->activeContext->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) && context->aux_buffers >= 1)
-    {
+    } else if((swapchain || myDevice->offscreenBuffer == GL_BACK) && myDevice->activeContext->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");
+        checkGLcall("glGenTextures\n");
         glBindTexture(GL_TEXTURE_2D, backup);
         glBindTexture(GL_TEXTURE_2D, backup);
-        checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
+        checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
         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->texture_target;
-        glBindTexture(texture_target, Src->texture_name);
-        checkGLcall("glBindTexture(texture_target, Src->texture_name)");
+        texture_target = Src->glDescription.target;
+        glBindTexture(texture_target, Src->glDescription.textureName);
+        checkGLcall("glBindTexture(texture_target, Src->glDescription.textureName)");
         glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
 
         glEnable(texture_target);
         checkGLcall("glEnable(texture_target)");
 
@@ -3180,14 +2980,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,
-            wined3d_gl_mag_filter(magLookup, Filter));
+                    magLookup[Filter - WINED3DTEXF_NONE]);
     checkGLcall("glTexParameteri");
     glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
     checkGLcall("glTexParameteri");
     glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
-            wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
+                    minMipLookup[Filter].mip[WINED3DTEXF_NONE]);
     checkGLcall("glTexParameteri");
 
     if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
     checkGLcall("glTexParameteri");
 
     if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
-        src = backup ? backup : Src->texture_name;
+        src = backup ? backup : Src->glDescription.textureName;
     } else {
         glReadBuffer(GL_FRONT);
         checkGLcall("glReadBuffer(GL_FRONT)");
     } else {
         glReadBuffer(GL_FRONT);
         checkGLcall("glReadBuffer(GL_FRONT)");
@@ -3269,15 +3069,14 @@ 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->texture_target)
-    {
+    if(texture_target != This->glDescription.target) {
         glDisable(texture_target);
         glDisable(texture_target);
-        glEnable(This->texture_target);
-        texture_target = This->texture_target;
+        glEnable(This->glDescription.target);
+        texture_target = This->glDescription.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->texture_name);
+    glBindTexture(texture_target, This->glDescription.textureName);
     checkGLcall("glBindTexture");
     glCopyTexSubImage2D(texture_target,
                         0,
     checkGLcall("glBindTexture");
     glCopyTexSubImage2D(texture_target,
                         0,
@@ -3297,27 +3096,26 @@ 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->texture_target)
-            {
+            if(texture_target != Src->glDescription.target) {
                 glDisable(texture_target);
                 glDisable(texture_target);
-                glEnable(Src->texture_target);
-                texture_target = Src->texture_target;
+                glEnable(Src->glDescription.target);
+                texture_target = Src->glDescription.target;
             }
             }
-            glBindTexture(Src->texture_target, Src->texture_name);
-            checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)");
+            glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
+            checkGLcall("glBindTexture(Src->glDescription.target, Src->glDescription.textureName)");
         }
 
         glBegin(GL_QUADS);
             /* top left */
         }
 
         glBegin(GL_QUADS);
             /* top left */
-            glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height);
+            glTexCoord2f(0.0, (float) fbheight / (float) Src->pow2Height);
             glVertex2i(0, 0);
 
             /* bottom left */
             glVertex2i(0, 0);
 
             /* bottom left */
-            glTexCoord2f(0.0f, 0.0f);
+            glTexCoord2f(0.0, 0.0);
             glVertex2i(0, fbheight);
 
             /* bottom right */
             glVertex2i(0, fbheight);
 
             /* bottom right */
-            glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f);
+            glTexCoord2f((float) fbwidth / (float) Src->pow2Width, 0.0);
             glVertex2i(fbwidth, Src->currentDesc.Height);
 
             /* top right */
             glVertex2i(fbwidth, Src->currentDesc.Height);
 
             /* top right */
@@ -3332,8 +3130,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     checkGLcall("glDisable(texture_target)");
 
     /* Cleanup */
     checkGLcall("glDisable(texture_target)");
 
     /* Cleanup */
-    if (src != Src->texture_name && src != backup)
-    {
+    if(src != Src->glDescription.textureName && src != backup) {
         glDeleteTextures(1, &src);
         checkGLcall("glDeleteTextures(1, &src)");
     }
         glDeleteTextures(1, &src);
         checkGLcall("glDeleteTextures(1, &src)");
     }
@@ -3587,9 +3384,7 @@ 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)
-                && surface_can_stretch_rect(Src, This))
-        {
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)) {
             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 ||
@@ -3651,10 +3446,8 @@ 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))
-                && surface_can_stretch_rect(Src, This))
-        {
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT) &&
+            (Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) == 0) {
             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
@@ -3718,76 +3511,67 @@ 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->texture_target, Src->pow2Width, Src->pow2Height);
+                Src->glDescription.target, Src->pow2Width, Src->pow2Height);
 
         ENTER_GL();
 
         /* Bind the texture */
 
         ENTER_GL();
 
         /* Bind the texture */
-        glBindTexture(Src->texture_target, Src->texture_name);
+        glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
         checkGLcall("glBindTexture");
 
         /* Filtering for StretchRect */
         checkGLcall("glBindTexture");
 
         /* Filtering for StretchRect */
-        glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER,
-                wined3d_gl_mag_filter(magLookup, Filter));
+        glTexParameteri(Src->glDescription.target, GL_TEXTURE_MAG_FILTER,
+                        magLookup[Filter - WINED3DTEXF_NONE]);
         checkGLcall("glTexParameteri");
         checkGLcall("glTexParameteri");
-        glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER,
-                wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
+        glTexParameteri(Src->glDescription.target, GL_TEXTURE_MIN_FILTER,
+                        minMipLookup[Filter].mip[WINED3DTEXF_NONE]);
         checkGLcall("glTexParameteri");
         checkGLcall("glTexParameteri");
-        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
-        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+        glTexParameteri(Src->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+        glTexParameteri(Src->glDescription.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.0f);
+                glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0);
             else
             else
-                glAlphaFunc(GL_NOTEQUAL, 0.0f);
-            checkGLcall("glAlphaFunc");
+                glAlphaFunc(GL_NOTEQUAL, 0.0);
+            checkGLcall("glAlphaFunc\n");
         } 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);
 
-        glColor3f(1.0f, 1.0f, 1.0f);
+        glColor3d(1.0f, 1.0f, 1.0f);
         glTexCoord2f(glTexCoord[0], glTexCoord[2]);
         glTexCoord2f(glTexCoord[0], glTexCoord[2]);
-        glVertex3f(rect.x1, rect.y1, 0.0f);
+        glVertex3f(rect.x1,
+                    rect.y1,
+                    0.0);
 
         glTexCoord2f(glTexCoord[0], glTexCoord[3]);
 
         glTexCoord2f(glTexCoord[0], glTexCoord[3]);
-        glVertex3f(rect.x1, rect.y2, 0.0f);
+        glVertex3f(rect.x1, rect.y2, 0.0);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[3]);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[3]);
-        glVertex3f(rect.x2, rect.y2, 0.0f);
+        glVertex3f(rect.x2,
+                    rect.y2,
+                    0.0);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[2]);
 
         glTexCoord2f(glTexCoord[1], glTexCoord[2]);
-        glVertex3f(rect.x2, rect.y1, 0.0f);
-
+        glVertex3f(rect.x2,
+                    rect.y1,
+                    0.0);
         glEnd();
         checkGLcall("glEnd");
 
         glEnd();
         checkGLcall("glEnd");
 
@@ -3796,8 +3580,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             checkGLcall("glDisable(GL_ALPHA_TEST)");
         }
 
             checkGLcall("glDisable(GL_ALPHA_TEST)");
         }
 
-        glBindTexture(Src->texture_target, 0);
-        checkGLcall("glBindTexture(Src->texture_target, 0)");
+        glBindTexture(Src->glDescription.target, 0);
+        checkGLcall("glBindTexture(Src->glDescription.target, 0)");
 
         /* Restore the color key parameters */
         Src->CKeyFlags = oldCKeyFlags;
 
         /* Restore the color key parameters */
         Src->CKeyFlags = oldCKeyFlags;
@@ -3814,7 +3598,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))
-            wglFlush();
+            glFlush();
 
         /* 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
@@ -3885,8 +3669,11 @@ 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.0f /* Z */, 0 /* Stencil */);
+            IWineD3DDeviceImpl_ClearSurface(myDevice, This,
+                                            1, /* Number of rectangles */
+                                            &rect, WINED3DCLEAR_TARGET, color,
+                                            0.0 /* Z */,
+                                            0 /* Stencil */);
             return WINED3D_OK;
         }
     }
             return WINED3D_OK;
         }
     }
@@ -3919,7 +3706,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.0f;
+                depth = 0.0;
                 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));
         }
 
@@ -4056,15 +3843,13 @@ 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);
+        BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX);
 
         /* 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);
 
@@ -4072,7 +3857,6 @@ 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)) {
@@ -4107,8 +3891,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->texture_name = 0;
-    This->texture_target = GL_TEXTURE_2D;
+    This->glDescription.textureName      = 0;
+    This->glDescription.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)) {
@@ -4124,8 +3908,11 @@ 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 (This->resource.format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+        if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3
+            || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5
+            || Format == WINED3DFMT_ATI2N)
         {
             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);
@@ -4163,9 +3950,10 @@ 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_READTEX
+                || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX)))
         {
         {
-            This->texture_target = GL_TEXTURE_RECTANGLE_ARB;
+            This->glDescription.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);
@@ -4285,7 +4073,6 @@ 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;
@@ -4295,14 +4082,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);
-    glDisable(GL_BLEND);
+    glEnable(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);
-    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+    glBlendFunc(GL_ZERO, GL_ONE);
     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);
@@ -4343,9 +4130,7 @@ void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) {
     This->Flags |= location;
 }
 
     This->Flags |= location;
 }
 
-/* Context activation is done by the caller. */
-void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location)
-{
+void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
@@ -4379,9 +4164,8 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             /* 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. */
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
-            if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
-            {
+            GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+            if (This->glDescription.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 {
@@ -4389,13 +4173,16 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
                 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->texture_level, This->resource.format_desc->glInternal,
-                    0, 0, This->currentDesc.Width, This->currentDesc.Height, 0);
+            glCopyTexImage2D(bind_target,
+                    This->glDescription.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);
 
@@ -4414,17 +4201,21 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
+            context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->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(context, GL_FRAMEBUFFER_EXT, iface, FALSE);
+            context_attach_depth_stencil_fbo(device, 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 (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
-            else context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            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()");
+            }
 
             LEAVE_GL();
         } else {
 
             LEAVE_GL();
         } else {
@@ -4436,12 +4227,15 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             ENTER_GL();
 
 
             ENTER_GL();
 
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
-            surface_depth_blt(This, This->texture_name, This->currentDesc.Width,
-                    This->currentDesc.Height, This->texture_target);
+            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);
             checkGLcall("depth_blt");
 
             checkGLcall("depth_blt");
 
-            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
+            if (device->activeContext->current_fbo) {
+                GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, device->activeContext->current_fbo->id));
+                checkGLcall("glBindFramebuffer()");
+            }
 
             LEAVE_GL();
         } else {
 
             LEAVE_GL();
         } else {
@@ -4526,9 +4320,7 @@ 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)
-{
-    const struct wined3d_context *context;
+static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in) {
     struct coords coords[4];
     RECT rect;
     IWineD3DSwapChain *swapchain;
     struct coords coords[4];
     RECT rect;
     IWineD3DSwapChain *swapchain;
@@ -4546,7 +4338,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
         rect.bottom = This->currentDesc.Height;
     }
 
         rect.bottom = This->currentDesc.Height;
     }
 
-    switch (This->texture_target)
+    switch(This->glDescription.target)
     {
         case GL_TEXTURE_2D:
             bind_target = GL_TEXTURE_2D;
     {
         case GL_TEXTURE_2D:
             bind_target = GL_TEXTURE_2D;
@@ -4631,24 +4423,23 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
             break;
 
         default:
             break;
 
         default:
-            ERR("Unexpected texture target %#x\n", This->texture_target);
+            ERR("Unexpected texture target %#x\n", This->glDescription.target);
             return;
     }
 
             return;
     }
 
-    context = ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);
-
+    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->texture_name);
-    checkGLcall("glBindTexture(bind_target, This->texture_name)");
+    glBindTexture(bind_target, This->glDescription.textureName);
+    checkGLcall("bind_target, This->glDescription.textureName)");
     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 (context->render_offscreen)
+    if (device->render_offscreen)
     {
         LONG tmp = rect.top;
         rect.top = rect.bottom;
     {
         LONG tmp = rect.top;
         rect.top = rect.bottom;
@@ -4680,7 +4471,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)
-            wglFlush();
+            glFlush();
 
         IWineD3DSwapChain_Release(swapchain);
     } else {
 
         IWineD3DSwapChain_Release(swapchain);
     } else {
@@ -4761,12 +4552,11 @@ 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, NULL, CTXUSAGE_RESOURCELOAD);
+            if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, 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));
@@ -4793,7 +4583,6 @@ 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);
             }
 
@@ -4845,7 +4634,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
                 }
             }
 
                 }
             }
 
-            if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+            if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
             surface_bind_and_dirtify(This, srgb);
 
             if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
             surface_bind_and_dirtify(This, srgb);
 
             if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
@@ -5040,6 +4829,7 @@ 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,
@@ -5052,24 +4842,18 @@ 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)) {
@@ -5080,7 +4864,6 @@ 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 5c00b2b..d487f80 100644 (file)
@@ -30,6 +30,8 @@
 #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 */
@@ -41,26 +43,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.0f) return 0x0000;
+    if(*in == 0.0) return 0x0000;
     if(isnan(*in)) return 0x7C01;
     if(isnan(*in)) return 0x7C01;
-    if (isinf(*in)) return (*in < 0.0f ? 0xFC00 : 0x7c00);
+    if(isinf(*in)) return (*in < 0.0 ? 0xFC00 : 0x7c00);
 
     if(tmp < pow(2, 10)) {
         do
         {
 
     if(tmp < pow(2, 10)) {
         do
         {
-            tmp = tmp * 2.0f;
+            tmp = tmp * 2.0;
             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.0f;
+            tmp /= 2.0;
             exp++;
         }while(tmp >= pow(2, 11));
     }
 
     mantissa = (unsigned int) tmp;
             exp++;
         }while(tmp >= pow(2, 11));
     }
 
     mantissa = (unsigned int) tmp;
-    if(tmp - mantissa >= 0.5f) mantissa++; /* round to nearest, away from zero */
+    if(tmp - mantissa >= 0.5) 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 */
@@ -78,7 +80,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.0f ? 1 : 0) << 15); /* Add the sign */
+    ret |= ((*in < 0.0 ? 1 : 0) << 15); /* Add the sign */
     return ret;
 }
 
     return ret;
 }
 
@@ -179,17 +181,15 @@ 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);
-
-    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;
-
+    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;
     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;
-    const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
+    WINED3DFORMAT format = This->resource.format_desc->format;
     DWORD ret;
     TRACE("(%p)\n", This);
 
     DWORD ret;
     TRACE("(%p)\n", This);
 
-    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
-    {
+    /* 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 {
         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,9 +519,20 @@ 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));
-
-    This->resource.size = surface_calculate_size(format_desc, This->resource.wineD3DDevice->surface_alignment,
-            This->pow2Width, This->pow2Height);
+    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->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;
 
 
     This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;
 
@@ -724,25 +735,6 @@ 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);
@@ -752,7 +744,6 @@ 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)
@@ -790,9 +781,10 @@ 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,
-            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, WINED3DRTYPE_SURFACE, 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");
@@ -1135,6 +1127,8 @@ 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
@@ -1635,6 +1629,7 @@ 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;
@@ -1655,39 +1650,63 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dst
         dEntry = This->resource.format_desc;
     }
 
         dEntry = This->resource.format_desc;
     }
 
-    /* Handle compressed surfaces first... */
-    if (sEntry->Flags & dEntry->Flags & WINED3DFMT_FLAG_COMPRESSED)
+    /* Handle first the FOURCC surfaces... */
+    if (sEntry->Flags & dEntry->Flags & WINED3DFMT_FLAG_FOURCC)
     {
     {
-        UINT row_block_count;
+        UINT block_width;
+        UINT block_height;
+        UINT block_byte_size;
 
 
-        TRACE("compressed -> compressed copy\n");
+        TRACE("Fourcc -> Fourcc copy\n");
         if (trans)
         if (trans)
-            FIXME("trans arg not supported when a compressed surface is involved\n");
+            FIXME("trans arg not supported when a FOURCC 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("compressed -> compressed copy only supported for the same type of surface\n");
+            FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n");
             ret = WINED3DERR_WRONGTEXTUREFORMAT;
             goto error;
         }
 
             ret = WINED3DERR_WRONGTEXTUREFORMAT;
             goto error;
         }
 
-        row_block_count = (w + dEntry->block_width - 1) / dEntry->block_width;
-        for (y = 0; y < h; y += dEntry->block_height)
+        if (This->resource.format_desc->format == WINED3DFMT_DXT1)
         {
         {
-            memcpy(dbuf, sbuf, row_block_count * dEntry->block_byte_count);
+            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);
             dbuf += dlock.Pitch;
             sbuf += slock.Pitch;
         }
 
         goto error;
     }
             dbuf += dlock.Pitch;
             sbuf += slock.Pitch;
         }
 
         goto error;
     }
-    if ((sEntry->Flags & WINED3DFMT_FLAG_COMPRESSED) && !(dEntry->Flags & WINED3DFMT_FLAG_COMPRESSED))
+    if ((sEntry->Flags & WINED3DFMT_FLAG_FOURCC) && !(dEntry->Flags & WINED3DFMT_FLAG_FOURCC))
     {
         /* 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("Software decompression not supported.\n");
+        ERR("DXTC decompression not supported by now\n");
         goto error;
     }
 
         goto error;
     }
 
@@ -1825,24 +1844,32 @@ 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);
 
-        if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
+        /* 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)
         {
         {
-            /* 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);
+            pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top / 4) + (pRect->left * 4);
         }
         else
         {
             pLockedRect->pBits = This->resource.allocatedMemory +
                     (pLockedRect->Pitch * pRect->top) +
         }
         else
         {
             pLockedRect->pBits = This->resource.allocatedMemory +
                     (pLockedRect->Pitch * pRect->top) +
-                    (pRect->left * format_desc->byte_count);
+                    (pRect->left * This->resource.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 0246782..0ad65e0 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
  *
@@ -68,15 +46,32 @@ 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 (!ref)
-    {
-        surface_gdi_cleanup(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);
 
 
-        TRACE("(%p) Released.\n", This);
+        resource_cleanup((IWineD3DResource *)iface);
+
+        if(This->overlay_dest) {
+            list_remove(&This->overlay_entry);
+        }
+
+        TRACE("(%p) Released\n", This);
         HeapFree(GetProcessHeap(), 0, This);
         HeapFree(GetProcessHeap(), 0, This);
-    }
 
 
+    }
     return ref;
 }
 
     return ref;
 }
 
@@ -183,8 +178,7 @@ 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->texture_target, This->texture_level, gen);
+                snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen);
                 IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
             }
             /*
                 IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
             }
             /*
@@ -200,10 +194,7 @@ 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)))
     {
-        if(iface == swapchain->frontBuffer)
-        {
-            x11_copy_to_screen(swapchain, &This->lockedRect);
-        }
+        x11_copy_to_screen(swapchain, &This->lockedRect);
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
@@ -494,10 +485,7 @@ 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)))
     {
-        if(iface == swapchain->frontBuffer)
-        {
-            x11_copy_to_screen(swapchain, NULL);
-        }
+        x11_copy_to_screen(swapchain, NULL);
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
         IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
     }
 
@@ -548,6 +536,12 @@ 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;
 
@@ -677,6 +671,7 @@ 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 d8d3733..12f812e 100644 (file)
@@ -45,36 +45,26 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
 
     IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
 
 
     IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
 
-    /* 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)
-    {
+    /* release the ref to the front and back buffer parents */
+    if(This->frontBuffer) {
         IWineD3DSurface_SetContainer(This->frontBuffer, 0);
         IWineD3DSurface_SetContainer(This->frontBuffer, 0);
-        if (D3DCB_DestroyRenderTarget(This->frontBuffer))
-        {
-            FIXME("(%p) Something's still holding the front buffer (%p).\n",
-                    This, This->frontBuffer);
+        if(D3DCB_DestroyRenderTarget(This->frontBuffer) > 0) {
+            FIXME("(%p) Something's still holding the front buffer\n",This);
         }
         }
-        This->frontBuffer = NULL;
     }
 
     }
 
-    if (This->backBuffer)
-    {
-        UINT i = This->presentParms.BackBufferCount;
-
-        while (i--)
-        {
+    if(This->backBuffer) {
+        UINT i;
+        for(i = 0; i < This->presentParms.BackBufferCount; i++) {
             IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
             IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
-            if (D3DCB_DestroyRenderTarget(This->backBuffer[i]))
-                FIXME("(%p) Something's still holding back buffer %u (%p).\n",
-                        This, i, This->backBuffer[i]);
+            if(D3DCB_DestroyRenderTarget(This->backBuffer[i]) > 0) {
+                FIXME("(%p) Something's still holding the back buffer\n",This);
+            }
         }
         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
@@ -121,9 +111,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.texture_name = This->wineD3DDevice->cursorTexture;
-        cursor.texture_target = GL_TEXTURE_2D;
-        cursor.texture_level = 0;
+        cursor.glDescription.textureName = This->wineD3DDevice->cursorTexture;
+        cursor.glDescription.target = GL_TEXTURE_2D;
+        cursor.glDescription.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;
@@ -141,8 +131,7 @@ 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_POINT);
+        IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_NONE);
     }
     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 */
@@ -234,7 +223,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.0f, 0);
+                              WINED3DCLEAR_TARGET, 0xff00ffff, 1.0, 0);
     }
 
     if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags   & SFLAG_INSYSMEM ||
     }
 
     if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags   & SFLAG_INSYSMEM ||
@@ -382,11 +371,10 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
     IWineD3DBaseSwapChainImpl_GetGammaRamp
 };
 
     IWineD3DBaseSwapChainImpl_GetGammaRamp
 };
 
-struct wined3d_context *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface)
-{
+WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface) {
+    WineD3DContext *ctx;
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
-    struct wined3d_context **newArray;
-    struct wined3d_context *ctx;
+    WineD3DContext **newArray;
 
     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());
 
@@ -413,11 +401,10 @@ struct wined3d_context *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwa
     return ctx;
 }
 
     return ctx;
 }
 
-void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, UINT *height)
-{
-    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)context->current_rt;
+void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) {
     /* 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 = surface->currentDesc.Width;
-    *height = surface->currentDesc.Height;
+     * (Actually: The window size, but the surface is created in window size)
+     */
+    *width = This->currentDesc.Width;
+    *height = This->currentDesc.Height;
 }
 }
index 8f0b980..dda4353 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 (*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;
-        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
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 /* *******************************************
    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;
@@ -344,6 +92,61 @@ 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);
 }
@@ -410,7 +213,6 @@ 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;
@@ -469,13 +271,33 @@ 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;
 
 
-    texture_cleanup(This, D3DCB_DestroySurface);
+    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);
     /* free the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
     /* free the object */
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -579,6 +401,7 @@ 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 3c25ebe..d697372 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,  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_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_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,        0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4,      0,      0,      FALSE},
+    {WINED3DFMT_A2R10G10B10,        0xb0000000, 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,24 +134,6 @@ 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;
@@ -188,7 +170,6 @@ 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;
 
 /*****************************************************************************
@@ -200,8 +181,10 @@ 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
-            extension */
+            flags */
+    {WINED3DFMT_UNKNOWN,            0,                                0,                                      0,
+            0,                      0,
+            0},
     /* 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
@@ -209,278 +192,208 @@ 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,
-            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_FLAG_FILTERING},
     {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,
-            APPLE_YCBCR_422},
+            WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_FILTERING},
     {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,
-            EXT_TEXTURE_COMPRESSION_S3TC},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            EXT_TEXTURE_COMPRESSION_S3TC},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            EXT_TEXTURE_COMPRESSION_S3TC},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            EXT_TEXTURE_COMPRESSION_S3TC},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            EXT_TEXTURE_COMPRESSION_S3TC},
+            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},
     /* 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,
-            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_FLAG_RENDERTARGET},
     {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,
-            ARB_TEXTURE_RG},
+            WINED3DFMT_FLAG_RENDERTARGET},
     {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,
-            ARB_TEXTURE_FLOAT},
+            WINED3DFMT_FLAG_RENDERTARGET},
+    /* Hmm? */
+    {WINED3DFMT_CxV8U8,             0,                                0,                                      0,
+            0,                      0,
+            0},
     /* 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_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},
+            GL_RED,             GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {WINED3DFMT_R16G16_FLOAT,       GL_RG16F,                         GL_RG16F,                               0,
     {WINED3DFMT_R16G16_FLOAT,       GL_RG16F,                         GL_RG16F,                               0,
-            GL_RG,                  GL_HALF_FLOAT_ARB,
-            WINED3DFMT_FLAG_RENDERTARGET,
-            ARB_TEXTURE_RG},
+            GL_RG,              GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {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_RENDERTARGET,
-            ARB_TEXTURE_FLOAT},
+            GL_RGBA,            GL_HALF_FLOAT_ARB,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     /* Palettized formats */
     /* Palettized formats */
-    {WINED3DFMT_P8,                 GL_RGBA,                          GL_RGBA,                                0,
-            GL_RGBA,                GL_UNSIGNED_BYTE,
-            0,
-            ARB_FRAGMENT_PROGRAM},
+    {WINED3DFMT_A8P8,               0,                                0,                                      0,
+            0,                      0,
+            0},
     {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,
-            EXT_PALETTED_TEXTURE},
+            0},
     /* 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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING},
+    {WINED3DFMT_A8R3G3B2,           0,                                0,                                      0,
+            0,                      0,
+            0},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
-    {WINED3DFMT_R16G16_UNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           GL_RGBA16_EXT,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+    {WINED3DFMT_R16G16_UNORM,       GL_RGB16_EXT,                     GL_RGB16_EXT,                           0,
             GL_RGB,                 GL_UNSIGNED_SHORT,
             GL_RGB,                 GL_UNSIGNED_SHORT,
-            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET},
     /* 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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            WINED3D_GL_EXT_NONE},
+            0},
     /* 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,
-            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_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            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_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            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_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            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_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
     {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,
-            NV_TEXTURE_SHADER},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING},
+    {WINED3DFMT_W11V11U10,          0,                                0,                                      0,
+            0,                      0,
+            0},
+    {WINED3DFMT_A2W10V10U10,        0,                                0,                                      0,
+            0,                      0,
+            0},
     /* 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,
-            ARB_DEPTH_TEXTURE},
+            WINED3DFMT_FLAG_DEPTH},
     {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,
-            ARB_DEPTH_TEXTURE},
+            WINED3DFMT_FLAG_DEPTH},
     {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,
-            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_FLAG_DEPTH | WINED3DFMT_FLAG_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,
-            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_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_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,
-            ARB_DEPTH_TEXTURE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
     {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,
-            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_FLAG_DEPTH | WINED3DFMT_FLAG_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,
-            ARB_DEPTH_TEXTURE},
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH},
     {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,
-            WINED3D_GL_EXT_NONE},
-    {WINED3DFMT_D32F_LOCKABLE,      GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
+            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,
             GL_DEPTH_COMPONENT,     GL_FLOAT,
             GL_DEPTH_COMPONENT,     GL_FLOAT,
-            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},
+            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},
     /* Vendor-specific formats */
     /* Vendor-specific formats */
-    {WINED3DFMT_ATI2N,              GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
+    {WINED3DFMT_ATI2N,              0,                                0,                                      0,
+            GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
+            0},
+    {WINED3DFMT_NVHU,               0,                                0,                                      0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0,
-            ATI_TEXTURE_COMPRESSION_3DC},
-    {WINED3DFMT_ATI2N,              GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT,     0,
+            0},
+    {WINED3DFMT_NVHS,               0,                                0,                                      0,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
-            0,
-            EXT_TEXTURE_COMPRESSION_RGTC},
+            0}
 };
 
 static inline int getFmtIdx(WINED3DFORMAT fmt) {
 };
 
 static inline int getFmtIdx(WINED3DFORMAT fmt) {
@@ -500,7 +413,7 @@ static inline int getFmtIdx(WINED3DFORMAT fmt) {
     return -1;
 }
 
     return -1;
 }
 
-static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_base_info(WineD3D_GL_Info *gl_info)
 {
     UINT format_count = sizeof(formats) / sizeof(*formats);
     UINT i;
 {
     UINT format_count = sizeof(formats) / sizeof(*formats);
     UINT i;
@@ -529,216 +442,32 @@ static BOOL init_format_base_info(struct 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)
 
-/* Context activation is done by the caller. */
-static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPixelFormatDesc *format_desc)
+static BOOL check_fbo_compat(const WineD3D_GL_Info *gl_info, GLint internal_format)
 {
 {
-    /* 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. */
+    GLuint tex, fb;
     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);
 
 
-    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(glGenFramebuffersEXT(1, &fb));
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb));
     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));
-    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");
-        }
-    }
-
+    GL_EXTCALL(glDeleteFramebuffersEXT(1, &fb));
     glDeleteTextures(1, &tex);
 
     glDeleteTextures(1, &tex);
 
-    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;
-        }
-
-        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));
+    checkGLcall("Framebuffer format check");
 
 
-        LEAVE_GL();
-    }
+    return status == GL_FRAMEBUFFER_COMPLETE_EXT;
 }
 
 }
 
-static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_texture_info(WineD3D_GL_Info *gl_info)
 {
     unsigned int i;
 
 {
     unsigned int i;
 
@@ -754,203 +483,65 @@ static BOOL init_format_texture_info(struct 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.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;
-}
+        desc->heightscale = 1.0;
 
 
-/* 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))
-        {
-            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
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && gl_formats_template[i].rtInternal)
         {
         {
-            TRACE("Assuming no float16 blending\n");
-            filtered = FALSE;
-        }
-
-        if(filtered)
-        {
-            for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
+            /* 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))
             {
             {
-                fmt_idx = getFmtIdx(fmts16[i]);
-                gl_info->gl_formats[fmt_idx].Flags |= WINED3DFMT_FLAG_FILTERING;
+                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("Format %s is supported as fbo target\n", debug_d3dformat(gl_formats_template[i].fmt));
+                desc->rtInternal = gl_formats_template[i].glInternal;
             }
             }
-        }
-        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
         {
-            TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
+            desc->rtInternal = gl_formats_template[i].glInternal;
         }
     }
         }
     }
+
+    return TRUE;
 }
 
 }
 
-static void apply_format_fixups(struct wined3d_gl_info *gl_info)
+static void apply_format_fixups(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(
@@ -1019,12 +610,16 @@ static void apply_format_fixups(struct 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);
     }
@@ -1032,14 +627,22 @@ static void apply_format_fixups(struct 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.5f;
+    gl_info->gl_formats[idx].heightscale = 1.5;
     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))
@@ -1060,7 +663,7 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info)
     }
 }
 
     }
 }
 
-static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_vertex_info(WineD3D_GL_Info *gl_info)
 {
     unsigned int i;
 
 {
     unsigned int i;
 
@@ -1088,44 +691,37 @@ static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
     return TRUE;
 }
 
     return TRUE;
 }
 
-BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
+BOOL initPixelFormatsNoGL(WineD3D_GL_Info *gl_info)
+{
+    return init_format_base_info(gl_info);
+}
+
+BOOL initPixelFormats(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_compression_info(gl_info))
+    if (!init_format_texture_info(gl_info))
     {
         HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
         return FALSE;
     }
 
     {
         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;
+    if (!init_format_vertex_info(gl_info))
+    {
+        HeapFree(GetProcessHeap(), 0, gl_info->gl_formats);
+        return FALSE;
+    }
 
     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 struct wined3d_gl_info *gl_info)
+const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const WineD3D_GL_Info *gl_info)
 {
     int idx = getFmtIdx(fmt);
 
 {
     int idx = getFmtIdx(fmt);
 
@@ -1311,12 +907,9 @@ const char* debug_d3ddevicetype(WINED3DDEVTYPE devtype) {
   }
 }
 
   }
 }
 
-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; }
+const char* debug_d3dusage(DWORD usage) {
+  switch (usage & WINED3DUSAGE_MASK) {
+#define WINED3DUSAGE_TO_STR(u) case u: return #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);
@@ -1329,17 +922,16 @@ 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
-    if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
-
-    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+  case 0: return "none";
+  default:
+    FIXME("Unrecognized %u Usage!\n", usage);
+    return "unrecognized";
+  }
 }
 
 }
 
-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; }
+const char* debug_d3dusagequery(DWORD usagequery) {
+  switch (usagequery & WINED3DUSAGE_QUERY_MASK) {
+#define WINED3DUSAGEQUERY_TO_STR(u) case u: return #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);
@@ -1348,9 +940,11 @@ 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
-    if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
-
-    return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+  case 0: return "none";
+  default:
+    FIXME("Unrecognized %u Usage Query!\n", usagequery);
+    return "unrecognized";
+  }
 }
 
 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
 }
 
 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
@@ -1918,7 +1512,6 @@ 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)
 {
@@ -2200,8 +1793,7 @@ 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->texture_target == GL_TEXTURE_RECTANGLE_ARB)
-        {
+        if(This->glDescription.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;
@@ -2302,6 +1894,238 @@ 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
@@ -2339,7 +2163,6 @@ 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;
@@ -2393,7 +2216,8 @@ 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(device, i, cop, carg1, carg2, carg0)) {
+        if(is_invalid_op(stateblock->wineD3DDevice, i, cop,
+                         carg1, carg2, carg0)) {
             carg0 = ARG_UNUSED;
             carg2 = ARG_UNUSED;
             carg1 = WINED3DTA_CURRENT;
             carg0 = ARG_UNUSED;
             carg2 = ARG_UNUSED;
             carg1 = WINED3DTA_CURRENT;
@@ -2452,7 +2276,8 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting
             }
         }
 
             }
         }
 
-        if(is_invalid_op(device, i, aop, aarg1, aarg2, aarg0)) {
+        if(is_invalid_op(stateblock->wineD3DDevice, i, aop,
+           aarg1, aarg2, aarg0)) {
                aarg0 = ARG_UNUSED;
                aarg2 = ARG_UNUSED;
                aarg1 = WINED3DTA_CURRENT;
                aarg0 = ARG_UNUSED;
                aarg2 = ARG_UNUSED;
                aarg1 = WINED3DTA_CURRENT;
@@ -2531,32 +2356,23 @@ 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 wine_rb_tree *fragment_shaders,
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
         const struct ffp_frag_settings *settings)
 {
         const struct ffp_frag_settings *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;
+    return hash_table_get(fragment_shaders, settings);
 }
 
 }
 
-void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
-{
+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));
     /* 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. */
-    if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
-    {
-        ERR("Failed to insert ffp frag shader.\n");
-    }
+     * 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);
 }
 
 /* Activates the texture dimension according to the bound D3D texture.
 }
 
 /* Activates the texture dimension according to the bound D3D texture.
@@ -2564,9 +2380,7 @@ void add_ffp_frag_shader(struct wine_rb_tree *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
-/* GL locking is done by the caller (state handler) */
-void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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:
@@ -2639,9 +2453,7 @@ void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock
     }
 }
 
     }
 }
 
-/* GL locking is done by the caller (state handler) */
-void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
-{
+void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *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];
 
@@ -2657,57 +2469,61 @@ void sampler_texdim(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
 }
 #undef GLINFO_LOCATION
 
 }
 #undef GLINFO_LOCATION
 
-void *wined3d_rb_alloc(size_t size)
+unsigned int ffp_frag_program_key_hash(const void *key)
 {
 {
-    return HeapAlloc(GetProcessHeap(), 0, 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];
+    }
 
 
-void *wined3d_rb_realloc(void *ptr, size_t size)
-{
-    return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
-}
+    hash += ~(hash << 15);
+    hash ^=  (hash >> 10);
+    hash +=  (hash << 3);
+    hash ^=  (hash >> 6);
+    hash += ~(hash << 11);
+    hash ^=  (hash >> 16);
 
 
-void wined3d_rb_free(void *ptr)
-{
-    HeapFree(GetProcessHeap(), 0, ptr);
+    return hash;
 }
 
 }
 
-static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+BOOL ffp_frag_program_key_compare(const void *keya, const void *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;
+    const struct ffp_frag_settings *ka = keya;
+    const struct ffp_frag_settings *kb = keyb;
 
 
-    return memcmp(ka, kb, sizeof(*ka));
+    return memcmp(ka, kb, sizeof(*ka)) == 0;
 }
 
 }
 
-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 UINT l[] =
+    static const BYTE l[] =
     {
     {
-        ~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,
+        0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     };
     UINT32 i;
 
     };
     UINT32 i;
 
index d24ecd6..7dba4e3 100644 (file)
@@ -71,10 +71,6 @@ 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;
@@ -105,6 +101,26 @@ 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;
@@ -114,18 +130,19 @@ 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;
-    WORD map = This->baseShader.reg_maps.input_registers;
-    unsigned int i;
+BOOL vshader_get_input(
+    IWineD3DVertexShader* iface,
+    BYTE usage_req, BYTE usage_idx_req,
+    unsigned int* regnum) {
 
 
-    for (i = 0; map; map >>= 1, ++i)
-    {
-        if (!(map & 1)) continue;
+    IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
+    int i;
+
+    for (i = 0; i < MAX_ATTRIBS; i++) {
+        if (!This->baseShader.reg_maps.attributes[i]) continue;
 
 
-        if (match_usage(This->attributes[i].usage,
-                This->attributes[i].usage_idx, usage_req, usage_idx_req))
+        if (match_usage(This->semantics_in[i].usage,
+                This->semantics_in[i].usage_idx, usage_req, usage_idx_req))
         {
             *regnum = i;
             return TRUE;
         {
             *regnum = i;
             return TRUE;
@@ -186,7 +203,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);
@@ -232,7 +249,6 @@ 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;
 
@@ -264,26 +280,16 @@ 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->attributes, NULL, This->output_signature,
-            pFunction, GL_LIMITS(vshader_constantsF));
+            reg_maps, This->semantics_in, This->semantics_out, pFunction,
+            GL_LIMITS(vshader_constantsF));
     if (hr != WINED3D_OK) return hr;
 
     if (hr != WINED3D_OK) return hr;
 
-    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;
-        }
-    }
-
     vshader_set_limits(This);
 
     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(deviceImpl->vs_selected_mode == SHADER_ARB &&
+       (GLINFO_LOCATION).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");
@@ -306,6 +312,19 @@ 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) {
@@ -332,6 +351,22 @@ 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 ***/
@@ -345,6 +380,7 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
     /*** IWineD3DVertexShader methods ***/
     IWineD3DVertexShaderImpl_GetDevice,
     IWineD3DVertexShaderImpl_GetFunction,
     /*** IWineD3DVertexShader methods ***/
     IWineD3DVertexShaderImpl_GetDevice,
     IWineD3DVertexShaderImpl_GetFunction,
+    IWineD3DVertexShaderImpl_FakeSemantics,
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
 
     IWIneD3DVertexShaderImpl_SetLocalConstantsF
 };
 
@@ -352,3 +388,52 @@ 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 85e8f3a..64d871b 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;
-    DWORD active_sampler;
+    int 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
@@ -53,8 +52,7 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
         active_sampler = 0;
     }
 
         active_sampler = 0;
     }
 
-    if (active_sampler != WINED3D_UNMAPPED_STAGE)
-    {
+    if (active_sampler != -1) {
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
 
         IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
     }
 
@@ -198,15 +196,14 @@ 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;
 }
 
@@ -303,7 +300,6 @@ 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 134ff74..41a1160 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 (*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
+#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
 
 /* *******************************************
    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;
@@ -256,6 +90,43 @@ 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);
 }
@@ -320,7 +191,6 @@ 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;
@@ -341,14 +211,30 @@ 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;
-
-    volumetexture_cleanup(This, D3DCB_DestroyVolume);
-
+    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);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -444,6 +330,7 @@ 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 f65ee31..2f2677c 100644 (file)
@@ -1,4 +1,2 @@
 @ stdcall WineDirect3DCreate(long ptr)
 @ stdcall WineDirect3DCreateClipper(ptr)
 @ stdcall WineDirect3DCreate(long ptr)
 @ stdcall WineDirect3DCreateClipper(ptr)
-@ stdcall wined3d_mutex_lock()
-@ stdcall wined3d_mutex_unlock()
index f5f5e18..1a9c925 100644 (file)
@@ -1141,13 +1141,10 @@ 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.
- *
- * They are wgl functions and must not be called inside the gl lock, give them a
- * name that makes this clear
+ * __stdcall calling convention
  */
  */
-void (__stdcall  *wglFinish) ();
-void (__stdcall  *wglFlush) ();
+void (__stdcall  *glFinish) ();
+void (__stdcall  *glFlush) ();
 
 /* WGL functions */
 HGLRC   (WINAPI *pwglCreateContext)(HDC);
 
 /* WGL functions */
 HGLRC   (WINAPI *pwglCreateContext)(HDC);
@@ -1520,14 +1517,6 @@ 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_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
@@ -1908,15 +1897,6 @@ 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
@@ -1955,17 +1935,6 @@ 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
@@ -3111,13 +3080,6 @@ 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
@@ -3340,18 +3302,6 @@ 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,
@@ -3392,20 +3342,39 @@ 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_TEXTURE,
   ARB_DRAW_BUFFERS,
   ARB_FRAGMENT_PROGRAM,
   ARB_FRAGMENT_SHADER,
   ARB_DRAW_BUFFERS,
   ARB_FRAGMENT_PROGRAM,
   ARB_FRAGMENT_SHADER,
@@ -3445,11 +3414,9 @@ 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,
@@ -3482,9 +3449,7 @@ 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,
@@ -3513,7 +3478,7 @@ typedef enum _GL_SupportedExt {
   WGL_ARB_PIXEL_FORMAT,
   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
 
   WGL_ARB_PIXEL_FORMAT,
   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
 
-  WINED3D_GL_EXT_COUNT,
+  OPENGL_SUPPORTED_EXT_END
 } GL_SupportedExt;
 
 
 } GL_SupportedExt;
 
 
@@ -3626,8 +3591,6 @@ 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 )\
@@ -3943,61 +3906,77 @@ 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 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;
+struct driver_quirk {
+    BOOL        (*match)(const WineD3D_GL_Info *gl_info);
+    void        (*apply)(WineD3D_GL_Info *gl_info);
+    const char  *description;
 };
 
 };
 
-#undef USE_GL_FUNC
-
 #endif /* __WINE_WINED3D_GL */
 #endif /* __WINE_WINED3D_GL */
index bdb544a..687fe89 100644 (file)
@@ -32,25 +32,17 @@ 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_FBO,        /* Use FBOs to do offscreen rendering */
-    RTL_READTEX,    /* Default render target locking method */
+    ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
+    RTL_AUTO,       /* Automatically determine best 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 */
@@ -105,7 +97,6 @@ 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);
@@ -114,15 +105,6 @@ 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. */
@@ -135,16 +117,11 @@ 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_WINDOW_CLASS_NAME;
+    wc.lpszClassName        = "WineD3D_OpenGL";
 
 
-    if (!RegisterClassA(&wc))
+    if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
     {
         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;
     }
 
@@ -204,6 +181,19 @@ 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"))
@@ -247,6 +237,16 @@ 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,6 +309,8 @@ 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");
 
@@ -318,32 +320,13 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
     return TRUE;
 }
 
     return TRUE;
 }
 
-static BOOL wined3d_destroy(HINSTANCE hInstDLL)
+static BOOL wined3d_destroy(void)
 {
 {
-    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)
 {
@@ -355,16 +338,7 @@ 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(hInstDLL);
-
-        case DLL_THREAD_DETACH:
-        {
-            if (!context_set_current(NULL))
-            {
-                ERR("Failed to clear current context.\n");
-            }
-            return TRUE;
-        }
+            return wined3d_destroy();
 
         default:
             return TRUE;
 
         default:
             return TRUE;
index 8dbac4e..303fb70 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 */
 
@@ -133,9 +126,38 @@ static inline enum yuv_fixup get_yuv_fixup(struct color_fixup_desc fixup)
     return yuv_fixup;
 }
 
     return yuv_fixup;
 }
 
-void *wined3d_rb_alloc(size_t size);
-void *wined3d_rb_realloc(void *ptr, size_t size);
-void wined3d_rb_free(void *ptr);
+/* 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);
 
 /* Device caps */
 #define MAX_PALETTES            65536
 
 /* Device caps */
 #define MAX_PALETTES            65536
@@ -176,21 +198,13 @@ struct min_lookup
     GLenum mip[WINED3DTEXF_LINEAR + 1];
 };
 
     GLenum mip[WINED3DTEXF_LINEAR + 1];
 };
 
-const struct min_lookup minMipLookup[WINED3DTEXF_LINEAR + 1];
-const struct min_lookup minMipLookup_noFilter[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];
-}
+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];
 
 
-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];
-}
+extern const struct filter_lookup filter_lookup_nofilter;
+extern struct filter_lookup filter_lookup;
 
 /* 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
@@ -206,43 +220,21 @@ 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.0f : 1.0f);
+    const float sgn = (s ? -1.0 : 1.0);
 
     if(e == 0) {
 
     if(e == 0) {
-        if(m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
-        else return sgn * pow(2, -14.0f) * ((float)m / 1024.0f);
+        if(m == 0) return sgn * 0.0; /* +0.0 or -0.0 */
+        else return sgn * pow(2, -14.0) * ( (float) m / 1024.0);
     } else if(e < 31) {
     } else if(e < 31) {
-        return sgn * pow(2, (float)e - 15.0f) * (1.0f + ((float)m / 1024.0f));
+        return sgn * pow(2, (float) e-15.0) * (1.0 + ((float) m / 1024.0));
     } else {
     } else {
-        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 */
+        if(m == 0) return sgn / 0.0; /* +INF / -INF */
+        else return 0.0 / 0.0; /* NAN */
     }
 }
 
 /**
     }
 }
 
 /**
- * Settings
+ * Settings 
  */
 #define VS_NONE    0
 #define VS_HW      1
  */
 #define VS_NONE    0
 #define VS_HW      1
@@ -267,8 +259,11 @@ static inline float float_24_to_32(DWORD 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 */
@@ -279,6 +274,7 @@ 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. */
@@ -329,7 +325,6 @@ 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
@@ -511,14 +506,12 @@ typedef enum COMPARISON_TYPE
 #define MAX_LABELS 16
 
 #define SHADER_PGMSIZE 65535
 #define MAX_LABELS 16
 
 #define SHADER_PGMSIZE 65535
-
-struct wined3d_shader_buffer
-{
-    char *buffer;
+typedef struct 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
 {
@@ -627,40 +620,28 @@ 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;
-    BYTE texcoord;                          /* MAX_REG_TEXCRD, 8 */
-    BYTE address;                           /* MAX_REG_ADDR, 1 */
-    WORD labels;                            /* MAX_LABELS, 16 */
-    DWORD temporary;                        /* MAX_REG_TEMP, 32 */
+    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 */
     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)];
-    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;
+    BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
+    char usesnrm, vpos, usesdsy, usestexldd;
+    char usesrelconstF;
 
     /* 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;
-    unsigned highest_render_target;
+
+    /* Whether or not this shader uses fog */
+    char fog;
 
 } shader_reg_maps;
 
 
 } shader_reg_maps;
 
@@ -668,15 +649,13 @@ struct wined3d_shader_context
 {
     IWineD3DBaseShader *shader;
     const struct shader_reg_maps *reg_maps;
 {
     IWineD3DBaseShader *shader;
     const struct shader_reg_maps *reg_maps;
-    struct wined3d_shader_buffer *buffer;
-    void *backend_data;
+    SHADER_BUFFER *buffer;
 };
 
 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];
@@ -718,19 +697,6 @@ 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);
@@ -766,8 +732,6 @@ struct shader_caps {
     DWORD               MaxPShaderInstructionsExecuted;
     DWORD               MaxVertexShader30InstructionSlots;
     DWORD               MaxPixelShader30InstructionSlots;
     DWORD               MaxPShaderInstructionsExecuted;
     DWORD               MaxVertexShader30InstructionSlots;
     DWORD               MaxPixelShader30InstructionSlots;
-
-    BOOL                VSClipping;
 };
 
 enum tex_types
 };
 
 enum tex_types
@@ -788,6 +752,11 @@ 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,
@@ -821,22 +790,24 @@ struct vs_compile_args {
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
 };
 
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
 };
 
-struct wined3d_context;
-
 typedef struct {
 typedef struct {
-    void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
-    void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
+    const SHADER_HANDLER *shader_instruction_handler_table;
+    void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL useVS);
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum tex_types tex_type);
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);
     void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_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)(const struct wined3d_context *context, char usePS, char useVS);
+    void (*shader_load_constants)(IWineD3DDevice *iface, 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);
-    void (*shader_get_caps)(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
+    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);
     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;
@@ -899,19 +870,17 @@ 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;                                                      \
-    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);                                   \
+#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);                               \
 } while(0)
 #else
 #define checkGLcall(A) do {} while(0)
 } while(0)
 #else
 #define checkGLcall(A) do {} while(0)
@@ -941,11 +910,10 @@ 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) do { if (si->use_map & (1 << 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) 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); } while(0)
+        si->elements[name].buffer_object, si->elements[name].stream_idx);
 
 /* Defines used for optimizations */
 
 
 /* Defines used for optimizations */
 
@@ -969,8 +937,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 */
@@ -983,21 +951,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;
@@ -1085,6 +1053,8 @@ 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))
@@ -1136,31 +1106,71 @@ extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
 
 #define STATE_HIGHEST (STATE_FRONTFACE)
 
 
 #define STATE_HIGHEST (STATE_FRONTFACE)
 
-enum fogsource {
-    FOGSOURCE_FFP,
-    FOGSOURCE_VS,
-    FOGSOURCE_COORD,
+struct StateEntry
+{
+    DWORD               representative;
+    APPLYSTATEFUNC      apply;
 };
 
 };
 
-#define WINED3D_MAX_FBO_ENTRIES 64
-
-struct wined3d_occlusion_query
+struct StateEntryTemplate
 {
 {
-    struct list entry;
-    GLuint id;
-    struct wined3d_context *context;
+    DWORD               state;
+    struct StateEntry   content;
+    GL_SupportedExt     extension;
 };
 
 };
 
-struct wined3d_event_query
-{
-    struct list entry;
-    GLuint id;
-    struct wined3d_context *context;
+struct fragment_caps {
+    DWORD               PrimitiveMiscCaps;
+
+    DWORD               TextureOpCaps;
+    DWORD               MaxTextureBlendStages;
+    DWORD               MaxSimultaneousTextures;
 };
 
 };
 
-struct wined3d_context
-{
-    const struct wined3d_gl_info *gl_info;
+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;
+};
+
+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);
+
+/* 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;
+
+enum fogsource {
+    FOGSOURCE_FFP,
+    FOGSOURCE_VS,
+    FOGSOURCE_COORD,
+};
+
+/* The new context manager that should deal with onscreen and offscreen rendering */
+struct WineD3DContext {
     /* 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,
@@ -1172,11 +1182,9 @@ struct wined3d_context
     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;
@@ -1189,8 +1197,7 @@ struct wined3d_context
     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 current : 1;
-    WORD destroyed : 1;
+    WORD padding : 3;
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
     BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */
     DWORD                   numbered_array_mask;
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
     BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */
     DWORD                   numbered_array_mask;
@@ -1209,93 +1216,17 @@ struct wined3d_context
     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 */
@@ -1303,24 +1234,14 @@ 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;
 
-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 ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
+WineD3DContext *getActiveContext(void);
+WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
+void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type);
-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 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 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);
@@ -1379,7 +1300,7 @@ struct WineD3DAdapter
     UINT                    num;
     BOOL                    opengl;
     POINT                   monitorPoint;
     UINT                    num;
     BOOL                    opengl;
     POINT                   monitorPoint;
-    struct wined3d_gl_info  gl_info;
+    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 */
@@ -1390,10 +1311,10 @@ struct WineD3DAdapter
     unsigned int            UsedTextureRam;
 };
 
     unsigned int            UsedTextureRam;
 };
 
-extern BOOL initPixelFormats(struct wined3d_gl_info *gl_info);
-BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info);
+extern BOOL initPixelFormats(WineD3D_GL_Info *gl_info);
+BOOL initPixelFormatsNoGL(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(struct wined3d_gl_info *gl_info);
+extern void add_gl_compat_wrappers(WineD3D_GL_Info *gl_info);
 
 /*****************************************************************************
  * High order patch management
 
 /*****************************************************************************
  * High order patch management
@@ -1450,23 +1371,21 @@ 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 shorts instead of chars to get dword alignment */
-    unsigned short sRGB_write;
-    unsigned short emul_clipplanes;
+    /* Use an int instead of a char to get dword alignment */
+    unsigned int sRGB_write;
 };
 
 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 wine_rb_tree *fragment_shaders,
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct hash_table_t *fragment_shaders,
         const struct ffp_frag_settings *settings);
         const struct ffp_frag_settings *settings);
-void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc);
+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);
 
 /*****************************************************************************
  * IWineD3D implementation structure
 
 /*****************************************************************************
  * IWineD3D implementation structure
@@ -1489,6 +1408,12 @@ 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);
 
@@ -1535,13 +1460,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;
@@ -1549,7 +1474,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 : 4;
+    WORD padding : 3;
 
     BYTE fixed_function_usage_map;      /* MAX_TEXTURES, 8 */
 
 
     BYTE fixed_function_usage_map;      /* MAX_TEXTURES, 8 */
 
@@ -1578,6 +1503,10 @@ 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;
@@ -1625,9 +1554,11 @@ struct IWineD3DDeviceImpl
     const WineDirect3DVertexStridedData *up_strided;
 
     /* Context management */
     const WineDirect3DVertexStridedData *up_strided;
 
     /* Context management */
-    struct wined3d_context **contexts;
+    WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
+    WineD3DContext          *activeContext;
+    DWORD                   lastThread;
     UINT                    numContexts;
     UINT                    numContexts;
-    struct wined3d_context *pbufferContext;              /* The context that has a pbuffer as drawable */
+    WineD3DContext          *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 */
@@ -1639,8 +1570,6 @@ 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,
@@ -1650,8 +1579,7 @@ 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(struct wined3d_context *context, DWORD state)
-{
+static inline BOOL isStateDirty(WineD3DContext *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);
@@ -1712,7 +1640,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(IWineD3DResource *iface, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(struct IWineD3DResourceClass *resource, 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);
@@ -1726,6 +1654,8 @@ 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,
@@ -1774,6 +1704,9 @@ 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
@@ -1795,13 +1728,15 @@ 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);
-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);
+void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWORD usage);
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE filter_type);
 BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
 DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
 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)
@@ -1822,9 +1757,6 @@ 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)
  */
@@ -1841,9 +1773,6 @@ 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;
@@ -1890,9 +1819,6 @@ 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;
@@ -1963,23 +1889,21 @@ 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)(struct wined3d_context *context, UINT *width, UINT *height);
+    void (*get_drawable_size)(IWineD3DSurfaceImpl *This, 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;
@@ -2010,13 +1934,6 @@ 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);
@@ -2057,10 +1974,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(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 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 flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
 
 
 void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
 
@@ -2143,9 +2060,6 @@ 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);
@@ -2362,7 +2276,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
@@ -2376,12 +2290,25 @@ 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
@@ -2430,7 +2357,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);
-BYTE *buffer_get_sysmem(struct wined3d_buffer *This);
+const BYTE *buffer_get_sysmem(struct wined3d_buffer *This);
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
@@ -2468,7 +2395,7 @@ typedef struct IWineD3DSwapChainImpl
     long prev_time, frames;   /* Performance tracking */
     unsigned int vSyncCounter;
 
     long prev_time, frames;   /* Performance tracking */
     unsigned int vSyncCounter;
 
-    struct wined3d_context **context;
+    WineD3DContext        **context; /* Later a array for multithreading */
     unsigned int            num_contexts;
 
     HWND                    win_handle;
     unsigned int            num_contexts;
 
     HWND                    win_handle;
@@ -2491,12 +2418,10 @@ 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);
 
-struct wined3d_context *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);
-
-#define DEFAULT_REFRESH_RATE 0
+WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);
 
 /*****************************************************************************
 
 /*****************************************************************************
- * Utility function prototypes
+ * Utility function prototypes 
  */
 
 /* Trace routines */
  */
 
 /* Trace routines */
@@ -2528,18 +2453,19 @@ 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, 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 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 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, struct wined3d_context *context, DWORD location);
+void surface_load_ds_location(IWineD3DSurface *iface, 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);
@@ -2574,8 +2500,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];
@@ -2587,9 +2513,12 @@ typedef struct SHADER_PARSE_STATE {
 #define PRINTF_ATTR(fmt,args)
 #endif
 
 #define PRINTF_ATTR(fmt,args)
 #endif
 
-/* 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);
+/* 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);
 
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
 
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
@@ -2637,23 +2566,19 @@ typedef struct IWineD3DBaseShaderImpl {
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
-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_buffer_init(struct SHADER_BUFFER *buffer);
+void shader_buffer_free(struct 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);
-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);
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+        const shader_reg_maps *reg_maps, const DWORD *pFunction);
 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_attribute *attributes,
-        struct wined3d_shader_signature_element *input_signature,
-        struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size);
+        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);
 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);
 
@@ -2722,8 +2647,14 @@ 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 */
@@ -2735,40 +2666,31 @@ typedef struct IWineD3DVertexShaderImpl {
     DWORD                       usage;
 
     /* The GL shader */
     DWORD                       usage;
 
     /* The GL shader */
-    void                        *backend_priv;
+    struct vs_compiled_shader   *gl_shaders;
+    UINT                        num_gl_shaders, shader_array_size;
 
     /* Vertex shader input and output semantics */
 
     /* Vertex shader input and output semantics */
-    struct wined3d_shader_attribute attributes[MAX_ATTRIBS];
-    struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
+    struct wined3d_shader_semantic semantics_in[MAX_ATTRIBS];
+    struct wined3d_shader_semantic semantics_out[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
  */
-
-/* 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;
+struct ps_compiled_shader {
+    struct ps_compile_args      args;
+    GLuint                      prgId;
 };
 
 typedef struct IWineD3DPixelShaderImpl {
 };
 
 typedef struct IWineD3DPixelShaderImpl {
@@ -2782,32 +2704,34 @@ typedef struct IWineD3DPixelShaderImpl {
     IUnknown                   *parent;
 
     /* Pixel shader input semantics */
     IUnknown                   *parent;
 
     /* Pixel shader input semantics */
-    struct wined3d_shader_signature_element input_signature[MAX_REG_INPUT];
+    struct wined3d_shader_semantic semantics_in[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];
-    unsigned int declared_in_count;
+    int                         declared_in_count;
 
     /* The GL shader */
 
     /* The GL shader */
-    void                        *backend_priv;
+    struct ps_compiled_shader   *gl_shaders;
+    UINT                        num_gl_shaders, shader_array_size;
 
     /* 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;
 
-    BOOL                        color0_mov;
-    DWORD                       color0_reg;
-
+    const struct ps_compile_args *cur_args;
 } IWineD3DPixelShaderImpl;
 
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
 } IWineD3DPixelShaderImpl;
 
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
-void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD3DBaseTexture * const *textures);
+GLuint find_gl_pshader(IWineD3DPixelShaderImpl *shader, const struct ps_compile_args *args);
 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.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;
+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;
 
 /*****************************************************************************
  * IWineD3DPalette implementation structure
 
 /*****************************************************************************
  * IWineD3DPalette implementation structure
@@ -2847,8 +2771,6 @@ 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
 {
@@ -2861,10 +2783,6 @@ 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;
@@ -2882,16 +2800,12 @@ struct GlPixelFormatDesc
     struct color_fixup_desc color_fixup;
 };
 
     struct color_fixup_desc color_fixup;
 };
 
-const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const struct wined3d_gl_info *gl_info);
+const struct GlPixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt, const 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
-            && !((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->position_transformed
+            && !stateblock->wineD3DDevice->strided_streams.position_transformed
             && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE);
 }
 
             && stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE);
 }
 
@@ -2903,8 +2817,4 @@ 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 ec20433..3845ded 100644 (file)
@@ -1691,19 +1691,16 @@ typedef struct _WINED3DTRIPATCH_INFO
 
 typedef struct _WINED3DADAPTER_IDENTIFIER
 {
 
 typedef struct _WINED3DADAPTER_IDENTIFIER
 {
-    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;
+    char *Driver;
+    char *Description;
+    char *DeviceName;
+    LARGE_INTEGER *DriverVersion;
+    DWORD *VendorId;
+    DWORD *DeviceId;
+    DWORD *SubSysId;
+    DWORD *Revision;
+    GUID *DeviceIdentifier;
+    DWORD *WHQLLevel;
 } WINED3DADAPTER_IDENTIFIER;
 
 typedef struct _WINED3DPRESENT_PARAMETERS
 } WINED3DADAPTER_IDENTIFIER;
 
 typedef struct _WINED3DPRESENT_PARAMETERS
@@ -1727,27 +1724,27 @@ typedef struct _WINED3DPRESENT_PARAMETERS
 
 typedef struct _WINED3DSURFACE_DESC
 {
 
 typedef struct _WINED3DSURFACE_DESC
 {
-    WINED3DFORMAT format;
-    WINED3DRESOURCETYPE resource_type;
-    DWORD usage;
-    WINED3DPOOL pool;
-    UINT size;
-    WINED3DMULTISAMPLE_TYPE multisample_type;
-    DWORD multisample_quality;
-    UINT width;
-    UINT height;
+    WINED3DFORMAT *Format;
+    WINED3DRESOURCETYPE *Type;
+    DWORD *Usage;
+    WINED3DPOOL *Pool;
+    UINT *Size;
+    WINED3DMULTISAMPLE_TYPE *MultiSampleType;
+    DWORD *MultiSampleQuality;
+    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
@@ -1886,6 +1883,13 @@ 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 */
@@ -2525,6 +2529,9 @@ 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(
@@ -2609,6 +2616,10 @@ 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]
+    );
 }
 
 [
 }
 
 [
@@ -2861,6 +2872,9 @@ 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,
@@ -2925,6 +2939,7 @@ 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,
@@ -3000,8 +3015,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
     );
@@ -3460,6 +3475,9 @@ 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
@@ -3468,5 +3486,3 @@ 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);