- sync wined3d, d3d8, d3d9, ddraw with Wine 1.1.21
authorKamil Hornicek <kamil.hornicek@reactos.org>
Fri, 15 May 2009 09:33:59 +0000 (09:33 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Fri, 15 May 2009 09:33:59 +0000 (09:33 +0000)
svn path=/trunk/; revision=40924

41 files changed:
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/d3d9/cubetexture.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/texture.c
reactos/dll/directx/wine/d3d9/vertexbuffer.c
reactos/dll/directx/wine/d3d9/vertexshader.c
reactos/dll/directx/wine/d3d9/volumetexture.c
reactos/dll/directx/wine/ddraw/ddcomimpl.h [deleted file]
reactos/dll/directx/wine/ddraw/ddraw.c
reactos/dll/directx/wine/ddraw/device.c
reactos/dll/directx/wine/ddraw/direct3d.c
reactos/dll/directx/wine/ddraw/viewport.c
reactos/dll/directx/wine/wined3d/arb_program_shader.c
reactos/dll/directx/wine/wined3d/baseshader.c
reactos/dll/directx/wine/wined3d/buffer.c
reactos/dll/directx/wine/wined3d/context.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/pixelshader.c
reactos/dll/directx/wine/wined3d/shader_sm1.c [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/shader_sm4.c [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/surface.c
reactos/dll/directx/wine/wined3d/surface_base.c
reactos/dll/directx/wine/wined3d/surface_gdi.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexdeclaration.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/wined3d.rbuild
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/dll/directx/wine/wined3d/wined3d_private_types.h [deleted file]
reactos/include/reactos/wine/wined3d.idl

index c9afe17..c38d8cc 100644 (file)
@@ -601,6 +601,8 @@ struct IDirect3DVertexShader8Impl {
   IWineD3DVertexShader             *wineD3DVertexShader;
 };
 
   IWineD3DVertexShader             *wineD3DVertexShader;
 };
 
+#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256
+
 
 /* ------------------------ */
 /* IDirect3DPixelShaderImpl */
 
 /* ------------------------ */
 /* IDirect3DPixelShaderImpl */
index 985557c..206697d 100644 (file)
@@ -359,6 +359,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
     if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
         pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
     }
     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;
@@ -620,7 +621,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
-            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, NULL, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (FAILED(hrc)) {
     LeaveCriticalSection(&d3d8_cs);
 
     if (FAILED(hrc)) {
@@ -660,8 +661,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
-            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
-            &object->wineD3DVolumeTexture, NULL, (IUnknown *)object);
+            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
+            Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (hrc != D3D_OK) {
     LeaveCriticalSection(&d3d8_cs);
 
     if (hrc != D3D_OK) {
@@ -701,7 +702,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 i
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
-            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, NULL, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (hr != D3D_OK){
     LeaveCriticalSection(&d3d8_cs);
 
     if (hr != D3D_OK){
@@ -738,8 +739,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
-            0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL,
-            (IUnknown *)object);
+            0 /* fvf for ddraw only */, (WINED3DPOOL)Pool, &object->wineD3DVertexBuffer, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
     object->fvf = FVF;
 
     LeaveCriticalSection(&d3d8_cs);
     object->fvf = FVF;
 
@@ -777,8 +777,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
-            (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer,
-            NULL, (IUnknown *)object);
+            (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (D3D_OK != hrc) {
     LeaveCriticalSection(&d3d8_cs);
 
     if (D3D_OK != hrc) {
@@ -827,7 +826,7 @@ static HRESULT IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
             Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
             Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
-            (WINED3DPOOL)Pool, MultiSample,MultisampleQuality, NULL, SURFACE_OPENGL, (IUnknown *)object);
+            (WINED3DPOOL)Pool, MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
        /* free up object */
     LeaveCriticalSection(&d3d8_cs);
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
        /* free up object */
@@ -2000,6 +1999,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+             Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
@@ -2011,6 +2016,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+             Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
@@ -2155,7 +2166,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i
 
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
 
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
-            &object->wineD3DPixelShader, (IUnknown *)object);
+            NULL, &object->wineD3DPixelShader, (IUnknown *)object);
     if (FAILED(hr))
     {
         LeaveCriticalSection(&d3d8_cs);
     if (FAILED(hr))
     {
         LeaveCriticalSection(&d3d8_cs);
@@ -2651,7 +2662,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent
     object->lpVtbl = &Direct3DVolume8_Vtbl;
     object->ref = 1;
     hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage,
     object->lpVtbl = &Direct3DVolume8_Vtbl;
     object->ref = 1;
     hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage,
-            format, pool, &object->wineD3DVolume, NULL, (IUnknown *)object);
+            format, pool, &object->wineD3DVolume, (IUnknown *)object);
     if (FAILED(hr))
     {
         ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
index 64fc360..d39d3d6 100644 (file)
@@ -265,6 +265,7 @@ static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Ada
     if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
         pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
     }
     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;
index c4b4860..bbd171e 100644 (file)
@@ -365,8 +365,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
-            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture,
-            pSharedHandle, (IUnknown*)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
 
     if (hr != D3D_OK){
     LeaveCriticalSection(&d3d9_cs);
 
     if (hr != D3D_OK){
index 25b6ae2..7e43974 100644 (file)
@@ -497,6 +497,8 @@ typedef struct IDirect3DVertexShader9Impl {
   LPDIRECT3DDEVICE9EX parentDevice;
 } IDirect3DVertexShader9Impl;
 
   LPDIRECT3DDEVICE9EX parentDevice;
 } IDirect3DVertexShader9Impl;
 
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+
 /* --------------------- */
 /* IDirect3DPixelShader9 */
 /* --------------------- */
 /* --------------------- */
 /* IDirect3DPixelShader9 */
 /* --------------------- */
index 8d88e52..e5ca4c4 100644 (file)
@@ -678,8 +678,8 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
 
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
 
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
-            Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
-            MultiSample, MultisampleQuality, pSharedHandle, SURFACE_OPENGL, (IUnknown *)object);
+            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) {
     LeaveCriticalSection(&d3d9_cs);
 
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
@@ -2099,7 +2099,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent
     object->lpVtbl = &Direct3DVolume9_Vtbl;
     object->ref = 1;
     hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage & WINED3DUSAGE_MASK,
     object->lpVtbl = &Direct3DVolume9_Vtbl;
     object->ref = 1;
     hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage & WINED3DUSAGE_MASK,
-            format, pool, &object->wineD3DVolume, NULL, (IUnknown *)object);
+            format, pool, &object->wineD3DVolume, (IUnknown *)object);
     if (FAILED(hr))
     {
         ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
index 229368a..e9547a7 100644 (file)
@@ -311,6 +311,8 @@ void filter_caps(D3DCAPS9* pCaps)
         D3DPTEXTURECAPS_PROJECTED      | D3DPTEXTURECAPS_CUBEMAP       | D3DPTEXTURECAPS_VOLUMEMAP       |
         D3DPTEXTURECAPS_MIPMAP         | D3DPTEXTURECAPS_MIPVOLUMEMAP  | D3DPTEXTURECAPS_MIPCUBEMAP      |
         D3DPTEXTURECAPS_CUBEMAP_POW2   | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
         D3DPTEXTURECAPS_PROJECTED      | D3DPTEXTURECAPS_CUBEMAP       | D3DPTEXTURECAPS_VOLUMEMAP       |
         D3DPTEXTURECAPS_MIPMAP         | D3DPTEXTURECAPS_MIPVOLUMEMAP  | D3DPTEXTURECAPS_MIPCUBEMAP      |
         D3DPTEXTURECAPS_CUBEMAP_POW2   | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
+
+    pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
 }
 
 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) {
 }
 
 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) {
index 161ff64..8802bd1 100644 (file)
@@ -245,8 +245,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
-            (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
-            pSharedHandle, (IUnknown *)object);
+            (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
     LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
index 9c528d9..3939f59 100644 (file)
@@ -128,7 +128,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(LPDIRECT3DDEVICE9EX iface,
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
     EnterCriticalSection(&d3d9_cs);
     object->ref    = 1;
     object->lpVtbl = &Direct3DPixelShader9_Vtbl;
     EnterCriticalSection(&d3d9_cs);
-    hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object);
+    hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, NULL,
+            &object->wineD3DPixelShader, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
     LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
index e128350..f0a9c38 100644 (file)
@@ -358,7 +358,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
-            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, pSharedHandle, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     if (FAILED(hrc)) {
 
     LeaveCriticalSection(&d3d9_cs);
     if (FAILED(hrc)) {
 
index 8c65a88..501db41 100644 (file)
@@ -248,8 +248,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface
     object->fvf = FVF;
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
     object->fvf = FVF;
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
-            0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer),
-            pSharedHandle, (IUnknown *)object);
+            0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     
     if (hrc != D3D_OK) {
     LeaveCriticalSection(&d3d9_cs);
     
     if (hrc != D3D_OK) {
index 6478b68..fd2837d 100644 (file)
@@ -192,6 +192,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+             Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     LeaveCriticalSection(&d3d9_cs);
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     LeaveCriticalSection(&d3d9_cs);
@@ -202,6 +208,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
 
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
 
+    if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+             Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     TRACE("(%p) : Relay\n", This);
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     TRACE("(%p) : Relay\n", This);
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
index 81327cd..07b686f 100644 (file)
@@ -431,8 +431,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX if
     EnterCriticalSection(&d3d9_cs);
 
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
     EnterCriticalSection(&d3d9_cs);
 
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
-            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
-            &object->wineD3DVolumeTexture, pSharedHandle, (IUnknown *)object);
+            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format),
+            Pool, &object->wineD3DVolumeTexture, (IUnknown *)object);
 
     LeaveCriticalSection(&d3d9_cs);
 
 
     LeaveCriticalSection(&d3d9_cs);
 
diff --git a/reactos/dll/directx/wine/ddraw/ddcomimpl.h b/reactos/dll/directx/wine/ddraw/ddcomimpl.h
deleted file mode 100644 (file)
index 553d29f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* A few helpful macros for implementing COM objects.
- *
- * Copyright 2000 TransGaming Technologies Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef _DDCOMIMPL_H_
-#define _DDCOMIMPL_H_
-
-#include <stddef.h>
-
-/* Generates the name for a vtable pointer for a given interface. */
-/* The canonical name for a single interface is "lpVtbl". */
-#define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface
-#define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)
-
-/* Declares a vtable pointer field in an implementation. */
-#define ICOM_VFIELD_MULTI(iface) \
-       iface ICOM_VFIELD_MULTI_NAME(iface)
-
-/* Returns the offset of a vtable pointer within an implementation object. */
-#define ICOM_VFIELD_OFFSET(impltype, iface) \
-       offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))
-
-/* Given an interface pointer, returns the implementation pointer. */
-#define ICOM_OBJECT(impltype, ifacename, ifaceptr)             \
-       (impltype*)((ifaceptr) == NULL ? NULL                   \
-                 : (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))
-
-#define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \
-       impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)
-
-/* Given an object and interface name, returns a pointer to that interface. */
-#define ICOM_INTERFACE(implobj, iface) \
-       (implobj == NULL ? NULL :&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
-
-#define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
-       do { \
-         (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \
-       } while (0)
-
-#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr)   \
-       ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
-
-#endif /* _DDCOMIMPL_H_ */
index 5e2717e..7011afa 100644 (file)
@@ -1727,20 +1727,9 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
     }
 
     /* Create the new surface */
     }
 
     /* Create the new surface */
-    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
-                                      Width, Height, Format,
-                                      TRUE /* Lockable */,
-                                      FALSE /* Discard */,
-                                      surfImpl->mipmap_level,
-                                      &surfImpl->WineD3DSurface,
-                                      Type,
-                                      Usage,
-                                      Pool,
-                                      MultiSampleType,
-                                      MultiSampleQuality,
-                                      0 /* SharedHandle */,
-                                      This->ImplType,
-                                      Parent);
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, Width, Height, Format,
+            TRUE /* Lockable */, FALSE /* Discard */, surfImpl->mipmap_level, &surfImpl->WineD3DSurface,
+            Type, Usage, Pool, MultiSampleType, MultiSampleQuality, This->ImplType, Parent);
 
     if(hr != D3D_OK)
         return hr;
 
     if(hr != D3D_OK)
         return hr;
@@ -2036,21 +2025,9 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
     }
 
     /* Now create the WineD3D Surface */
     }
 
     /* Now create the WineD3D Surface */
-    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
-                                      pDDSD->dwWidth,
-                                      pDDSD->dwHeight,
-                                      Format,
-                                      TRUE /* Lockable */,
-                                      FALSE /* Discard */,
-                                      level,
-                                      &(*ppSurf)->WineD3DSurface,
-                                      ResType, Usage,
-                                      Pool,
-                                      WINED3DMULTISAMPLE_NONE,
-                                      0 /* MultiSampleQuality */,
-                                      0 /* SharedHandle */,
-                                      ImplType,
-                                      Parent);
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
+            TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface, ResType, Usage,
+            Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType, Parent);
 
     if(hr != D3D_OK)
     {
 
     if(hr != D3D_OK)
     {
@@ -2725,15 +2702,13 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
          */
         if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
         {
          */
         if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
         {
-            hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */,
-                    levels, 0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture,
-                    0 /* SharedHandle */, (IUnknown *)object);
+            hr = IWineD3DDevice_CreateCubeTexture(This->wineD3DDevice, DDSD->dwWidth /* Edgelength */, levels,
+                    0 /* usage */, Format, Pool, (IWineD3DCubeTexture **)&object->wineD3DTexture, (IUnknown *)object);
         }
         else
         {
             hr = IWineD3DDevice_CreateTexture(This->wineD3DDevice, DDSD->dwWidth, DDSD->dwHeight, levels,
         }
         else
         {
             hr = IWineD3DDevice_CreateTexture(This->wineD3DDevice, DDSD->dwWidth, DDSD->dwHeight, levels,
-                    0 /* usage */, Format, Pool, (IWineD3DTexture **) &object->wineD3DTexture,
-                    0 /* SharedHandle */, (IUnknown *)object);
+                    0 /* usage */, Format, Pool, (IWineD3DTexture **)&object->wineD3DTexture, (IUnknown *)object);
         }
         This->tex_root = NULL;
     }
         }
         This->tex_root = NULL;
     }
index 7c8e222..3b7778f 100644 (file)
@@ -4356,8 +4356,6 @@ Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
  * The return value consist of a combination of D3DCLIP_* flags, or it's
  * 0 if the sphere is completely visible(according to the SDK, not checked)
  *
  * The return value consist of a combination of D3DCLIP_* flags, or it's
  * 0 if the sphere is completely visible(according to the SDK, not checked)
  *
- * Sounds like an overdose of math ;)
- *
  * Version 3 and 7
  *
  * Params:
  * Version 3 and 7
  *
  * Params:
@@ -4368,7 +4366,7 @@ Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
  *  ReturnValues: Array to write the results to
  *
  * Returns:
  *  ReturnValues: Array to write the results to
  *
  * Returns:
- *  D3D_OK because it's a stub
+ *  D3D_OK
  *  (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
  *  (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
  *  is singular)
  *  (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
  *  (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
  *  is singular)
index aeba55b..9ce0d36 100644 (file)
@@ -824,8 +824,7 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
      * takes the pointer and avoids the memcpy
      */
     hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
      * takes the pointer and avoids the memcpy
      */
     hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
-            WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT,
-            &object->indexbuffer, 0 /* Handle */, (IUnknown *)IndexBufferParent);
+            WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, (IUnknown *)IndexBufferParent);
 
     if(FAILED(hr))
     {
 
     if(FAILED(hr))
     {
@@ -1021,13 +1020,10 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface,
 
     EnterCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
 
     EnterCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
-                                           get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
-                                           Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0,
-                                           Desc->dwFVF,
-                                           Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
-                                           &object->wineD3DVertexBuffer,
-                                           0 /* SharedHandle */,
-                                           (IUnknown *)object);
+            get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices,
+            Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0, Desc->dwFVF,
+            Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
+            &object->wineD3DVertexBuffer, (IUnknown *)object);
     if(hr != D3D_OK)
     {
         ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08x\n", This, hr);
     if(hr != D3D_OK)
     {
         ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08x\n", This, hr);
index 30d5e18..c6e346e 100644 (file)
@@ -751,6 +751,7 @@ IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
     /* Add the light in the 'linked' chain */
     lpDirect3DLightImpl->next = This->lights;
     This->lights = lpDirect3DLightImpl;
     /* Add the light in the 'linked' chain */
     lpDirect3DLightImpl->next = This->lights;
     This->lights = lpDirect3DLightImpl;
+    IDirect3DLight_AddRef(lpDirect3DLight);
 
     /* Attach the light to the viewport */
     lpDirect3DLightImpl->active_viewport = This;
 
     /* Attach the light to the viewport */
     lpDirect3DLightImpl->active_viewport = This;
@@ -796,6 +797,7 @@ IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface,
            else prev_light->next = cur_light->next;
            /* Detach the light to the viewport */
            cur_light->active_viewport = NULL;
            else prev_light->next = cur_light->next;
            /* Detach the light to the viewport */
            cur_light->active_viewport = NULL;
+           IDirect3DLight_Release( (IDirect3DLight *)cur_light );
            This->num_lights--;
            This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
             LeaveCriticalSection(&ddraw_cs);
            This->num_lights--;
            This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
             LeaveCriticalSection(&ddraw_cs);
@@ -871,6 +873,9 @@ IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface,
             break;
     }
 
             break;
     }
 
+    if (*lplpDirect3DLight)
+        IDirect3DLight_AddRef(*lplpDirect3DLight);
+
     LeaveCriticalSection(&ddraw_cs);
 
     return *lplpDirect3DLight ? D3D_OK : DDERR_INVALIDPARAMS;
     LeaveCriticalSection(&ddraw_cs);
 
     return *lplpDirect3DLight ? D3D_OK : DDERR_INVALIDPARAMS;
index b5b5ad4..56ee162 100644 (file)
@@ -10,6 +10,7 @@
  * Copyright 2006 Jason Green
  * Copyright 2006 Henri Verbeet
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Copyright 2006 Jason Green
  * Copyright 2006 Henri Verbeet
  * 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
@@ -80,7 +81,6 @@ struct shader_arb_priv {
 static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
 static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, const WineD3D_GL_Info *gl_info,
         GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
 {
-    DWORD shader_version = This->baseShader.reg_maps.shader_version;
     local_constant* lconst;
     DWORD i, j;
     unsigned int ret;
     local_constant* lconst;
     DWORD i, j;
     unsigned int ret;
@@ -94,7 +94,7 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con
         }
     }
     /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
         }
     }
     /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
-    if (target_type == GL_FRAGMENT_PROGRAM_ARB && WINED3DSHADER_VERSION_MAJOR(shader_version) == 1)
+    if (target_type == GL_FRAGMENT_PROGRAM_ARB && This->baseShader.reg_maps.shader_version.major == 1)
     {
         float lcl_const[4];
         for(i = 0; i < max_constants; i++) {
     {
         float lcl_const[4];
         for(i = 0; i < max_constants; i++) {
@@ -269,14 +269,34 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDevice *iface, UINT
     This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
 }
 
     This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, start + count + 1);
 }
 
+static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
+{
+    DWORD *ret;
+    DWORD idx = 0;
+    const local_constant *lconst;
+
+    if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL;
+
+    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.temporary);
+    if(!ret) {
+        ERR("Out of memory\n");
+        return NULL;
+    }
+
+    LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
+        ret[lconst->idx] = idx++;
+    }
+    return ret;
+}
+
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
 static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
 /* Generate the variable & register declarations for the ARB_vertex_program output target */
 static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const shader_reg_maps *reg_maps,
-        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info)
+        SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, DWORD *lconst_map)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     DWORD i, cur;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
     DWORD i, cur;
-    char pshader = shader_is_pshader_version(reg_maps->shader_version);
+    char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
     unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
             (pshader ? GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS :
                        GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS));
     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));
@@ -343,25 +363,19 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
     }
 
     if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
     }
 
     if(device->stateBlock->renderState[WINED3DRS_SRGBWRITEENABLE] && pshader) {
-        shader_addline(buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
-                        srgb_mul_low, srgb_mul_low, srgb_mul_low);
-        shader_addline(buffer, "PARAM srgb_comparison =  {%f, %f, %f, %f};\n",
-                        srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
-        shader_addline(buffer, "PARAM srgb_pow =  {%f, %f, %f, 1.0};\n",
-                       srgb_pow, srgb_pow, srgb_pow);
-        shader_addline(buffer, "PARAM srgb_mul_hi =  {%f, %f, %f, 1.0};\n",
-                       srgb_mul_high, srgb_mul_high, srgb_mul_high);
-        shader_addline(buffer, "PARAM srgb_sub_hi =  {%f, %f, %f, 0.0};\n",
-                       srgb_sub_high, srgb_sub_high, srgb_sub_high);
+        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,
      * this avoids reloading them each time the shader is used
      */
     }
 
     /* Load local constants using the program-local space,
      * this avoids reloading them each time the shader is used
      */
-    if(!This->baseShader.load_local_constsF) {
+    if(lconst_map) {
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
             shader_addline(buffer, "PARAM C%u = program.local[%u];\n", 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->idx);
+                           lconst_map[lconst->idx]);
         }
     }
 
         }
     }
 
@@ -371,13 +385,16 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
      * local constants do not declare the loaded constants as an array because ARB compilers usually
      * do not optimize unused constants away
      */
      * local constants do not declare the loaded constants as an array because ARB compilers usually
      * do not optimize unused constants away
      */
-    if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) {
+    if(This->baseShader.reg_maps.usesrelconstF) {
         /* Need to PARAM the environment parameters (constants) so we can use relative addressing */
         shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
                     max_constantsF, max_constantsF - 1);
     } else {
         for(i = 0; i < max_constantsF; i++) {
         /* Need to PARAM the environment parameters (constants) so we can use relative addressing */
         shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
                     max_constantsF, max_constantsF - 1);
     } else {
         for(i = 0; i < max_constantsF; i++) {
-            if(!shader_constant_is_local(This, i)) {
+            DWORD idx, mask;
+            idx = i >> 5;
+            mask = 1 << (i & 0x1f);
+            if(!shader_constant_is_local(This, i) && (This->baseShader.reg_maps.constf[idx] & mask)) {
                 shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
             }
         }
                 shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
             }
         }
@@ -407,9 +424,9 @@ 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->reg_maps->shader_version);
+    char vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
 
 
-    if (vshader && dst->register_type == WINED3DSPR_ADDR)
+    if (vshader && dst->reg.type == WINED3DSPR_ADDR)
     {
         *ptr++ = '.';
         *ptr++ = 'x';
     {
         *ptr++ = '.';
         *ptr++ = 'x';
@@ -426,7 +443,8 @@ static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *i
     *ptr = '\0';
 }
 
     *ptr = '\0';
 }
 
-static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_str) {
+static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param, BOOL fixup, char *swizzle_str)
+{
     /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
      * but addressed as "rgba". To fix this we need to swap the register's x
      * and z components. */
     /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
      * but addressed as "rgba". To fix this we need to swap the register's x
      * and z components. */
@@ -434,7 +452,7 @@ static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_
     char *ptr = swizzle_str;
 
     /* swizzle bits fields: wwzzyyxx */
     char *ptr = swizzle_str;
 
     /* swizzle bits fields: wwzzyyxx */
-    DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+    DWORD swizzle = param->swizzle;
     DWORD swizzle_x = swizzle & 0x03;
     DWORD swizzle_y = (swizzle >> 2) & 0x03;
     DWORD swizzle_z = (swizzle >> 4) & 0x03;
     DWORD swizzle_x = swizzle & 0x03;
     DWORD swizzle_y = (swizzle >> 2) & 0x03;
     DWORD swizzle_z = (swizzle >> 4) & 0x03;
@@ -442,7 +460,8 @@ static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_
 
     /* If the swizzle is the default swizzle (ie, "xyzw"), we don't need to
      * generate a swizzle string. Unless we need to our own swizzling. */
 
     /* If the swizzle is the default swizzle (ie, "xyzw"), we don't need to
      * generate a swizzle string. Unless we need to our own swizzling. */
-    if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) != swizzle || fixup) {
+    if (swizzle != WINED3DSP_NOSWIZZLE || fixup)
+    {
         *ptr++ = '.';
         if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w) {
             *ptr++ = swizzle_chars[swizzle_x];
         *ptr++ = '.';
         if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w) {
             *ptr++ = swizzle_chars[swizzle_x];
@@ -463,8 +482,7 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE
     /* oPos, oFog and oPts in D3D */
     static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
     /* oPos, oFog and oPts in D3D */
     static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
-    DWORD shader_version = This->baseShader.reg_maps.shader_version;
-    BOOL pshader = shader_is_pshader_version(shader_version);
+    BOOL pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
 
 
     *is_color = FALSE;
 
@@ -498,7 +516,7 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE
             }
             else
             {
             }
             else
             {
-                if (This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF))
+                if (This->baseShader.reg_maps.usesrelconstF)
                     sprintf(register_name, "C[%u]", register_idx);
                 else
                     sprintf(register_name, "C%u", register_idx);
                     sprintf(register_name, "C[%u]", register_idx);
                 else
                     sprintf(register_name, "C%u", register_idx);
@@ -549,36 +567,16 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE
     }
 }
 
     }
 }
 
-static void shader_arb_add_src_param(const struct wined3d_shader_instruction *ins,
-        DWORD param, char *str)
-{
-    char register_name[255];
-    char swizzle[6];
-    BOOL is_color;
-
-    if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) strcat(str, " -");
-    else strcat(str, " ");
-
-    shader_arb_get_register_name(ins->shader, shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
-            param & WINED3DSHADER_ADDRMODE_RELATIVE, register_name, &is_color);
-    strcat(str, register_name);
-
-    shader_arb_get_swizzle(param, is_color, swizzle);
-    strcat(str, swizzle);
-}
-
-static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *ins,
+static void shader_arb_get_dst_param(const struct wined3d_shader_instruction *ins,
         const struct wined3d_shader_dst_param *wined3d_dst, char *str)
 {
     char register_name[255];
     char write_mask[6];
     BOOL is_color;
 
         const struct wined3d_shader_dst_param *wined3d_dst, char *str)
 {
     char register_name[255];
     char write_mask[6];
     BOOL is_color;
 
-    strcat(str, " ");
-
-    shader_arb_get_register_name(ins->shader, wined3d_dst->register_type,
-            wined3d_dst->register_idx, wined3d_dst->has_rel_addr, register_name, &is_color);
-    strcat(str, register_name);
+    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);
     strcat(str, write_mask);
 
     shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
     strcat(str, write_mask);
@@ -655,10 +653,10 @@ static void gen_color_correction(SHADER_BUFFER *buffer, const char *reg, DWORD d
 static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
         const char *dst_str, const char *coord_reg, BOOL projected, BOOL bias)
 {
 static 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)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     const char *tex_type;
     const char *tex_type;
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 
     switch(sampler_type) {
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 
     switch(sampler_type) {
@@ -673,7 +671,8 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             } else {
                 tex_type = "2D";
             }
             } else {
                 tex_type = "2D";
             }
-            if(shader_is_pshader_version(ins->reg_maps->shader_version)) {
+            if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
+            {
                const IWineD3DPixelShaderImpl* const ps = (const IWineD3DPixelShaderImpl*)This;
                if(ps->cur_args->np2_fixup & (1 << sampler_idx)) {
                    FIXME("NP2 texcoord fixup is currently not implemented in ARB mode (use GLSL instead).\n");
                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");
@@ -705,36 +704,34 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
         shader_addline(buffer, "TEX %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
     }
 
         shader_addline(buffer, "TEX %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
     }
 
-    if (shader_is_pshader_version(ins->reg_maps->shader_version))
+    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
     {
-        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->shader;
+        IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
         gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
                 "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
     }
 }
 
         gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
                 "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
     }
 }
 
-static void pshader_gen_input_modifier_line (
-    IWineD3DBaseShader *iface,
-    SHADER_BUFFER* buffer,
-    const DWORD instr,
-    int tmpreg,
-    char *outregstr) {
-
+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)
+{
     /* Generate a line that does the input modifier computation and return the input register to use */
     BOOL is_color = FALSE;
     char regstr[256];
     char swzstr[20];
     int insert_line;
     /* Generate a line that does the input modifier computation and return the input register to use */
     BOOL is_color = FALSE;
     char regstr[256];
     char swzstr[20];
     int insert_line;
+    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(iface, shader_get_regtype(instr), instr & WINED3DSP_REGNUM_MASK,
-            instr & WINED3DSHADER_ADDRMODE_RELATIVE, regstr, &is_color);
-    shader_arb_get_swizzle(instr, is_color, swzstr);
+    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 (instr & WINED3DSP_SRCMOD_MASK) {
+    switch (src->modifiers)
+    {
     case WINED3DSPSM_NONE:
         sprintf(outregstr, "%s%s", regstr, swzstr);
         insert_line = 0;
     case WINED3DSPSM_NONE:
         sprintf(outregstr, "%s%s", regstr, swzstr);
         insert_line = 0;
@@ -782,23 +779,15 @@ static void pshader_gen_input_modifier_line (
         sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
 }
 
         sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
 }
 
-static inline void pshader_gen_output_modifier_line(SHADER_BUFFER *buffer, int saturate, const char *write_mask,
-        int shift, const char *regstr)
-{
-    /* Generate a line that does the output modifier computation */
-    shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
-        regstr, write_mask, regstr, shift_tab[shift]);
-}
-
 static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
 static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[2][50];
     char dst_wmask[20];
     char dst_name[50];
     char src_name[2][50];
     char dst_wmask[20];
-    DWORD sampler_code = dst->register_idx;
+    DWORD sampler_code = dst->reg.idx;
     BOOL has_bumpmat = FALSE;
     BOOL is_color;
     int i;
     BOOL has_bumpmat = FALSE;
     BOOL is_color;
     int i;
@@ -812,13 +801,13 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
         }
     }
 
         }
     }
 
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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);
     strcat(dst_name, dst_wmask);
 
     shader_arb_get_write_mask(ins, dst, dst_wmask);
     strcat(dst_name, dst_wmask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
+    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]);
 
     if(has_bumpmat) {
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
     if(has_bumpmat) {
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
@@ -836,28 +825,29 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
-    DWORD shift = dst->shift;
     BOOL is_color;
     BOOL is_color;
+    DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+            ins->ctx->reg_maps->shader_version.minor);
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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);
 
     /* Generate input register names (with modifiers) */
     shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     /* Generate input register names (with modifiers) */
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+    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]);
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
 
     /* The coissue flag changes the semantic of the cnd instruction in <= 1.3 shaders */
-    if (ins->reg_maps->shader_version <= WINED3DPS_VERSION(1, 3) && ins->coissue)
+    if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue)
     {
         shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
     } else {
     {
         shader_addline(buffer, "MOV%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1]);
     } else {
@@ -865,38 +855,32 @@ static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
         shader_addline(buffer, "CMP%s %s%s, TMP, %s, %s;\n",
                                 sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1], src_name[2]);
     }
         shader_addline(buffer, "CMP%s %s%s, TMP, %s, %s;\n",
                                 sat ? "_SAT" : "", dst_name, dst_wmask, src_name[1], src_name[2]);
     }
-    if (shift != 0)
-        pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
 static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 }
 
 static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
-    DWORD shift = dst->shift;
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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);
 
     /* Generate input register names (with modifiers) */
     shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     /* Generate input register names (with modifiers) */
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+    shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+    shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
 
     shader_addline(buffer, "CMP%s %s%s, %s, %s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
                    src_name[0], src_name[2], src_name[1]);
 
     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]);
-
-    if (shift != 0)
-        pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
 /** Process the WINED3DSIO_DP2ADD instruction in ARB.
 }
 
 /** Process the WINED3DSIO_DP2ADD instruction in ARB.
@@ -904,40 +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];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
-    DWORD shift = dst->shift;
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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_write_mask(ins, dst, dst_wmask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[2], 2, src_name[2]);
+    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]);
 
     /* 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]);
 
     /* Emulate a DP2 with a DP3 and 0.0 */
     shader_addline(buffer, "MOV TMP, %s;\n", src_name[0]);
     shader_addline(buffer, "MOV TMP.z, 0.0;\n");
     shader_addline(buffer, "DP3 TMP2, TMP, %s;\n", src_name[1]);
     shader_addline(buffer, "ADD%s %s%s, TMP2, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, src_name[2]);
-
-    if (shift != 0)
-        pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
 /* Map the opcode 1-to-1 to the GL code */
 static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
 {
 }
 
 /* Map the opcode 1-to-1 to the GL code */
 static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    const DWORD *src = ins->src;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     const char *instruction;
     const char *instruction;
-    char arguments[256];
+    char arguments[256], dst_str[50];
     unsigned int i;
     unsigned int i;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+    const char *modifier;
 
     switch (ins->handler_idx)
     {
 
     switch (ins->handler_idx)
     {
@@ -959,7 +940,6 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         case WINED3DSIH_MIN: instruction = "MIN"; break;
         case WINED3DSIH_MOV: instruction = "MOV"; break;
         case WINED3DSIH_MUL: instruction = "MUL"; break;
         case WINED3DSIH_MIN: instruction = "MIN"; break;
         case WINED3DSIH_MOV: instruction = "MOV"; break;
         case WINED3DSIH_MUL: instruction = "MUL"; break;
-        case WINED3DSIH_NOP: instruction = "NOP"; break;
         case WINED3DSIH_POW: instruction = "POW"; break;
         case WINED3DSIH_SGE: instruction = "SGE"; break;
         case WINED3DSIH_SLT: instruction = "SLT"; break;
         case WINED3DSIH_POW: instruction = "POW"; break;
         case WINED3DSIH_SGE: instruction = "SGE"; break;
         case WINED3DSIH_SLT: instruction = "SLT"; break;
@@ -969,96 +949,39 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
             break;
     }
 
             break;
     }
 
-    if (shader_is_pshader_version(ins->reg_maps->shader_version))
-    {
-        /* Output token related */
-        const struct wined3d_shader_dst_param *dst;
-        char output_rname[256];
-        char output_wmask[20];
-        char operands[4][100];
-        BOOL saturate = FALSE;
-        BOOL centroid = FALSE;
-        BOOL partialprecision = FALSE;
-        const char *modifier;
-        BOOL is_color;
-        DWORD shift;
-
-        if (!(ins->dst_count + ins->src_count))
-        {
-            ERR("Opcode \"%#x\" has no parameters\n", ins->handler_idx);
-            return;
-        }
-        dst = &ins->dst[0];
-
-        /* Process modifiers */
-        if (dst->modifiers)
-        {
-            DWORD mask = dst->modifiers;
-
-            saturate = mask & WINED3DSPDM_SATURATE;
-            centroid = mask & WINED3DSPDM_MSAMPCENTROID;
-            partialprecision = mask & WINED3DSPDM_PARTIALPRECISION;
-            mask &= ~(WINED3DSPDM_MSAMPCENTROID | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_SATURATE);
-            if (mask)
-                FIXME("Unrecognized modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT);
-
-            if (centroid)
-                FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT);
-        }
-        shift = dst->shift;
-        modifier = (saturate && !shift) ? "_SAT" : "";
-
-        /* Generate input register names (with modifiers) */
-        for (i = 0; i < ins->src_count; ++i)
-        {
-            pshader_gen_input_modifier_line(ins->shader, buffer, src[i], i, operands[i + 1]);
-        }
-
-        /* Handle output register */
-        shader_arb_get_register_name(ins->shader, dst->register_type,
-                dst->register_idx, dst->has_rel_addr, output_rname, &is_color);
-        strcpy(operands[0], output_rname);
-        shader_arb_get_write_mask(ins, dst, output_wmask);
-        strcat(operands[0], output_wmask);
+    /* All instructions handled by this function have a destination parameter */
+    if(dst->modifiers & WINED3DSPDM_SATURATE) modifier = "_SAT";
+    else modifier = "";
 
 
-        arguments[0] = '\0';
-        strcat(arguments, operands[0]);
-        for (i = 0; i < ins->src_count; ++i)
-        {
-            strcat(arguments, ", ");
-            strcat(arguments, operands[i + 1]);
-        }
-        shader_addline(buffer, "%s%s %s;\n", instruction, modifier, arguments);
-
-        /* A shift requires another line. */
-        if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname);
-    } else {
-        /* Note that shader_arb_add_*_param() adds spaces. */
-
-        arguments[0] = '\0';
-        if (ins->dst_count)
-        {
-            shader_arb_add_dst_param(ins, &ins->dst[0], arguments);
-            for (i = 0; i < ins->src_count; ++i)
-            {
-                strcat(arguments, ",");
-                shader_arb_add_src_param(ins, src[i], arguments);
-            }
-        }
-        shader_addline(buffer, "%s%s;\n", instruction, arguments);
+    /* Note that shader_arb_add_dst_param() adds spaces. */
+    arguments[0] = '\0';
+    shader_arb_get_dst_param(ins, dst, dst_str);
+    for (i = 0; i < ins->src_count; ++i)
+    {
+        char operand[100];
+        strcat(arguments, ", ");
+        shader_arb_get_src_param(ins, &ins->src[i], i, operand);
+        strcat(arguments, operand);
     }
     }
+    shader_addline(buffer, "%s%s %s%s;\n", instruction, modifier, dst_str, arguments);
+}
+
+static void shader_hw_nop(const struct wined3d_shader_instruction *ins)
+{
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    shader_addline(buffer, "NOP;\n");
 }
 
 static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
 
 
-    if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
-            && !shader_is_pshader_version(ins->reg_maps->shader_version)
-            && ins->dst[0].register_type == WINED3DSPR_ADDR)
+    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)
     {
             || ins->handler_idx == WINED3DSIH_MOVA)
     {
-        SHADER_BUFFER *buffer = ins->buffer;
+        SHADER_BUFFER *buffer = ins->ctx->buffer;
         char src0_param[256];
 
         if (ins->handler_idx == WINED3DSIH_MOVA)
         char src0_param[256];
 
         if (ins->handler_idx == WINED3DSIH_MOVA)
@@ -1067,7 +990,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
-            shader_arb_add_src_param(ins, ins->src[0], src0_param);
+            shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
             shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
             shader_addline(buffer, "ARL A0.x, TMP.x;\n");
         }
             shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
             shader_addline(buffer, "ARL A0.x, TMP.x;\n");
         }
@@ -1075,18 +998,10 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
         {
             /* Apple's ARB_vertex_program implementation does not accept an ARL source argument
              * with more than one component. Thus replicate the first source argument over all
         {
             /* Apple's ARB_vertex_program implementation does not accept an ARL source argument
              * with more than one component. Thus replicate the first source argument over all
-             * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc)
-             */
-            DWORD parm = ins->src[0] & ~(WINED3DVS_SWIZZLE_MASK);
-            if((ins->src[0] & WINED3DVS_X_W) == WINED3DVS_X_W)
-                parm |= WINED3DVS_X_W | WINED3DVS_Y_W | WINED3DVS_Z_W | WINED3DVS_W_W;
-            else if((ins->src[0] & WINED3DVS_X_Z) == WINED3DVS_X_Z)
-                parm |= WINED3DVS_X_Z | WINED3DVS_Y_Z | WINED3DVS_Z_Z | WINED3DVS_W_Z;
-            else if((ins->src[0] & WINED3DVS_X_Y) == WINED3DVS_X_Y)
-                parm |= WINED3DVS_X_Y | WINED3DVS_Y_Y | WINED3DVS_Z_Y | WINED3DVS_W_Y;
-            else if((ins->src[0] & WINED3DVS_X_X) == WINED3DVS_X_X)
-                parm |= WINED3DVS_X_X | WINED3DVS_Y_X | WINED3DVS_Z_X | WINED3DVS_W_X;
-            shader_arb_add_src_param(ins, parm, src0_param);
+             * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc) */
+            struct wined3d_shader_src_param tmp_src = ins->src[0];
+            tmp_src.swizzle = (tmp_src.swizzle & 0x3) * 0x55;
+            shader_arb_get_src_param(ins, &tmp_src, 0, src0_param);
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
@@ -1099,18 +1014,15 @@ 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];
-    DWORD shader_version = ins->reg_maps->shader_version;
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char reg_dest[40];
     char reg_dest[40];
-    BOOL is_color;
 
     /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
      * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit)
      */
 
     /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
      * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit)
      */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
+    shader_arb_get_dst_param(ins, dst, reg_dest);
 
 
-    if (shader_version >= WINED3DPS_VERSION(2,0))
+    if (ins->ctx->reg_maps->shader_version.major >= 2)
     {
         /* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
         shader_addline(buffer, "KIL %s;\n", reg_dest);
     {
         /* 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);
@@ -1118,22 +1030,19 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
         /* 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
          */
         /* 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
          */
-        shader_addline(buffer, "MOV TMP, %s;\n", reg_dest);
-        shader_addline(buffer, "MOV TMP.w, one.w;\n");
+        shader_addline(buffer, "SWZ TMP, %s, x, y, z, 1;\n", reg_dest);
         shader_addline(buffer, "KIL TMP;\n");
     }
 }
 
 static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 {
         shader_addline(buffer, "KIL TMP;\n");
     }
 }
 
 static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    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;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     BOOL is_color;
-
-    const DWORD *src = ins->src;
-    SHADER_BUFFER* buffer = ins->buffer;
-    DWORD shader_version = ins->reg_maps->shader_version;
+    DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+            ins->ctx->reg_maps->shader_version.minor);
     BOOL projected = FALSE, bias = FALSE;
 
     char reg_dest[40];
     BOOL projected = FALSE, bias = FALSE;
 
     char reg_dest[40];
@@ -1141,29 +1050,29 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
     DWORD reg_sampler_code;
 
     /* All versions have a destination register */
     DWORD reg_sampler_code;
 
     /* All versions have a destination register */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
+    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 destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
-   if (shader_version < WINED3DPS_VERSION(1,4))
+   if (shader_version < WINED3D_SHADER_VERSION(1,4))
       strcpy(reg_coord, reg_dest);
    else
       strcpy(reg_coord, reg_dest);
    else
-      pshader_gen_input_modifier_line(ins->shader, buffer, src[0], 0, reg_coord);
+      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. */
 
   /* 1.0-1.4: Use destination register number as texture code.
      2.0+: Use provided sampler number as texure code. */
-  if (shader_version < WINED3DPS_VERSION(2,0))
-     reg_sampler_code = dst->register_idx;
+  if (shader_version < WINED3D_SHADER_VERSION(2,0))
+     reg_sampler_code = dst->reg.idx;
   else
   else
-     reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
+     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
    */
 
   /* 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 < WINED3DPS_VERSION(1,4))
+  if (shader_version < WINED3D_SHADER_VERSION(1,4))
   {
       DWORD flags = 0;
       if(reg_sampler_code < MAX_TEXTURES) {
   {
       DWORD flags = 0;
       if(reg_sampler_code < MAX_TEXTURES) {
@@ -1173,9 +1082,9 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
           projected = TRUE;
       }
   }
           projected = TRUE;
       }
   }
-  else if (shader_version < WINED3DPS_VERSION(2,0))
+  else if (shader_version < WINED3D_SHADER_VERSION(2,0))
   {
   {
-      DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+      DWORD src_mod = ins->src[0].modifiers;
       if (src_mod == WINED3DSPSM_DZ) {
           projected = TRUE;
       } else if(src_mod == WINED3DSPSM_DW) {
       if (src_mod == WINED3DSPSM_DZ) {
           projected = TRUE;
       } else if(src_mod == WINED3DSPSM_DW) {
@@ -1191,35 +1100,37 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->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);
 
     char tmp[20];
     shader_arb_get_write_mask(ins, dst, tmp);
 
     char tmp[20];
     shader_arb_get_write_mask(ins, dst, tmp);
-    if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+    if (shader_version != WINED3D_SHADER_VERSION(1,4))
     {
     {
-        DWORD reg = dst->register_idx;
+        DWORD reg = dst->reg.idx;
         shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
     } else {
         char reg_src[40];
 
         shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
     } else {
         char reg_src[40];
 
-        pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, reg_src);
-        shader_addline(buffer, "MOV R%u%s, %s;\n", dst->register_idx, tmp, reg_src);
+        shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src);
+        shader_addline(buffer, "MOV R%u%s, %s;\n", dst->reg.idx, tmp, reg_src);
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
    }
 }
 
 static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
-     SHADER_BUFFER *buffer = ins->buffer;
-     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+     SHADER_BUFFER *buffer = ins->ctx->buffer;
+     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
      IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
      DWORD flags;
 
      IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
      DWORD flags;
 
-     DWORD reg1 = ins->dst[0].register_idx;
+     DWORD reg1 = ins->dst[0].reg.idx;
      char dst_str[8];
      char src_str[50];
 
      sprintf(dst_str, "T%u", reg1);
      char dst_str[8];
      char src_str[50];
 
      sprintf(dst_str, "T%u", reg1);
-     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+     shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
      shader_addline(buffer, "MOV TMP.x, %s.w;\n", src_str);
      shader_addline(buffer, "MOV TMP.y, %s.x;\n", src_str);
      flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
      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;
@@ -1228,14 +1139,14 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
-     SHADER_BUFFER *buffer = ins->buffer;
+     SHADER_BUFFER *buffer = ins->ctx->buffer;
 
 
-     DWORD reg1 = ins->dst[0].register_idx;
+     DWORD reg1 = ins->dst[0].reg.idx;
      char dst_str[8];
      char src_str[50];
 
      sprintf(dst_str, "T%u", reg1);
      char dst_str[8];
      char src_str[50];
 
      sprintf(dst_str, "T%u", reg1);
-     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+     shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
      shader_addline(buffer, "MOV TMP.x, %s.y;\n", src_str);
      shader_addline(buffer, "MOV TMP.y, %s.z;\n", src_str);
      shader_hw_sample(ins, reg1, dst_str, "TMP", FALSE, FALSE);
      shader_addline(buffer, "MOV 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);
@@ -1243,36 +1154,34 @@ static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD reg1 = ins->dst[0].register_idx;
+    DWORD reg1 = ins->dst[0].reg.idx;
     char dst_str[8];
     char src_str[50];
 
     sprintf(dst_str, "T%u", reg1);
     char dst_str[8];
     char src_str[50];
 
     sprintf(dst_str, "T%u", reg1);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_str);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
     shader_hw_sample(ins, reg1, dst_str, src_str, FALSE, FALSE);
 }
 
 static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 {
     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->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     BOOL has_bumpmat = FALSE;
     BOOL has_luminance = FALSE;
     BOOL is_color;
     int i;
 
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     BOOL has_bumpmat = FALSE;
     BOOL has_luminance = FALSE;
     BOOL is_color;
     int i;
 
-    DWORD src = ins->src[0] & WINED3DSP_REGNUM_MASK;
-    SHADER_BUFFER* buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
 
     char reg_coord[40];
     DWORD reg_dest_code;
 
     /* All versions have a destination register */
 
     char reg_coord[40];
     DWORD reg_dest_code;
 
     /* All versions have a destination register */
-    reg_dest_code = dst->register_idx;
+    reg_dest_code = dst->reg.idx;
     /* Can directly use the name because texbem is only valid for <= 1.3 shaders */
     /* Can directly use the name because texbem is only valid for <= 1.3 shaders */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, reg_coord, &is_color);
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+            dst->reg.idx, !!dst->reg.rel_addr, reg_coord, &is_color);
 
     for(i = 0; i < This->numbumpenvmatconsts; i++) {
         if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
 
     for(i = 0; i < This->numbumpenvmatconsts; i++) {
         if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
@@ -1292,6 +1201,8 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
     }
 
     if(has_bumpmat) {
     }
 
     if(has_bumpmat) {
+        DWORD src = ins->src[0].reg.idx;
+
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
         /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
         shader_addline(buffer, "SWZ TMP2, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
@@ -1334,26 +1245,26 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char src0_name[50];
 
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name);
 }
 
 static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
     shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", reg, src0_name);
 }
 
 static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_str[8];
     char src0_name[50];
 
     sprintf(dst_str, "T%u", reg);
     char dst_str[8];
     char src0_name[50];
 
     sprintf(dst_str, "T%u", reg);
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", reg, src0_name);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
     shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", reg, src0_name);
     flags = reg < MAX_TEXTURES ? deviceImpl->stateBlock->textureState[reg][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0;
     shader_hw_sample(ins, reg, dst_str, "TMP", flags & WINED3DTTFF_PROJECTED, FALSE);
@@ -1361,29 +1272,29 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char src0_name[50];
 
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.%c, T%u, %s;\n", 'x' + current_state->current_row, reg, src0_name);
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
 
 static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
 {
     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;
 }
 
 static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char dst_str[8];
     char src0_name[50];
 
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char dst_str[8];
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Sample the texture using the calculated coordinates */
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Sample the texture using the calculated coordinates */
@@ -1395,16 +1306,16 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char dst_str[8];
     char src0_name[50];
 
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char dst_str[8];
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Construct the eye-ray vector from w coordinates */
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Construct the eye-ray vector from w coordinates */
@@ -1431,17 +1342,18 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins
 
 static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
 
 static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD flags;
-    DWORD reg = ins->dst[0].register_idx;
-    DWORD reg3 = ins->src[1] & WINED3DSP_REGNUM_MASK;
+    DWORD reg = ins->dst[0].reg.idx;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_str[8];
     char src0_name[50];
     char dst_str[8];
     char src0_name[50];
+    char src1_name[50];
 
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name);
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Calculate reflection vector.
     shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", reg, src0_name);
 
     /* Calculate reflection vector.
@@ -1452,12 +1364,12 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
      *
      * Which normalizes the normal vector
      */
      *
      * Which normalizes the normal vector
      */
-    shader_addline(buffer, "DP3 TMP.w, TMP, C[%u];\n", reg3);
+    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, "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, -C[%u];\n", reg3);
+    shader_addline(buffer, "MAD TMP, coefmul.x, TMP, -%s;\n", src1_name);
 
     /* Sample the texture using the calculated coordinates */
     sprintf(dst_str, "T%u", reg);
 
     /* Sample the texture using the calculated coordinates */
     sprintf(dst_str, "T%u", reg);
@@ -1469,7 +1381,7 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     BOOL is_color;
 
     char dst_name[50];
     BOOL is_color;
 
@@ -1478,8 +1390,8 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
      * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
      * here
      */
      * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
      * here
      */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    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
@@ -1501,12 +1413,12 @@ static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD sampler_idx = ins->dst[0].register_idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
     char src0[50];
     char dst_str[8];
 
     char src0[50];
     char dst_str[8];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_addline(buffer, "MOV TMP, 0.0;\n");
     shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0);
 
     shader_addline(buffer, "MOV TMP, 0.0;\n");
     shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0);
 
@@ -1522,16 +1434,16 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
     char src0[50];
     char dst_str[50];
     char dst_mask[6];
     char src0[50];
     char dst_str[50];
     char dst_mask[6];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     BOOL is_color;
 
     /* Handle output register */
     BOOL is_color;
 
     /* Handle output register */
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+            dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
     shader_arb_get_write_mask(ins, dst, dst_mask);
 
     shader_arb_get_write_mask(ins, dst, dst_mask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->register_idx, src0);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->reg.idx, src0);
 
     /* TODO: Handle output modifiers */
 }
 
     /* TODO: Handle output modifiers */
 }
@@ -1541,18 +1453,18 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_str[50];
     char dst_mask[6];
     char src0[50];
     BOOL is_color;
 
     char dst_str[50];
     char dst_mask[6];
     char src0[50];
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+    shader_arb_get_register_name(ins->ctx->shader, dst->reg.type,
+            dst->reg.idx, !!dst->reg.rel_addr, dst_str, &is_color);
     shader_arb_get_write_mask(ins, dst, dst_mask);
 
     shader_arb_get_write_mask(ins, dst, dst_mask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->register_idx, src0);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->reg.idx, src0);
     shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask);
 
     /* TODO: Handle output modifiers */
     shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask);
 
     /* TODO: Handle output modifiers */
@@ -1565,11 +1477,11 @@ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
  */
 static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
  */
 static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD dst_reg = ins->dst[0].register_idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    DWORD dst_reg = ins->dst[0].reg.idx;
     char src0[50];
 
     char src0[50];
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
     shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, src0);
 
     /* How to deal with the special case dst_name.g == 0? if r != 0, then
     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
@@ -1588,21 +1500,18 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
 {
     int i;
     int nComponents = 0;
 {
     int i;
     int nComponents = 0;
-    struct wined3d_shader_dst_param tmp_dst = {0};
+    struct wined3d_shader_dst_param tmp_dst = {{0}};
+    struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
     struct wined3d_shader_instruction tmp_ins;
 
     memset(&tmp_ins, 0, sizeof(tmp_ins));
 
     /* Set constants for the temporary argument */
     struct wined3d_shader_instruction tmp_ins;
 
     memset(&tmp_ins, 0, sizeof(tmp_ins));
 
     /* Set constants for the temporary argument */
-    tmp_ins.shader      = ins->shader;
-    tmp_ins.buffer      = ins->buffer;
-    tmp_ins.src[0]      = ins->src[0];
-    tmp_ins.src_addr[0] = ins->src_addr[0];
-    tmp_ins.src_addr[1] = ins->src_addr[1];
-    tmp_ins.reg_maps = ins->reg_maps;
+    tmp_ins.ctx = ins->ctx;
     tmp_ins.dst_count = 1;
     tmp_ins.dst = &tmp_dst;
     tmp_ins.src_count = 2;
     tmp_ins.dst_count = 1;
     tmp_ins.dst = &tmp_dst;
     tmp_ins.src_count = 2;
+    tmp_ins.src = tmp_src;
 
     switch(ins->handler_idx)
     {
 
     switch(ins->handler_idx)
     {
@@ -1632,21 +1541,22 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
     }
 
     tmp_dst = ins->dst[0];
     }
 
     tmp_dst = ins->dst[0];
+    tmp_src[0] = ins->src[0];
+    tmp_src[1] = ins->src[1];
     for (i = 0; i < nComponents; i++) {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
     for (i = 0; i < nComponents; i++) {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
-        tmp_ins.src[1] = ins->src[1]+i;
         shader_hw_map2gl(&tmp_ins);
         shader_hw_map2gl(&tmp_ins);
+        ++tmp_src[1].reg.idx;
     }
 }
 
     }
 }
 
-static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
+static void shader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
 {
 {
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD src = ins->src[0];
-    DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
-    const char *instruction;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    const char *instruction, *sat;
 
 
-    char tmpLine[256];
+    char dst[50];
+    char src[50];
 
     switch(ins->handler_idx)
     {
 
     switch(ins->handler_idx)
     {
@@ -1657,44 +1567,42 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
             break;
     }
 
             break;
     }
 
-    strcpy(tmpLine, instruction);
-    shader_arb_add_dst_param(ins, &ins->dst[0], tmpLine); /* Destination */
-    strcat(tmpLine, ",");
-    shader_arb_add_src_param(ins, src, tmpLine);
-    if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) == swizzle) {
+    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)
+    {
         /* Dx sdk says .x is used if no swizzle is given, but our test shows that
          * .w is used
          */
         /* Dx sdk says .x is used if no swizzle is given, but our test shows that
          * .w is used
          */
-        strcat(tmpLine, ".w");
+        strcat(src, ".w");
     }
 
     }
 
-    shader_addline(buffer, "%s;\n", tmpLine);
+    shader_addline(buffer, "%s%s %s, %s;\n", instruction, sat, dst, src);
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
 }
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
-    DWORD shift = dst->shift;
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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_write_mask(ins, dst, dst_wmask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name);
+    shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
     shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name);
     shader_addline(buffer, "RSQ TMP, TMP.x;\n");
     /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
     shader_addline(buffer, "MUL%s %s%s, %s, TMP;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
                    src_name);
     shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name);
     shader_addline(buffer, "RSQ TMP, TMP.x;\n");
     /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
     shader_addline(buffer, "MUL%s %s%s, %s, TMP;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
                    src_name);
-
-    if (shift != 0)
-        pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
 }
 
 static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
@@ -1704,25 +1612,20 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
      * can't use map2gl
      */
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
      * can't use map2gl
      */
     const struct wined3d_shader_dst_param *dst = &ins->dst[0];
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
-    DWORD shift = dst->shift;
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
     BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
     BOOL is_color;
 
-    shader_arb_get_register_name(ins->shader, dst->register_type,
-            dst->register_idx, dst->has_rel_addr, dst_name, &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_write_mask(ins, dst, dst_wmask);
 
-    pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_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);
     shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
                    src_name);
-
-    if (shift != 0)
-        pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name);
-
 }
 
 static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
 }
 
 static GLuint create_arb_blt_vertex_program(const WineD3D_GL_Info *gl_info)
@@ -1904,7 +1807,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
     IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
 
     IWineD3DBaseShaderImpl *baseShader = (IWineD3DBaseShaderImpl *) iface;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)baseShader->baseShader.device)->adapter->gl_info;
 
-    if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version))
+    if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version.type))
     {
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
         UINT i;
     {
         IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
         UINT i;
@@ -1969,16 +1872,16 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
     /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
 
     /* Calculate the > 0.0031308 case */
     /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
 
     /* Calculate the > 0.0031308 case */
-    shader_addline(buffer, "POW %s.x, %s.x, srgb_pow.x;\n", tmp1, fragcolor);
-    shader_addline(buffer, "POW %s.y, %s.y, srgb_pow.y;\n", tmp1, fragcolor);
-    shader_addline(buffer, "POW %s.z, %s.z, srgb_pow.z;\n", tmp1, fragcolor);
-    shader_addline(buffer, "MUL %s, %s, srgb_mul_hi;\n", tmp1, tmp1);
-    shader_addline(buffer, "SUB %s, %s, srgb_sub_hi;\n", tmp1, tmp1);
+    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 */
     /* Calculate the < case */
-    shader_addline(buffer, "MUL %s, srgb_mul_low, %s;\n", tmp2, fragcolor);
+    shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
     /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
     /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
-    shader_addline(buffer, "SLT %s, srgb_comparison, %s;\n", tmp3, fragcolor);
-    shader_addline(buffer, "SGE %s, srgb_comparison, %s;\n", tmp4, fragcolor);
+    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 */
     /* 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 */
@@ -1986,20 +1889,23 @@ static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcol
     /* [0.0;1.0] clamping. Not needed, this is done implicitly */
 }
 
     /* [0.0;1.0] clamping. Not needed, this is done implicitly */
 }
 
-static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
+static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface,
+        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
-    DWORD shader_version = reg_maps->shader_version;
     const WineD3D_GL_Info *gl_info = &((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info;
     const local_constant *lconst;
     GLuint retval;
     const char *fragcolor;
     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");
 
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBfp1.0\n");
 
-    if (shader_version < WINED3DPS_VERSION(3,0)) {
+    if (reg_maps->shader_version.major < 3)
+    {
         switch(args->fog) {
             case FOG_OFF:
                 break;
         switch(args->fog) {
             case FOG_OFF:
                 break;
@@ -2024,7 +1930,8 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
     shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
     shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
     shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
     shader_addline(buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
 
-    if (shader_version < WINED3DPS_VERSION(2,0)) {
+    if (reg_maps->shader_version.major < 2)
+    {
         fragcolor = "R0";
     } else {
         shader_addline(buffer, "TEMP TMP_COLOR;\n");
         fragcolor = "R0";
     } else {
         shader_addline(buffer, "TEMP TMP_COLOR;\n");
@@ -2032,10 +1939,10 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
     }
 
     /* Base Declarations */
     }
 
     /* Base Declarations */
-    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, lconst_map);
 
     /* Base Shader Body */
 
     /* Base Shader Body */
-    shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
 
     if(args->srgb_correction) {
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
 
     if(args->srgb_correction) {
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
@@ -2063,18 +1970,21 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF
     }
 
     /* Load immediate constants */
     }
 
     /* Load immediate constants */
-    if(!This->baseShader.load_local_constsF) {
+    if(lconst_map) {
         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
             const float *value = (const float *)lconst->value;
         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->idx, value));
+            GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
             checkGLcall("glProgramLocalParameter4fvARB");
         }
             checkGLcall("glProgramLocalParameter4fvARB");
         }
+        HeapFree(GetProcessHeap(), 0, lconst_map);
     }
 
     return retval;
 }
 
     }
 
     return retval;
 }
 
-static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+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;
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
@@ -2082,6 +1992,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
     const WineD3D_GL_Info *gl_info = &device->adapter->gl_info;
     const local_constant *lconst;
     GLuint ret;
     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");
 
     /*  Create the hw ARB shader */
     shader_addline(buffer, "!!ARBvp1.0\n");
@@ -2095,7 +2006,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
     shader_addline(buffer, "TEMP TMP;\n");
 
     /* Base Declarations */
     shader_addline(buffer, "TEMP TMP;\n");
 
     /* Base Declarations */
-    shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION);
+    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);
 
     /* We need a constant to fixup the final position */
     shader_addline(buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS);
@@ -2126,7 +2037,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
     }
 
     /* Base Shader Body */
     }
 
     /* Base Shader Body */
-    shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+    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 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),
@@ -2136,7 +2047,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
     if(args->fog_src == VS_FOG_Z) {
         shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
     } else if (!reg_maps->fog) {
     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, 0.0;\n");
+        shader_addline(buffer, "MOV result.fogcoord, helper_const.w;\n");
     }
 
     /* Write the final position.
     }
 
     /* Write the final position.
@@ -2178,13 +2089,15 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU
         ret = -1;
     } else {
         /* Load immediate constants */
         ret = -1;
     } else {
         /* Load immediate constants */
-        if(!This->baseShader.load_local_constsF) {
+        if(lconst_map) {
             LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
                 const float *value = (const float *)lconst->value;
             LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
                 const float *value = (const float *)lconst->value;
-                GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst->idx, value));
+                GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst_map[lconst->idx], value));
             }
         }
     }
             }
         }
     }
+    HeapFree(GetProcessHeap(), 0, lconst_map);
+
     return ret;
 }
 
     return ret;
 }
 
@@ -2228,6 +2141,30 @@ static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
     return FALSE;
 }
 
     return FALSE;
 }
 
+static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {
+    BOOL saturate;
+    DWORD shift;
+    char write_mask[20], regstr[50];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    BOOL is_color = FALSE;
+    const struct wined3d_shader_dst_param *dst;
+
+    if (!ins->dst_count) return;
+
+    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_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 */
+    shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", saturate ? "_SAT" : "",
+                   regstr, write_mask, regstr, shift_tab[shift]);
+}
+
 static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
 {
     /* WINED3DSIH_ABS           */ shader_hw_map2gl,
 static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
 {
     /* WINED3DSIH_ABS           */ shader_hw_map2gl,
@@ -2277,14 +2214,14 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_MOV           */ shader_hw_mov,
     /* WINED3DSIH_MOVA          */ shader_hw_mov,
     /* WINED3DSIH_MUL           */ shader_hw_map2gl,
     /* WINED3DSIH_MOV           */ shader_hw_mov,
     /* WINED3DSIH_MOVA          */ shader_hw_mov,
     /* WINED3DSIH_MUL           */ shader_hw_map2gl,
-    /* WINED3DSIH_NOP           */ shader_hw_map2gl,
+    /* WINED3DSIH_NOP           */ shader_hw_nop,
     /* WINED3DSIH_NRM           */ shader_hw_nrm,
     /* WINED3DSIH_PHASE         */ NULL,
     /* WINED3DSIH_POW           */ shader_hw_map2gl,
     /* WINED3DSIH_NRM           */ shader_hw_nrm,
     /* WINED3DSIH_PHASE         */ NULL,
     /* WINED3DSIH_POW           */ shader_hw_map2gl,
-    /* WINED3DSIH_RCP           */ vshader_hw_rsq_rcp,
+    /* WINED3DSIH_RCP           */ shader_hw_rsq_rcp,
     /* WINED3DSIH_REP           */ NULL,
     /* WINED3DSIH_RET           */ NULL,
     /* WINED3DSIH_REP           */ NULL,
     /* WINED3DSIH_RET           */ NULL,
-    /* WINED3DSIH_RSQ           */ vshader_hw_rsq_rcp,
+    /* WINED3DSIH_RSQ           */ shader_hw_rsq_rcp,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
     /* WINED3DSIH_SGN           */ NULL,
     /* WINED3DSIH_SETP          */ NULL,
     /* WINED3DSIH_SGE           */ shader_hw_map2gl,
     /* WINED3DSIH_SGN           */ NULL,
@@ -2332,6 +2269,7 @@ const shader_backend_t arb_program_shader_backend = {
     shader_arb_generate_vshader,
     shader_arb_get_caps,
     shader_arb_color_fixup_supported,
     shader_arb_generate_vshader,
     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 */
@@ -2865,16 +2803,10 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
         shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
 
     if(settings->sRGB_write) {
         shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
 
     if(settings->sRGB_write) {
-        shader_addline(&buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
-                       srgb_mul_low, srgb_mul_low, srgb_mul_low);
-        shader_addline(&buffer, "PARAM srgb_comparison =  {%f, %f, %f, %f};\n",
-                       srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
-        shader_addline(&buffer, "PARAM srgb_pow =  {%f, %f, %f, 1.0};\n",
-                       srgb_pow, srgb_pow, srgb_pow);
-        shader_addline(&buffer, "PARAM srgb_mul_hi =  {%f, %f, %f, 1.0};\n",
-                       srgb_mul_high, srgb_mul_high, srgb_mul_high);
-        shader_addline(&buffer, "PARAM srgb_sub_hi =  {%f, %f, %f, 0.0};\n",
-                       srgb_sub_high, srgb_sub_high, srgb_sub_high);
+        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);
     }
 
     /* Generate texture sampling instructions) */
     }
 
     /* Generate texture sampling instructions) */
index 08415c2..8b8aef4 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright 2005 Oliver Stieber
  * Copyright 2006 Ivan Gyurdiev
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Copyright 2005 Oliver Stieber
  * Copyright 2006 Ivan Gyurdiev
  * 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_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
-static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD shader_version);
+static const char *shader_opcode_names[] =
+{
+    /* WINED3DSIH_ABS           */ "abs",
+    /* WINED3DSIH_ADD           */ "add",
+    /* WINED3DSIH_BEM           */ "bem",
+    /* WINED3DSIH_BREAK         */ "break",
+    /* WINED3DSIH_BREAKC        */ "breakc",
+    /* WINED3DSIH_BREAKP        */ "breakp",
+    /* WINED3DSIH_CALL          */ "call",
+    /* WINED3DSIH_CALLNZ        */ "callnz",
+    /* WINED3DSIH_CMP           */ "cmp",
+    /* WINED3DSIH_CND           */ "cnd",
+    /* WINED3DSIH_CRS           */ "crs",
+    /* WINED3DSIH_DCL           */ "dcl",
+    /* WINED3DSIH_DEF           */ "def",
+    /* WINED3DSIH_DEFB          */ "defb",
+    /* WINED3DSIH_DEFI          */ "defi",
+    /* WINED3DSIH_DP2ADD        */ "dp2add",
+    /* WINED3DSIH_DP3           */ "dp3",
+    /* WINED3DSIH_DP4           */ "dp4",
+    /* WINED3DSIH_DST           */ "dst",
+    /* WINED3DSIH_DSX           */ "dsx",
+    /* WINED3DSIH_DSY           */ "dsy",
+    /* WINED3DSIH_ELSE          */ "else",
+    /* WINED3DSIH_ENDIF         */ "endif",
+    /* WINED3DSIH_ENDLOOP       */ "endloop",
+    /* WINED3DSIH_ENDREP        */ "endrep",
+    /* WINED3DSIH_EXP           */ "exp",
+    /* WINED3DSIH_EXPP          */ "expp",
+    /* WINED3DSIH_FRC           */ "frc",
+    /* WINED3DSIH_IF            */ "if",
+    /* WINED3DSIH_IFC           */ "ifc",
+    /* WINED3DSIH_LABEL         */ "label",
+    /* WINED3DSIH_LIT           */ "lit",
+    /* WINED3DSIH_LOG           */ "log",
+    /* WINED3DSIH_LOGP          */ "logp",
+    /* WINED3DSIH_LOOP          */ "loop",
+    /* WINED3DSIH_LRP           */ "lrp",
+    /* WINED3DSIH_M3x2          */ "m3x2",
+    /* WINED3DSIH_M3x3          */ "m3x3",
+    /* WINED3DSIH_M3x4          */ "m3x4",
+    /* WINED3DSIH_M4x3          */ "m4x3",
+    /* WINED3DSIH_M4x4          */ "m4x4",
+    /* WINED3DSIH_MAD           */ "mad",
+    /* WINED3DSIH_MAX           */ "max",
+    /* WINED3DSIH_MIN           */ "min",
+    /* WINED3DSIH_MOV           */ "mov",
+    /* WINED3DSIH_MOVA          */ "mova",
+    /* WINED3DSIH_MUL           */ "mul",
+    /* WINED3DSIH_NOP           */ "nop",
+    /* WINED3DSIH_NRM           */ "nrm",
+    /* WINED3DSIH_PHASE         */ "phase",
+    /* WINED3DSIH_POW           */ "pow",
+    /* WINED3DSIH_RCP           */ "rcp",
+    /* WINED3DSIH_REP           */ "rep",
+    /* WINED3DSIH_RET           */ "ret",
+    /* WINED3DSIH_RSQ           */ "rsq",
+    /* WINED3DSIH_SETP          */ "setp",
+    /* WINED3DSIH_SGE           */ "sge",
+    /* WINED3DSIH_SGN           */ "sgn",
+    /* WINED3DSIH_SINCOS        */ "sincos",
+    /* WINED3DSIH_SLT           */ "slt",
+    /* WINED3DSIH_SUB           */ "sub",
+    /* WINED3DSIH_TEX           */ "texld",
+    /* WINED3DSIH_TEXBEM        */ "texbem",
+    /* WINED3DSIH_TEXBEML       */ "texbeml",
+    /* WINED3DSIH_TEXCOORD      */ "texcrd",
+    /* WINED3DSIH_TEXDEPTH      */ "texdepth",
+    /* WINED3DSIH_TEXDP3        */ "texdp3",
+    /* WINED3DSIH_TEXDP3TEX     */ "texdp3tex",
+    /* WINED3DSIH_TEXKILL       */ "texkill",
+    /* WINED3DSIH_TEXLDD        */ "texldd",
+    /* WINED3DSIH_TEXLDL        */ "texldl",
+    /* WINED3DSIH_TEXM3x2DEPTH  */ "texm3x2depth",
+    /* WINED3DSIH_TEXM3x2PAD    */ "texm3x2pad",
+    /* WINED3DSIH_TEXM3x2TEX    */ "texm3x2tex",
+    /* WINED3DSIH_TEXM3x3       */ "texm3x3",
+    /* WINED3DSIH_TEXM3x3DIFF   */ "texm3x3diff",
+    /* WINED3DSIH_TEXM3x3PAD    */ "texm3x3pad",
+    /* WINED3DSIH_TEXM3x3SPEC   */ "texm3x3spec",
+    /* WINED3DSIH_TEXM3x3TEX    */ "texm3x3tex",
+    /* WINED3DSIH_TEXM3x3VSPEC  */ "texm3x3vspec",
+    /* WINED3DSIH_TEXREG2AR     */ "texreg2ar",
+    /* WINED3DSIH_TEXREG2GB     */ "texreg2gb",
+    /* WINED3DSIH_TEXREG2RGB    */ "texreg2rgb",
+};
+
+const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
+{
+    switch (version_token >> 16)
+    {
+        case WINED3D_SM1_VS:
+        case WINED3D_SM1_PS:
+            return &sm1_shader_frontend;
+
+        case WINED3D_SM4_PS:
+        case WINED3D_SM4_VS:
+        case WINED3D_SM4_GS:
+            return &sm4_shader_frontend;
+
+        default:
+            FIXME("Unrecognised version token %#x\n", version_token);
+            return NULL;
+    }
+}
 
 static inline BOOL shader_is_version_token(DWORD token) {
     return shader_is_pshader_version(token) ||
 
 static inline BOOL shader_is_version_token(DWORD token) {
     return shader_is_pshader_version(token) ||
@@ -95,153 +200,164 @@ int shader_addline(SHADER_BUFFER* buffer, const char *format, ...)
     return ret;
 }
 
     return ret;
 }
 
-void shader_init(struct IWineD3DBaseShaderClass *shader,
-        IWineD3DDevice *device, const SHADER_OPCODE *instruction_table)
+void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device)
 {
     shader->ref = 1;
     shader->device = device;
 {
     shader->ref = 1;
     shader->device = device;
-    shader->shader_ins = instruction_table;
     list_init(&shader->linked_programs);
 }
 
     list_init(&shader->linked_programs);
 }
 
-const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code)
+/* Convert floating point offset relative
+ * to a register file to an absolute offset for float constants */
+static unsigned int shader_get_float_offset(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx)
 {
 {
-    DWORD i = 0;
-
-    /** TODO: use dichotomic search */
-    while (opcode_table[i].name)
+    switch (register_type)
     {
     {
-        if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
-                && shader_version >= opcode_table[i].min_version
-                && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
-        {
-            return &opcode_table[i];
-        }
-        ++i;
+        case WINED3DSPR_CONST: return register_idx;
+        case WINED3DSPR_CONST2: return 2048 + register_idx;
+        case WINED3DSPR_CONST3: return 4096 + register_idx;
+        case WINED3DSPR_CONST4: return 6144 + register_idx;
+        default:
+            FIXME("Unsupported register type: %d\n", register_type);
+            return register_idx;
     }
     }
-
-    FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
-            code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
-
-    return NULL;
 }
 
 }
 
-/* Read a parameter opcode from the input stream,
- * and possibly a relative addressing token.
- * Return the number of tokens read */
-static int shader_get_param(const DWORD *pToken, DWORD shader_version, DWORD *param, DWORD *addr_token)
-{
-    /* PS >= 3.0 have relative addressing (with token)
-     * VS >= 2.0 have relative addressing (with token)
-     * VS >= 1.0 < 2.0 have relative addressing (without token)
-     * The version check below should work in general */
+static void shader_delete_constant_list(struct list* clist) {
 
 
-    char rel_token = WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2 &&
-        ((*pToken & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
+    struct list *ptr;
+    struct local_constant* constant;
 
 
-    *param = *pToken;
-    *addr_token = rel_token? *(pToken + 1): 0;
-    return rel_token? 2:1;
+    ptr = list_head(clist);
+    while (ptr) {
+        constant = LIST_ENTRY(ptr, struct local_constant, entry);
+        ptr = list_next(clist, ptr);
+        HeapFree(GetProcessHeap(), 0, constant);
+    }
+    list_init(clist);
 }
 
 }
 
-/* Return the number of parameters to skip for an opcode */
-static inline int shader_skip_opcode(const SHADER_OPCODE *curOpcode, DWORD opcode_token, DWORD shader_version)
+static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
 {
 {
-   /* Shaders >= 2.0 may contain address tokens, but fortunately they
-    * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
-    return (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
-            ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : curOpcode->num_params;
+    DWORD idx, shift;
+    idx = bit >> 5;
+    shift = bit & 0x1f;
+    bitmap[idx] |= (1 << shift);
 }
 
 }
 
-/* Read the parameters of an unrecognized opcode from the input stream
- * Return the number of tokens read. 
- * 
- * Note: This function assumes source or destination token format.
- * It will not work with specially-formatted tokens like DEF or DCL, 
- * but hopefully those would be recognized */
-static int shader_skip_unrecognized(const DWORD *pToken, DWORD shader_version)
+static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
+        DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
 {
 {
-    int tokens_read = 0;
-    int i = 0;
+    switch (register_type)
+    {
+        case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
+            if (pshader) reg_maps->texcoord[register_idx] = 1;
+            else reg_maps->address[register_idx] = 1;
+            break;
+
+        case WINED3DSPR_TEMP:
+            reg_maps->temporary[register_idx] = 1;
+            break;
+
+        case WINED3DSPR_INPUT:
+            if (!pshader) reg_maps->attributes[register_idx] = 1;
+            else
+            {
+                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
+                     * that v0, v1 and v2 aren't read because aL can be negative */
+                    unsigned int i;
+                    for (i = 0; i < MAX_REG_INPUT; ++i)
+                    {
+                        ((IWineD3DPixelShaderImpl *)This)->input_reg_used[i] = TRUE;
+                    }
+                }
+                else
+                {
+                    ((IWineD3DPixelShaderImpl *)This)->input_reg_used[register_idx] = TRUE;
+                }
+            }
+            break;
+
+        case WINED3DSPR_RASTOUT:
+            if (register_idx == 1) reg_maps->fog = 1;
+            break;
+
+        case WINED3DSPR_MISCTYPE:
+            if (pshader && register_idx == 0) reg_maps->vpos = 1;
+            break;
+
+        case WINED3DSPR_CONST:
+            if (has_rel_addr)
+            {
+                if (!pshader)
+                {
+                    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
+            {
+                set_bitmap_bit(reg_maps->constf, register_idx);
+            }
+            break;
 
 
-    /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
-    while (*pToken & 0x80000000) {
+        case WINED3DSPR_CONSTINT:
+            reg_maps->integer_constants |= (1 << register_idx);
+            break;
 
 
-        DWORD param, addr_token;
-        tokens_read += shader_get_param(pToken, shader_version, &param, &addr_token);
-        pToken += tokens_read;
+        case WINED3DSPR_CONSTBOOL:
+            reg_maps->boolean_constants |= (1 << register_idx);
+            break;
 
 
-        FIXME("Unrecognized opcode param: token=0x%08x "
-            "addr_token=0x%08x name=", param, addr_token);
-        shader_dump_param(param, addr_token, i, shader_version);
-        FIXME("\n");
-        ++i;
+        default:
+            TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx);
+            break;
     }
     }
-    return tokens_read;
 }
 
 }
 
-/* Convert floating point offset relative
- * to a register file to an absolute offset for float constants */
-static unsigned int shader_get_float_offset(const DWORD reg)
+static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
 {
 {
-     unsigned int regnum = reg & WINED3DSP_REGNUM_MASK;
-     int regtype = shader_get_regtype(reg);
-
-     switch (regtype) {
-        case WINED3DSPR_CONST: return regnum;
-        case WINED3DSPR_CONST2: return 2048 + regnum;
-        case WINED3DSPR_CONST3: return 4096 + regnum;
-        case WINED3DSPR_CONST4: return 6144 + regnum;
-        default:
-            FIXME("Unsupported register type: %d\n", regtype);
-            return regnum;
-     }
-}
+    switch(instr)
+    {
+        case WINED3DSIH_M4x4:
+        case WINED3DSIH_M3x4:
+            return param == 1 ? 4 : 1;
 
 
-static void shader_delete_constant_list(struct list* clist) {
+        case WINED3DSIH_M4x3:
+        case WINED3DSIH_M3x3:
+            return param == 1 ? 3 : 1;
 
 
-    struct list *ptr;
-    struct local_constant* constant;
+        case WINED3DSIH_M3x2:
+            return param == 1 ? 2 : 1;
 
 
-    ptr = list_head(clist);
-    while (ptr) {
-        constant = LIST_ENTRY(ptr, struct local_constant, entry);
-        ptr = list_next(clist, ptr);
-        HeapFree(GetProcessHeap(), 0, constant);
+        default:
+            return 1;
     }
     }
-    list_init(clist);
-}
-
-static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst)
-{
-    dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
-            | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
-    dst->register_idx = param & WINED3DSP_REGNUM_MASK;
-    dst->write_mask = param & WINED3DSP_WRITEMASK_ALL;
-    dst->modifiers = param & WINED3DSP_DSTMOD_MASK;
-    dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    dst->has_rel_addr = param & WINED3DSHADER_ADDRMODE_RELATIVE;
-    dst->addr_token = addr_param;
 }
 
 /* Note that this does not count the loop register
  * as an address register. */
 
 }
 
 /* Note that this does not count the loop register
  * as an address register. */
 
-HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
-        struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
-        const DWORD *byte_code)
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
+        struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
+        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
-    const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
-    DWORD shader_version;
+    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 */
 
     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 */
 
-    memset(reg_maps->bumpmat, 0, sizeof(reg_maps->bumpmat));
-    memset(reg_maps->luminanceparams, 0, sizeof(reg_maps->luminanceparams));
+    memset(reg_maps, 0, sizeof(*reg_maps));
 
     /* get_registers_used is called on every compile on some 1.x shaders, which can result
      * in stacking up a collection of local constants. Delete the old constants if existing
 
     /* get_registers_used is called on every compile on some 1.x shaders, which can result
      * in stacking up a collection of local constants. Delete the old constants if existing
@@ -250,83 +366,88 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
 
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
 
-    /* The version token is supposed to be the first token */
-    if (!shader_is_version_token(*pToken))
-    {
-        FIXME("First token is not a version token, invalid shader.\n");
-        return WINED3DERR_INVALIDCALL;
+    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));
+    if(!reg_maps->constf) {
+        ERR("Out of memory\n");
+        return E_OUTOFMEMORY;
     }
     }
-    reg_maps->shader_version = shader_version = *pToken++;
-    pshader = shader_is_pshader_version(shader_version);
 
 
-    while (WINED3DVS_END() != *pToken) {
-        CONST SHADER_OPCODE* curOpcode;
-        DWORD opcode_token;
+    while (!fe->shader_is_end(fe_data, &pToken))
+    {
+        struct wined3d_shader_instruction ins;
+        const char *comment;
+        UINT param_size;
 
         /* Skip comments */
 
         /* Skip comments */
-        if (shader_is_comment(*pToken))
-        {
-             DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
-             ++pToken;
-             pToken += comment_len;
-             continue;
-        }
+        fe->shader_read_comment(&pToken, &comment);
+        if (comment) continue;
 
         /* Fetch opcode */
 
         /* Fetch opcode */
-        opcode_token = *pToken++;
-        curOpcode = shader_get_opcode(shader_ins, shader_version, opcode_token);
+        fe->shader_read_opcode(fe_data, &pToken, &ins, &param_size);
 
         /* Unhandled opcode, and its parameters */
 
         /* Unhandled opcode, and its parameters */
-        if (NULL == curOpcode) {
-           while (*pToken & 0x80000000)
-               ++pToken;
+        if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+        {
+            TRACE("Skipping unrecognized instruction.\n");
+            pToken += param_size;
+            continue;
+        }
 
         /* Handle declarations */
 
         /* Handle declarations */
-        } else if (WINED3DSIO_DCL == curOpcode->opcode) {
-
-            DWORD usage = *pToken++;
-            DWORD param = *pToken++;
-            DWORD regtype = shader_get_regtype(param);
-            unsigned int regnum = param & WINED3DSP_REGNUM_MASK;
-
-            /* Vshader: mark attributes used
-               Pshader: mark 3.0 input registers used, save token */
-            if (WINED3DSPR_INPUT == regtype) {
-
-                if (!pshader)
-                    reg_maps->attributes[regnum] = 1;
-                else
-                    reg_maps->packed_input[regnum] = 1;
-
-                semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-                semantics_in[regnum].usage_idx =
-                        (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-                shader_parse_dst_param(param, 0, &semantics_in[regnum].reg);
-
-            /* Vshader: mark 3.0 output registers used, save token */
-            } else if (WINED3DSPR_OUTPUT == regtype) {
-                reg_maps->packed_output[regnum] = 1;
-                semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-                semantics_out[regnum].usage_idx =
-                        (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-                shader_parse_dst_param(param, 0, &semantics_out[regnum].reg);
+        if (ins.handler_idx == WINED3DSIH_DCL)
+        {
+            struct wined3d_shader_semantic semantic;
 
 
-                if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT))
-                    reg_maps->fog = 1;
+            fe->shader_read_semantic(&pToken, &semantic);
 
 
-            /* Save sampler usage token */
-            } else if (WINED3DSPR_SAMPLER == regtype)
-                reg_maps->samplers[regnum] = usage;
+            switch (semantic.reg.reg.type)
+            {
+                /* Vshader: mark attributes used
+                 * Pshader: mark 3.0 input registers used, save token */
+                case WINED3DSPR_INPUT:
+                    if (!pshader) reg_maps->attributes[semantic.reg.reg.idx] = 1;
+                    else reg_maps->packed_input[semantic.reg.reg.idx] = 1;
+                    semantics_in[semantic.reg.reg.idx] = semantic;
+                    break;
+
+                /* Vshader: mark 3.0 output registers used, save token */
+                case WINED3DSPR_OUTPUT:
+                    reg_maps->packed_output[semantic.reg.reg.idx] = 1;
+                    semantics_out[semantic.reg.reg.idx] = semantic;
+                    if (semantic.usage == WINED3DDECLUSAGE_FOG) reg_maps->fog = 1;
+                    break;
+
+                /* Save sampler usage token */
+                case WINED3DSPR_SAMPLER:
+                    reg_maps->sampler_type[semantic.reg.reg.idx] = semantic.sampler_type;
+                    break;
 
 
-        } else if (WINED3DSIO_DEF == curOpcode->opcode) {
+                default:
+                    TRACE("Not recording DCL register type %#x.\n", semantic.reg.reg.type);
+                    break;
+            }
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEF)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
-            lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
-            memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
+
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+            lconst->idx = dst.reg.idx;
+
+            memcpy(lconst->value, pToken, 4 * sizeof(DWORD));
+            pToken += 4;
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
-            if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1 && pshader)
+            if (shader_version.major == 1 && pshader)
             {
                 float *value = (float *) lconst->value;
                 if(value[0] < -1.0) value[0] = -1.0;
             {
                 float *value = (float *) lconst->value;
                 if(value[0] < -1.0) value[0] = -1.0;
@@ -340,176 +461,185 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
             }
 
             list_add_head(&This->baseShader.constantsF, &lconst->entry);
-            pToken += curOpcode->num_params;
-
-        } else if (WINED3DSIO_DEFI == curOpcode->opcode) {
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEFI)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
-            lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
-            memcpy(lconst->value, pToken + 1, 4 * sizeof(DWORD));
-            list_add_head(&This->baseShader.constantsI, &lconst->entry);
-            pToken += curOpcode->num_params;
 
 
-        } else if (WINED3DSIO_DEFB == curOpcode->opcode) {
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+            lconst->idx = dst.reg.idx;
+
+            memcpy(lconst->value, pToken, 4 * sizeof(DWORD));
+            pToken += 4;
+
+            list_add_head(&This->baseShader.constantsI, &lconst->entry);
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEFB)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
 
             local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
             if (!lconst) return E_OUTOFMEMORY;
-            lconst->idx = *pToken & WINED3DSP_REGNUM_MASK;
-            memcpy(lconst->value, pToken + 1, 1 * sizeof(DWORD));
-            list_add_head(&This->baseShader.constantsB, &lconst->entry);
-            pToken += curOpcode->num_params;
 
 
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+            lconst->idx = dst.reg.idx;
+
+            memcpy(lconst->value, pToken, sizeof(DWORD));
+            ++pToken;
+
+            list_add_head(&This->baseShader.constantsB, &lconst->entry);
+        }
         /* If there's a loop in the shader */
         /* If there's a loop in the shader */
-        } else if (WINED3DSIO_LOOP == curOpcode->opcode ||
-                   WINED3DSIO_REP == curOpcode->opcode) {
+        else if (ins.handler_idx == WINED3DSIH_LOOP
+                || ins.handler_idx == WINED3DSIH_REP)
+        {
+            struct wined3d_shader_src_param src, rel_addr;
+
+            fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+
+            /* Rep and Loop always use an integer constant for the control parameters */
+            if (ins.handler_idx == WINED3DSIH_REP)
+            {
+                reg_maps->integer_constants |= 1 << src.reg.idx;
+            }
+            else
+            {
+                fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+                reg_maps->integer_constants |= 1 << src.reg.idx;
+            }
+
             cur_loop_depth++;
             if(cur_loop_depth > max_loop_depth)
                 max_loop_depth = cur_loop_depth;
             cur_loop_depth++;
             if(cur_loop_depth > max_loop_depth)
                 max_loop_depth = cur_loop_depth;
-            pToken += curOpcode->num_params;
-
-            /* Rep and Loop always use an integer constant for the control parameters */
-            This->baseShader.uses_int_consts = TRUE;
-        } else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
-                   WINED3DSIO_ENDREP == curOpcode->opcode) {
+        }
+        else if (ins.handler_idx == WINED3DSIH_ENDLOOP
+                || ins.handler_idx == WINED3DSIH_ENDREP)
+        {
             cur_loop_depth--;
             cur_loop_depth--;
-
+        }
         /* For subroutine prototypes */
         /* For subroutine prototypes */
-        } else if (WINED3DSIO_LABEL == curOpcode->opcode) {
-
-            DWORD snum = *pToken & WINED3DSP_REGNUM_MASK; 
-            reg_maps->labels[snum] = 1;
-            pToken += curOpcode->num_params;
+        else if (ins.handler_idx == WINED3DSIH_LABEL)
+        {
+            struct wined3d_shader_src_param src, rel_addr;
 
 
+            fe->shader_read_src_param(fe_data, &pToken, &src, &rel_addr);
+            reg_maps->labels[src.reg.idx] = 1;
+        }
         /* Set texture, address, temporary registers */
         /* Set texture, address, temporary registers */
-        } else {
+        else
+        {
             int i, limit;
 
             int i, limit;
 
-            /* Declare 1.X samplers implicitly, based on the destination reg. number */
-            if (WINED3DSHADER_VERSION_MAJOR(shader_version) == 1
-                    && pshader /* Filter different instructions with the same enum values in VS */
-                    && (WINED3DSIO_TEX == curOpcode->opcode
-                        || WINED3DSIO_TEXBEM == curOpcode->opcode
-                        || WINED3DSIO_TEXBEML == curOpcode->opcode
-                        || WINED3DSIO_TEXDP3TEX == curOpcode->opcode
-                        || WINED3DSIO_TEXM3x2TEX == curOpcode->opcode
-                        || WINED3DSIO_TEXM3x3SPEC == curOpcode->opcode
-                        || WINED3DSIO_TEXM3x3TEX == curOpcode->opcode
-                        || WINED3DSIO_TEXM3x3VSPEC == curOpcode->opcode
-                        || WINED3DSIO_TEXREG2AR == curOpcode->opcode
-                        || WINED3DSIO_TEXREG2GB == curOpcode->opcode
-                        || WINED3DSIO_TEXREG2RGB == curOpcode->opcode))
-            {
-                /* Fake sampler usage, only set reserved bit and ttype */
-                DWORD sampler_code = *pToken & WINED3DSP_REGNUM_MASK;
-
-                TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
-                reg_maps->samplers[sampler_code] = (0x1 << 31) | WINED3DSTT_2D;
-
-                /* texbem is only valid with < 1.4 pixel shaders */
-                if(WINED3DSIO_TEXBEM  == curOpcode->opcode ||
-                    WINED3DSIO_TEXBEML == curOpcode->opcode) {
-                    reg_maps->bumpmat[sampler_code] = TRUE;
-                    if(WINED3DSIO_TEXBEML == curOpcode->opcode) {
-                        reg_maps->luminanceparams[sampler_code] = TRUE;
-                    }
-                }
-            }
-            if(WINED3DSIO_NRM  == curOpcode->opcode) {
-                reg_maps->usesnrm = 1;
-            } else if(WINED3DSIO_BEM == curOpcode->opcode && pshader) {
-                DWORD regnum = *pToken & WINED3DSP_REGNUM_MASK;
-                reg_maps->bumpmat[regnum] = TRUE;
-            } else if(WINED3DSIO_DSY  == curOpcode->opcode) {
-                reg_maps->usesdsy = 1;
-            }
-
             /* This will loop over all the registers and try to
             /* This will loop over all the registers and try to
-             * make a bitmask of the ones we're interested in. 
+             * make a bitmask of the ones we're interested in.
              *
              *
-             * Relative addressing tokens are ignored, but that's 
-             * okay, since we'll catch any address registers when 
+             * Relative addressing tokens are ignored, but that's
+             * okay, since we'll catch any address registers when
              * they are initialized (required by spec) */
 
              * they are initialized (required by spec) */
 
-            limit = (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)?
-                curOpcode->num_params + 1: curOpcode->num_params;
-
-            for (i = 0; i < limit; ++i) {
-
-                DWORD param, addr_token, reg, regtype;
-                pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
-
-                regtype = shader_get_regtype(param);
-                reg = param & WINED3DSP_REGNUM_MASK;
+            if (ins.dst_count)
+            {
+                struct wined3d_shader_dst_param dst_param;
+                struct wined3d_shader_src_param dst_rel_addr;
 
 
-                if (WINED3DSPR_TEXTURE == regtype) { /* vs: WINED3DSPR_ADDR */
+                fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
 
-                    if (pshader)
-                        reg_maps->texcoord[reg] = 1;
-                    else
-                        reg_maps->address[reg] = 1;
+                /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
+                 * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
+                 * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
+                if (!pshader && shader_version.major < 3 && dst_param.reg.type == WINED3DSPR_TEXCRDOUT)
+                {
+                    reg_maps->texcoord_mask[dst_param.reg.type] |= dst_param.write_mask;
                 }
                 }
-
-                else if (WINED3DSPR_TEMP == regtype)
-                    reg_maps->temporary[reg] = 1;
-
-                else if (WINED3DSPR_INPUT == regtype) {
-                    if( !pshader)
-                        reg_maps->attributes[reg] = 1;
-                    else {
-                        if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
-                            /* 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
-                             * that v0, v1 and v2 aren't read because aL can be negative
-                             */
-                            unsigned int i;
-                            for(i = 0; i < MAX_REG_INPUT; i++) {
-                                ((IWineD3DPixelShaderImpl *) This)->input_reg_used[i] = TRUE;
-                            }
-                        } else {
-                            ((IWineD3DPixelShaderImpl *) This)->input_reg_used[reg] = TRUE;
-                        }
-                    }
+                else
+                {
+                    shader_record_register_usage(This, reg_maps, dst_param.reg.type,
+                            dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader);
                 }
 
                 }
 
-                else if (WINED3DSPR_RASTOUT == regtype && reg == 1)
-                    reg_maps->fog = 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_TEXDP3TEX
+                            || ins.handler_idx == WINED3DSIH_TEXM3x2TEX
+                            || ins.handler_idx == WINED3DSIH_TEXM3x3SPEC
+                            || ins.handler_idx == WINED3DSIH_TEXM3x3TEX
+                            || ins.handler_idx == WINED3DSIH_TEXM3x3VSPEC
+                            || ins.handler_idx == WINED3DSIH_TEXREG2AR
+                            || ins.handler_idx == WINED3DSIH_TEXREG2GB
+                            || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
+                {
+                    /* Fake sampler usage, only set reserved bit and ttype */
+                    DWORD sampler_code = dst_param.reg.idx;
 
 
-                else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader)
-                    reg_maps->vpos = 1;
+                    TRACE("Setting fake 2D sampler for 1.x pixelshader\n");
+                    reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
 
 
-                else if(WINED3DSPR_CONST == regtype) {
-                    if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
-                        if(!pshader) {
-                            if(reg <= ((IWineD3DVertexShaderImpl *) This)->min_rel_offset) {
-                                ((IWineD3DVertexShaderImpl *) This)->min_rel_offset = reg;
-                            } else if(reg >= ((IWineD3DVertexShaderImpl *) This)->max_rel_offset) {
-                                ((IWineD3DVertexShaderImpl *) This)->max_rel_offset = reg;
-                            }
+                    /* texbem is only valid with < 1.4 pixel shaders */
+                    if (ins.handler_idx == WINED3DSIH_TEXBEM
+                            || ins.handler_idx == WINED3DSIH_TEXBEML)
+                    {
+                        reg_maps->bumpmat[sampler_code] = TRUE;
+                        if (ins.handler_idx == WINED3DSIH_TEXBEML)
+                        {
+                            reg_maps->luminanceparams[sampler_code] = TRUE;
                         }
                         }
-                        reg_maps->usesrelconstF = TRUE;
                     }
                 }
                     }
                 }
-                else if(WINED3DSPR_CONSTINT == regtype) {
-                    This->baseShader.uses_int_consts = TRUE;
-                }
-                else if(WINED3DSPR_CONSTBOOL == regtype) {
-                    This->baseShader.uses_bool_consts = TRUE;
+                else if (pshader && ins.handler_idx == WINED3DSIH_BEM)
+                {
+                    reg_maps->bumpmat[dst_param.reg.idx] = TRUE;
                 }
                 }
+            }
 
 
-                /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used
-                 * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT
-                 * isn't used in them, but future register types might cause issues
-                 */
-                else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */
-                        && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3)
+            if (ins.handler_idx == WINED3DSIH_NRM)
+            {
+                reg_maps->usesnrm = 1;
+            }
+            else if (ins.handler_idx == WINED3DSIH_DSY)
+            {
+                reg_maps->usesdsy = 1;
+            }
+            else if(ins.handler_idx == WINED3DSIH_TEXLDD)
+            {
+                reg_maps->usestexldd = 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;
+
+                fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+                switch(get_instr_regcount(ins.handler_idx, i))
                 {
                 {
-                    reg_maps->texcoord_mask[reg] |= shader_get_writemask(param);
+                    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);
                 }
             }
         }
     }
                 }
             }
         }
     }
-    ++pToken;
     reg_maps->loop_depth = max_loop_depth;
 
     This->baseShader.functionLength = ((char *)pToken - (char *)byte_code);
     reg_maps->loop_depth = max_loop_depth;
 
     This->baseShader.functionLength = ((char *)pToken - (char *)byte_code);
@@ -517,389 +647,395 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static void shader_dump_decl_usage(DWORD decl, DWORD param, DWORD shader_version)
+static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
+        const struct wined3d_shader_version *shader_version)
 {
 {
-    DWORD regtype = shader_get_regtype(param);
-
     TRACE("dcl");
 
     TRACE("dcl");
 
-    if (regtype == WINED3DSPR_SAMPLER) {
-        DWORD ttype = decl & WINED3DSP_TEXTURETYPE_MASK;
-
-        switch (ttype) {
+    if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
+    {
+        switch (semantic->sampler_type)
+        {
             case WINED3DSTT_2D: TRACE("_2d"); break;
             case WINED3DSTT_CUBE: TRACE("_cube"); break;
             case WINED3DSTT_VOLUME: TRACE("_volume"); break;
             case WINED3DSTT_2D: TRACE("_2d"); break;
             case WINED3DSTT_CUBE: TRACE("_cube"); break;
             case WINED3DSTT_VOLUME: TRACE("_volume"); break;
-            default: TRACE("_unknown_ttype(0x%08x)", ttype);
-       }
-
-    } else { 
-
-        DWORD usage = decl & WINED3DSP_DCL_USAGE_MASK;
-        DWORD idx = (decl & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-
+            default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
+        }
+    }
+    else
+    {
         /* Pixel shaders 3.0 don't have usage semantics */
         /* Pixel shaders 3.0 don't have usage semantics */
-        if (shader_is_pshader_version(shader_version) && shader_version < WINED3DPS_VERSION(3,0))
+        if (shader_is_pshader_version(shader_version->type) && shader_version->major < 3)
             return;
         else
             TRACE("_");
 
             return;
         else
             TRACE("_");
 
-        switch(usage) {
-        case WINED3DDECLUSAGE_POSITION:
-            TRACE("position%d", idx);
-            break;
-        case WINED3DDECLUSAGE_BLENDINDICES:
-            TRACE("blend");
-            break;
-        case WINED3DDECLUSAGE_BLENDWEIGHT:
-            TRACE("weight");
-            break;
-        case WINED3DDECLUSAGE_NORMAL:
-            TRACE("normal%d", idx);
-            break;
-        case WINED3DDECLUSAGE_PSIZE:
-            TRACE("psize");
-            break;
-        case WINED3DDECLUSAGE_COLOR:
-            if(idx == 0)  {
-                TRACE("color");
-            } else {
-                TRACE("specular%d", (idx - 1));
-            }
-            break;
-        case WINED3DDECLUSAGE_TEXCOORD:
-            TRACE("texture%d", idx);
-            break;
-        case WINED3DDECLUSAGE_TANGENT:
-            TRACE("tangent");
-            break;
-        case WINED3DDECLUSAGE_BINORMAL:
-            TRACE("binormal");
-            break;
-        case WINED3DDECLUSAGE_TESSFACTOR:
-            TRACE("tessfactor");
-            break;
-        case WINED3DDECLUSAGE_POSITIONT:
-            TRACE("positionT%d", idx);
-            break;
-        case WINED3DDECLUSAGE_FOG:
-            TRACE("fog");
-            break;
-        case WINED3DDECLUSAGE_DEPTH:
-            TRACE("depth");
-            break;
-        case WINED3DDECLUSAGE_SAMPLE:
-            TRACE("sample");
-            break;
-        default:
-            FIXME("unknown_semantics(0x%08x)", usage);
+        switch (semantic->usage)
+        {
+            case WINED3DDECLUSAGE_POSITION:
+                TRACE("position%d", semantic->usage_idx);
+                break;
+            case WINED3DDECLUSAGE_BLENDINDICES:
+                TRACE("blend");
+                break;
+            case WINED3DDECLUSAGE_BLENDWEIGHT:
+                TRACE("weight");
+                break;
+            case WINED3DDECLUSAGE_NORMAL:
+                TRACE("normal%d", semantic->usage_idx);
+                break;
+            case WINED3DDECLUSAGE_PSIZE:
+                TRACE("psize");
+                break;
+            case WINED3DDECLUSAGE_COLOR:
+                if (semantic->usage_idx == 0) TRACE("color");
+                else TRACE("specular%d", (semantic->usage_idx - 1));
+                break;
+            case WINED3DDECLUSAGE_TEXCOORD:
+                TRACE("texture%d", semantic->usage_idx);
+                break;
+            case WINED3DDECLUSAGE_TANGENT:
+                TRACE("tangent");
+                break;
+            case WINED3DDECLUSAGE_BINORMAL:
+                TRACE("binormal");
+                break;
+            case WINED3DDECLUSAGE_TESSFACTOR:
+                TRACE("tessfactor");
+                break;
+            case WINED3DDECLUSAGE_POSITIONT:
+                TRACE("positionT%d", semantic->usage_idx);
+                break;
+            case WINED3DDECLUSAGE_FOG:
+                TRACE("fog");
+                break;
+            case WINED3DDECLUSAGE_DEPTH:
+                TRACE("depth");
+                break;
+            case WINED3DDECLUSAGE_SAMPLE:
+                TRACE("sample");
+                break;
+            default:
+                FIXME("unknown_semantics(0x%08x)", semantic->usage);
         }
     }
 }
 
         }
     }
 }
 
-static void shader_dump_arr_entry(const DWORD param, const DWORD addr_token,
-        unsigned int reg, int input, DWORD shader_version)
-{
-    char relative =
-        ((param & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE);
-
-    if (relative) {
-        TRACE("[");
-        if (addr_token)
-            shader_dump_param(addr_token, 0, input, shader_version);
-        else
-            TRACE("a0.x");
-        TRACE(" + ");
-     }
-     TRACE("%u", reg);
-     if (relative)
-         TRACE("]");
-}
-
-static void shader_dump_param(const DWORD param, const DWORD addr_token, int input, DWORD 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"};
-    const char *swizzle_reg_chars = "xyzw";
-
-    DWORD reg = param & WINED3DSP_REGNUM_MASK;
-    DWORD regtype = shader_get_regtype(param);
-    DWORD modifier = param & WINED3DSP_SRCMOD_MASK;
+    static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
+    static const char * const misctype_reg_names[] = {"vPos", "vFace"};
+    UINT offset = register_idx;
 
 
-    /* There are some minor differences between pixel and vertex shaders */
-    char pshader = shader_is_pshader_version(shader_version);
-
-    if (input) {
-        if ( (modifier == WINED3DSPSM_NEG) ||
-             (modifier == WINED3DSPSM_BIASNEG) ||
-             (modifier == WINED3DSPSM_SIGNNEG) ||
-             (modifier == WINED3DSPSM_X2NEG) ||
-             (modifier == WINED3DSPSM_ABSNEG) )
-            TRACE("-");
-        else if (modifier == WINED3DSPSM_COMP)
-            TRACE("1-");
-        else if (modifier == WINED3DSPSM_NOT)
-            TRACE("!");
-
-        if (modifier == WINED3DSPSM_ABS || modifier == WINED3DSPSM_ABSNEG) 
-            TRACE("abs(");
-    }
-
-    switch (regtype) {
+    switch (register_type)
+    {
         case WINED3DSPR_TEMP:
         case WINED3DSPR_TEMP:
-            TRACE("r%u", reg);
+            TRACE("r");
             break;
             break;
+
         case WINED3DSPR_INPUT:
             TRACE("v");
         case WINED3DSPR_INPUT:
             TRACE("v");
-            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
             break;
+
         case WINED3DSPR_CONST:
         case WINED3DSPR_CONST2:
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
         case WINED3DSPR_CONST:
         case WINED3DSPR_CONST2:
         case WINED3DSPR_CONST3:
         case WINED3DSPR_CONST4:
             TRACE("c");
-            shader_dump_arr_entry(param, addr_token, shader_get_float_offset(param), input, shader_version);
+            offset = shader_get_float_offset(register_type, register_idx);
             break;
             break;
-        case WINED3DSPR_TEXTURE: /* vs: case D3DSPR_ADDR */
-            TRACE("%c%u", (pshader? 't':'a'), reg);
-            break;        
+
+        case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
+            TRACE("%c", shader_is_pshader_version(shader_version->type) ? 't' : 'a');
+            break;
+
         case WINED3DSPR_RASTOUT:
         case WINED3DSPR_RASTOUT:
-            TRACE("%s", rastout_reg_names[reg]);
+            TRACE("%s", rastout_reg_names[register_idx]);
             break;
             break;
+
         case WINED3DSPR_COLOROUT:
         case WINED3DSPR_COLOROUT:
-            TRACE("oC%u", reg);
+            TRACE("oC");
             break;
             break;
+
         case WINED3DSPR_DEPTHOUT:
             TRACE("oDepth");
             break;
         case WINED3DSPR_DEPTHOUT:
             TRACE("oDepth");
             break;
+
         case WINED3DSPR_ATTROUT:
         case WINED3DSPR_ATTROUT:
-            TRACE("oD%u", reg);
+            TRACE("oD");
             break;
             break;
-        case WINED3DSPR_TEXCRDOUT: 
 
 
+        case WINED3DSPR_TEXCRDOUT:
             /* Vertex shaders >= 3.0 use general purpose output registers
              * (WINED3DSPR_OUTPUT), which can include an address token */
             /* Vertex shaders >= 3.0 use general purpose output registers
              * (WINED3DSPR_OUTPUT), which can include an address token */
-
-            if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) {
-                TRACE("o");
-                shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
-            }
-            else 
-               TRACE("oT%u", reg);
+            if (shader_version->major >= 3) TRACE("o");
+            else TRACE("oT");
             break;
             break;
+
         case WINED3DSPR_CONSTINT:
             TRACE("i");
         case WINED3DSPR_CONSTINT:
             TRACE("i");
-            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
             break;
+
         case WINED3DSPR_CONSTBOOL:
             TRACE("b");
         case WINED3DSPR_CONSTBOOL:
             TRACE("b");
-            shader_dump_arr_entry(param, addr_token, reg, input, shader_version);
             break;
             break;
+
         case WINED3DSPR_LABEL:
         case WINED3DSPR_LABEL:
-            TRACE("l%u", reg);
+            TRACE("l");
             break;
             break;
+
         case WINED3DSPR_LOOP:
             TRACE("aL");
             break;
         case WINED3DSPR_LOOP:
             TRACE("aL");
             break;
+
         case WINED3DSPR_SAMPLER:
         case WINED3DSPR_SAMPLER:
-            TRACE("s%u", reg);
+            TRACE("s");
             break;
             break;
+
         case WINED3DSPR_MISCTYPE:
         case WINED3DSPR_MISCTYPE:
-            if (reg > 1) {
-                FIXME("Unhandled misctype register %d\n", reg);
-            } else {
-                TRACE("%s", misctype_reg_names[reg]);
-            }
+            if (register_idx > 1) FIXME("Unhandled misctype register %d\n", register_idx);
+            else TRACE("%s", misctype_reg_names[register_idx]);
             break;
             break;
+
         case WINED3DSPR_PREDICATE:
         case WINED3DSPR_PREDICATE:
-            TRACE("p%u", reg);
+            TRACE("p");
             break;
             break;
+
+        case WINED3DSPR_IMMCONST:
+            TRACE("l");
+            break;
+
         default:
         default:
-            TRACE("unhandled_rtype(%#x)", regtype);
+            TRACE("unhandled_rtype(%#x)", register_type);
             break;
             break;
-   }
-
-   if (!input) {
-       /* operand output (for modifiers and shift, see dump_ins_modifiers) */
-
-       if ((param & WINED3DSP_WRITEMASK_ALL) != WINED3DSP_WRITEMASK_ALL) {
-           TRACE(".");
-           if (param & WINED3DSP_WRITEMASK_0) TRACE("%c", swizzle_reg_chars[0]);
-           if (param & WINED3DSP_WRITEMASK_1) TRACE("%c", swizzle_reg_chars[1]);
-           if (param & WINED3DSP_WRITEMASK_2) TRACE("%c", swizzle_reg_chars[2]);
-           if (param & WINED3DSP_WRITEMASK_3) TRACE("%c", swizzle_reg_chars[3]);
-       }
-
-   } else {
-        /** operand input */
-        DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+    }
+
+    if (register_type == WINED3DSPR_IMMCONST)
+    {
+        TRACE("(");
+        switch (immconst_type)
+        {
+            case WINED3D_IMMCONST_FLOAT:
+                TRACE("%.8e", *(float *)immconst_data);
+                break;
+
+            case WINED3D_IMMCONST_FLOAT4:
+                TRACE("%.8e, %.8e, %.8e, %.8e",
+                        *(float *)&immconst_data[0], *(float *)&immconst_data[1],
+                        *(float *)&immconst_data[2], *(float *)&immconst_data[3]);
+                break;
+
+            default:
+                TRACE("<unhandled immconst_type %#x>", immconst_type);
+                break;
+        }
+        TRACE(")");
+    }
+    else if (register_type != WINED3DSPR_RASTOUT && register_type != WINED3DSPR_MISCTYPE)
+    {
+        if (rel_addr)
+        {
+            TRACE("[");
+            shader_dump_src_param(rel_addr, shader_version);
+            TRACE(" + ");
+        }
+        TRACE("%u", offset);
+        if (rel_addr) TRACE("]");
+    }
+}
+
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+        const struct wined3d_shader_version *shader_version)
+{
+    DWORD write_mask = param->write_mask;
+
+    shader_dump_register(param->reg.type, param->reg.idx, 0, NULL, param->reg.rel_addr, shader_version);
+
+    if (write_mask != WINED3DSP_WRITEMASK_ALL)
+    {
+        static const char *write_mask_chars = "xyzw";
+
+        TRACE(".");
+        if (write_mask & WINED3DSP_WRITEMASK_0) TRACE("%c", write_mask_chars[0]);
+        if (write_mask & WINED3DSP_WRITEMASK_1) TRACE("%c", write_mask_chars[1]);
+        if (write_mask & WINED3DSP_WRITEMASK_2) TRACE("%c", write_mask_chars[2]);
+        if (write_mask & WINED3DSP_WRITEMASK_3) TRACE("%c", write_mask_chars[3]);
+    }
+}
+
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+        const struct wined3d_shader_version *shader_version)
+{
+    DWORD src_modifier = param->modifiers;
+    DWORD swizzle = param->swizzle;
+
+    if (src_modifier == WINED3DSPSM_NEG
+            || src_modifier == WINED3DSPSM_BIASNEG
+            || src_modifier == WINED3DSPSM_SIGNNEG
+            || src_modifier == WINED3DSPSM_X2NEG
+            || src_modifier == WINED3DSPSM_ABSNEG)
+        TRACE("-");
+    else if (src_modifier == WINED3DSPSM_COMP)
+        TRACE("1-");
+    else if (src_modifier == WINED3DSPSM_NOT)
+        TRACE("!");
+
+    if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
+        TRACE("abs(");
+
+    shader_dump_register(param->reg.type, param->reg.idx, param->reg.immconst_type,
+            param->reg.immconst_data, param->reg.rel_addr, shader_version);
+
+    if (src_modifier)
+    {
+        switch (src_modifier)
+        {
+            case WINED3DSPSM_NONE:    break;
+            case WINED3DSPSM_NEG:     break;
+            case WINED3DSPSM_NOT:     break;
+            case WINED3DSPSM_BIAS:    TRACE("_bias"); break;
+            case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
+            case WINED3DSPSM_SIGN:    TRACE("_bx2"); break;
+            case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
+            case WINED3DSPSM_COMP:    break;
+            case WINED3DSPSM_X2:      TRACE("_x2"); break;
+            case WINED3DSPSM_X2NEG:   TRACE("_x2"); break;
+            case WINED3DSPSM_DZ:      TRACE("_dz"); break;
+            case WINED3DSPSM_DW:      TRACE("_dw"); break;
+            case WINED3DSPSM_ABSNEG:  TRACE(")"); break;
+            case WINED3DSPSM_ABS:     TRACE(")"); break;
+            default:
+                                      TRACE("_unknown_modifier(%#x)", src_modifier);
+        }
+    }
+
+    if (swizzle != WINED3DSP_NOSWIZZLE)
+    {
+        static const char *swizzle_chars = "xyzw";
         DWORD swizzle_x = swizzle & 0x03;
         DWORD swizzle_y = (swizzle >> 2) & 0x03;
         DWORD swizzle_z = (swizzle >> 4) & 0x03;
         DWORD swizzle_w = (swizzle >> 6) & 0x03;
 
         DWORD swizzle_x = swizzle & 0x03;
         DWORD swizzle_y = (swizzle >> 2) & 0x03;
         DWORD swizzle_z = (swizzle >> 4) & 0x03;
         DWORD swizzle_w = (swizzle >> 6) & 0x03;
 
-        if (0 != modifier) {
-            switch (modifier) {
-                case WINED3DSPSM_NONE:    break;
-                case WINED3DSPSM_NEG:     break;
-                case WINED3DSPSM_NOT:     break;
-                case WINED3DSPSM_BIAS:    TRACE("_bias"); break;
-                case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
-                case WINED3DSPSM_SIGN:    TRACE("_bx2"); break;
-                case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
-                case WINED3DSPSM_COMP:    break;
-                case WINED3DSPSM_X2:      TRACE("_x2"); break;
-                case WINED3DSPSM_X2NEG:   TRACE("_x2"); break;
-                case WINED3DSPSM_DZ:      TRACE("_dz"); break;
-                case WINED3DSPSM_DW:      TRACE("_dw"); break;
-                case WINED3DSPSM_ABSNEG:  TRACE(")"); break;
-                case WINED3DSPSM_ABS:     TRACE(")"); break;
-                default:
-                    TRACE("_unknown_modifier(%#x)", modifier >> WINED3DSP_SRCMOD_SHIFT);
-            }
+        if (swizzle_x == swizzle_y
+                && swizzle_x == swizzle_z
+                && swizzle_x == swizzle_w)
+        {
+            TRACE(".%c", swizzle_chars[swizzle_x]);
         }
         }
-
-        /**
-        * swizzle bits fields:
-        *  RRGGBBAA
-        */
-        if ((WINED3DVS_NOSWIZZLE >> WINED3DVS_SWIZZLE_SHIFT) != swizzle) {
-            if (swizzle_x == swizzle_y &&
-                swizzle_x == swizzle_z &&
-                swizzle_x == swizzle_w) {
-                    TRACE(".%c", swizzle_reg_chars[swizzle_x]);
-            } else {
-                TRACE(".%c%c%c%c",
-                swizzle_reg_chars[swizzle_x],
-                swizzle_reg_chars[swizzle_y],
-                swizzle_reg_chars[swizzle_z],
-                swizzle_reg_chars[swizzle_w]);
-            }
+        else
+        {
+            TRACE(".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
+                    swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]);
         }
     }
 }
 
 /* Shared code in order to generate the bulk of the shader string.
  * NOTE: A description of how to parse tokens can be found on msdn */
         }
     }
 }
 
 /* Shared code in order to generate the bulk of the shader string.
  * NOTE: A description of how to parse tokens can be found on msdn */
-void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFERbuffer,
-        const shader_reg_maps* reg_maps, CONST DWORD* pFunction)
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+        const shader_reg_maps *reg_maps, const DWORD *pFunction)
 {
     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_OPCODE *opcode_table = This->baseShader.shader_ins;
     const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
     const SHADER_HANDLER *handler_table = device->shader_backend->shader_instruction_handler_table;
-    DWORD shader_version = reg_maps->shader_version;
+    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];
+    struct wined3d_shader_src_param src_param[4];
+    struct wined3d_shader_version shader_version;
+    struct wined3d_shader_src_param dst_rel_addr;
     struct wined3d_shader_dst_param dst_param;
     struct wined3d_shader_instruction ins;
     struct wined3d_shader_dst_param dst_param;
     struct wined3d_shader_instruction ins;
+    struct wined3d_shader_context ctx;
     const DWORD *pToken = pFunction;
     const DWORD *pToken = pFunction;
-    const SHADER_OPCODE *curOpcode;
     SHADER_HANDLER hw_fct;
     DWORD i;
 
     /* Initialize current parsing state */
     SHADER_HANDLER hw_fct;
     DWORD i;
 
     /* Initialize current parsing state */
-    ins.shader = iface;
-    ins.buffer = buffer;
-    ins.reg_maps = reg_maps;
+    ctx.shader = iface;
+    ctx.reg_maps = reg_maps;
+    ctx.buffer = buffer;
+
+    ins.ctx = &ctx;
     ins.dst = &dst_param;
     ins.dst = &dst_param;
+    ins.src = src_param;
     This->baseShader.parse_state.current_row = 0;
 
     This->baseShader.parse_state.current_row = 0;
 
-    while (WINED3DPS_END() != *pToken)
-    {
-        DWORD opcode_token;
+    fe->shader_read_header(fe_data, &pToken, &shader_version);
 
 
-        /* Skip version token */
-        if (shader_is_version_token(*pToken))
-        {
-            ++pToken;
-            continue;
-        }
+    while (!fe->shader_is_end(fe_data, &pToken))
+    {
+        const char *comment;
+        UINT param_size;
 
         /* Skip comment tokens */
 
         /* Skip comment tokens */
-        if (shader_is_comment(*pToken))
-        {
-            pToken += (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
-            ++pToken;
-            continue;
-        }
+        fe->shader_read_comment(&pToken, &comment);
+        if (comment) continue;
 
         /* Read opcode */
 
         /* Read opcode */
-        opcode_token = *pToken++;
-        curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token);
+        fe->shader_read_opcode(fe_data, &pToken, &ins, &param_size);
 
         /* Unknown opcode and its parameters */
 
         /* Unknown opcode and its parameters */
-        if (!curOpcode)
+        if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
         {
         {
-            FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
-            pToken += shader_skip_unrecognized(pToken, shader_version);
+            TRACE("Skipping unrecognized instruction.\n");
+            pToken += param_size;
             continue;
         }
 
         /* Nothing to do */
             continue;
         }
 
         /* Nothing to do */
-        if (WINED3DSIO_DCL == curOpcode->opcode
-                || WINED3DSIO_NOP == curOpcode->opcode
-                || WINED3DSIO_DEF == curOpcode->opcode
-                || WINED3DSIO_DEFI == curOpcode->opcode
-                || WINED3DSIO_DEFB == curOpcode->opcode
-                || WINED3DSIO_PHASE == curOpcode->opcode
-                || WINED3DSIO_RET == curOpcode->opcode)
+        if (ins.handler_idx == WINED3DSIH_DCL
+                || ins.handler_idx == WINED3DSIH_NOP
+                || ins.handler_idx == WINED3DSIH_DEF
+                || ins.handler_idx == WINED3DSIH_DEFI
+                || ins.handler_idx == WINED3DSIH_DEFB
+                || ins.handler_idx == WINED3DSIH_PHASE
+                || ins.handler_idx == WINED3DSIH_RET)
         {
         {
-            pToken += shader_skip_opcode(curOpcode, opcode_token, shader_version);
+            pToken += param_size;
             continue;
         }
 
         /* Select handler */
             continue;
         }
 
         /* Select handler */
-        hw_fct = handler_table[curOpcode->handler_idx];
+        hw_fct = handler_table[ins.handler_idx];
 
         /* Unhandled opcode */
         if (!hw_fct)
         {
 
         /* Unhandled opcode */
         if (!hw_fct)
         {
-            FIXME("Can't handle opcode %s in hwShader\n", curOpcode->name);
-            pToken += shader_skip_opcode(curOpcode, opcode_token, shader_version);
+            FIXME("Backend can't handle opcode %#x\n", ins.handler_idx);
+            pToken += param_size;
             continue;
         }
 
             continue;
         }
 
-        ins.handler_idx = curOpcode->handler_idx;
-        ins.flags = opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK;
-        ins.coissue = opcode_token & WINED3DSI_COISSUE;
-
         /* Destination token */
         /* Destination token */
-        ins.dst_count = curOpcode->dst_token ? 1 : 0;
-        if (ins.dst_count)
-        {
-            DWORD param, addr_param = 0;
-            pToken += shader_get_param(pToken, shader_version, &param, &addr_param);
-            shader_parse_dst_param(param, addr_param, &dst_param);
-        }
+        if (ins.dst_count) fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
 
         /* Predication token */
 
         /* Predication token */
-        if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) ins.predicate = *pToken++;
+        if (ins.predicate) ins.predicate = *pToken++;
 
         /* Other source tokens */
 
         /* Other source tokens */
-        ins.src_count = curOpcode->num_params - curOpcode->dst_token;
         for (i = 0; i < ins.src_count; ++i)
         {
         for (i = 0; i < ins.src_count; ++i)
         {
-            DWORD param, addr_token = 0;
-            pToken += shader_get_param(pToken, shader_version, &param, &addr_token);
-            ins.src[i] = param;
-            ins.src_addr[i] = addr_token;
+            fe->shader_read_src_param(fe_data, &pToken, &src_param[i], &src_rel_addr[i]);
         }
 
         /* Call appropriate function for output target */
         hw_fct(&ins);
 
         /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
         }
 
         /* Call appropriate function for output target */
         hw_fct(&ins);
 
         /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
-        /* FIXME: This should be internal to the shader backend.
-         * Also, right now this is the only reason "shader_mode" exists. */
-        if (This->baseShader.shader_mode == SHADER_GLSL) shader_glsl_add_instruction_modifiers(&ins);
+        device->shader_backend->shader_add_instruction_modifiers(&ins);
     }
 }
 
     }
 }
 
-static void shader_dump_ins_modifiers(const DWORD output)
+static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst)
 {
 {
-    DWORD shift = (output & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    DWORD mmask = output & WINED3DSP_DSTMOD_MASK;
+    DWORD mmask = dst->modifiers;
 
 
-    switch (shift) {
+    switch (dst->shift)
+    {
         case 0: break;
         case 13: TRACE("_d8"); break;
         case 14: TRACE("_d4"); break;
         case 0: break;
         case 13: TRACE("_d8"); break;
         case 14: TRACE("_d4"); break;
@@ -907,7 +1043,7 @@ static void shader_dump_ins_modifiers(const DWORD output)
         case 1: TRACE("_x2"); break;
         case 2: TRACE("_x4"); break;
         case 3: TRACE("_x8"); break;
         case 1: TRACE("_x2"); break;
         case 2: TRACE("_x4"); break;
         case 3: TRACE("_x8"); break;
-        default: TRACE("_unhandled_shift(%d)", shift); break;
+        default: TRACE("_unhandled_shift(%d)", dst->shift); break;
     }
 
     if (mmask & WINED3DSPDM_SATURATE)         TRACE("_sat");
     }
 
     if (mmask & WINED3DSPDM_SATURATE)         TRACE("_sat");
@@ -916,161 +1052,157 @@ static void shader_dump_ins_modifiers(const DWORD output)
 
     mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
     if (mmask)
 
     mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
     if (mmask)
-        FIXME("_unrecognized_modifier(%#x)", mmask >> WINED3DSP_DSTMOD_SHIFT);
+        FIXME("_unrecognized_modifier(%#x)", mmask);
 }
 
 }
 
-void shader_trace_init(const DWORD *pFunction, const SHADER_OPCODE *opcode_table)
+void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction)
 {
 {
+    struct wined3d_shader_version shader_version;
     const DWORD* pToken = pFunction;
     const DWORD* pToken = pFunction;
-    const SHADER_OPCODE* curOpcode = NULL;
-    DWORD shader_version;
-    DWORD opcode_token;
     DWORD i;
 
     TRACE("Parsing %p\n", pFunction);
 
     DWORD i;
 
     TRACE("Parsing %p\n", pFunction);
 
-    /* The version token is supposed to be the first token */
-    if (!shader_is_version_token(*pToken))
-    {
-        FIXME("First token is not a version token, invalid shader.\n");
-        return;
-    }
-    shader_version = *pToken++;
-    TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version) ? "ps": "vs",
-            WINED3DSHADER_VERSION_MAJOR(shader_version), WINED3DSHADER_VERSION_MINOR(shader_version));
+    fe->shader_read_header(fe_data, &pToken, &shader_version);
+
+    TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version.type) ? "ps": "vs",
+            shader_version.major, shader_version.minor);
 
 
-    while (WINED3DVS_END() != *pToken)
+    while (!fe->shader_is_end(fe_data, &pToken))
     {
     {
-        if (shader_is_comment(*pToken)) /* comment */
+        struct wined3d_shader_instruction ins;
+        const char *comment;
+        UINT param_size;
+
+        /* comment */
+        fe->shader_read_comment(&pToken, &comment);
+        if (comment)
         {
         {
-            DWORD comment_len = (*pToken & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
-            ++pToken;
-            TRACE("//%s\n", (const char*)pToken);
-            pToken += comment_len;
+            TRACE("//%s\n", comment);
+            continue;
+        }
+
+        fe->shader_read_opcode(fe_data, &pToken, &ins, &param_size);
+        if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+        {
+            TRACE("Skipping unrecognized instruction.\n");
+            pToken += param_size;
             continue;
         }
             continue;
         }
-        opcode_token = *pToken++;
-        curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token);
 
 
-        if (!curOpcode)
+        if (ins.handler_idx == WINED3DSIH_DCL)
         {
         {
-            int tokens_read;
-            FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
-            tokens_read = shader_skip_unrecognized(pToken, shader_version);
-            pToken += tokens_read;
+            struct wined3d_shader_semantic semantic;
+
+            fe->shader_read_semantic(&pToken, &semantic);
+
+            shader_dump_decl_usage(&semantic, &shader_version);
+            shader_dump_ins_modifiers(&semantic.reg);
+            TRACE(" ");
+            shader_dump_dst_param(&semantic.reg, &shader_version);
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEF)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
+
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+            TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(dst.reg.type, dst.reg.idx),
+                    *(const float *)(pToken),
+                    *(const float *)(pToken + 1),
+                    *(const float *)(pToken + 2),
+                    *(const float *)(pToken + 3));
+            pToken += 4;
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEFI)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
+
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+            TRACE("defi i%u = %d, %d, %d, %d", dst.reg.idx,
+                    *(pToken),
+                    *(pToken + 1),
+                    *(pToken + 2),
+                    *(pToken + 3));
+            pToken += 4;
+        }
+        else if (ins.handler_idx == WINED3DSIH_DEFB)
+        {
+            struct wined3d_shader_dst_param dst;
+            struct wined3d_shader_src_param rel_addr;
+
+            fe->shader_read_dst_param(fe_data, &pToken, &dst, &rel_addr);
+
+            TRACE("defb b%u = %s", dst.reg.idx, *pToken ? "true" : "false");
+            ++pToken;
         }
         else
         {
         }
         else
         {
-            if (curOpcode->opcode == WINED3DSIO_DCL)
-            {
-                DWORD usage = *pToken;
-                DWORD param = *(pToken + 1);
+            struct wined3d_shader_src_param dst_rel_addr, src_rel_addr;
+            struct wined3d_shader_dst_param dst_param;
+            struct wined3d_shader_src_param src_param;
 
 
-                shader_dump_decl_usage(usage, param, shader_version);
-                shader_dump_ins_modifiers(param);
-                TRACE(" ");
-                shader_dump_param(param, 0, 0, shader_version);
-                pToken += 2;
-            }
-            else if (curOpcode->opcode == WINED3DSIO_DEF)
-            {
-                unsigned int offset = shader_get_float_offset(*pToken);
-
-                TRACE("def c%u = %f, %f, %f, %f", offset,
-                        *(const float *)(pToken + 1),
-                        *(const float *)(pToken + 2),
-                        *(const float *)(pToken + 3),
-                        *(const float *)(pToken + 4));
-                pToken += 5;
-            }
-            else if (curOpcode->opcode == WINED3DSIO_DEFI)
+            if (ins.dst_count)
             {
             {
-                TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK,
-                        *(pToken + 1),
-                        *(pToken + 2),
-                        *(pToken + 3),
-                        *(pToken + 4));
-                pToken += 5;
+                fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr);
             }
             }
-            else if (curOpcode->opcode == WINED3DSIO_DEFB)
+
+            /* Print out predication source token first - it follows
+             * the destination token. */
+            if (ins.predicate)
             {
             {
-                TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK,
-                        *(pToken + 1)? "true": "false");
-                pToken += 2;
+                fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+                TRACE("(");
+                shader_dump_src_param(&src_param, &shader_version);
+                TRACE(") ");
             }
             }
-            else
-            {
-                DWORD param, addr_token;
-                int tokens_read;
 
 
-                /* Print out predication source token first - it follows
-                 * the destination token. */
-                if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
-                {
-                    TRACE("(");
-                    shader_dump_param(*(pToken + 2), 0, 1, shader_version);
-                    TRACE(") ");
-                }
-                if (opcode_token & WINED3DSI_COISSUE)
-                {
-                    /* PixWin marks instructions with the coissue flag with a '+' */
-                    TRACE("+");
-                }
+            /* PixWin marks instructions with the coissue flag with a '+' */
+            if (ins.coissue) TRACE("+");
 
 
-                TRACE("%s", curOpcode->name);
+            TRACE("%s", shader_opcode_names[ins.handler_idx]);
 
 
-                if (curOpcode->opcode == WINED3DSIO_IFC
-                        || curOpcode->opcode == WINED3DSIO_BREAKC)
-                {
-                    DWORD op = (opcode_token & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
-
-                    switch (op)
-                    {
-                        case COMPARISON_GT: TRACE("_gt"); break;
-                        case COMPARISON_EQ: TRACE("_eq"); break;
-                        case COMPARISON_GE: TRACE("_ge"); break;
-                        case COMPARISON_LT: TRACE("_lt"); break;
-                        case COMPARISON_NE: TRACE("_ne"); break;
-                        case COMPARISON_LE: TRACE("_le"); break;
-                        default: TRACE("_(%u)", op);
-                    }
-                }
-                else if (curOpcode->opcode == WINED3DSIO_TEX
-                        && shader_version >= WINED3DPS_VERSION(2,0)
-                        && (opcode_token & WINED3DSI_TEXLD_PROJECT))
-                {
-                    TRACE("p");
-                }
-
-                /* Destination token */
-                if (curOpcode->dst_token)
-                {
-                    tokens_read = shader_get_param(pToken, shader_version, &param, &addr_token);
-                    pToken += tokens_read;
-
-                    shader_dump_ins_modifiers(param);
-                    TRACE(" ");
-                    shader_dump_param(param, addr_token, 0, shader_version);
-                }
-
-                /* Predication token - already printed out, just skip it */
-                if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)
+            if (ins.handler_idx == WINED3DSIH_IFC
+                    || ins.handler_idx == WINED3DSIH_BREAKC)
+            {
+                switch (ins.flags)
                 {
                 {
-                    pToken++;
+                    case COMPARISON_GT: TRACE("_gt"); break;
+                    case COMPARISON_EQ: TRACE("_eq"); break;
+                    case COMPARISON_GE: TRACE("_ge"); break;
+                    case COMPARISON_LT: TRACE("_lt"); break;
+                    case COMPARISON_NE: TRACE("_ne"); break;
+                    case COMPARISON_LE: TRACE("_le"); break;
+                    default: TRACE("_(%u)", ins.flags);
                 }
                 }
+            }
+            else if (ins.handler_idx == WINED3DSIH_TEX
+                    && shader_version.major >= 2
+                    && (ins.flags & WINED3DSI_TEXLD_PROJECT))
+            {
+                TRACE("p");
+            }
 
 
-                /* Other source tokens */
-                for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i)
-                {
-                    tokens_read = shader_get_param(pToken, shader_version, &param, &addr_token);
-                    pToken += tokens_read;
+            /* We already read the destination token, print it. */
+            if (ins.dst_count)
+            {
+                shader_dump_ins_modifiers(&dst_param);
+                TRACE(" ");
+                shader_dump_dst_param(&dst_param, &shader_version);
+            }
 
 
-                    TRACE((i == 0)? " " : ", ");
-                    shader_dump_param(param, addr_token, 1, shader_version);
-                }
+            /* Other source tokens */
+            for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i)
+            {
+                fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
+                TRACE(!i ? " " : ", ");
+                shader_dump_src_param(&src_param, &shader_version);
             }
             }
-            TRACE("\n");
         }
         }
+        TRACE("\n");
     }
 }
 
     }
 }
 
@@ -1079,11 +1211,17 @@ void shader_cleanup(IWineD3DBaseShader *iface)
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
 
     ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
 
     ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
+    HeapFree(GetProcessHeap(), 0, This->baseShader.reg_maps.constf);
     HeapFree(GetProcessHeap(), 0, This->baseShader.function);
     shader_delete_constant_list(&This->baseShader.constantsF);
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
     list_remove(&This->baseShader.shader_list_entry);
     HeapFree(GetProcessHeap(), 0, This->baseShader.function);
     shader_delete_constant_list(&This->baseShader.constantsF);
     shader_delete_constant_list(&This->baseShader.constantsB);
     shader_delete_constant_list(&This->baseShader.constantsI);
     list_remove(&This->baseShader.shader_list_entry);
+
+    if (This->baseShader.frontend && This->baseShader.frontend_data)
+    {
+        This->baseShader.frontend->shader_free(This->baseShader.frontend_data);
+    }
 }
 
 static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
 }
 
 static const SHADER_HANDLER shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = {0};
@@ -1098,14 +1236,19 @@ 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 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) {
+static GLuint shader_none_generate_pshader(IWineD3DPixelShader *iface,
+        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
     FIXME("NONE shader backend asked to generate a pixel shader\n");
     return 0;
 }
     FIXME("NONE shader backend asked to generate a pixel shader\n");
     return 0;
 }
-static GLuint shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+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;
 }
     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)
 static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
 
 #define GLINFO_LOCATION      (*gl_info)
 static void shader_none_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *gl_info, struct shader_caps *pCaps)
@@ -1152,4 +1295,5 @@ const shader_backend_t none_shader_backend = {
     shader_none_generate_vshader,
     shader_none_get_caps,
     shader_none_color_fixup_supported,
     shader_none_generate_vshader,
     shader_none_get_caps,
     shader_none_color_fixup_supported,
+    shader_none_add_instruction_modifiers,
 };
 };
index b68dcf7..666de8e 100644 (file)
@@ -214,7 +214,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This,
 
     format = attrib->format_desc->format;
     /* Look for newly appeared conversion */
 
     format = attrib->format_desc->format;
     /* Look for newly appeared conversion */
-    if (!GL_SUPPORT(NV_HALF_FLOAT) && (format == WINED3DFMT_R16G16_FLOAT || format == WINED3DFMT_R16G16B16A16_FLOAT))
+    if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX) && (format == WINED3DFMT_R16G16_FLOAT || format == WINED3DFMT_R16G16B16A16_FLOAT))
     {
         ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run);
 
     {
         ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run);
 
@@ -327,7 +327,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
     /* Certain declaration types need some fixups before we can pass them to
      * opengl. This means D3DCOLOR attributes with fixed function vertex
      * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
     /* Certain declaration types need some fixups before we can pass them to
      * opengl. This means D3DCOLOR attributes with fixed function vertex
      * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
-     * GL_NV_half_float is not supported.
+     * GL_ARB_half_float_vertex is not supported.
      *
      * Note for d3d8 and d3d9:
      * The vertex buffer FVF doesn't help with finding them, we have to use
      *
      * Note for d3d8 and d3d9:
      * The vertex buffer FVF doesn't help with finding them, we have to use
@@ -590,7 +590,8 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface)
 
 const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
 {
 
 const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
 {
-    if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) 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;
 
     This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
     This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
 
     This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
     This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
@@ -951,12 +952,18 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
     {
         if(count == 1)
         {
     {
         if(count == 1)
         {
+            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
             if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
             {
                 IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
             }
             if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
             {
                 IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
             }
+
+            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));
             GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
             This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
+            LEAVE_GL();
         }
     }
     else
         }
     }
     else
@@ -987,12 +994,19 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
 
     if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
     {
 
     if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
     {
+        IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
         if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
         {
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
         if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
         {
             IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
         }
+
+        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));
         GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+        LEAVE_GL();
+
         This->resource.allocatedMemory = NULL;
     }
     else if (This->flags & WINED3D_BUFFER_HASDESC)
         This->resource.allocatedMemory = NULL;
     }
     else if (This->flags & WINED3D_BUFFER_HASDESC)
index a510d2e..2c6703f 100644 (file)
@@ -895,12 +895,10 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
         }
     }
 
         }
     }
 
-    if(GL_SUPPORT(ARB_POINT_SPRITE)) {
-        for(s = 0; s < GL_LIMITS(textures); s++) {
-            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
-            glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
-            checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
-        }
+    for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
+        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
+        glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
+        checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
     }
     LEAVE_GL();
 
     }
     LEAVE_GL();
 
index 1099872..ec6d3f0 100644 (file)
@@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
             {
                 WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
                 buffer_object = 0;
             {
                 WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
                 buffer_object = 0;
-                data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot])->resource.allocatedMemory;
+                data = buffer_get_sysmem((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot]);
                 if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride)
                 {
                     FIXME("System memory vertex data load offset is negative!\n");
                 if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride)
                 {
                     FIXME("System memory vertex data load offset is negative!\n");
@@ -503,7 +503,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage,
-        DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent)
+        DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     /* Dummy format for now */
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     /* Dummy format for now */
@@ -582,9 +582,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage,
-                                                    WINED3DPOOL Pool, IWineD3DBuffer** ppIndexBuffer,
-                                                    HANDLE *sharedHandle, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface,
+        UINT Length, DWORD Usage, WINED3DPOOL Pool, IWineD3DBuffer **ppIndexBuffer, IUnknown *parent)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
     struct wined3d_buffer *object;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
     struct wined3d_buffer *object;
@@ -897,8 +897,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
     return WINED3D_OK;
 }
 
     return WINED3D_OK;
 }
 
-static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UINT Width, UINT Height, WINED3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IWineD3DSurface **ppSurface,WINED3DRESOURCETYPE Type, DWORD Usage, WINED3DPOOL Pool, WINED3DMULTISAMPLE_TYPE MultiSample ,DWORD MultisampleQuality, HANDLE* pSharedHandle, WINED3DSURFTYPE Impl, IUnknown *parent) {
-    IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;    
+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;
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
     unsigned int Size       = 1;
     const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
     unsigned int Size       = 1;
     const struct GlPixelFormatDesc *glDesc = getFormatDescEntry(Format, &GLINFO_LOCATION);
@@ -1085,8 +1089,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice *
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
-        UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
-        IWineD3DTexture **ppTexture, HANDLE *pSharedHandle, IUnknown *parent)
+        UINT Width, UINT Height, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+        WINED3DPOOL Pool, IWineD3DTexture **ppTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
@@ -1099,8 +1103,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
     unsigned int pow2Height;
 
     TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#x\n", This, Width, Height, Levels, Usage);
     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, pSharedHandle %p, parent %p\n",
-            Format, debug_d3dformat(Format), Pool, ppTexture, pSharedHandle, parent);
+    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 */
 
     /* TODO: It should only be possible to create textures for formats
              that are reported as supported */
@@ -1269,8 +1273,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface,
-        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
-        IWineD3DVolumeTexture **ppVolumeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+        UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+        WINED3DPOOL Pool, IWineD3DVolumeTexture **ppVolumeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
 {
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
@@ -1391,12 +1395,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
-                                               UINT Width, UINT Height, UINT Depth,
-                                               DWORD Usage,
-                                               WINED3DFORMAT Format, WINED3DPOOL Pool,
-                                               IWineD3DVolume** ppVolume,
-                                               HANDLE* pSharedHandle, IUnknown *parent) {
-
+        UINT Width, UINT Height, UINT Depth, DWORD Usage, WINED3DFORMAT Format,
+        WINED3DPOOL Pool, IWineD3DVolume **ppVolume, IUnknown *parent)
+{
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeImpl        *object; /** NOTE: impl ref allowed since this is a create function **/
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &GLINFO_LOCATION);
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeImpl        *object; /** NOTE: impl ref allowed since this is a create function **/
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &GLINFO_LOCATION);
@@ -1451,8 +1452,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface,
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface,
-        UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format, WINED3DPOOL Pool,
-        IWineD3DCubeTexture **ppCubeTexture, HANDLE *pSharedHandle, IUnknown *parent)
+        UINT EdgeLength, UINT Levels, DWORD Usage, WINED3DFORMAT Format,
+        WINED3DPOOL Pool, IWineD3DCubeTexture **ppCubeTexture, IUnknown *parent)
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
 {
     IWineD3DDeviceImpl      *This = (IWineD3DDeviceImpl *)iface;
     const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
@@ -2343,7 +2344,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
 
     object->lpVtbl = &IWineD3DVertexShader_Vtbl;
     object->parent = parent;
 
     object->lpVtbl = &IWineD3DVertexShader_Vtbl;
     object->parent = parent;
-    shader_init(&object->baseShader, iface, IWineD3DVertexShaderImpl_shader_ins);
+    shader_init(&object->baseShader, iface);
     list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
     *ppVertexShader = (IWineD3DVertexShader *)object;
 
     list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
     *ppVertexShader = (IWineD3DVertexShader *)object;
 
@@ -2353,7 +2354,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
         IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
     }
 
         IWineD3DVertexShader_FakeSemantics(*ppVertexShader, vertex_declaration);
     }
 
-    hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
+    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);
@@ -2365,7 +2366,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
     return hr;
 }
 
     return hr;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DPixelShader **ppPixelShader, IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface,
+        const DWORD *pFunction, const struct wined3d_shader_signature *output_signature,
+        IWineD3DPixelShader **ppPixelShader, IUnknown *parent)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
@@ -2382,13 +2386,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface
 
     object->lpVtbl = &IWineD3DPixelShader_Vtbl;
     object->parent = parent;
 
     object->lpVtbl = &IWineD3DPixelShader_Vtbl;
     object->parent = parent;
-    shader_init(&object->baseShader, iface, IWineD3DPixelShaderImpl_shader_ins);
+    shader_init(&object->baseShader, iface);
     list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
     *ppPixelShader = (IWineD3DPixelShader *)object;
 
     TRACE("(%p) : Created pixel shader %p\n", This, *ppPixelShader);
 
     list_add_head(&This->shaders, &object->baseShader.shader_list_entry);
     *ppPixelShader = (IWineD3DPixelShader *)object;
 
     TRACE("(%p) : Created pixel shader %p\n", This, *ppPixelShader);
 
-    hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);
+    hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction, output_signature);
     if (FAILED(hr))
     {
         WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
     if (FAILED(hr))
     {
         WARN("(%p) : Failed to set function, returning %#x\n", iface, hr);
@@ -2466,7 +2470,7 @@ static void IWineD3DDeviceImpl_LoadLogo(IWineD3DDeviceImpl *This, const char *fi
 
     hr = IWineD3DDevice_CreateSurface((IWineD3DDevice *) This, bm.bmWidth, bm.bmHeight, WINED3DFMT_R5G6B5,
                                       TRUE, FALSE, 0, &This->logo_surface, WINED3DRTYPE_SURFACE, 0,
 
     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, NULL, SURFACE_OPENGL, NULL);
+                                      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;
@@ -4207,12 +4211,13 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
 }
 
 static void device_map_psamplers(IWineD3DDeviceImpl *This) {
 }
 
 static void device_map_psamplers(IWineD3DDeviceImpl *This) {
-    const DWORD *sampler_tokens =
-            ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.samplers;
+    const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type =
+            ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type;
     unsigned int i;
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
     unsigned int i;
 
     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
-        if (sampler_tokens[i] && This->texUnitMap[i] != i) {
+        if (sampler_type[i] && This->texUnitMap[i] != i)
+        {
             device_map_stage(This, i, i);
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
             if (i < MAX_TEXTURES) {
             device_map_stage(This, i, i);
             IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
             if (i < MAX_TEXTURES) {
@@ -4249,9 +4254,9 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshad
 }
 
 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
 }
 
 static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
-    const DWORD *vshader_sampler_tokens =
-            ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.samplers;
-    const DWORD *pshader_sampler_tokens = NULL;
+    const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
+            ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
+    const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
     int start = GL_LIMITS(combined_samplers) - 1;
     int i;
 
     int start = GL_LIMITS(combined_samplers) - 1;
     int i;
 
@@ -4260,12 +4265,13 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
 
         /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
          * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
 
         /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
          * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
-        pshader_sampler_tokens = pshader->baseShader.reg_maps.samplers;
+        pshader_sampler_type = pshader->baseShader.reg_maps.sampler_type;
     }
 
     for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
         int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
     }
 
     for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
         int vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
-        if (vshader_sampler_tokens[i]) {
+        if (vshader_sampler_type[i])
+        {
             if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
             {
                 /* Already mapped somewhere */
             if (This->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
             {
                 /* Already mapped somewhere */
@@ -4273,7 +4279,8 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
             }
 
             while (start >= 0) {
             }
 
             while (start >= 0) {
-                if (device_unit_free_for_vs(This, pshader_sampler_tokens, vshader_sampler_tokens, start)) {
+                if (device_unit_free_for_vs(This, pshader_sampler_type, vshader_sampler_type, start))
+                {
                     device_map_stage(This, vsampler_idx, start);
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(vsampler_idx));
 
                     device_map_stage(This, vsampler_idx, start);
                     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(vsampler_idx));
 
@@ -4530,27 +4537,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
     ENTER_GL();
 
     if (dest->resource.allocatedMemory == NULL) {
     ENTER_GL();
 
     if (dest->resource.allocatedMemory == NULL) {
-        /* This may happen if we do direct locking into a vbo. Unlikely,
-         * but theoretically possible(ddraw processvertices test)
-         */
-        dest->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), 0, dest->resource.size);
-        if(!dest->resource.allocatedMemory) {
-            LEAVE_GL();
-            ERR("Out of memory\n");
-            return E_OUTOFMEMORY;
-        }
-        if (dest->buffer_object)
-        {
-            const void *src;
-            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object));
-            checkGLcall("glBindBufferARB");
-            src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB));
-            if(src) {
-                memcpy(dest->resource.allocatedMemory, src, dest->resource.size);
-            }
-            GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB));
-            checkGLcall("glUnmapBufferARB");
-        }
+        buffer_get_sysmem(dest);
     }
 
     /* Get a pointer into the destination vbo(create one if none exists) and
     }
 
     /* Get a pointer into the destination vbo(create one if none exists) and
@@ -7611,8 +7598,25 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         ERR("Cannot change the device window yet\n");
     }
     if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) {
         ERR("Cannot change the device window yet\n");
     }
     if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) {
-        WARN("Auto depth stencil enabled, but no auto depth stencil present, returning WINED3DERR_INVALIDCALL\n");
-        return WINED3DERR_INVALIDCALL;
+        HRESULT hrc;
+
+        TRACE("Creating the depth stencil buffer\n");
+
+        hrc = IWineD3DDeviceParent_CreateDepthStencilSurface(This->device_parent,
+                This->parent,
+                pPresentationParameters->BackBufferWidth,
+                pPresentationParameters->BackBufferHeight,
+                pPresentationParameters->AutoDepthStencilFormat,
+                pPresentationParameters->MultiSampleType,
+                pPresentationParameters->MultiSampleQuality,
+                FALSE,
+                &This->auto_depth_stencil_buffer);
+
+        if (FAILED(hrc)) {
+            ERR("Failed to create the depth stencil buffer\n");
+            IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
+            return WINED3DERR_INVALIDCALL;
+        }
     }
 
     /* Reset the depth stencil */
     }
 
     /* Reset the depth stencil */
index 7c6cc3b..9a064bb 100644 (file)
@@ -91,6 +91,8 @@ static const struct {
     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
+    {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD,         0                           },
+    {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX,          0                           },
 
     /* EXT */
     {"GL_EXT_blend_color",                  EXT_BLEND_COLOR,                0                           },
 
     /* EXT */
     {"GL_EXT_blend_color",                  EXT_BLEND_COLOR,                0                           },
@@ -232,8 +234,7 @@ static void WineD3D_ReleaseFakeGLContext(void) {
         if(!wined3d_fake_gl_context_foreign && glCtx) {
             TRACE_(d3d_caps)("destroying fake GL context\n");
             pwglMakeCurrent(NULL, NULL);
         if(!wined3d_fake_gl_context_foreign && glCtx) {
             TRACE_(d3d_caps)("destroying fake GL context\n");
             pwglMakeCurrent(NULL, NULL);
-            //ros hack, this line does destire the real icd interface in windows and reactos
-            // pwglDeleteContext(glCtx);
+            //pwglDeleteContext(glCtx);
         }
         if(wined3d_fake_gl_context_hdc)
             ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
         }
         if(wined3d_fake_gl_context_hdc)
             ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
@@ -1009,7 +1010,15 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
             gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
             gl_info->supported[NV_TEXTURE_SHADER3] = 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\n");
 
     }
     checkGLcall("extension detection\n");
 
@@ -2392,6 +2401,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
 
             /* Floating point formats */
         case WINED3DFMT_R16_FLOAT:
 
             /* Floating point formats */
         case WINED3DFMT_R16_FLOAT:
+        case WINED3DFMT_R16G16_FLOAT:
         case WINED3DFMT_R16G16B16A16_FLOAT:
             if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
                 TRACE_(d3d_caps)("[OK]\n");
         case WINED3DFMT_R16G16B16A16_FLOAT:
             if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
                 TRACE_(d3d_caps)("[OK]\n");
@@ -2401,6 +2411,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
             return FALSE;
 
         case WINED3DFMT_R32_FLOAT:
             return FALSE;
 
         case WINED3DFMT_R32_FLOAT:
+        case WINED3DFMT_R32G32_FLOAT:
         case WINED3DFMT_R32G32B32A32_FLOAT:
             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
                 TRACE_(d3d_caps)("[OK]\n");
         case WINED3DFMT_R32G32B32A32_FLOAT:
             if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
                 TRACE_(d3d_caps)("[OK]\n");
@@ -2409,15 +2420,6 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
             TRACE_(d3d_caps)("[FAILED]\n");
             return FALSE;
 
             TRACE_(d3d_caps)("[FAILED]\n");
             return FALSE;
 
-        case WINED3DFMT_R16G16_FLOAT:
-        case WINED3DFMT_R32G32_FLOAT:
-            if(GL_SUPPORT(ARB_TEXTURE_RG)) {
-                TRACE_(d3d_caps)("[OK]\n");
-                return TRUE;
-            }
-            TRACE_(d3d_caps)("[FAILED]\n");
-            return FALSE;
-
         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
@@ -3636,7 +3638,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
                            WINED3DDTCAPS_UBYTE4N   |
                            WINED3DDTCAPS_SHORT2N   |
                            WINED3DDTCAPS_SHORT4N;
                            WINED3DDTCAPS_UBYTE4N   |
                            WINED3DDTCAPS_SHORT2N   |
                            WINED3DDTCAPS_SHORT4N;
-        if (GL_SUPPORT(NV_HALF_FLOAT)) {
+        if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) {
             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
                                 WINED3DDTCAPS_FLOAT16_4;
         }
             pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
                                 WINED3DDTCAPS_FLOAT16_4;
         }
@@ -3851,7 +3853,7 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) {
     return IUnknown_Release(volumeParent);
 }
 
     return IUnknown_Release(volumeParent);
 }
 
-static BOOL implementation_is_apple(const WineD3D_GL_Info *gl_info)
+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
 {
     /* 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
@@ -3908,6 +3910,8 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
     while(glGetError());
     glGenTextures(1, &texture);
     glBindTexture(GL_TEXTURE_2D, texture);
     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");
 
     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");
 
@@ -4003,46 +4007,80 @@ static const struct driver_version_information driver_version_table[] = {
     /* TODO: Add information about legacy ATI hardware, Intel and other cards */
 };
 
     /* TODO: Add information about legacy ATI hardware, Intel and other cards */
 };
 
-static void fixup_extensions(WineD3D_GL_Info *gl_info) {
-    unsigned int i;
-    BOOL apple = implementation_is_apple(gl_info);
+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;
+}
 
 
-    if(apple) {
-        /* 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
-         */
-        if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
-            FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
-        } else {
-            TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
-                  gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
-            gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+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;
+}
 
 
-        /* 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.
-         */
-        if(gl_info->gl_vendor == VENDOR_INTEL ||
-           (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
-            TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
-            gl_info->set_texcoord_w = TRUE;
-        }
+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).
 
     /* 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).
@@ -4056,16 +4094,18 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
      * 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.
      */
      * 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] && gl_info->gl_vendor == VENDOR_ATI) {
-        if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
-            gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500  ||
-            gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
-            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;
-        }
-    }
+    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
     /*  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
@@ -4081,12 +4121,77 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
      *  post-processing effects in the game "Max Payne 2").
      *  The behaviour can be verified through a simple test app attached in bugreport #14724.
      */
      *  post-processing effects in the game "Max Payne 2").
      *  The behaviour can be verified through a simple test app attached in bugreport #14724.
      */
-    if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_NVIDIA) {
-        if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
-            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;
-        }
+    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 */
     }
 
     /* Find out if PBOs work as they are supposed to */
@@ -4276,6 +4381,7 @@ static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
     multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N]     = invalid_texcoord_func;
     if (GL_SUPPORT(NV_HALF_FLOAT))
     {
     multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N]     = invalid_texcoord_func;
     if (GL_SUPPORT(NV_HALF_FLOAT))
     {
+        /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
     } else {
         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
     } else {
index c96b975..68821b4 100644 (file)
@@ -370,6 +370,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format
              * byte float according to the IEEE standard
              */
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
              * byte float according to the IEEE standard
              */
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
+                /* Not supported by GL_ARB_half_float_vertex */
                 GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
@@ -379,6 +380,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format
             break;
         case WINED3DFMT_R16G16B16A16_FLOAT:
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
             break;
         case WINED3DFMT_R16G16B16A16_FLOAT:
             if (GL_SUPPORT(NV_HALF_FLOAT)) {
+                /* Not supported by GL_ARB_half_float_vertex */
                 GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
                 GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
             } else {
                 float x = float_16_to_32(((const unsigned short *)ptr) + 0);
index 61c5701..ca50305 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2006 Jason Green 
  * Copyright 2006-2007 Henri Verbeet
  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
  * Copyright 2006 Jason Green 
  * Copyright 2006-2007 Henri Verbeet
  * 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
@@ -43,6 +44,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 #define WINED3D_GLSL_SAMPLE_PROJECTED   0x1
 #define WINED3D_GLSL_SAMPLE_RECT        0x2
 #define WINED3D_GLSL_SAMPLE_LOD         0x4
 #define WINED3D_GLSL_SAMPLE_PROJECTED   0x1
 #define WINED3D_GLSL_SAMPLE_RECT        0x2
 #define WINED3D_GLSL_SAMPLE_LOD         0x4
+#define WINED3D_GLSL_SAMPLE_GRAD        0x8
 
 typedef struct {
     char reg_name[150];
 
 typedef struct {
     char reg_name[150];
@@ -51,7 +53,7 @@ typedef struct {
 
 typedef struct {
     char reg_name[150];
 
 typedef struct {
     char reg_name[150];
-    char param_str[100];
+    char param_str[200];
 } glsl_src_param_t;
 
 typedef struct {
 } glsl_src_param_t;
 
 typedef struct {
@@ -367,8 +369,8 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const Wine
     const local_constant *lconst;
 
     /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
     const local_constant *lconst;
 
     /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
-    if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.reg_maps.shader_version) == 1
-            && shader_is_pshader_version(This->baseShader.reg_maps.shader_version))
+    if (This->baseShader.reg_maps.shader_version.major == 1
+            && shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type))
         walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
     else
         walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
         walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
     else
         walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
@@ -432,7 +434,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine
     GLint tmp_loc;
     unsigned int i;
     char tmp_name[8];
     GLint tmp_loc;
     unsigned int i;
     char tmp_name[8];
-    char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
+    char is_pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
     const char* prefix = is_pshader? "PB":"VB";
     struct list* ptr;
 
     const char* prefix = is_pshader? "PB":"VB";
     struct list* ptr;
 
@@ -513,7 +515,7 @@ static void shader_glsl_load_np2fixup_constants(
             if (-1 != prog->np2Fixup_location[i]) {
                 const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
                 if (!tex) {
             if (-1 != prog->np2Fixup_location[i]) {
                 const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
                 if (!tex) {
-                    FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n");
+                    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]};
                     continue;
                 } else {
                     const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
@@ -557,16 +559,12 @@ static void shader_glsl_load_constants(
                 prog->vuniformF_locations, &priv->vconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
                 prog->vuniformF_locations, &priv->vconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
-        if(vshader->baseShader.uses_int_consts) {
-            shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations,
-                    stateBlock->vertexShaderConstantI, stateBlock->changed.vertexShaderConstantsI);
-        }
+        shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, stateBlock->vertexShaderConstantI,
+                stateBlock->changed.vertexShaderConstantsI & vshader->baseShader.reg_maps.integer_constants);
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
-        if(vshader->baseShader.uses_bool_consts) {
-            shader_glsl_load_constantsB(vshader, gl_info, programId,
-                    stateBlock->vertexShaderConstantB, stateBlock->changed.vertexShaderConstantsB);
-        }
+        shader_glsl_load_constantsB(vshader, gl_info, programId, stateBlock->vertexShaderConstantB,
+                stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants);
 
         /* Upload the position fixup params */
         GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
 
         /* Upload the position fixup params */
         GL_EXTCALL(glUniform4fvARB(prog->posFixup_location, 1, &deviceImpl->posFixup[0]));
@@ -582,16 +580,12 @@ static void shader_glsl_load_constants(
                 prog->puniformF_locations, &priv->pconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
                 prog->puniformF_locations, &priv->pconst_heap, priv->stack, constant_version);
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
-        if(pshader->baseShader.uses_int_consts) {
-            shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations,
-                    stateBlock->pixelShaderConstantI, stateBlock->changed.pixelShaderConstantsI);
-        }
+        shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, stateBlock->pixelShaderConstantI,
+                stateBlock->changed.pixelShaderConstantsI & pshader->baseShader.reg_maps.integer_constants);
 
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
 
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
-        if(pshader->baseShader.uses_bool_consts) {
-            shader_glsl_load_constantsB(pshader, gl_info, programId,
-                    stateBlock->pixelShaderConstantB, stateBlock->changed.pixelShaderConstantsB);
-        }
+        shader_glsl_load_constantsB(pshader, gl_info, programId, stateBlock->pixelShaderConstantB,
+                stateBlock->changed.pixelShaderConstantsB & pshader->baseShader.reg_maps.boolean_constants);
 
         /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
          * It can't be 0 for a valid texbem instruction.
 
         /* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
          * It can't be 0 for a valid texbem instruction.
@@ -706,12 +700,11 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->baseShader.device;
-    DWORD shader_version = reg_maps->shader_version;
     unsigned int i, extra_constants_needed = 0;
     const local_constant *lconst;
 
     /* There are some minor differences between pixel and vertex shaders */
     unsigned int i, extra_constants_needed = 0;
     const local_constant *lconst;
 
     /* There are some minor differences between pixel and vertex shaders */
-    char pshader = shader_is_pshader_version(shader_version);
+    char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
     char prefix = pshader ? 'P' : 'V';
 
     /* Prototype the subroutines */
@@ -723,21 +716,53 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
     /* Declare the constants (aka uniforms) */
     if (This->baseShader.limits.constant_float > 0) {
         unsigned max_constantsF;
     /* Declare the constants (aka uniforms) */
     if (This->baseShader.limits.constant_float > 0) {
         unsigned max_constantsF;
+        /* Unless the shader uses indirect addressing, always declare the maximum array size and ignore that we need some
+         * uniforms privately. E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup and immediate values, still
+         * declare VC[256]. If the shader needs more uniforms than we have it won't work in any case. If it uses less, the
+         * compiler will figure out which uniforms are really used and strip them out. This allows a shader to use c255 on
+         * a dx9 card, as long as it doesn't also use all the other constants.
+         *
+         * If the shader uses indirect addressing the compiler must assume that all declared uniforms are used. In this case,
+         * declare only the amount that we're assured to have.
+         *
+         * Thus we run into problems in these two cases:
+         * 1) The shader really uses more uniforms than supported
+         * 2) The shader uses indirect addressing, less constants than supported, but uses a constant index > #supported consts
+         */
         if(pshader) {
         if(pshader) {
-            max_constantsF = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
-            max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+            /* No indirect addressing here */
+            max_constantsF = GL_LIMITS(pshader_constantsF);
         } else {
         } else {
-            /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
-            max_constantsF = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
-            max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+            if(This->baseShader.reg_maps.usesrelconstF) {
+                /* 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
+                 */
+                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
+                 * for now take this into account when calculating the number of available constants
+                 */
+                max_constantsF -= count_bits(This->baseShader.reg_maps.boolean_constants);
+                /* Set by driver quirks in directx.c */
+                max_constantsF -= GLINFO_LOCATION.reserved_glsl_constants;
+            } else {
+                max_constantsF = GL_LIMITS(vshader_constantsF);
+            }
         }
         }
+        max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
         shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
     }
 
         shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
     }
 
-    if (This->baseShader.limits.constant_int > 0)
+    /* Always declare the full set of constants, the compiler can remove the unused ones because d3d doesn't(yet)
+     * support indirect int and bool constant addressing. This avoids problems if the app uses e.g. i0 and i9.
+     */
+    if (This->baseShader.limits.constant_int > 0 && This->baseShader.reg_maps.integer_constants)
         shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
 
         shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
 
-    if (This->baseShader.limits.constant_bool > 0)
+    if (This->baseShader.limits.constant_bool > 0 && This->baseShader.reg_maps.boolean_constants)
         shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
 
     if(!pshader) {
         shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
 
     if(!pshader) {
@@ -752,7 +777,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
          * out. The nvidia driver only does that if the parameter is inout instead of out, hence the
          * inout.
          */
          * out. The nvidia driver only does that if the parameter is inout instead of out, hence the
          * inout.
          */
-        if (shader_version >= WINED3DVS_VERSION(3, 0))
+        if (reg_maps->shader_version.major >= 3)
         {
             shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
         } else {
         {
             shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", MAX_REG_OUTPUT);
         } else {
@@ -809,11 +834,10 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
 
     /* Declare texture samplers */ 
     for (i = 0; i < This->baseShader.limits.sampler; i++) {
 
     /* Declare texture samplers */ 
     for (i = 0; i < This->baseShader.limits.sampler; i++) {
-        if (reg_maps->samplers[i]) {
-
-            DWORD stype = reg_maps->samplers[i] & WINED3DSP_TEXTURETYPE_MASK;
-            switch (stype) {
-
+        if (reg_maps->sampler_type[i])
+        {
+            switch (reg_maps->sampler_type[i])
+            {
                 case WINED3DSTT_1D:
                     shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i);
                     break;
                 case WINED3DSTT_1D:
                     shader_addline(buffer, "uniform sampler1D %csampler%u;\n", prefix, i);
                     break;
@@ -825,7 +849,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
 
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
 
-                    if(ps_args->np2_fixup & (1 << 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
                         /* 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
@@ -841,7 +866,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                     break;
                 default:
                     shader_addline(buffer, "uniform unsupported_sampler %csampler%u;\n", prefix, i);
                     break;
                 default:
                     shader_addline(buffer, "uniform unsupported_sampler %csampler%u;\n", prefix, i);
-                    FIXME("Unrecognized sampler type: %#x\n", stype);
+                    FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]);
                     break;
             }
         }
                     break;
             }
         }
@@ -862,7 +887,7 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
      * helper function shader that is linked in at link time
      */
     /* Declare input register varyings. Only pixel shader, vertex shaders have that declared in the
      * helper function shader that is linked in at link time
      */
-    if (pshader && shader_version >= WINED3DPS_VERSION(3, 0))
+    if (pshader && reg_maps->shader_version.major >= 3)
     {
         if (use_vs(device->stateBlock))
         {
     {
         if (use_vs(device->stateBlock))
         {
@@ -941,8 +966,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
  ****************************************************************************/
 
 /* Prototypes */
  ****************************************************************************/
 
 /* Prototypes */
-static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins, const DWORD param,
-        const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param);
+static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
+        const struct wined3d_shader_src_param *wined3d_src, DWORD mask, glsl_src_param_t *glsl_src);
 
 /** 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[] = {
@@ -965,15 +990,12 @@ static const char * const shift_glsl_tab[] = {
 };
 
 /* 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 */
-static void shader_glsl_gen_modifier (
-    const DWORD instr,
-    const char *in_reg,
-    const char *in_regswizzle,
-    char *out_str) {
-
+static void shader_glsl_gen_modifier(DWORD src_modifier, const char *in_reg, const char *in_regswizzle, char *out_str)
+{
     out_str[0] = 0;
 
     out_str[0] = 0;
 
-    switch (instr & WINED3DSP_SRCMOD_MASK) {
+    switch (src_modifier)
+    {
     case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
     case WINED3DSPSM_DW:
     case WINED3DSPSM_NONE:
     case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
     case WINED3DSPSM_DW:
     case WINED3DSPSM_NONE:
@@ -1013,207 +1035,214 @@ static void shader_glsl_gen_modifier (
         sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
         break;
     default:
         sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
         break;
     default:
-        FIXME("Unhandled modifier %u\n", (instr & WINED3DSP_SRCMOD_MASK));
+        FIXME("Unhandled modifier %u\n", src_modifier);
         sprintf(out_str, "%s%s", in_reg, in_regswizzle);
     }
 }
 
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
         sprintf(out_str, "%s%s", in_reg, in_regswizzle);
     }
 }
 
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
-static void shader_glsl_get_register_name(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx,
-        BOOL rel_addr, const DWORD addr_token, char *register_name, BOOL *is_color,
-        const struct wined3d_shader_instruction *ins)
+static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
+        char *register_name, BOOL *is_color, const struct wined3d_shader_instruction *ins)
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
 
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
 
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
-    DWORD shader_version = This->baseShader.reg_maps.shader_version;
-    char pshader = shader_is_pshader_version(shader_version);
+    char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     *is_color = FALSE;
 
 
     *is_color = FALSE;
 
-    switch (register_type)
+    switch (reg->type)
     {
     {
-    case WINED3DSPR_TEMP:
-        sprintf(register_name, "R%u", register_idx);
-    break;
-    case WINED3DSPR_INPUT:
-        if (pshader) {
-            /* Pixel shaders >= 3.0 */
-            if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3)
+        case WINED3DSPR_TEMP:
+            sprintf(register_name, "R%u", reg->idx);
+            break;
+
+        case WINED3DSPR_INPUT:
+            /* vertex shaders */
+            if (!pshader)
+            {
+                if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg->idx)) *is_color = TRUE;
+                sprintf(register_name, "attrib%u", reg->idx);
+                break;
+            }
+
+            /* pixel shaders >= 3.0 */
+            if (This->baseShader.reg_maps.shader_version.major >= 3)
             {
             {
+                DWORD idx = ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg->idx];
                 DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
                 DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
-                if (rel_addr)
+                if (reg->rel_addr)
                 {
                     glsl_src_param_t rel_param;
                 {
                     glsl_src_param_t rel_param;
-                    shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
+
+                    shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
 
                     /* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP
 
                     /* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP
-                     * operation there
-                     */
-                    if (((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx])
+                     * operation there */
+                    if (idx)
                     {
                     {
-                        if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
-                            sprintf(register_name, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count - 1,
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count,
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
-                        } else {
-                            sprintf(register_name, "IN[%s + %u]", rel_param.param_str,
-                                    ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
+                        if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count)
+                        {
+                            sprintf(register_name,
+                                    "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
+                                    rel_param.param_str, idx, in_count - 1, rel_param.param_str, idx, in_count,
+                                    rel_param.param_str, idx);
                         }
                         }
-                    } else {
-                        if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
+                        else
+                        {
+                            sprintf(register_name, "IN[%s + %u]", rel_param.param_str, idx);
+                        }
+                    }
+                    else
+                    {
+                        if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count)
+                        {
                             sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
                             sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
-                                    rel_param.param_str, in_count - 1,
-                                    rel_param.param_str, in_count,
+                                    rel_param.param_str, in_count - 1, rel_param.param_str, in_count,
                                     rel_param.param_str);
                                     rel_param.param_str);
-                        } else {
+                        }
+                        else
+                        {
                             sprintf(register_name, "IN[%s]", rel_param.param_str);
                         }
                     }
                             sprintf(register_name, "IN[%s]", rel_param.param_str);
                         }
                     }
-                } else {
-                    DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[register_idx];
-                    if (idx == in_count) {
-                        sprintf(register_name, "gl_Color");
-                    } else if (idx == in_count + 1) {
-                        sprintf(register_name, "gl_SecondaryColor");
-                    } else {
-                        sprintf(register_name, "IN[%u]", idx);
-                    }
                 }
                 }
-            } else {
-                if (register_idx == 0)
-                    strcpy(register_name, "gl_Color");
                 else
                 else
-                    strcpy(register_name, "gl_SecondaryColor");
+                {
+                    if (idx == in_count) sprintf(register_name, "gl_Color");
+                    else if (idx == in_count + 1) sprintf(register_name, "gl_SecondaryColor");
+                    else sprintf(register_name, "IN[%u]", idx);
+                }
             }
             }
-        } else {
-            if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
-            sprintf(register_name, "attrib%u", register_idx);
-        }
-        break;
-    case WINED3DSPR_CONST:
-    {
-        const char prefix = pshader? 'P':'V';
+            else
+            {
+                if (reg->idx == 0) strcpy(register_name, "gl_Color");
+                else strcpy(register_name, "gl_SecondaryColor");
+                break;
+            }
+            break;
 
 
-        /* Relative addressing */
-        if (rel_addr)
-        {
-           /* Relative addressing on shaders 2.0+ have a relative address token, 
-            * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
-           if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
-           {
-               glsl_src_param_t rel_param;
-               shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
-               if (register_idx)
-               {
-                   sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, register_idx);
-               } else {
-                   sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str);
-               }
-           } else {
-               if (register_idx)
-               {
-                   sprintf(register_name, "%cC[A0.x + %u]", prefix, register_idx);
-               } else {
-                   sprintf(register_name, "%cC[A0.x]", prefix);
-               }
-           }
+        case WINED3DSPR_CONST:
+            {
+                const char prefix = pshader ? 'P' : 'V';
 
 
-        } else {
-            if (shader_constant_is_local(This, register_idx))
+                /* Relative addressing */
+                if (reg->rel_addr)
+                {
+                    glsl_src_param_t rel_param;
+                    shader_glsl_add_src_param(ins, reg->rel_addr, WINED3DSP_WRITEMASK_0, &rel_param);
+                    if (reg->idx) sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, reg->idx);
+                    else sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str);
+                }
+                else
+                {
+                    if (shader_constant_is_local(This, reg->idx))
+                        sprintf(register_name, "%cLC%u", prefix, reg->idx);
+                    else
+                        sprintf(register_name, "%cC[%u]", prefix, reg->idx);
+                }
+            }
+            break;
+
+        case WINED3DSPR_CONSTINT:
+            if (pshader) sprintf(register_name, "PI[%u]", reg->idx);
+            else sprintf(register_name, "VI[%u]", reg->idx);
+            break;
+
+        case WINED3DSPR_CONSTBOOL:
+            if (pshader) sprintf(register_name, "PB[%u]", reg->idx);
+            else sprintf(register_name, "VB[%u]", reg->idx);
+            break;
+
+        case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
+            if (pshader) sprintf(register_name, "T%u", reg->idx);
+            else sprintf(register_name, "A%u", reg->idx);
+            break;
+
+        case WINED3DSPR_LOOP:
+            sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1);
+            break;
+
+        case WINED3DSPR_SAMPLER:
+            if (pshader) sprintf(register_name, "Psampler%u", reg->idx);
+            else sprintf(register_name, "Vsampler%u", reg->idx);
+            break;
+
+        case WINED3DSPR_COLOROUT:
+            if (reg->idx >= GL_LIMITS(buffers))
+                WARN("Write to render target %u, only %d supported\n", reg->idx, 4);
+
+            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:
+            sprintf(register_name, "%s", hwrastout_reg_names[reg->idx]);
+            break;
+
+        case WINED3DSPR_DEPTHOUT:
+            sprintf(register_name, "gl_FragDepth");
+            break;
+
+        case WINED3DSPR_ATTROUT:
+            if (reg->idx == 0) sprintf(register_name, "gl_FrontColor");
+            else sprintf(register_name, "gl_FrontSecondaryColor");
+            break;
+
+        case WINED3DSPR_TEXCRDOUT:
+            /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
+            if (This->baseShader.reg_maps.shader_version.major >= 3) sprintf(register_name, "OUT[%u]", reg->idx);
+            else sprintf(register_name, "gl_TexCoord[%u]", reg->idx);
+            break;
+
+        case WINED3DSPR_MISCTYPE:
+            if (reg->idx == 0)
             {
             {
-                sprintf(register_name, "%cLC%u", prefix, register_idx);
-            } else {
-                sprintf(register_name, "%cC[%u]", prefix, register_idx);
+                /* vPos */
+                sprintf(register_name, "vpos");
             }
             }
-        }
+            else if (reg->idx == 1)
+            {
+                /* Note that gl_FrontFacing is a bool, while vFace is
+                 * a float for which the sign determines front/back */
+                sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
+            }
+            else
+            {
+                FIXME("Unhandled misctype register %d\n", reg->idx);
+                sprintf(register_name, "unrecognized_register");
+            }
+            break;
 
 
-        break;
-    }
-    case WINED3DSPR_CONSTINT:
-        if (pshader)
-            sprintf(register_name, "PI[%u]", register_idx);
-        else
-            sprintf(register_name, "VI[%u]", register_idx);
-        break;
-    case WINED3DSPR_CONSTBOOL:
-        if (pshader)
-            sprintf(register_name, "PB[%u]", register_idx);
-        else
-            sprintf(register_name, "VB[%u]", register_idx);
-        break;
-    case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
-        if (pshader) {
-            sprintf(register_name, "T%u", register_idx);
-        } else {
-            sprintf(register_name, "A%u", register_idx);
-        }
-    break;
-    case WINED3DSPR_LOOP:
-        sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1);
-    break;
-    case WINED3DSPR_SAMPLER:
-        if (pshader)
-            sprintf(register_name, "Psampler%u", register_idx);
-        else
-            sprintf(register_name, "Vsampler%u", register_idx);
-    break;
-    case WINED3DSPR_COLOROUT:
-        if (register_idx >= GL_LIMITS(buffers))
-            WARN("Write to render target %u, only %d supported\n", register_idx, 4);
-
-        if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
-            sprintf(register_name, "gl_FragData[%u]", register_idx);
-        } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
-            sprintf(register_name, "gl_FragColor");
-        }
-    break;
-    case WINED3DSPR_RASTOUT:
-        sprintf(register_name, "%s", hwrastout_reg_names[register_idx]);
-    break;
-    case WINED3DSPR_DEPTHOUT:
-        sprintf(register_name, "gl_FragDepth");
-    break;
-    case WINED3DSPR_ATTROUT:
-        if (register_idx == 0)
-        {
-            sprintf(register_name, "gl_FrontColor");
-        } else {
-            sprintf(register_name, "gl_FrontSecondaryColor");
-        }
-    break;
-    case WINED3DSPR_TEXCRDOUT:
-        /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
-        if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(register_name, "OUT[%u]", register_idx);
-        else sprintf(register_name, "gl_TexCoord[%u]", register_idx);
-    break;
-    case WINED3DSPR_MISCTYPE:
-        if (register_idx == 0)
-        {
-            /* vPos */
-            sprintf(register_name, "vpos");
-        }
-        else if (register_idx == 1)
-        {
-            /* Note that gl_FrontFacing is a bool, while vFace is
-             * a float for which the sign determines front/back
-             */
-            sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
-        } else {
-            FIXME("Unhandled misctype register %d\n", register_idx);
+        case WINED3DSPR_IMMCONST:
+            switch (reg->immconst_type)
+            {
+                case WINED3D_IMMCONST_FLOAT:
+                    sprintf(register_name, "%.8e", *(float *)reg->immconst_data);
+                    break;
+
+                case WINED3D_IMMCONST_FLOAT4:
+                    sprintf(register_name, "vec4(%.8e, %.8e, %.8e, %.8e)",
+                            *(float *)&reg->immconst_data[0], *(float *)&reg->immconst_data[1],
+                            *(float *)&reg->immconst_data[2], *(float *)&reg->immconst_data[3]);
+                    break;
+
+                default:
+                    FIXME("Unhandled immconst type %#x\n", reg->immconst_type);
+                    sprintf(register_name, "<unhandled_immconst_type %#x>", reg->immconst_type);
+            }
+            break;
+
+        default:
+            FIXME("Unhandled register name Type(%d)\n", reg->type);
             sprintf(register_name, "unrecognized_register");
             sprintf(register_name, "unrecognized_register");
-        }
-        break;
-    default:
-        FIXME("Unhandled register name Type(%d)\n", register_type);
-        sprintf(register_name, "unrecognized_register");
-    break;
+            break;
     }
 }
 
     }
 }
 
@@ -1232,7 +1261,7 @@ static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *p
 {
     DWORD mask = param->write_mask;
 
 {
     DWORD mask = param->write_mask;
 
-    if (shader_is_scalar(param->register_type, param->register_idx))
+    if (shader_is_scalar(&param->reg))
     {
         mask = WINED3DSP_WRITEMASK_0;
         *write_mask = '\0';
     {
         mask = WINED3DSP_WRITEMASK_0;
         *write_mask = '\0';
@@ -1256,45 +1285,47 @@ static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask) {
     return size;
 }
 
     return size;
 }
 
-static void shader_glsl_get_swizzle(const DWORD param, BOOL fixup, DWORD mask, char *swizzle_str) {
+static void shader_glsl_swizzle_to_str(const DWORD swizzle, BOOL fixup, DWORD mask, char *str)
+{
     /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
      * but addressed as "rgba". To fix this we need to swap the register's x
      * and z components. */
     /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
      * but addressed as "rgba". To fix this we need to swap the register's x
      * and z components. */
-    DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
     const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
-    char *ptr = swizzle_str;
 
 
-    if (!shader_is_scalar(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK))
-    {
-        *ptr++ = '.';
-        /* swizzle bits fields: wwzzyyxx */
-        if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = swizzle_chars[swizzle & 0x03];
-        if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = swizzle_chars[(swizzle >> 2) & 0x03];
-        if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = swizzle_chars[(swizzle >> 4) & 0x03];
-        if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = swizzle_chars[(swizzle >> 6) & 0x03];
-    }
+    *str++ = '.';
+    /* swizzle bits fields: wwzzyyxx */
+    if (mask & WINED3DSP_WRITEMASK_0) *str++ = swizzle_chars[swizzle & 0x03];
+    if (mask & WINED3DSP_WRITEMASK_1) *str++ = swizzle_chars[(swizzle >> 2) & 0x03];
+    if (mask & WINED3DSP_WRITEMASK_2) *str++ = swizzle_chars[(swizzle >> 4) & 0x03];
+    if (mask & WINED3DSP_WRITEMASK_3) *str++ = swizzle_chars[(swizzle >> 6) & 0x03];
+    *str = '\0';
+}
 
 
-    *ptr = '\0';
+static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param,
+        BOOL fixup, DWORD mask, char *swizzle_str)
+{
+    if (shader_is_scalar(&param->reg))
+        *swizzle_str = '\0';
+    else
+        shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
 }
 
 /* From a given parameter token, generate the corresponding GLSL string.
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
 static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
 }
 
 /* From a given parameter token, generate the corresponding GLSL string.
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
 static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
-        const DWORD param, const DWORD addr_token, DWORD mask, glsl_src_param_t *src_param)
+        const struct wined3d_shader_src_param *wined3d_src, DWORD mask, glsl_src_param_t *glsl_src)
 {
     BOOL is_color = FALSE;
     char swizzle_str[6];
 
 {
     BOOL is_color = FALSE;
     char swizzle_str[6];
 
-    src_param->reg_name[0] = '\0';
-    src_param->param_str[0] = '\0';
+    glsl_src->reg_name[0] = '\0';
+    glsl_src->param_str[0] = '\0';
     swizzle_str[0] = '\0';
 
     swizzle_str[0] = '\0';
 
-    shader_glsl_get_register_name(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
-            param & WINED3DSHADER_ADDRMODE_RELATIVE, addr_token, src_param->reg_name, &is_color, ins);
-
-    shader_glsl_get_swizzle(param, is_color, mask, swizzle_str);
-    shader_glsl_gen_modifier(param, src_param->reg_name, swizzle_str, src_param->param_str);
+    shader_glsl_get_register_name(&wined3d_src->reg, glsl_src->reg_name, &is_color, ins);
+    shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str);
+    shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, glsl_src->param_str);
 }
 
 /* From a given parameter token, generate the corresponding GLSL string.
 }
 
 /* From a given parameter token, generate the corresponding GLSL string.
@@ -1308,8 +1339,7 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *
     glsl_dst->mask_str[0] = '\0';
     glsl_dst->reg_name[0] = '\0';
 
     glsl_dst->mask_str[0] = '\0';
     glsl_dst->reg_name[0] = '\0';
 
-    shader_glsl_get_register_name(wined3d_dst->register_type, wined3d_dst->register_idx,
-            wined3d_dst->has_rel_addr, wined3d_dst->addr_token, glsl_dst->reg_name, &is_color, ins);
+    shader_glsl_get_register_name(&wined3d_dst->reg, glsl_dst->reg_name, &is_color, ins);
     return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
 }
 
     return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
 }
 
@@ -1333,7 +1363,7 @@ static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const struct wined3d_
 }
 
 /** Process GLSL instruction modifiers */
 }
 
 /** Process GLSL instruction modifiers */
-void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
     DWORD modifiers;
 {
     glsl_dst_param_t dst_param;
     DWORD modifiers;
@@ -1348,7 +1378,7 @@ void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instructi
     if (modifiers & WINED3DSPDM_SATURATE)
     {
         /* _SAT means to clamp the value of the register to between 0 and 1 */
     if (modifiers & WINED3DSPDM_SATURATE)
     {
         /* _SAT means to clamp the value of the register to between 0 and 1 */
-        shader_addline(ins->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
+        shader_addline(ins->ctx->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
                 dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
     }
 
                 dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
     }
 
@@ -1363,9 +1393,8 @@ void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instructi
     }
 }
 
     }
 }
 
-static inline const char *shader_get_comp_op(DWORD flags)
+static inline const char *shader_get_comp_op(DWORD op)
 {
 {
-    DWORD op = (flags & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
     switch (op) {
         case COMPARISON_GT: return ">";
         case COMPARISON_EQ: return "==";
     switch (op) {
         case COMPARISON_GT: return ">";
         case COMPARISON_EQ: return "==";
@@ -1384,12 +1413,15 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
     BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
     BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
+    BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
 
     /* Note that there's no such thing as a projected cube texture. */
     switch(sampler_type) {
         case WINED3DSTT_1D:
             if(lod) {
                 sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
 
     /* Note that there's no such thing as a projected cube texture. */
     switch(sampler_type) {
         case WINED3DSTT_1D:
             if(lod) {
                 sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
+            } else  if(grad) {
+                sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
             } else {
                 sample_function->name = projected ? "texture1DProj" : "texture1D";
             }
             } else {
                 sample_function->name = projected ? "texture1DProj" : "texture1D";
             }
@@ -1399,12 +1431,19 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
             if(texrect) {
                 if(lod) {
                     sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
             if(texrect) {
                 if(lod) {
                     sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
+                } else  if(grad) {
+                    /* What good are texrect grad functions? I don't know, but GL_EXT_gpu_shader4 defines them.
+                    * There is no GL_ARB_shader_texture_lod spec yet, so I don't know if they're defined there
+                     */
+                    sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
                 } else {
                     sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
                 }
             } else {
                 if(lod) {
                     sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
                 } else {
                     sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
                 }
             } else {
                 if(lod) {
                     sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
+                } else  if(grad) {
+                    sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
                 } else {
                     sample_function->name = projected ? "texture2DProj" : "texture2D";
                 }
                 } else {
                     sample_function->name = projected ? "texture2DProj" : "texture2D";
                 }
@@ -1414,6 +1453,8 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
         case WINED3DSTT_CUBE:
             if(lod) {
                 sample_function->name = "textureCubeLod";
         case WINED3DSTT_CUBE:
             if(lod) {
                 sample_function->name = "textureCubeLod";
+            } else if(grad) {
+                sample_function->name = "textureCubeGradARB";
             } else {
                 sample_function->name = "textureCube";
             }
             } else {
                 sample_function->name = "textureCube";
             }
@@ -1422,6 +1463,8 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
         case WINED3DSTT_VOLUME:
             if(lod) {
                 sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
         case WINED3DSTT_VOLUME:
             if(lod) {
                 sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+            } else  if(grad) {
+                sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
             } else {
                 sample_function->name = projected ? "texture3DProj" : "texture3D";
             }
             } else {
                 sample_function->name = projected ? "texture3DProj" : "texture3D";
             }
@@ -1532,17 +1575,18 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction
 
     if (mask_size > 1)
     {
 
     if (mask_size > 1)
     {
-        shader_addline(ins->buffer, "%s%s = vec%u(%s);\n",
+        shader_addline(ins->ctx->buffer, "%s%s = vec%u(%s);\n",
                 dst_param.reg_name, dst_param.mask_str, mask_size, arguments);
     }
     else
     {
                 dst_param.reg_name, dst_param.mask_str, mask_size, arguments);
     }
     else
     {
-        shader_addline(ins->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
+        shader_addline(ins->ctx->buffer, "%s%s = %s;\n", dst_param.reg_name, dst_param.mask_str, arguments);
     }
 }
 
     }
 }
 
-static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
+static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
         DWORD sampler, const glsl_sample_function_t *sample_function, DWORD swizzle,
         DWORD sampler, const glsl_sample_function_t *sample_function, DWORD swizzle,
+        const char *dx, const char *dy,
         const char *bias, const char *coord_reg_fmt, ...)
 {
     const char *sampler_base;
         const char *bias, const char *coord_reg_fmt, ...)
 {
     const char *sampler_base;
@@ -1551,11 +1595,11 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
     BOOL np2_fixup = FALSE;
     va_list args;
 
     BOOL np2_fixup = FALSE;
     va_list args;
 
-    shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
+    shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
 
 
-    if (shader_is_pshader_version(ins->reg_maps->shader_version))
+    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
     {
-        IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+        IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
         fixup = This->cur_args->color_fixup[sampler];
         sampler_base = "Psampler";
 
         fixup = This->cur_args->color_fixup[sampler];
         sampler_base = "Psampler";
 
@@ -1571,21 +1615,23 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
         fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
     }
 
         fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
     }
 
-    shader_glsl_append_dst(ins->buffer, ins);
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
 
 
-    shader_addline(ins->buffer, "%s(%s%u, ", sample_function->name, sampler_base, sampler);
+    shader_addline(ins->ctx->buffer, "%s(%s%u, ", sample_function->name, sampler_base, sampler);
 
     va_start(args, coord_reg_fmt);
 
     va_start(args, coord_reg_fmt);
-    shader_vaddline(ins->buffer, coord_reg_fmt, args);
+    shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args);
     va_end(args);
 
     if(bias) {
     va_end(args);
 
     if(bias) {
-        shader_addline(ins->buffer, ", %s)%s);\n", bias, dst_swizzle);
+        shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
     } else {
         if (np2_fixup) {
     } else {
         if (np2_fixup) {
-            shader_addline(ins->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, 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 {
-            shader_addline(ins->buffer, ")%s);\n", dst_swizzle);
+            shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle);
         }
     }
 
         }
     }
 
@@ -1603,7 +1649,7 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
 static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
 {
 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
 static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1622,26 +1668,26 @@ static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
     }
 
     write_mask = shader_glsl_append_dst(buffer, ins);
     }
 
     write_mask = shader_glsl_append_dst(buffer, ins);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
     shader_addline(buffer, "%s %c %s);\n", src0_param.param_str, op, src1_param.param_str);
 }
 
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 {
     shader_addline(buffer, "%s %c %s);\n", src0_param.param_str, op, src1_param.param_str);
 }
 
 /* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
 static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
     write_mask = shader_glsl_append_dst(buffer, ins);
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
     write_mask = shader_glsl_append_dst(buffer, ins);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
 
     /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
      * shader versions WINED3DSIO_MOVA is used for this. */
 
     /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
      * shader versions WINED3DSIO_MOVA is used for this. */
-    if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
-            && !shader_is_pshader_version(ins->reg_maps->shader_version)
-            && ins->dst[0].register_type == WINED3DSPR_ADDR))
+    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)
     {
         /* This is a simple floor() */
         unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
     {
         /* This is a simple floor() */
         unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
@@ -1668,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)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1685,8 +1731,8 @@ static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
         src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     }
 
         src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     }
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_write_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_write_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
@@ -1705,10 +1751,10 @@ static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
     char dst_mask[6];
 
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
     char dst_mask[6];
 
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
-    shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param);
-    shader_addline(ins->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
+    shader_addline(ins->ctx->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
 }
 
 /* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
 }
 
 /* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
@@ -1716,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)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1725,8 +1771,8 @@ static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
     dst_write_mask = shader_glsl_append_dst(buffer, ins);
     dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
 
     dst_write_mask = shader_glsl_append_dst(buffer, ins);
     dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(pow(abs(%s), %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(pow(abs(%s), %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
@@ -1740,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)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1748,7 +1794,7 @@ static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
     dst_write_mask = shader_glsl_append_dst(buffer, ins);
     dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
 
     dst_write_mask = shader_glsl_append_dst(buffer, ins);
     dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(log2(abs(%s))));\n", dst_size, src0_param.param_str);
 
     if (dst_size > 1) {
         shader_addline(buffer, "vec%d(log2(abs(%s))));\n", dst_size, src0_param.param_str);
@@ -1760,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)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1790,11 +1836,11 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
 
     if (ins->src_count)
     {
 
     if (ins->src_count)
     {
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
         shader_addline(buffer, "%s", src_param.param_str);
         for (i = 1; i < ins->src_count; ++i)
         {
         shader_addline(buffer, "%s", src_param.param_str);
         for (i = 1; i < ins->src_count; ++i)
         {
-            shader_glsl_add_src_param(ins, ins->src[i], ins->src_addr[i], write_mask, &src_param);
+            shader_glsl_add_src_param(ins, &ins->src[i], write_mask, &src_param);
             shader_addline(buffer, ", %s", src_param.param_str);
         }
     }
             shader_addline(buffer, ", %s", src_param.param_str);
         }
     }
@@ -1815,31 +1861,31 @@ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src_param;
 
 {
     glsl_src_param_t src_param;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param);
 
 
-    if (ins->reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+    if (ins->ctx->reg_maps->shader_version.major < 2)
     {
         char dst_mask[6];
 
     {
         char dst_mask[6];
 
-        shader_addline(ins->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
-        shader_addline(ins->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
-        shader_addline(ins->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
-        shader_addline(ins->buffer, "tmp0.w = 1.0;\n");
+        shader_addline(ins->ctx->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
+        shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
+        shader_addline(ins->ctx->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
+        shader_addline(ins->ctx->buffer, "tmp0.w = 1.0;\n");
 
 
-        shader_glsl_append_dst(ins->buffer, ins);
+        shader_glsl_append_dst(ins->ctx->buffer, ins);
         shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
         shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
-        shader_addline(ins->buffer, "tmp0%s);\n", dst_mask);
+        shader_addline(ins->ctx->buffer, "tmp0%s);\n", dst_mask);
     } else {
         DWORD write_mask;
         unsigned int mask_size;
 
     } else {
         DWORD write_mask;
         unsigned int mask_size;
 
-        write_mask = shader_glsl_append_dst(ins->buffer, ins);
+        write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
         mask_size = shader_glsl_get_write_mask_size(write_mask);
 
         if (mask_size > 1) {
         mask_size = shader_glsl_get_write_mask_size(write_mask);
 
         if (mask_size > 1) {
-            shader_addline(ins->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str);
+            shader_addline(ins->ctx->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str);
         } else {
         } else {
-            shader_addline(ins->buffer, "exp2(%s));\n", src_param.param_str);
+            shader_addline(ins->ctx->buffer, "exp2(%s));\n", src_param.param_str);
         }
     }
 }
         }
     }
 }
@@ -1851,20 +1897,20 @@ static void shader_glsl_rcp(const struct wined3d_shader_instruction *ins)
     DWORD write_mask;
     unsigned int mask_size;
 
     DWORD write_mask;
     unsigned int mask_size;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
 
     if (mask_size > 1) {
 
     if (mask_size > 1) {
-        shader_addline(ins->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
+        shader_addline(ins->ctx->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
     } else {
     } else {
-        shader_addline(ins->buffer, "1.0 / %s);\n", src_param.param_str);
+        shader_addline(ins->ctx->buffer, "1.0 / %s);\n", src_param.param_str);
     }
 }
 
 static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
 {
     }
 }
 
 static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
 {
-    SHADER_BUFFER *buffer = ins->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;
@@ -1872,7 +1918,7 @@ static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
     write_mask = shader_glsl_append_dst(buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
 
     write_mask = shader_glsl_append_dst(buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
 
     if (mask_size > 1) {
         shader_addline(buffer, "vec%d(inversesqrt(%s)));\n", mask_size, src_param.param_str);
 
     if (mask_size > 1) {
         shader_addline(buffer, "vec%d(inversesqrt(%s)));\n", mask_size, src_param.param_str);
@@ -1889,10 +1935,10 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
     DWORD write_mask;
     unsigned int mask_size;
 
     DWORD write_mask;
     unsigned int mask_size;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
 
     if (mask_size > 1) {
         const char *compare;
 
     if (mask_size > 1) {
         const char *compare;
@@ -1905,7 +1951,7 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
                 FIXME("Can't handle opcode %#x\n", ins->handler_idx);
         }
 
                 FIXME("Can't handle opcode %#x\n", ins->handler_idx);
         }
 
-        shader_addline(ins->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
+        shader_addline(ins->ctx->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
                 src0_param.param_str, src1_param.param_str);
     } else {
         switch(ins->handler_idx)
                 src0_param.param_str, src1_param.param_str);
     } else {
         switch(ins->handler_idx)
@@ -1918,11 +1964,12 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
                  * issue. Playing with not() is not possible either because not() does not accept
                  * a scalar.
                  */
                  * issue. Playing with not() is not possible either because not() does not accept
                  * a scalar.
                  */
-                shader_addline(ins->buffer, "(%s < %s) ? 1.0 : 0.0);\n", src0_param.param_str, src1_param.param_str);
+                shader_addline(ins->ctx->buffer, "(%s < %s) ? 1.0 : 0.0);\n",
+                        src0_param.param_str, src1_param.param_str);
                 break;
             case WINED3DSIH_SGE:
                 /* Here we can use the step() function and safe a conditional */
                 break;
             case WINED3DSIH_SGE:
                 /* Here we can use the step() function and safe a conditional */
-                shader_addline(ins->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
+                shader_addline(ins->ctx->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
                 break;
             default:
                 FIXME("Can't handle opcode %#x\n", ins->handler_idx);
                 break;
             default:
                 FIXME("Can't handle opcode %#x\n", ins->handler_idx);
@@ -1942,25 +1989,17 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
     char mask_char[6];
     BOOL temp_destination = FALSE;
 
     char mask_char[6];
     BOOL temp_destination = FALSE;
 
-    if (shader_is_scalar(shader_get_regtype(ins->src[0]), ins->src[0] & WINED3DSP_REGNUM_MASK))
+    if (shader_is_scalar(&ins->src[0].reg))
     {
     {
-        write_mask = shader_glsl_append_dst(ins->buffer, ins);
+        write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
 
 
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
-        shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-        shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+        shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+        shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
 
-        shader_addline(ins->buffer, "%s >= 0.0 ? %s : %s);\n",
+        shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
                        src0_param.param_str, src1_param.param_str, src2_param.param_str);
     } else {
                        src0_param.param_str, src1_param.param_str, src2_param.param_str);
     } else {
-        DWORD src0reg = ins->src[0] & WINED3DSP_REGNUM_MASK;
-        DWORD src1reg = ins->src[1] & WINED3DSP_REGNUM_MASK;
-        DWORD src2reg = ins->src[2] & WINED3DSP_REGNUM_MASK;
-        DWORD src0regtype = shader_get_regtype(ins->src[0]);
-        DWORD src1regtype = shader_get_regtype(ins->src[1]);
-        DWORD src2regtype = shader_get_regtype(ins->src[2]);
-        DWORD dstreg = ins->dst[0].register_idx;
-        DWORD dstregtype = ins->dst[0].register_type;
         DWORD dst_mask = ins->dst[0].write_mask;
         struct wined3d_shader_dst_param dst = ins->dst[0];
 
         DWORD dst_mask = ins->dst[0].write_mask;
         struct wined3d_shader_dst_param dst = ins->dst[0];
 
@@ -1969,7 +2008,7 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
             write_mask = 0;
             /* Find the destination channels which use the current source0 channel */
             for (j=0; j<4; j++) {
             write_mask = 0;
             /* Find the destination channels which use the current source0 channel */
             for (j=0; j<4; j++) {
-                if (((ins->src[0] >> (WINED3DSP_SWIZZLE_SHIFT + 2 * j)) & 0x3) == i)
+                if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
                 {
                     write_mask |= WINED3DSP_WRITEMASK_0 << j;
                     cmp_channel = WINED3DSP_WRITEMASK_0 << j;
                 {
                     write_mask |= WINED3DSP_WRITEMASK_0 << j;
                     cmp_channel = WINED3DSP_WRITEMASK_0 << j;
@@ -1981,31 +2020,34 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
             * The first lines may overwrite source parameters of the following lines.
             * Deal with that by using a temporary destination register if needed
             */
             * The first lines may overwrite source parameters of the following lines.
             * Deal with that by using a temporary destination register if needed
             */
-            if ((src0reg == dstreg && src0regtype == dstregtype)
-                    || (src1reg == dstreg && src1regtype == dstregtype)
-                    || (src2reg == dstreg && src2regtype == dstregtype))
+            if ((ins->src[0].reg.idx == ins->dst[0].reg.idx
+                    && ins->src[0].reg.type == ins->dst[0].reg.type)
+                    || (ins->src[1].reg.idx == ins->dst[0].reg.idx
+                    && ins->src[1].reg.type == ins->dst[0].reg.type)
+                    || (ins->src[2].reg.idx == ins->dst[0].reg.idx
+                    && ins->src[2].reg.type == ins->dst[0].reg.type))
             {
                 write_mask = shader_glsl_get_write_mask(&dst, mask_char);
                 if (!write_mask) continue;
             {
                 write_mask = shader_glsl_get_write_mask(&dst, mask_char);
                 if (!write_mask) continue;
-                shader_addline(ins->buffer, "tmp0%s = (", mask_char);
+                shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
                 temp_destination = TRUE;
             } else {
                 temp_destination = TRUE;
             } else {
-                write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
+                write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
                 if (!write_mask) continue;
             }
 
                 if (!write_mask) continue;
             }
 
-            shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param);
-            shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-            shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+            shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+            shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+            shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
 
-            shader_addline(ins->buffer, "%s >= 0.0 ? %s : %s);\n",
+            shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
                         src0_param.param_str, src1_param.param_str, src2_param.param_str);
         }
 
         if(temp_destination) {
             shader_glsl_get_write_mask(&ins->dst[0], mask_char);
                         src0_param.param_str, src1_param.param_str, src2_param.param_str);
         }
 
         if(temp_destination) {
             shader_glsl_get_write_mask(&ins->dst[0], mask_char);
-            shader_glsl_append_dst(ins->buffer, ins);
-            shader_addline(ins->buffer, "tmp0%s);\n", mask_char);
+            shader_glsl_append_dst(ins->ctx->buffer, ins);
+            shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
         }
     }
 
         }
     }
 
@@ -2023,20 +2065,22 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
     DWORD write_mask, cmp_channel = 0;
     unsigned int i, j;
     DWORD dst_mask;
     DWORD write_mask, cmp_channel = 0;
     unsigned int i, j;
     DWORD dst_mask;
+    DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+            ins->ctx->reg_maps->shader_version.minor);
 
 
-    if (ins->reg_maps->shader_version < WINED3DPS_VERSION(1, 4))
+    if (shader_version < WINED3D_SHADER_VERSION(1, 4))
     {
     {
-        write_mask = shader_glsl_append_dst(ins->buffer, ins);
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-        shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-        shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+        write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+        shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+        shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
         /* Fun: The D3DSI_COISSUE flag changes the semantic of the cnd instruction for < 1.4 shaders */
         if (ins->coissue)
         {
 
         /* Fun: The D3DSI_COISSUE flag changes the semantic of the cnd instruction for < 1.4 shaders */
         if (ins->coissue)
         {
-            shader_addline(ins->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
+            shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
         } else {
         } else {
-            shader_addline(ins->buffer, "%s > 0.5 ? %s : %s);\n",
+            shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
                     src0_param.param_str, src1_param.param_str, src2_param.param_str);
         }
         return;
                     src0_param.param_str, src1_param.param_str, src2_param.param_str);
         }
         return;
@@ -2048,7 +2092,7 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
         write_mask = 0;
         /* Find the destination channels which use the current source0 channel */
         for (j=0; j<4; j++) {
         write_mask = 0;
         /* Find the destination channels which use the current source0 channel */
         for (j=0; j<4; j++) {
-            if (((ins->src[0] >> (WINED3DSP_SWIZZLE_SHIFT + 2 * j)) & 0x3) == i)
+            if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
             {
                 write_mask |= WINED3DSP_WRITEMASK_0 << j;
                 cmp_channel = WINED3DSP_WRITEMASK_0 << j;
             {
                 write_mask |= WINED3DSP_WRITEMASK_0 << j;
                 cmp_channel = WINED3DSP_WRITEMASK_0 << j;
@@ -2056,14 +2100,14 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
         }
 
         dst.write_mask = dst_mask & write_mask;
         }
 
         dst.write_mask = dst_mask & write_mask;
-        write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
+        write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
         if (!write_mask) continue;
 
         if (!write_mask) continue;
 
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param);
-        shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-        shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+        shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+        shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
 
-        shader_addline(ins->buffer, "%s > 0.5 ? %s : %s);\n",
+        shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
                 src0_param.param_str, src1_param.param_str, src2_param.param_str);
     }
 }
                 src0_param.param_str, src1_param.param_str, src2_param.param_str);
     }
 }
@@ -2076,11 +2120,11 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src2_param;
     DWORD write_mask;
 
     glsl_src_param_t src2_param;
     DWORD write_mask;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-    shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
-    shader_addline(ins->buffer, "(%s * %s) + %s);\n",
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+    shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n",
             src0_param.param_str, src1_param.param_str, src2_param.param_str);
 }
 
             src0_param.param_str, src1_param.param_str, src2_param.param_str);
 }
 
@@ -2090,21 +2134,18 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
 {
     int i;
     int nComponents = 0;
 {
     int i;
     int nComponents = 0;
-    struct wined3d_shader_dst_param tmp_dst = {0};
+    struct wined3d_shader_dst_param tmp_dst = {{0}};
+    struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
     struct wined3d_shader_instruction tmp_ins;
 
     memset(&tmp_ins, 0, sizeof(tmp_ins));
 
     /* Set constants for the temporary argument */
     struct wined3d_shader_instruction tmp_ins;
 
     memset(&tmp_ins, 0, sizeof(tmp_ins));
 
     /* Set constants for the temporary argument */
-    tmp_ins.shader      = ins->shader;
-    tmp_ins.buffer      = ins->buffer;
-    tmp_ins.src[0]      = ins->src[0];
-    tmp_ins.src_addr[0] = ins->src_addr[0];
-    tmp_ins.src_addr[1] = ins->src_addr[1];
-    tmp_ins.reg_maps = ins->reg_maps;
+    tmp_ins.ctx = ins->ctx;
     tmp_ins.dst_count = 1;
     tmp_ins.dst = &tmp_dst;
     tmp_ins.src_count = 2;
     tmp_ins.dst_count = 1;
     tmp_ins.dst = &tmp_dst;
     tmp_ins.src_count = 2;
+    tmp_ins.src = tmp_src;
 
     switch(ins->handler_idx)
     {
 
     switch(ins->handler_idx)
     {
@@ -2133,11 +2174,13 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
     }
 
     tmp_dst = ins->dst[0];
     }
 
     tmp_dst = ins->dst[0];
+    tmp_src[0] = ins->src[0];
+    tmp_src[1] = ins->src[1];
     for (i = 0; i < nComponents; ++i)
     {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
     for (i = 0; i < nComponents; ++i)
     {
         tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
-        tmp_ins.src[1] = ins->src[1] + i;
         shader_glsl_dot(&tmp_ins);
         shader_glsl_dot(&tmp_ins);
+        ++tmp_src[1].reg.idx;
     }
 }
 
     }
 }
 
@@ -2154,13 +2197,13 @@ static void shader_glsl_lrp(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src2_param;
     DWORD write_mask;
 
     glsl_src_param_t src2_param;
     DWORD write_mask;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
 
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], write_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], write_mask, &src1_param);
-    shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2], write_mask, &src2_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
 
-    shader_addline(ins->buffer, "mix(%s, %s, %s));\n",
+    shader_addline(ins->ctx->buffer, "mix(%s, %s, %s));\n",
             src2_param.param_str, src1_param.param_str, src0_param.param_str);
 }
 
             src2_param.param_str, src1_param.param_str, src0_param.param_str);
 }
 
@@ -2177,12 +2220,12 @@ static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src3_param;
     char dst_mask[6];
 
     glsl_src_param_t src3_param;
     char dst_mask[6];
 
-    shader_glsl_append_dst(ins->buffer, ins);
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src1_param);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &src3_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src3_param);
 
     /* The sdk specifies the instruction like this
      * dst.x = 1.0;
 
     /* The sdk specifies the instruction like this
      * dst.x = 1.0;
@@ -2205,7 +2248,7 @@ static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
      * which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
      * if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to
      */
      * which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
      * if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to
      */
-    shader_addline(ins->buffer,
+    shader_addline(ins->ctx->buffer,
             "vec4(1.0, max(%s, 0.0), pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
             src0_param.param_str, src1_param.param_str, src0_param.param_str, src3_param.param_str, dst_mask);
 }
             "vec4(1.0, max(%s, 0.0), pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
             src0_param.param_str, src1_param.param_str, src0_param.param_str, src3_param.param_str, dst_mask);
 }
@@ -2224,15 +2267,15 @@ static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src1w_param;
     char dst_mask[6];
 
     glsl_src_param_t src1w_param;
     char dst_mask[6];
 
-    shader_glsl_append_dst(ins->buffer, ins);
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src0y_param);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &src0z_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_1, &src1y_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_3, &src1w_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src0y_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &src0z_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_1, &src1y_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_3, &src1w_param);
 
 
-    shader_addline(ins->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
+    shader_addline(ins->ctx->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
             src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
 }
 
             src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
 }
 
@@ -2250,20 +2293,20 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
     glsl_src_param_t src0_param;
     DWORD write_mask;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
 
     switch (write_mask) {
         case WINED3DSP_WRITEMASK_0:
 
     switch (write_mask) {
         case WINED3DSP_WRITEMASK_0:
-            shader_addline(ins->buffer, "cos(%s));\n", src0_param.param_str);
+            shader_addline(ins->ctx->buffer, "cos(%s));\n", src0_param.param_str);
             break;
 
         case WINED3DSP_WRITEMASK_1:
             break;
 
         case WINED3DSP_WRITEMASK_1:
-            shader_addline(ins->buffer, "sin(%s));\n", src0_param.param_str);
+            shader_addline(ins->ctx->buffer, "sin(%s));\n", src0_param.param_str);
             break;
 
         case (WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1):
             break;
 
         case (WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1):
-            shader_addline(ins->buffer, "vec2(cos(%s), sin(%s)));\n", src0_param.param_str, src0_param.param_str);
+            shader_addline(ins->ctx->buffer, "vec2(cos(%s), sin(%s)));\n", src0_param.param_str, src0_param.param_str);
             break;
 
         default:
             break;
 
         default:
@@ -2281,22 +2324,22 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src1_param;
 static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src1_param;
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
-    DWORD regtype = shader_get_regtype(ins->src[1]);
-    DWORD reg = ins->src[1] & WINED3DSP_REGNUM_MASK;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     const DWORD *control_values = NULL;
     const local_constant *constant;
 
     const DWORD *control_values = NULL;
     const local_constant *constant;
 
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
 
     /* Try to hardcode the loop control parameters if possible. Direct3D 9 class hardware doesn't support real
      * varying indexing, but Microsoft designed this feature for Shader model 2.x+. If the loop control is
      * known at compile time, the GLSL compiler can unroll the loop, and replace indirect addressing with direct
      * addressing.
      */
 
     /* Try to hardcode the loop control parameters if possible. Direct3D 9 class hardware doesn't support real
      * varying indexing, but Microsoft designed this feature for Shader model 2.x+. If the loop control is
      * known at compile time, the GLSL compiler can unroll the loop, and replace indirect addressing with direct
      * addressing.
      */
-    if(regtype == WINED3DSPR_CONSTINT) {
+    if (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
+    {
         LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) {
         LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) {
-            if(constant->idx == reg) {
+            if (constant->idx == ins->src[1].reg.idx)
+            {
                 control_values = constant->value;
                 break;
             }
                 control_values = constant->value;
                 break;
             }
@@ -2305,23 +2348,24 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
 
     if(control_values) {
         if(control_values[2] > 0) {
 
     if(control_values) {
         if(control_values[2] > 0) {
-            shader_addline(ins->buffer, "for (aL%u = %d; aL%u < (%d * %d + %d); aL%u += %d) {\n",
+            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->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->buffer, "for (aL%u = %d, tmpInt%u = 0; tmpInt%u < %d; tmpInt%u++) {\n",
+            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);
         } else {
                     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);
         } else {
-            shader_addline(ins->buffer, "for (aL%u = %d; aL%u > (%d * %d + %d); aL%u += %d) {\n",
+            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->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->buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
+        shader_addline(ins->ctx->buffer,
+                "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
                 shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno,
                 src1_param.reg_name, shader->baseShader.cur_loop_depth, src1_param.reg_name,
                 shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno, src1_param.reg_name);
                 shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno,
                 src1_param.reg_name, shader->baseShader.cur_loop_depth, src1_param.reg_name,
                 shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno, src1_param.reg_name);
@@ -2333,9 +2377,9 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
 
 static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
 {
 
 static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
 
 
-    shader_addline(ins->buffer, "}\n");
+    shader_addline(ins->ctx->buffer, "}\n");
 
     if (ins->handler_idx == WINED3DSIH_ENDLOOP)
     {
 
     if (ins->handler_idx == WINED3DSIH_ENDLOOP)
     {
@@ -2351,13 +2395,34 @@ static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
 
 static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
 {
 
 static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     glsl_src_param_t src0_param;
     glsl_src_param_t src0_param;
+    const DWORD *control_values = NULL;
+    const local_constant *constant;
+
+    /* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */
+    if (ins->src[0].reg.type == WINED3DSPR_CONSTINT)
+    {
+        LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry)
+        {
+            if (constant->idx == ins->src[0].reg.idx)
+            {
+                control_values = constant->value;
+                break;
+            }
+        }
+    }
 
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_addline(ins->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
-            shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
-            src0_param.param_str, shader->baseShader.cur_loop_depth);
+    if(control_values) {
+        shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n",
+                       shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
+                       control_values[0], shader->baseShader.cur_loop_depth);
+    } else {
+        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+        shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
+                shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
+                src0_param.param_str, shader->baseShader.cur_loop_depth);
+    }
     shader->baseShader.cur_loop_depth++;
 }
 
     shader->baseShader.cur_loop_depth++;
 }
 
@@ -2365,8 +2430,8 @@ static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
 
 {
     glsl_src_param_t src0_param;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_addline(ins->buffer, "if (%s) {\n", src0_param.param_str);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_addline(ins->ctx->buffer, "if (%s) {\n", src0_param.param_str);
 }
 
 static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
 }
 
 static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
@@ -2374,21 +2439,21 @@ static void shader_glsl_ifc(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;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
 
 
-    shader_addline(ins->buffer, "if (%s %s %s) {\n",
+    shader_addline(ins->ctx->buffer, "if (%s %s %s) {\n",
             src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
 }
 
 static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
 {
             src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
 }
 
 static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
 {
-    shader_addline(ins->buffer, "} else {\n");
+    shader_addline(ins->ctx->buffer, "} else {\n");
 }
 
 static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
 {
-    shader_addline(ins->buffer, "break;\n");
+    shader_addline(ins->ctx->buffer, "break;\n");
 }
 
 /* FIXME: According to MSDN the compare is done per component. */
 }
 
 /* FIXME: According to MSDN the compare is done per component. */
@@ -2397,34 +2462,30 @@ static void shader_glsl_breakc(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;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
 
 
-    shader_addline(ins->buffer, "if (%s %s %s) break;\n",
+    shader_addline(ins->ctx->buffer, "if (%s %s %s) break;\n",
             src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
 }
 
 static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
 {
             src0_param.param_str, shader_get_comp_op(ins->flags), src1_param.param_str);
 }
 
 static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
 {
-
-    DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
-    shader_addline(ins->buffer, "}\n");
-    shader_addline(ins->buffer, "void subroutine%u () {\n",  snum);
+    shader_addline(ins->ctx->buffer, "}\n");
+    shader_addline(ins->ctx->buffer, "void subroutine%u () {\n",  ins->src[0].reg.idx);
 }
 
 static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
 {
 }
 
 static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
 {
-    DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
-    shader_addline(ins->buffer, "subroutine%u();\n", snum);
+    shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx);
 }
 
 static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src1_param;
 
 }
 
 static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src1_param;
 
-    DWORD snum = (ins->src[0]) & WINED3DSP_REGNUM_MASK;
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], WINED3DSP_WRITEMASK_0, &src1_param);
-    shader_addline(ins->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, snum);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+    shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n", src1_param.param_str, ins->src[0].reg.idx);
 }
 
 /*********************************************
 }
 
 /*********************************************
@@ -2432,22 +2493,23 @@ static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
  ********************************************/
 static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
 {
  ********************************************/
 static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
-    DWORD shader_version = ins->reg_maps->shader_version;
+    DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+            ins->ctx->reg_maps->shader_version.minor);
     glsl_sample_function_t sample_function;
     DWORD sample_flags = 0;
     glsl_sample_function_t sample_function;
     DWORD sample_flags = 0;
-    DWORD sampler_type;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
     DWORD sampler_idx;
     DWORD mask = 0, swizzle;
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
     DWORD sampler_idx;
     DWORD mask = 0, swizzle;
 
     /* 1.0-1.4: Use destination register as sampler source.
      * 2.0+: Use provided sampler source. */
-    if (shader_version < WINED3DPS_VERSION(2,0)) sampler_idx = ins->dst[0].register_idx;
-    else sampler_idx = ins->src[1] & WINED3DSP_REGNUM_MASK;
-    sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    if (shader_version < WINED3D_SHADER_VERSION(2,0)) sampler_idx = ins->dst[0].reg.idx;
+    else sampler_idx = ins->src[1].reg.idx;
+    sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
 
 
-    if (shader_version < WINED3DPS_VERSION(1,4))
+    if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
         DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
     {
         DWORD flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
@@ -2463,9 +2525,9 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
             }
         }
     }
             }
         }
     }
-    else if (shader_version < WINED3DPS_VERSION(2,0))
+    else if (shader_version < WINED3D_SHADER_VERSION(2,0))
     {
     {
-        DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+        DWORD src_mod = ins->src[0].modifiers;
 
         if (src_mod == WINED3DSPSM_DZ) {
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
 
         if (src_mod == WINED3DSPSM_DZ) {
             sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
@@ -2491,89 +2553,122 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
     shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
     mask |= sample_function.coord_mask;
 
     shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
     mask |= sample_function.coord_mask;
 
-    if (shader_version < WINED3DPS_VERSION(2,0)) swizzle = WINED3DVS_NOSWIZZLE;
-    else swizzle = ins->src[1] & WINED3DSP_SWIZZLE_MASK;
+    if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
+    else swizzle = ins->src[1].swizzle;
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
-    if (shader_version < WINED3DPS_VERSION(1,4))
+    if (shader_version < WINED3D_SHADER_VERSION(1,4))
     {
         char coord_mask[6];
         shader_glsl_write_mask_to_str(mask, coord_mask);
     {
         char coord_mask[6];
         shader_glsl_write_mask_to_str(mask, coord_mask);
-        shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
+        shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
                 "T%u%s", sampler_idx, coord_mask);
     } else {
         glsl_src_param_t coord_param;
                 "T%u%s", sampler_idx, coord_mask);
     } else {
         glsl_src_param_t coord_param;
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], mask, &coord_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], mask, &coord_param);
         if (ins->flags & WINED3DSI_TEXLD_BIAS)
         {
             glsl_src_param_t bias;
         if (ins->flags & WINED3DSI_TEXLD_BIAS)
         {
             glsl_src_param_t bias;
-            shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &bias);
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, bias.param_str,
+            shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
+            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
                     "%s", coord_param.param_str);
         } else {
                     "%s", coord_param.param_str);
         } else {
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
+            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
                     "%s", coord_param.param_str);
         }
     }
 }
 
                     "%s", coord_param.param_str);
         }
     }
 }
 
+static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
+{
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
+    IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    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;
+    DWORD sampler_type;
+    DWORD sampler_idx;
+    DWORD swizzle = ins->src[1].swizzle;
+
+    if(!GL_SUPPORT(ARB_SHADER_TEXTURE_LOD)) {
+        FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
+        return pshader_glsl_tex(ins);
+    }
+
+    sampler_idx = ins->src[1].reg.idx;
+    sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+    if(deviceImpl->stateBlock->textures[sampler_idx] &&
+       IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
+        sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
+    }
+
+    shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
+    shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+    shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
+    shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
+
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL,
+                                "%s", coord_param.param_str);
+}
+
 static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
 {
 static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, lod_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
     DWORD sampler_type;
     DWORD sampler_idx;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param, lod_param;
     DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
     DWORD sampler_type;
     DWORD sampler_idx;
-    DWORD swizzle = ins->src[1] & WINED3DSP_SWIZZLE_MASK;
+    DWORD swizzle = ins->src[1].swizzle;
 
 
-    sampler_idx = ins->src[1] & WINED3DSP_REGNUM_MASK;
-    sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    sampler_idx = ins->src[1].reg.idx;
+    sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     if(deviceImpl->stateBlock->textures[sampler_idx] &&
        IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
     }
     shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
     if(deviceImpl->stateBlock->textures[sampler_idx] &&
        IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
     }
     shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], sample_function.coord_mask, &coord_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
 
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &lod_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
 
-    if (shader_is_pshader_version(ins->reg_maps->shader_version))
+    if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
         WARN("Using %s in fragment shader.\n", sample_function.name);
     }
     {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
          * However, they seem to work just fine in fragment shaders as well. */
         WARN("Using %s in fragment shader.\n", sample_function.name);
     }
-    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, lod_param.param_str,
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str,
             "%s", coord_param.param_str);
 }
 
 static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 {
     /* FIXME: Make this work for more than just 2D textures */
             "%s", coord_param.param_str);
 }
 
 static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 {
     /* FIXME: Make this work for more than just 2D textures */
-    SHADER_BUFFER *buffer = ins->buffer;
-    DWORD write_mask = shader_glsl_append_dst(ins->buffer, ins);
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
 
 
-    if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
+    if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
     {
         char dst_mask[6];
 
         shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
         shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
     {
         char dst_mask[6];
 
         shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
         shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
-                ins->dst[0].register_idx, dst_mask);
+                ins->dst[0].reg.idx, dst_mask);
     } else {
     } else {
-        DWORD reg = ins->src[0] & WINED3DSP_REGNUM_MASK;
-        DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
+        DWORD reg = ins->src[0].reg.idx;
+        DWORD src_mod = ins->src[0].modifiers;
         char dst_swizzle[6];
 
         char dst_swizzle[6];
 
-        shader_glsl_get_swizzle(ins->src[0], FALSE, write_mask, dst_swizzle);
+        shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
 
         if (src_mod == WINED3DSPSM_DZ) {
             glsl_src_param_t div_param;
             unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
 
         if (src_mod == WINED3DSPSM_DZ) {
             glsl_src_param_t div_param;
             unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
-            shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &div_param);
+            shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &div_param);
 
             if (mask_size > 1) {
                 shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
 
             if (mask_size > 1) {
                 shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
@@ -2583,7 +2678,7 @@ static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
         } else if (src_mod == WINED3DSPSM_DW) {
             glsl_src_param_t div_param;
             unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
         } else if (src_mod == WINED3DSPSM_DW) {
             glsl_src_param_t div_param;
             unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
-            shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_3, &div_param);
+            shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &div_param);
 
             if (mask_size > 1) {
                 shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
 
             if (mask_size > 1) {
                 shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
@@ -2603,12 +2698,12 @@ 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;
-    DWORD sampler_idx = ins->dst[0].register_idx;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     UINT mask_size;
 
     UINT mask_size;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
     /* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one
      * scalar, and projected sampling would require 4.
 
     /* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one
      * scalar, and projected sampling would require 4.
@@ -2621,17 +2716,17 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
     switch(mask_size)
     {
         case 1:
     switch(mask_size)
     {
         case 1:
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
                     "dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
             break;
 
         case 2:
                     "dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
             break;
 
         case 2:
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
                     "vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
             break;
 
         case 3:
                     "vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
             break;
 
         case 3:
-            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+            shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
                     "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
             break;
 
                     "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
             break;
 
@@ -2646,19 +2741,19 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
 static void pshader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
 static void pshader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
-    DWORD dstreg = ins->dst[0].register_idx;
+    DWORD dstreg = ins->dst[0].reg.idx;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD dst_mask;
     unsigned int mask_size;
 
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD dst_mask;
     unsigned int mask_size;
 
-    dst_mask = shader_glsl_append_dst(ins->buffer, ins);
+    dst_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(dst_mask);
     mask_size = shader_glsl_get_write_mask_size(dst_mask);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
     if (mask_size > 1) {
 
     if (mask_size > 1) {
-        shader_addline(ins->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
+        shader_addline(ins->ctx->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
     } else {
     } else {
-        shader_addline(ins->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
+        shader_addline(ins->ctx->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
     }
 }
 
     }
 }
 
@@ -2676,7 +2771,7 @@ static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
      * too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
      * >= 1.0 or < 0.0
      */
      * too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
      * >= 1.0 or < 0.0
      */
-    shader_addline(ins->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
+    shader_addline(ins->ctx->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
             dst_param.reg_name, dst_param.reg_name);
 }
 
             dst_param.reg_name, dst_param.reg_name);
 }
 
@@ -2688,13 +2783,13 @@ static void pshader_glsl_texdepth(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;
 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].register_idx;
+    DWORD dstreg = ins->dst[0].reg.idx;
     glsl_src_param_t src0_param;
 
     glsl_src_param_t src0_param;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
 
-    shader_addline(ins->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
-    shader_addline(ins->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
+    shader_addline(ins->ctx->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
+    shader_addline(ins->ctx->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
 }
 
 /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
 }
 
 /** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
@@ -2702,11 +2797,11 @@ static void pshader_glsl_texm3x2depth(const struct wined3d_shader_instruction *i
 static void pshader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
 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].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
 
     glsl_src_param_t src0_param;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     shader_addline(buffer, "tmp0.x = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 }
 
     shader_addline(buffer, "tmp0.x = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 }
 
@@ -2714,14 +2809,14 @@ static void pshader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins
  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
 static void pshader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
 static void pshader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    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;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + current_state->current_row, reg, src0_param.param_str);
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
     shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + current_state->current_row, reg, src0_param.param_str);
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
@@ -2729,19 +2824,19 @@ static void pshader_glsl_texm3x3pad(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;
 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].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    DWORD reg = ins->dst[0].reg.idx;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     glsl_src_param_t src0_param;
     glsl_src_param_t src0_param;
-    DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
     glsl_sample_function_t sample_function;
 
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
     shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
-    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xy");
+    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
 }
 
 /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
 }
 
 /** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
@@ -2750,20 +2845,20 @@ 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;
-    DWORD reg = ins->dst[0].register_idx;
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    DWORD reg = ins->dst[0].reg.idx;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
-    DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
     glsl_sample_function_t sample_function;
 
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
-    shader_addline(ins->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+    shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
-    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
 
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
@@ -2775,15 +2870,15 @@ 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;
     char dst_mask[6];
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_src_param_t src0_param;
     char dst_mask[6];
-    DWORD reg = ins->dst[0].register_idx;
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    DWORD reg = ins->dst[0].reg.idx;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
 
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
 
-    shader_glsl_append_dst(ins->buffer, ins);
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
     shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
-    shader_addline(ins->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
+    shader_addline(ins->ctx->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
 
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
@@ -2792,18 +2887,18 @@ static void pshader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
-    DWORD reg = ins->dst[0].register_idx;
+    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;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
-    SHADER_BUFFER *buffer = ins->buffer;
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
-    DWORD stype = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+    WINED3DSAMPLER_TEXTURE_TYPE stype = ins->ctx->reg_maps->sampler_type[reg];
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_sample_function_t sample_function;
 
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
 
     /* Perform the last matrix multiply operation */
     shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
     /* Perform the last matrix multiply operation */
     shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
@@ -2814,7 +2909,7 @@ static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *in
     shader_glsl_get_sample_function(stype, 0, &sample_function);
 
     /* Sample the texture */
     shader_glsl_get_sample_function(stype, 0, &sample_function);
 
     /* Sample the texture */
-    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
 
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
@@ -2823,16 +2918,16 @@ static void pshader_glsl_texm3x3spec(const struct wined3d_shader_instruction *in
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
  * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader;
-    DWORD reg = ins->dst[0].register_idx;
-    SHADER_BUFFER *buffer = ins->buffer;
+    IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+    DWORD reg = ins->dst[0].reg.idx;
+    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;
-    DWORD sampler_type = ins->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
     glsl_sample_function_t sample_function;
 
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
 
     /* Perform the last matrix multiply operation */
     shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
 
     /* Perform the last matrix multiply operation */
     shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
@@ -2846,7 +2941,7 @@ static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *i
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
-    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DVS_NOSWIZZLE, NULL, "tmp0.xyz");
+    shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
 
     current_state->current_row = 0;
 }
 
     current_state->current_row = 0;
 }
@@ -2857,20 +2952,20 @@ static void pshader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *i
  */
 static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 {
  */
 static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 {
-    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param;
-    DWORD sampler_type;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
     DWORD sampler_idx;
     DWORD mask;
     DWORD flags;
     char coord_mask[6];
 
     DWORD sampler_idx;
     DWORD mask;
     DWORD flags;
     char coord_mask[6];
 
-    sampler_idx = ins->dst[0].register_idx;
+    sampler_idx = ins->dst[0].reg.idx;
     flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
     flags = deviceImpl->stateBlock->textureState[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS];
 
-    sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
     mask = sample_function.coord_mask;
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
     mask = sample_function.coord_mask;
@@ -2891,13 +2986,12 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
             case WINED3DTTFF_DISABLE: div_mask = WINED3DSP_WRITEMASK_3; break;
         }
         shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
             case WINED3DTTFF_DISABLE: div_mask = WINED3DSP_WRITEMASK_3; break;
         }
         shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
-        shader_addline(ins->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
+        shader_addline(ins->ctx->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
     }
 
     }
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
-            WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
 
 
-    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
             coord_param.param_str, coord_mask);
 
             "T%u%s + vec4(bumpenvmat%d * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
             coord_param.param_str, coord_mask);
 
@@ -2906,10 +3000,10 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
         glsl_src_param_t luminance_param;
         glsl_dst_param_t dst_param;
 
         glsl_src_param_t luminance_param;
         glsl_dst_param_t dst_param;
 
-        shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &luminance_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &luminance_param);
         shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
         shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
-        shader_addline(ins->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n",
+        shader_addline(ins->ctx->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n",
                 dst_param.reg_name, dst_param.mask_str,
                 luminance_param.param_str, sampler_idx, sampler_idx);
     }
                 dst_param.reg_name, dst_param.mask_str,
                 luminance_param.param_str, sampler_idx, sampler_idx);
     }
@@ -2918,15 +3012,13 @@ static void pshader_glsl_texbem(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;
 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].register_idx;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
 
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
-            WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1],
-            WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
 
 
-    shader_glsl_append_dst(ins->buffer, ins);
-    shader_addline(ins->buffer, "%s + bumpenvmat%d * %s);\n",
+    shader_glsl_append_dst(ins->ctx->buffer, ins);
+    shader_addline(ins->ctx->buffer, "%s + bumpenvmat%d * %s);\n",
             src0_param.param_str, sampler_idx, src1_param.param_str);
 }
 
             src0_param.param_str, sampler_idx, src1_param.param_str);
 }
 
@@ -2935,14 +3027,14 @@ static void pshader_glsl_bem(const struct wined3d_shader_instruction *ins)
 static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
 static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
-    DWORD sampler_idx = ins->dst[0].register_idx;
-    DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     glsl_sample_function_t sample_function;
 
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
-    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "%s.wx", src0_param.reg_name);
 }
 
             "%s.wx", src0_param.reg_name);
 }
 
@@ -2951,14 +3043,14 @@ static void pshader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
 static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
-    DWORD sampler_idx = ins->dst[0].register_idx;
-    DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     glsl_sample_function_t sample_function;
 
     glsl_sample_function_t sample_function;
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
 
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
-    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "%s.yz", src0_param.reg_name);
 }
 
             "%s.yz", src0_param.reg_name);
 }
 
@@ -2967,15 +3059,15 @@ static void pshader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
 static void pshader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
     glsl_src_param_t src0_param;
-    DWORD sampler_idx = ins->dst[0].register_idx;
-    DWORD sampler_type = ins->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
+    DWORD sampler_idx = ins->dst[0].reg.idx;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     glsl_sample_function_t sample_function;
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
     glsl_sample_function_t sample_function;
 
     /* Dependent read, not valid with conditional NP2 */
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], sample_function.coord_mask, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
 
 
-    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DVS_NOSWIZZLE, NULL,
+    shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "%s", src0_param.param_str);
 }
 
             "%s", src0_param.param_str);
 }
 
@@ -2987,16 +3079,16 @@ static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins)
 
     /* The argument is a destination parameter, and no writemasks are allowed */
     shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
     /* The argument is a destination parameter, and no writemasks are allowed */
     shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
-    if ((ins->reg_maps->shader_version >= WINED3DPS_VERSION(2,0)))
+    if (ins->ctx->reg_maps->shader_version.major >= 2)
     {
         /* 2.0 shaders compare all 4 components in texkill */
     {
         /* 2.0 shaders compare all 4 components in texkill */
-        shader_addline(ins->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
+        shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
     } else {
         /* 1.X shaders only compare the first 3 components, probably due to the nature of the texkill
          * instruction as a tex* instruction, and phase, which kills all a / w components. Even if all
          * 4 components are defined, only the first 3 are used
          */
     } else {
         /* 1.X shaders only compare the first 3 components, probably due to the nature of the texkill
          * instruction as a tex* instruction, and phase, which kills all a / w components. Even if all
          * 4 components are defined, only the first 3 are used
          */
-        shader_addline(ins->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
+        shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
     }
 }
 
     }
 }
 
@@ -3010,21 +3102,18 @@ static void pshader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
     DWORD write_mask;
     unsigned int mask_size;
 
     DWORD write_mask;
     unsigned int mask_size;
 
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
     mask_size = shader_glsl_get_write_mask_size(write_mask);
 
     mask_size = shader_glsl_get_write_mask_size(write_mask);
 
-    shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0],
-            WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
-    shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1],
-            WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
-    shader_glsl_add_src_param(ins, ins->src[2], ins->src_addr[2],
-            WINED3DSP_WRITEMASK_0, &src2_param);
+    shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+    shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+    shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &src2_param);
 
     if (mask_size > 1) {
 
     if (mask_size > 1) {
-        shader_addline(ins->buffer, "vec%d(dot(%s, %s) + %s));\n",
+        shader_addline(ins->ctx->buffer, "vec%d(dot(%s, %s) + %s));\n",
                 mask_size, src0_param.param_str, src1_param.param_str, src2_param.param_str);
     } else {
                 mask_size, src0_param.param_str, src1_param.param_str, src2_param.param_str);
     } else {
-        shader_addline(ins->buffer, "dot(%s, %s) + %s);\n",
+        shader_addline(ins->ctx->buffer, "dot(%s, %s) + %s);\n",
                 src0_param.param_str, src1_param.param_str, src2_param.param_str);
     }
 }
                 src0_param.param_str, src1_param.param_str, src2_param.param_str);
     }
 }
@@ -3281,8 +3370,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
     IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
     IWineD3DDeviceImpl *device;
     IWineD3DVertexShaderImpl *vs = (IWineD3DVertexShaderImpl *) vertexshader;
     IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) pixelshader;
     IWineD3DDeviceImpl *device;
-    DWORD vs_major = WINED3DSHADER_VERSION_MAJOR(vs->baseShader.reg_maps.shader_version);
-    DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0;
+    DWORD vs_major = vs->baseShader.reg_maps.shader_version.major;
+    DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
     unsigned int i;
     SHADER_BUFFER buffer;
     DWORD usage, usage_idx, writemask;
     unsigned int i;
     SHADER_BUFFER buffer;
     DWORD usage, usage_idx, writemask;
@@ -3607,7 +3696,7 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
     checkGLcall("Find glsl program uniform locations");
 
     if (pshader
     checkGLcall("Find glsl program uniform locations");
 
     if (pshader
-            && WINED3DSHADER_VERSION_MAJOR(((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version) >= 3
+            && ((IWineD3DPixelShaderImpl *)pshader)->baseShader.reg_maps.shader_version.major >= 3
             && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
             && ((IWineD3DPixelShaderImpl *)pshader)->declared_in_count > GL_LIMITS(glsl_varyings) / 4)
     {
         TRACE("Shader %d needs vertex color clamping disabled\n", programId);
@@ -3794,7 +3883,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     /* Note: Do not use QueryInterface here to find out which shader type this is because this code
      * can be called from IWineD3DBaseShader::Release
      */
     /* Note: Do not use QueryInterface here to find out which shader type this is because this code
      * can be called from IWineD3DBaseShader::Release
      */
-    char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version);
+    char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
 
     if(pshader) {
         ps = (IWineD3DPixelShaderImpl *) This;
 
     if(pshader) {
         ps = (IWineD3DPixelShaderImpl *) This;
@@ -3970,7 +4059,9 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
     return FALSE;
 }
 
     return FALSE;
 }
 
-static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args) {
+static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface,
+        SHADER_BUFFER *buffer, const struct ps_compile_args *args)
+{
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
@@ -3985,6 +4076,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
         shader_addline(buffer, "#extension GL_ARB_draw_buffers : enable\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
     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
@@ -3996,15 +4090,16 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
 
     /* Pack 3.0 inputs */
     shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, args);
 
     /* Pack 3.0 inputs */
-    if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0) && args->vp_mode != vertexshader) {
+    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 */
         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);
+    shader_generate_main((IWineD3DBaseShader *)This, buffer, reg_maps, function);
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
 
     /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
-    if (reg_maps->shader_version < WINED3DPS_VERSION(2,0))
+    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))
     {
         /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
         if(GL_SUPPORT(ARB_DRAW_BUFFERS))
@@ -4034,7 +4129,8 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
      * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
      * -1/(e-s) and e/(e-s) respectively.
      */
      * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
      * -1/(e-s) and e/(e-s) respectively.
      */
-    if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {
+    if (reg_maps->shader_version.major < 3)
+    {
         switch(args->fog) {
             case FOG_OFF: break;
             case FOG_LINEAR:
         switch(args->fog) {
             case FOG_OFF: break;
             case FOG_LINEAR:
@@ -4069,7 +4165,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
     return shader_obj;
 }
 
     return shader_obj;
 }
 
-static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) {
+static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface,
+        SHADER_BUFFER *buffer, const struct vs_compile_args *args)
+{
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
     IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
     const struct shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     CONST DWORD *function = This->baseShader.function;
@@ -4084,10 +4182,10 @@ static GLuint shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_B
     shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
 
     /* Base Shader Body */
     shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, buffer, &GLINFO_LOCATION, NULL);
 
     /* Base Shader Body */
-    shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function);
+    shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function);
 
     /* Unpack 3.0 outputs */
 
     /* Unpack 3.0 outputs */
-    if (reg_maps->shader_version >= WINED3DVS_VERSION(3,0)) shader_addline(buffer, "order_ps_input(OUT);\n");
+    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
     else shader_addline(buffer, "order_ps_input();\n");
 
     /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
@@ -4144,8 +4242,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
     else
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
     TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff);
     else
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
     TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff);
-    /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
-    pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
+    pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
 
     /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
      * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
 
     /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
      * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
@@ -4163,12 +4260,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
     else
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
 
     else
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
 
-    /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
-     * In theory the texbem instruction may need one more shader constant too. But lets assume
-     * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
-     * and lets not take away a uniform needlessly from all other shaders.
-     */
-    pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+    pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF);
 
     /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
      * Direct3D minimum requirement.
 
     /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
      * Direct3D minimum requirement.
@@ -4276,7 +4368,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_TEXDP3        */ pshader_glsl_texdp3,
     /* WINED3DSIH_TEXDP3TEX     */ pshader_glsl_texdp3tex,
     /* WINED3DSIH_TEXKILL       */ pshader_glsl_texkill,
     /* WINED3DSIH_TEXDP3        */ pshader_glsl_texdp3,
     /* WINED3DSIH_TEXDP3TEX     */ pshader_glsl_texdp3tex,
     /* WINED3DSIH_TEXKILL       */ pshader_glsl_texkill,
-    /* WINED3DSIH_TEXLDD        */ NULL,
+    /* WINED3DSIH_TEXLDD        */ shader_glsl_texldd,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
     /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_glsl_texm3x2depth,
     /* WINED3DSIH_TEXM3x2PAD    */ pshader_glsl_texm3x2pad,
     /* WINED3DSIH_TEXLDL        */ shader_glsl_texldl,
     /* WINED3DSIH_TEXM3x2DEPTH  */ pshader_glsl_texm3x2depth,
     /* WINED3DSIH_TEXM3x2PAD    */ pshader_glsl_texm3x2pad,
@@ -4309,4 +4401,5 @@ const shader_backend_t glsl_shader_backend = {
     shader_glsl_generate_vshader,
     shader_glsl_get_caps,
     shader_glsl_color_fixup_supported,
     shader_glsl_generate_vshader,
     shader_glsl_get_caps,
     shader_glsl_color_fixup_supported,
+    shader_glsl_add_instruction_modifiers,
 };
 };
index d1701f5..33148c8 100644 (file)
@@ -120,192 +120,117 @@ static HRESULT  WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader*
   return WINED3D_OK;
 }
 
   return WINED3D_OK;
 }
 
-CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
-    /* Arithmetic */
-    {WINED3DSIO_NOP,          "nop",          0, 0, WINED3DSIH_NOP,          0,                      0                     },
-    {WINED3DSIO_MOV,          "mov",          1, 2, WINED3DSIH_MOV,          0,                      0                     },
-    {WINED3DSIO_ADD,          "add",          1, 3, WINED3DSIH_ADD,          0,                      0                     },
-    {WINED3DSIO_SUB,          "sub",          1, 3, WINED3DSIH_SUB,          0,                      0                     },
-    {WINED3DSIO_MAD,          "mad",          1, 4, WINED3DSIH_MAD,          0,                      0                     },
-    {WINED3DSIO_MUL,          "mul",          1, 3, WINED3DSIH_MUL,          0,                      0                     },
-    {WINED3DSIO_RCP,          "rcp",          1, 2, WINED3DSIH_RCP,          0,                      0                     },
-    {WINED3DSIO_RSQ,          "rsq",          1, 2, WINED3DSIH_RSQ,          0,                      0                     },
-    {WINED3DSIO_DP3,          "dp3",          1, 3, WINED3DSIH_DP3,          0,                      0                     },
-    {WINED3DSIO_DP4,          "dp4",          1, 3, WINED3DSIH_DP4,          0,                      0                     },
-    {WINED3DSIO_MIN,          "min",          1, 3, WINED3DSIH_MIN,          0,                      0                     },
-    {WINED3DSIO_MAX,          "max",          1, 3, WINED3DSIH_MAX,          0,                      0                     },
-    {WINED3DSIO_SLT,          "slt",          1, 3, WINED3DSIH_SLT,          0,                      0                     },
-    {WINED3DSIO_SGE,          "sge",          1, 3, WINED3DSIH_SGE,          0,                      0                     },
-    {WINED3DSIO_ABS,          "abs",          1, 2, WINED3DSIH_ABS,          0,                      0                     },
-    {WINED3DSIO_EXP,          "exp",          1, 2, WINED3DSIH_EXP,          0,                      0                     },
-    {WINED3DSIO_LOG,          "log",          1, 2, WINED3DSIH_LOG,          0,                      0                     },
-    {WINED3DSIO_EXPP,         "expp",         1, 2, WINED3DSIH_EXPP,         0,                      0                     },
-    {WINED3DSIO_LOGP,         "logp",         1, 2, WINED3DSIH_LOGP,         0,                      0                     },
-    {WINED3DSIO_DST,          "dst",          1, 3, WINED3DSIH_DST,          0,                      0                     },
-    {WINED3DSIO_LRP,          "lrp",          1, 4, WINED3DSIH_LRP,          0,                      0                     },
-    {WINED3DSIO_FRC,          "frc",          1, 2, WINED3DSIH_FRC,          0,                      0                     },
-    {WINED3DSIO_CND,          "cnd",          1, 4, WINED3DSIH_CND,          WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_CMP,          "cmp",          1, 4, WINED3DSIH_CMP,          WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
-    {WINED3DSIO_POW,          "pow",          1, 3, WINED3DSIH_POW,          0,                      0                     },
-    {WINED3DSIO_CRS,          "crs",          1, 3, WINED3DSIH_CRS,          0,                      0                     },
-    {WINED3DSIO_NRM,          "nrm",          1, 2, WINED3DSIH_NRM,          0,                      0                     },
-    {WINED3DSIO_SINCOS,       "sincos",       1, 4, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
-    {WINED3DSIO_SINCOS,       "sincos",       1, 2, WINED3DSIH_SINCOS,       WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_DP2ADD,       "dp2add",       1, 4, WINED3DSIH_DP2ADD,       WINED3DPS_VERSION(2,0), -1                    },
-    /* Matrix */
-    {WINED3DSIO_M4x4,         "m4x4",         1, 3, WINED3DSIH_M4x4,         0,                      0                     },
-    {WINED3DSIO_M4x3,         "m4x3",         1, 3, WINED3DSIH_M4x3,         0,                      0                     },
-    {WINED3DSIO_M3x4,         "m3x4",         1, 3, WINED3DSIH_M3x4,         0,                      0                     },
-    {WINED3DSIO_M3x3,         "m3x3",         1, 3, WINED3DSIH_M3x3,         0,                      0                     },
-    {WINED3DSIO_M3x2,         "m3x2",         1, 3, WINED3DSIH_M3x2,         0,                      0                     },
-    /* Register declarations */
-    {WINED3DSIO_DCL,          "dcl",          0, 2, WINED3DSIH_DCL,          0,                      0                     },
-    /* Flow control - requires GLSL or software shaders */
-    {WINED3DSIO_REP ,         "rep",          0, 1, WINED3DSIH_REP,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDREP,       "endrep",       0, 0, WINED3DSIH_ENDREP,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_IF,           "if",           0, 1, WINED3DSIH_IF,           WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_IFC,          "ifc",          0, 2, WINED3DSIH_IFC,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ELSE,         "else",         0, 0, WINED3DSIH_ELSE,         WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDIF,        "endif",        0, 0, WINED3DSIH_ENDIF,        WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAK,        "break",        0, 0, WINED3DSIH_BREAK,        WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKC,       "breakc",       0, 2, WINED3DSIH_BREAKC,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKP,       "breakp",       0, 1, WINED3DSIH_BREAKP,       0,                      0                     },
-    {WINED3DSIO_CALL,         "call",         0, 1, WINED3DSIH_CALL,         WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_CALLNZ,       "callnz",       0, 2, WINED3DSIH_CALLNZ,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_LOOP,         "loop",         0, 2, WINED3DSIH_LOOP,         WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_RET,          "ret",          0, 0, WINED3DSIH_RET,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ENDLOOP,      "endloop",      0, 0, WINED3DSIH_ENDLOOP,      WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_LABEL,        "label",        0, 1, WINED3DSIH_LABEL,        WINED3DPS_VERSION(2,1), -1                    },
-    /* Constant definitions */
-    {WINED3DSIO_DEF,          "def",          1, 5, WINED3DSIH_DEF,          0,                      0                     },
-    {WINED3DSIO_DEFB,         "defb",         1, 2, WINED3DSIH_DEFB,         0,                      0                     },
-    {WINED3DSIO_DEFI,         "defi",         1, 5, WINED3DSIH_DEFI,         0,                      0                     },
-    /* Texture */
-    {WINED3DSIO_TEXCOORD,     "texcoord",     1, 1, WINED3DSIH_TEXCOORD,     0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXCOORD,     "texcrd",       1, 2, WINED3DSIH_TEXCOORD,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_TEXKILL,      "texkill",      1, 1, WINED3DSIH_TEXKILL,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
-    {WINED3DSIO_TEX,          "tex",          1, 1, WINED3DSIH_TEX,          0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEX,          "texld",        1, 2, WINED3DSIH_TEX,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_TEX,          "texld",        1, 3, WINED3DSIH_TEX,          WINED3DPS_VERSION(2,0), -1                    },
-    {WINED3DSIO_TEXBEM,       "texbem",       1, 2, WINED3DSIH_TEXBEM,       0,                      WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXBEML,      "texbeml",      1, 2, WINED3DSIH_TEXBEML,      WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2AR,    "texreg2ar",    1, 2, WINED3DSIH_TEXREG2AR,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2GB,    "texreg2gb",    1, 2, WINED3DSIH_TEXREG2GB,    WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXREG2RGB,   "texreg2rgb",   1, 2, WINED3DSIH_TEXREG2RGB,   WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2PAD,   "texm3x2pad",   1, 2, WINED3DSIH_TEXM3x2PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2TEX,   "texm3x2tex",   1, 2, WINED3DSIH_TEXM3x2TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3PAD,   "texm3x3pad",   1, 2, WINED3DSIH_TEXM3x3PAD,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3DIFF,  "texm3x3diff",  1, 2, WINED3DSIH_TEXM3x3DIFF,  WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)},
-    {WINED3DSIO_TEXM3x3SPEC,  "texm3x3spec",  1, 3, WINED3DSIH_TEXM3x3SPEC,  WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3TEX,   "texm3x3tex",   1, 2, WINED3DSIH_TEXM3x3TEX,   WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDP3TEX,    "texdp3tex",    1, 2, WINED3DSIH_TEXDP3TEX,    WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDP3,       "texdp3",       1, 2, WINED3DSIH_TEXDP3,       WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXM3x3,      "texm3x3",      1, 2, WINED3DSIH_TEXM3x3,      WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
-    {WINED3DSIO_TEXDEPTH,     "texdepth",     1, 1, WINED3DSIH_TEXDEPTH,     WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_BEM,          "bem",          1, 3, WINED3DSIH_BEM,          WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
-    {WINED3DSIO_DSX,          "dsx",          1, 2, WINED3DSIH_DSX,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_DSY,          "dsy",          1, 2, WINED3DSIH_DSY,          WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_TEXLDD,       "texldd",       1, 5, WINED3DSIH_TEXLDD,       WINED3DPS_VERSION(2,1), -1                    },
-    {WINED3DSIO_SETP,         "setp",         1, 3, WINED3DSIH_SETP,         0,                      0                     },
-    {WINED3DSIO_TEXLDL,       "texldl",       1, 3, WINED3DSIH_TEXLDL,       WINED3DPS_VERSION(3,0), -1                    },
-    {WINED3DSIO_PHASE,        "phase",        0, 0, WINED3DSIH_PHASE,        0,                      0                     },
-    {0,                       NULL,           0, 0, 0,                       0,                      0                     }
-};
+static void pshader_set_limits(IWineD3DPixelShaderImpl *This)
+{
+    DWORD shader_version = WINED3D_SHADER_VERSION(This->baseShader.reg_maps.shader_version.major,
+            This->baseShader.reg_maps.shader_version.minor);
 
 
-static void pshader_set_limits(
-      IWineD3DPixelShaderImpl *This) { 
-
-      This->baseShader.limits.attributes = 0;
-      This->baseShader.limits.address = 0;
-      This->baseShader.limits.packed_output = 0;
-
-      switch (This->baseShader.reg_maps.shader_version)
-      {
-          case WINED3DPS_VERSION(1,0):
-          case WINED3DPS_VERSION(1,1):
-          case WINED3DPS_VERSION(1,2):
-          case WINED3DPS_VERSION(1,3): 
-                   This->baseShader.limits.temporary = 2;
-                   This->baseShader.limits.constant_float = 8;
-                   This->baseShader.limits.constant_int = 0;
-                   This->baseShader.limits.constant_bool = 0;
-                   This->baseShader.limits.texcoord = 4;
-                   This->baseShader.limits.sampler = 4;
-                   This->baseShader.limits.packed_input = 0;
-                   This->baseShader.limits.label = 0;
-                   break;
-
-          case WINED3DPS_VERSION(1,4):
-                   This->baseShader.limits.temporary = 6;
-                   This->baseShader.limits.constant_float = 8;
-                   This->baseShader.limits.constant_int = 0;
-                   This->baseShader.limits.constant_bool = 0;
-                   This->baseShader.limits.texcoord = 6;
-                   This->baseShader.limits.sampler = 6;
-                   This->baseShader.limits.packed_input = 0;
-                   This->baseShader.limits.label = 0;
-                   break;
-               
-          /* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */ 
-          case WINED3DPS_VERSION(2,0):
-                   This->baseShader.limits.temporary = 32;
-                   This->baseShader.limits.constant_float = 32;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.texcoord = 8;
-                   This->baseShader.limits.sampler = 16;
-                   This->baseShader.limits.packed_input = 0;
-                   break;
-
-          case WINED3DPS_VERSION(2,1):
-                   This->baseShader.limits.temporary = 32;
-                   This->baseShader.limits.constant_float = 32;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.texcoord = 8;
-                   This->baseShader.limits.sampler = 16;
-                   This->baseShader.limits.packed_input = 0;
-                   This->baseShader.limits.label = 16;
-                   break;
-
-          case WINED3DPS_VERSION(3,0):
-                   This->baseShader.limits.temporary = 32;
-                   This->baseShader.limits.constant_float = 224;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.texcoord = 0;
-                   This->baseShader.limits.sampler = 16;
-                   This->baseShader.limits.packed_input = 12;
-                   This->baseShader.limits.label = 16; /* FIXME: 2048 */
-                   break;
-
-          default: This->baseShader.limits.temporary = 32;
-                   This->baseShader.limits.constant_float = 32;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.texcoord = 8;
-                   This->baseShader.limits.sampler = 16;
-                   This->baseShader.limits.packed_input = 0;
-                   This->baseShader.limits.label = 0;
-                   FIXME("Unrecognized pixel shader version %#x\n",
-                           This->baseShader.reg_maps.shader_version);
-      }
-}
+    This->baseShader.limits.attributes = 0;
+    This->baseShader.limits.address = 0;
+    This->baseShader.limits.packed_output = 0;
 
 
-static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
+    switch (shader_version)
+    {
+        case WINED3D_SHADER_VERSION(1,0):
+        case WINED3D_SHADER_VERSION(1,1):
+        case WINED3D_SHADER_VERSION(1,2):
+        case WINED3D_SHADER_VERSION(1,3):
+            This->baseShader.limits.temporary = 2;
+            This->baseShader.limits.constant_float = 8;
+            This->baseShader.limits.constant_int = 0;
+            This->baseShader.limits.constant_bool = 0;
+            This->baseShader.limits.texcoord = 4;
+            This->baseShader.limits.sampler = 4;
+            This->baseShader.limits.packed_input = 0;
+            This->baseShader.limits.label = 0;
+            break;
+
+        case WINED3D_SHADER_VERSION(1,4):
+            This->baseShader.limits.temporary = 6;
+            This->baseShader.limits.constant_float = 8;
+            This->baseShader.limits.constant_int = 0;
+            This->baseShader.limits.constant_bool = 0;
+            This->baseShader.limits.texcoord = 6;
+            This->baseShader.limits.sampler = 6;
+            This->baseShader.limits.packed_input = 0;
+            This->baseShader.limits.label = 0;
+            break;
+
+        /* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
+        case WINED3D_SHADER_VERSION(2,0):
+            This->baseShader.limits.temporary = 32;
+            This->baseShader.limits.constant_float = 32;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.texcoord = 8;
+            This->baseShader.limits.sampler = 16;
+            This->baseShader.limits.packed_input = 0;
+            break;
+
+        case WINED3D_SHADER_VERSION(2,1):
+            This->baseShader.limits.temporary = 32;
+            This->baseShader.limits.constant_float = 32;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.texcoord = 8;
+            This->baseShader.limits.sampler = 16;
+            This->baseShader.limits.packed_input = 0;
+            This->baseShader.limits.label = 16;
+            break;
+
+        case WINED3D_SHADER_VERSION(3,0):
+            This->baseShader.limits.temporary = 32;
+            This->baseShader.limits.constant_float = 224;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.texcoord = 0;
+            This->baseShader.limits.sampler = 16;
+            This->baseShader.limits.packed_input = 12;
+            This->baseShader.limits.label = 16; /* FIXME: 2048 */
+            break;
+
+        default:
+            This->baseShader.limits.temporary = 32;
+            This->baseShader.limits.constant_float = 32;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.texcoord = 8;
+            This->baseShader.limits.sampler = 16;
+            This->baseShader.limits.packed_input = 0;
+            This->baseShader.limits.label = 0;
+            FIXME("Unrecognized pixel shader version %u.%u\n",
+                    This->baseShader.reg_maps.shader_version.major,
+                    This->baseShader.reg_maps.shader_version.minor);
+    }
+}
 
 
+static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface,
+        const DWORD *pFunction, const struct wined3d_shader_signature *output_signature)
+{
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
-    IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     unsigned int i, highest_reg_used = 0, num_regs_used = 0;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
     unsigned int i, highest_reg_used = 0, num_regs_used = 0;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
+    const struct wined3d_shader_frontend *fe;
     HRESULT hr;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     HRESULT hr;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
+    fe = shader_select_frontend(*pFunction);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+    This->baseShader.frontend = fe;
+    This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature);
+    if (!This->baseShader.frontend_data)
+    {
+        FIXME("Failed to initialize frontend.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     /* First pass: trace shader */
     /* First pass: trace shader */
-    if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(fe, This->baseShader.frontend_data, pFunction);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
@@ -313,8 +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.. */
-    memset(reg_maps, 0, sizeof(shader_reg_maps));
-    hr = shader_get_registers_used((IWineD3DBaseShader *)This, reg_maps, This->semantics_in, NULL, pFunction);
+    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);
@@ -360,8 +285,6 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
 
     This->baseShader.load_local_constsF = FALSE;
 
 
     This->baseShader.load_local_constsF = FALSE;
 
-    This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
-
     TRACE("(%p) : Copying the function\n", This);
 
     This->baseShader.function = HeapAlloc(GetProcessHeap(), 0, This->baseShader.functionLength);
     TRACE("(%p) : Copying the function\n", This);
 
     This->baseShader.function = HeapAlloc(GetProcessHeap(), 0, This->baseShader.functionLength);
@@ -373,21 +296,20 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
 
 static 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)
 {
-    DWORD shader_version = reg_maps->shader_version;
-    DWORD *samplers = reg_maps->samplers;
+    WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type;
     unsigned int i;
 
     unsigned int i;
 
-    if (WINED3DSHADER_VERSION_MAJOR(shader_version) != 1) return;
+    if (reg_maps->shader_version.major != 1) return;
 
     for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
     {
         /* We don't sample from this sampler */
 
     for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
     {
         /* We don't sample from this sampler */
-        if (!samplers[i]) continue;
+        if (!sampler_type[i]) continue;
 
         if (!textures[i])
         {
             ERR("No texture bound to sampler %u, using 2D\n", i);
 
         if (!textures[i])
         {
             ERR("No texture bound to sampler %u, using 2D\n", i);
-            samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+            sampler_type[i] = WINED3DSTT_2D;
             continue;
         }
 
             continue;
         }
 
@@ -397,21 +319,21 @@ static void pixelshader_update_samplers(struct shader_reg_maps *reg_maps, IWineD
             case GL_TEXTURE_2D:
                 /* We have to select between texture rectangles and 2D textures later because 2.0 and
                  * 3.0 shaders only have WINED3DSTT_2D as well */
             case GL_TEXTURE_2D:
                 /* We have to select between texture rectangles and 2D textures later because 2.0 and
                  * 3.0 shaders only have WINED3DSTT_2D as well */
-                samplers[i] = (1 << 31) | WINED3DSTT_2D;
+                sampler_type[i] = WINED3DSTT_2D;
                 break;
 
             case GL_TEXTURE_3D:
                 break;
 
             case GL_TEXTURE_3D:
-                samplers[i] = (1 << 31) | WINED3DSTT_VOLUME;
+                sampler_type[i] = WINED3DSTT_VOLUME;
                 break;
 
             case GL_TEXTURE_CUBE_MAP_ARB:
                 break;
 
             case GL_TEXTURE_CUBE_MAP_ARB:
-                samplers[i] = (1 << 31) | WINED3DSTT_CUBE;
+                sampler_type[i] = WINED3DSTT_CUBE;
                 break;
 
             default:
                 FIXME("Unrecognized texture type %#x, using 2D\n",
                         IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
                 break;
 
             default:
                 FIXME("Unrecognized texture type %#x, using 2D\n",
                         IWineD3DBaseTexture_GetTextureDimensions(textures[i]));
-                samplers[i] = (0x1 << 31) | WINED3DSTT_2D;
+                sampler_type[i] = WINED3DSTT_2D;
         }
     }
 }
         }
     }
 }
@@ -463,7 +385,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
     args->np2_fixup = 0;
 
     for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) {
     args->np2_fixup = 0;
 
     for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) {
-        if(shader->baseShader.reg_maps.samplers[i] == 0) continue;
+        if (!shader->baseShader.reg_maps.sampler_type[i]) continue;
         tex = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
         if(!tex) {
             args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
         tex = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
         if(!tex) {
             args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
@@ -476,7 +398,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
             args->np2_fixup |= (1 << i);
         }
     }
             args->np2_fixup |= (1 << i);
         }
     }
-    if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0))
+    if (shader->baseShader.reg_maps.shader_version.major >= 3)
     {
         if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.position_transformed)
         {
     {
         if (((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.position_transformed)
         {
diff --git a/reactos/dll/directx/wine/wined3d/shader_sm1.c b/reactos/dll/directx/wine/wined3d/shader_sm1.c
new file mode 100644 (file)
index 0000000..a626d52
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+/* DCL usage masks */
+#define WINED3DSP_DCL_USAGE_SHIFT               0
+#define WINED3DSP_DCL_USAGE_MASK                (0xf << WINED3DSP_DCL_USAGE_SHIFT)
+#define WINED3DSP_DCL_USAGEINDEX_SHIFT          16
+#define WINED3DSP_DCL_USAGEINDEX_MASK           (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
+
+/* DCL sampler type */
+#define WINED3DSP_TEXTURETYPE_SHIFT             27
+#define WINED3DSP_TEXTURETYPE_MASK              (0xf << WINED3DSP_TEXTURETYPE_SHIFT)
+
+/* Opcode-related masks */
+#define WINED3DSI_OPCODE_MASK                   0x0000ffff
+
+#define WINED3D_OPCODESPECIFICCONTROL_SHIFT     16
+#define WINED3D_OPCODESPECIFICCONTROL_MASK      (0xff << WINED3D_OPCODESPECIFICCONTROL_SHIFT)
+
+#define WINED3DSI_INSTLENGTH_SHIFT              24
+#define WINED3DSI_INSTLENGTH_MASK               (0xf << WINED3DSI_INSTLENGTH_SHIFT)
+
+#define WINED3DSI_COISSUE                       (1 << 30)
+
+#define WINED3DSI_COMMENTSIZE_SHIFT             16
+#define WINED3DSI_COMMENTSIZE_MASK              (0x7fff << WINED3DSI_COMMENTSIZE_SHIFT)
+
+#define WINED3DSHADER_INSTRUCTION_PREDICATED    (1 << 28)
+
+/* Register number mask */
+#define WINED3DSP_REGNUM_MASK                   0x000007ff
+
+/* Register type masks  */
+#define WINED3DSP_REGTYPE_SHIFT                 28
+#define WINED3DSP_REGTYPE_MASK                  (0x7 << WINED3DSP_REGTYPE_SHIFT)
+#define WINED3DSP_REGTYPE_SHIFT2                8
+#define WINED3DSP_REGTYPE_MASK2                 (0x18 << WINED3DSP_REGTYPE_SHIFT2)
+
+/* Relative addressing mask */
+#define WINED3DSHADER_ADDRESSMODE_SHIFT         13
+#define WINED3DSHADER_ADDRESSMODE_MASK          (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
+
+/* Destination modifier mask */
+#define WINED3DSP_DSTMOD_SHIFT                  20
+#define WINED3DSP_DSTMOD_MASK                   (0xf << WINED3DSP_DSTMOD_SHIFT)
+
+/* Destination shift mask */
+#define WINED3DSP_DSTSHIFT_SHIFT                24
+#define WINED3DSP_DSTSHIFT_MASK                 (0xf << WINED3DSP_DSTSHIFT_SHIFT)
+
+/* Write mask */
+#define WINED3D_SM1_WRITEMASK_SHIFT             16
+#define WINED3D_SM1_WRITEMASK_MASK              (0xf << WINED3D_SM1_WRITEMASK_SHIFT)
+
+/* Swizzle mask */
+#define WINED3DSP_SWIZZLE_SHIFT                 16
+#define WINED3DSP_SWIZZLE_MASK                  (0xff << WINED3DSP_SWIZZLE_SHIFT)
+
+/* Source modifier mask */
+#define WINED3DSP_SRCMOD_SHIFT                  24
+#define WINED3DSP_SRCMOD_MASK                   (0xf << WINED3DSP_SRCMOD_SHIFT)
+
+#define WINED3DSP_END                           0x0000ffff
+
+#define WINED3D_SM1_VERSION_MAJOR(version)      (((version) >> 8) & 0xff)
+#define WINED3D_SM1_VERSION_MINOR(version)      (((version) >> 0) & 0xff)
+
+enum WINED3DSHADER_ADDRESSMODE_TYPE
+{
+    WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+    WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+};
+
+struct wined3d_sm1_opcode_info
+{
+    unsigned int opcode;
+    UINT dst_count;
+    UINT param_count;
+    enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+    DWORD min_version;
+    DWORD max_version;
+};
+
+struct wined3d_sm1_data
+{
+    struct wined3d_shader_version shader_version;
+    const struct wined3d_sm1_opcode_info *opcode_table;
+};
+
+/* This table is not order or position dependent. */
+static const struct wined3d_sm1_opcode_info vs_opcode_table[] =
+{
+    /* Arithmetic */
+    {WINED3DSIO_NOP,          0, 0, WINED3DSIH_NOP,          0,                           0                          },
+    {WINED3DSIO_MOV,          1, 2, WINED3DSIH_MOV,          0,                           0                          },
+    {WINED3DSIO_MOVA,         1, 2, WINED3DSIH_MOVA,         WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_ADD,          1, 3, WINED3DSIH_ADD,          0,                           0                          },
+    {WINED3DSIO_SUB,          1, 3, WINED3DSIH_SUB,          0,                           0                          },
+    {WINED3DSIO_MAD,          1, 4, WINED3DSIH_MAD,          0,                           0                          },
+    {WINED3DSIO_MUL,          1, 3, WINED3DSIH_MUL,          0,                           0                          },
+    {WINED3DSIO_RCP,          1, 2, WINED3DSIH_RCP,          0,                           0                          },
+    {WINED3DSIO_RSQ,          1, 2, WINED3DSIH_RSQ,          0,                           0                          },
+    {WINED3DSIO_DP3,          1, 3, WINED3DSIH_DP3,          0,                           0                          },
+    {WINED3DSIO_DP4,          1, 3, WINED3DSIH_DP4,          0,                           0                          },
+    {WINED3DSIO_MIN,          1, 3, WINED3DSIH_MIN,          0,                           0                          },
+    {WINED3DSIO_MAX,          1, 3, WINED3DSIH_MAX,          0,                           0                          },
+    {WINED3DSIO_SLT,          1, 3, WINED3DSIH_SLT,          0,                           0                          },
+    {WINED3DSIO_SGE,          1, 3, WINED3DSIH_SGE,          0,                           0                          },
+    {WINED3DSIO_ABS,          1, 2, WINED3DSIH_ABS,          0,                           0                          },
+    {WINED3DSIO_EXP,          1, 2, WINED3DSIH_EXP,          0,                           0                          },
+    {WINED3DSIO_LOG,          1, 2, WINED3DSIH_LOG,          0,                           0                          },
+    {WINED3DSIO_EXPP,         1, 2, WINED3DSIH_EXPP,         0,                           0                          },
+    {WINED3DSIO_LOGP,         1, 2, WINED3DSIH_LOGP,         0,                           0                          },
+    {WINED3DSIO_LIT,          1, 2, WINED3DSIH_LIT,          0,                           0                          },
+    {WINED3DSIO_DST,          1, 3, WINED3DSIH_DST,          0,                           0                          },
+    {WINED3DSIO_LRP,          1, 4, WINED3DSIH_LRP,          0,                           0                          },
+    {WINED3DSIO_FRC,          1, 2, WINED3DSIH_FRC,          0,                           0                          },
+    {WINED3DSIO_POW,          1, 3, WINED3DSIH_POW,          0,                           0                          },
+    {WINED3DSIO_CRS,          1, 3, WINED3DSIH_CRS,          0,                           0                          },
+    {WINED3DSIO_SGN,          1, 2, WINED3DSIH_SGN,          0,                           0                          },
+    {WINED3DSIO_NRM,          1, 2, WINED3DSIH_NRM,          0,                           0                          },
+    {WINED3DSIO_SINCOS,       1, 4, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+    {WINED3DSIO_SINCOS,       1, 2, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(3,0), -1                         },
+    /* Matrix */
+    {WINED3DSIO_M4x4,         1, 3, WINED3DSIH_M4x4,         0,                           0                          },
+    {WINED3DSIO_M4x3,         1, 3, WINED3DSIH_M4x3,         0,                           0                          },
+    {WINED3DSIO_M3x4,         1, 3, WINED3DSIH_M3x4,         0,                           0                          },
+    {WINED3DSIO_M3x3,         1, 3, WINED3DSIH_M3x3,         0,                           0                          },
+    {WINED3DSIO_M3x2,         1, 3, WINED3DSIH_M3x2,         0,                           0                          },
+    /* Declare registers */
+    {WINED3DSIO_DCL,          0, 2, WINED3DSIH_DCL,          0,                           0                          },
+    /* Constant definitions */
+    {WINED3DSIO_DEF,          1, 5, WINED3DSIH_DEF,          0,                           0                          },
+    {WINED3DSIO_DEFB,         1, 2, WINED3DSIH_DEFB,         0,                           0                          },
+    {WINED3DSIO_DEFI,         1, 5, WINED3DSIH_DEFI,         0,                           0                          },
+    /* Flow control */
+    {WINED3DSIO_REP,          0, 1, WINED3DSIH_REP,          WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_ENDREP,       0, 0, WINED3DSIH_ENDREP,       WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_IF,           0, 1, WINED3DSIH_IF,           WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_IFC,          0, 2, WINED3DSIH_IFC,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_ELSE,         0, 0, WINED3DSIH_ELSE,         WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_ENDIF,        0, 0, WINED3DSIH_ENDIF,        WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_BREAK,        0, 0, WINED3DSIH_BREAK,        WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_BREAKC,       0, 2, WINED3DSIH_BREAKC,       WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_BREAKP,       0, 1, WINED3DSIH_BREAKP,       0,                           0                          },
+    {WINED3DSIO_CALL,         0, 1, WINED3DSIH_CALL,         WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_CALLNZ,       0, 2, WINED3DSIH_CALLNZ,       WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_LOOP,         0, 2, WINED3DSIH_LOOP,         WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_RET,          0, 0, WINED3DSIH_RET,          WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_ENDLOOP,      0, 0, WINED3DSIH_ENDLOOP,      WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_LABEL,        0, 1, WINED3DSIH_LABEL,        WINED3D_SHADER_VERSION(2,0), -1                         },
+
+    {WINED3DSIO_SETP,         1, 3, WINED3DSIH_SETP,         0,                           0                          },
+    {WINED3DSIO_TEXLDL,       1, 3, WINED3DSIH_TEXLDL,       WINED3D_SHADER_VERSION(3,0), -1                         },
+    {0,                       0, 0, WINED3DSIH_TABLE_SIZE,   0,                           0                          },
+};
+
+static const struct wined3d_sm1_opcode_info ps_opcode_table[] =
+{
+    /* Arithmetic */
+    {WINED3DSIO_NOP,          0, 0, WINED3DSIH_NOP,          0,                           0                          },
+    {WINED3DSIO_MOV,          1, 2, WINED3DSIH_MOV,          0,                           0                          },
+    {WINED3DSIO_ADD,          1, 3, WINED3DSIH_ADD,          0,                           0                          },
+    {WINED3DSIO_SUB,          1, 3, WINED3DSIH_SUB,          0,                           0                          },
+    {WINED3DSIO_MAD,          1, 4, WINED3DSIH_MAD,          0,                           0                          },
+    {WINED3DSIO_MUL,          1, 3, WINED3DSIH_MUL,          0,                           0                          },
+    {WINED3DSIO_RCP,          1, 2, WINED3DSIH_RCP,          0,                           0                          },
+    {WINED3DSIO_RSQ,          1, 2, WINED3DSIH_RSQ,          0,                           0                          },
+    {WINED3DSIO_DP3,          1, 3, WINED3DSIH_DP3,          0,                           0                          },
+    {WINED3DSIO_DP4,          1, 3, WINED3DSIH_DP4,          0,                           0                          },
+    {WINED3DSIO_MIN,          1, 3, WINED3DSIH_MIN,          0,                           0                          },
+    {WINED3DSIO_MAX,          1, 3, WINED3DSIH_MAX,          0,                           0                          },
+    {WINED3DSIO_SLT,          1, 3, WINED3DSIH_SLT,          0,                           0                          },
+    {WINED3DSIO_SGE,          1, 3, WINED3DSIH_SGE,          0,                           0                          },
+    {WINED3DSIO_ABS,          1, 2, WINED3DSIH_ABS,          0,                           0                          },
+    {WINED3DSIO_EXP,          1, 2, WINED3DSIH_EXP,          0,                           0                          },
+    {WINED3DSIO_LOG,          1, 2, WINED3DSIH_LOG,          0,                           0                          },
+    {WINED3DSIO_EXPP,         1, 2, WINED3DSIH_EXPP,         0,                           0                          },
+    {WINED3DSIO_LOGP,         1, 2, WINED3DSIH_LOGP,         0,                           0                          },
+    {WINED3DSIO_DST,          1, 3, WINED3DSIH_DST,          0,                           0                          },
+    {WINED3DSIO_LRP,          1, 4, WINED3DSIH_LRP,          0,                           0                          },
+    {WINED3DSIO_FRC,          1, 2, WINED3DSIH_FRC,          0,                           0                          },
+    {WINED3DSIO_CND,          1, 4, WINED3DSIH_CND,          WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,4)},
+    {WINED3DSIO_CMP,          1, 4, WINED3DSIH_CMP,          WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(3,0)},
+    {WINED3DSIO_POW,          1, 3, WINED3DSIH_POW,          0,                           0                          },
+    {WINED3DSIO_CRS,          1, 3, WINED3DSIH_CRS,          0,                           0                          },
+    {WINED3DSIO_NRM,          1, 2, WINED3DSIH_NRM,          0,                           0                          },
+    {WINED3DSIO_SINCOS,       1, 4, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+    {WINED3DSIO_SINCOS,       1, 2, WINED3DSIH_SINCOS,       WINED3D_SHADER_VERSION(3,0), -1                         },
+    {WINED3DSIO_DP2ADD,       1, 4, WINED3DSIH_DP2ADD,       WINED3D_SHADER_VERSION(2,0), -1                         },
+    /* Matrix */
+    {WINED3DSIO_M4x4,         1, 3, WINED3DSIH_M4x4,         0,                           0                          },
+    {WINED3DSIO_M4x3,         1, 3, WINED3DSIH_M4x3,         0,                           0                          },
+    {WINED3DSIO_M3x4,         1, 3, WINED3DSIH_M3x4,         0,                           0                          },
+    {WINED3DSIO_M3x3,         1, 3, WINED3DSIH_M3x3,         0,                           0                          },
+    {WINED3DSIO_M3x2,         1, 3, WINED3DSIH_M3x2,         0,                           0                          },
+    /* Register declarations */
+    {WINED3DSIO_DCL,          0, 2, WINED3DSIH_DCL,          0,                           0                          },
+    /* Flow control */
+    {WINED3DSIO_REP,          0, 1, WINED3DSIH_REP,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_ENDREP,       0, 0, WINED3DSIH_ENDREP,       WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_IF,           0, 1, WINED3DSIH_IF,           WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_IFC,          0, 2, WINED3DSIH_IFC,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_ELSE,         0, 0, WINED3DSIH_ELSE,         WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_ENDIF,        0, 0, WINED3DSIH_ENDIF,        WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_BREAK,        0, 0, WINED3DSIH_BREAK,        WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_BREAKC,       0, 2, WINED3DSIH_BREAKC,       WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_BREAKP,       0, 1, WINED3DSIH_BREAKP,       0,                           0                          },
+    {WINED3DSIO_CALL,         0, 1, WINED3DSIH_CALL,         WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_CALLNZ,       0, 2, WINED3DSIH_CALLNZ,       WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_LOOP,         0, 2, WINED3DSIH_LOOP,         WINED3D_SHADER_VERSION(3,0), -1                         },
+    {WINED3DSIO_RET,          0, 0, WINED3DSIH_RET,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_ENDLOOP,      0, 0, WINED3DSIH_ENDLOOP,      WINED3D_SHADER_VERSION(3,0), -1                         },
+    {WINED3DSIO_LABEL,        0, 1, WINED3DSIH_LABEL,        WINED3D_SHADER_VERSION(2,1), -1                         },
+    /* Constant definitions */
+    {WINED3DSIO_DEF,          1, 5, WINED3DSIH_DEF,          0,                           0                          },
+    {WINED3DSIO_DEFB,         1, 2, WINED3DSIH_DEFB,         0,                           0                          },
+    {WINED3DSIO_DEFI,         1, 5, WINED3DSIH_DEFI,         0,                           0                          },
+    /* Texture */
+    {WINED3DSIO_TEXCOORD,     1, 1, WINED3DSIH_TEXCOORD,     0,                           WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXCOORD,     1, 2, WINED3DSIH_TEXCOORD,     WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+    {WINED3DSIO_TEXKILL,      1, 1, WINED3DSIH_TEXKILL,      WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(3,0)},
+    {WINED3DSIO_TEX,          1, 1, WINED3DSIH_TEX,          0,                           WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEX,          1, 2, WINED3DSIH_TEX,          WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+    {WINED3DSIO_TEX,          1, 3, WINED3DSIH_TEX,          WINED3D_SHADER_VERSION(2,0), -1                         },
+    {WINED3DSIO_TEXBEM,       1, 2, WINED3DSIH_TEXBEM,       0,                           WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXBEML,      1, 2, WINED3DSIH_TEXBEML,      WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2AR,    1, 2, WINED3DSIH_TEXREG2AR,    WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2GB,    1, 2, WINED3DSIH_TEXREG2GB,    WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXREG2RGB,   1, 2, WINED3DSIH_TEXREG2RGB,   WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2PAD,   1, 2, WINED3DSIH_TEXM3x2PAD,   WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2TEX,   1, 2, WINED3DSIH_TEXM3x2TEX,   WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3PAD,   1, 2, WINED3DSIH_TEXM3x3PAD,   WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3DIFF,  1, 2, WINED3DSIH_TEXM3x3DIFF,  WINED3D_SHADER_VERSION(0,0), WINED3D_SHADER_VERSION(0,0)},
+    {WINED3DSIO_TEXM3x3SPEC,  1, 3, WINED3DSIH_TEXM3x3SPEC,  WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3VSPEC, 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3TEX,   1, 2, WINED3DSIH_TEXM3x3TEX,   WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXDP3TEX,    1, 2, WINED3DSIH_TEXDP3TEX,    WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x2DEPTH, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3D_SHADER_VERSION(1,3), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXDP3,       1, 2, WINED3DSIH_TEXDP3,       WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXM3x3,      1, 2, WINED3DSIH_TEXM3x3,      WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+    {WINED3DSIO_TEXDEPTH,     1, 1, WINED3DSIH_TEXDEPTH,     WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+    {WINED3DSIO_BEM,          1, 3, WINED3DSIH_BEM,          WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+    {WINED3DSIO_DSX,          1, 2, WINED3DSIH_DSX,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_DSY,          1, 2, WINED3DSIH_DSY,          WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_TEXLDD,       1, 5, WINED3DSIH_TEXLDD,       WINED3D_SHADER_VERSION(2,1), -1                         },
+    {WINED3DSIO_SETP,         1, 3, WINED3DSIH_SETP,         0,                           0                          },
+    {WINED3DSIO_TEXLDL,       1, 3, WINED3DSIH_TEXLDL,       WINED3D_SHADER_VERSION(3,0), -1                         },
+    {WINED3DSIO_PHASE,        0, 0, WINED3DSIH_PHASE,        0,                           0                          },
+    {0,                       0, 0, WINED3DSIH_TABLE_SIZE,   0,                           0                          },
+};
+
+/* Read a parameter opcode from the input stream,
+ * and possibly a relative addressing token.
+ * Return the number of tokens read */
+static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, DWORD *token, DWORD *addr_token)
+{
+    UINT count = 1;
+
+    *token = *ptr;
+
+    /* PS >= 3.0 have relative addressing (with token)
+     * VS >= 2.0 have relative addressing (with token)
+     * VS >= 1.0 < 2.0 have relative addressing (without token)
+     * The version check below should work in general */
+    if (*ptr & WINED3DSHADER_ADDRMODE_RELATIVE)
+    {
+        if (priv->shader_version.major < 2)
+        {
+            *addr_token = (1 << 31)
+                    | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2)
+                    | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK)
+                    | (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT);
+        }
+        else
+        {
+            *addr_token = *(ptr + 1);
+            ++count;
+        }
+    }
+
+    return count;
+}
+
+static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD code)
+{
+    DWORD shader_version = WINED3D_SHADER_VERSION(priv->shader_version.major, priv->shader_version.minor);
+    const struct wined3d_sm1_opcode_info *opcode_table = priv->opcode_table;
+    DWORD i = 0;
+
+    while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE)
+    {
+        if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
+                && shader_version >= opcode_table[i].min_version
+                && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
+        {
+            return &opcode_table[i];
+        }
+        ++i;
+    }
+
+    FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
+            code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
+
+    return NULL;
+}
+
+/* Return the number of parameters to skip for an opcode */
+static int shader_skip_opcode(const struct wined3d_sm1_data *priv,
+        const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token)
+{
+   /* Shaders >= 2.0 may contain address tokens, but fortunately they
+    * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
+    return (priv->shader_version.major >= 2)
+            ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->param_count;
+}
+
+static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+        struct wined3d_shader_src_param *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->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+    src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
+    src->reg.rel_addr = rel_addr;
+}
+
+static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+        struct wined3d_shader_dst_param *dst)
+{
+    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->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->reg.rel_addr = rel_addr;
+}
+
+/* Read the parameters of an unrecognized opcode from the input stream
+ * Return the number of tokens read.
+ *
+ * Note: This function assumes source or destination token format.
+ * It will not work with specially-formatted tokens like DEF or DCL,
+ * but hopefully those would be recognized */
+static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr)
+{
+    int tokens_read = 0;
+    int i = 0;
+
+    /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
+    while (*ptr & 0x80000000)
+    {
+        DWORD token, addr_token = 0;
+        struct wined3d_shader_src_param rel_addr;
+
+        tokens_read += shader_get_param(priv, ptr, &token, &addr_token);
+        ptr += tokens_read;
+
+        FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token);
+
+        if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr);
+
+        if (!i)
+        {
+            struct wined3d_shader_dst_param dst;
+
+            shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst);
+            shader_dump_dst_param(&dst, &priv->shader_version);
+        }
+        else
+        {
+            struct wined3d_shader_src_param src;
+
+            shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src);
+            shader_dump_src_param(&src, &priv->shader_version);
+        }
+        FIXME("\n");
+        ++i;
+    }
+    return tokens_read;
+}
+
+static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+    struct wined3d_sm1_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+    if (!priv)
+    {
+        ERR("Failed to allocate private data\n");
+        return NULL;
+    }
+
+    if (output_signature)
+    {
+        FIXME("SM 1-3 shader shouldn't have output signatures.\n");
+    }
+
+    switch (*byte_code >> 16)
+    {
+        case WINED3D_SM1_VS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+            priv->opcode_table = vs_opcode_table;
+            break;
+
+        case WINED3D_SM1_PS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+            priv->opcode_table = ps_opcode_table;
+            break;
+
+        default:
+            FIXME("Unrecognized shader type %#x\n", *byte_code >> 16);
+            HeapFree(GetProcessHeap(), 0, priv);
+            return NULL;
+    }
+
+    return priv;
+}
+
+static void shader_sm1_free(void *data)
+{
+    HeapFree(GetProcessHeap(), 0, data);
+}
+
+static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+    struct wined3d_sm1_data *priv = data;
+    DWORD version_token;
+
+    version_token = *(*ptr)++;
+    TRACE("version: 0x%08x\n", version_token);
+
+    priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(version_token);
+    priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(version_token);
+    *shader_version = priv->shader_version;
+}
+
+static void shader_sm1_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins,
+        UINT *param_size)
+{
+    struct wined3d_sm1_data *priv = data;
+    const struct wined3d_sm1_opcode_info *opcode_info;
+    DWORD opcode_token;
+
+    opcode_token = *(*ptr)++;
+    opcode_info = shader_get_opcode(priv, opcode_token);
+    if (!opcode_info)
+    {
+        FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token);
+        ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+        *param_size = shader_skip_unrecognized(priv, *ptr);
+        return;
+    }
+
+    ins->handler_idx = opcode_info->handler_idx;
+    ins->flags = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT;
+    ins->coissue = opcode_token & WINED3DSI_COISSUE;
+    ins->predicate = opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED;
+    ins->dst_count = opcode_info->dst_count ? 1 : 0;
+    ins->src_count = opcode_info->param_count - opcode_info->dst_count;
+    *param_size = shader_skip_opcode(priv, opcode_info, opcode_token);
+}
+
+static void shader_sm1_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+        struct wined3d_shader_src_param *src_rel_addr)
+{
+    struct wined3d_sm1_data *priv = data;
+    DWORD token, addr_token;
+
+    *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+    if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+    {
+        shader_parse_src_param(addr_token, NULL, src_rel_addr);
+        shader_parse_src_param(token, src_rel_addr, src_param);
+    }
+    else
+    {
+        shader_parse_src_param(token, NULL, src_param);
+    }
+}
+
+static void shader_sm1_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+        struct wined3d_shader_src_param *dst_rel_addr)
+{
+    struct wined3d_sm1_data *priv = data;
+    DWORD token, addr_token;
+
+    *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+    if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+    {
+        shader_parse_src_param(addr_token, NULL, dst_rel_addr);
+        shader_parse_dst_param(token, dst_rel_addr, dst_param);
+    }
+    else
+    {
+        shader_parse_dst_param(token, NULL, dst_param);
+    }
+}
+
+static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
+{
+    DWORD usage_token = *(*ptr)++;
+    DWORD dst_token = *(*ptr)++;
+
+    semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
+    semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+    semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT;
+    shader_parse_dst_param(dst_token, NULL, &semantic->reg);
+}
+
+static void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
+{
+    DWORD token = **ptr;
+
+    if ((token & WINED3DSI_OPCODE_MASK) != WINED3DSIO_COMMENT)
+    {
+        *comment = NULL;
+        return;
+    }
+
+    *comment = (const char *)++(*ptr);
+    *ptr += (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
+}
+
+static BOOL shader_sm1_is_end(void *data, const DWORD **ptr)
+{
+    if (**ptr == WINED3DSP_END)
+    {
+        ++(*ptr);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+const struct wined3d_shader_frontend sm1_shader_frontend =
+{
+    shader_sm1_init,
+    shader_sm1_free,
+    shader_sm1_read_header,
+    shader_sm1_read_opcode,
+    shader_sm1_read_src_param,
+    shader_sm1_read_dst_param,
+    shader_sm1_read_semantic,
+    shader_sm1_read_comment,
+    shader_sm1_is_end,
+};
diff --git a/reactos/dll/directx/wine/wined3d/shader_sm4.c b/reactos/dll/directx/wine/wined3d/shader_sm4.c
new file mode 100644 (file)
index 0000000..5cc445d
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT    24
+#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK     (0xf << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
+
+#define WINED3D_SM4_OPCODE_MASK                 0xff
+
+#define WINED3D_SM4_REGISTER_TYPE_SHIFT         12
+#define WINED3D_SM4_REGISTER_TYPE_MASK          (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
+
+#define WINED3D_SM4_IMMCONST_TYPE_SHIFT         0
+#define WINED3D_SM4_IMMCONST_TYPE_MASK          (0x3 << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
+
+#define WINED3D_SM4_WRITEMASK_SHIFT             4
+#define WINED3D_SM4_WRITEMASK_MASK              (0xf << WINED3D_SM4_WRITEMASK_SHIFT)
+
+#define WINED3D_SM4_SWIZZLE_SHIFT               4
+#define WINED3D_SM4_SWIZZLE_MASK                (0xff << WINED3D_SM4_SWIZZLE_SHIFT)
+
+#define WINED3D_SM4_VERSION_MAJOR(version)      (((version) >> 4) & 0xf)
+#define WINED3D_SM4_VERSION_MINOR(version)      (((version) >> 0) & 0xf)
+
+enum wined3d_sm4_opcode
+{
+    WINED3D_SM4_OP_ADD      = 0x00,
+    WINED3D_SM4_OP_EXP      = 0x19,
+    WINED3D_SM4_OP_MOV      = 0x36,
+    WINED3D_SM4_OP_MUL      = 0x38,
+    WINED3D_SM4_OP_RET      = 0x3e,
+    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,
+};
+
+enum wined3d_sm4_immconst_type
+{
+    WINED3D_SM4_IMMCONST_FLOAT  = 0x1,
+    WINED3D_SM4_IMMCONST_FLOAT4 = 0x2,
+};
+
+struct wined3d_sm4_data
+{
+    struct wined3d_shader_version shader_version;
+    const DWORD *end;
+    const struct wined3d_shader_signature *output_signature;
+};
+
+struct wined3d_sm4_opcode_info
+{
+    enum wined3d_sm4_opcode opcode;
+    enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+    UINT dst_count;
+    UINT src_count;
+};
+
+struct sysval_map
+{
+    enum wined3d_sysval_semantic sysval;
+    WINED3DSHADER_PARAM_REGISTER_TYPE register_type;
+    UINT register_idx;
+};
+
+static const struct wined3d_sm4_opcode_info opcode_table[] =
+{
+    {WINED3D_SM4_OP_ADD,    WINED3DSIH_ADD,         1,  2},
+    {WINED3D_SM4_OP_EXP,    WINED3DSIH_EXP,         1,  1},
+    {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_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,
+};
+
+static const struct sysval_map sysval_map[] =
+{
+    {WINED3D_SV_DEPTH,      WINED3DSPR_DEPTHOUT,    0},
+    {WINED3D_SV_TARGET0,    WINED3DSPR_COLOROUT,    0},
+    {WINED3D_SV_TARGET1,    WINED3DSPR_COLOROUT,    1},
+    {WINED3D_SV_TARGET2,    WINED3DSPR_COLOROUT,    2},
+    {WINED3D_SV_TARGET3,    WINED3DSPR_COLOROUT,    3},
+    {WINED3D_SV_TARGET4,    WINED3DSPR_COLOROUT,    4},
+    {WINED3D_SV_TARGET5,    WINED3DSPR_COLOROUT,    5},
+    {WINED3D_SV_TARGET6,    WINED3DSPR_COLOROUT,    6},
+    {WINED3D_SV_TARGET7,    WINED3DSPR_COLOROUT,    7},
+};
+
+static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode)
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i)
+    {
+        if (opcode == opcode_table[i].opcode) return &opcode_table[i];
+    }
+
+    return NULL;
+}
+
+static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg)
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i)
+    {
+        if (sysval == sysval_map[i].sysval)
+        {
+            reg->type = sysval_map[i].register_type;
+            reg->idx = sysval_map[i].register_idx;
+        }
+    }
+}
+
+static void map_register(struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg)
+{
+    switch (priv->shader_version.type)
+    {
+        case WINED3D_SHADER_TYPE_PIXEL:
+            if (reg->type == WINED3DSPR_OUTPUT)
+            {
+                unsigned int i;
+                const struct wined3d_shader_signature *s = priv->output_signature;
+
+                if (!s)
+                {
+                    ERR("Shader has no output signature, unable to map register.\n");
+                    break;
+                }
+
+                for (i = 0; i < s->element_count; ++i)
+                {
+                    if (s->elements[i].register_idx == reg->idx)
+                    {
+                        map_sysval(s->elements[i].sysval_semantic, reg);
+                        break;
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+}
+
+static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+    struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+    if (!priv)
+    {
+        ERR("Failed to allocate private data\n");
+        return NULL;
+    }
+
+    priv->output_signature = output_signature;
+
+    return priv;
+}
+
+static void shader_sm4_free(void *data)
+{
+    HeapFree(GetProcessHeap(), 0, data);
+}
+
+static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+    struct wined3d_sm4_data *priv = data;
+    DWORD version_token;
+
+    priv->end = *ptr;
+
+    version_token = *(*ptr)++;
+    TRACE("version: 0x%08x\n", version_token);
+
+    TRACE("token count: %u\n", **ptr);
+    priv->end += *(*ptr)++;
+
+    switch (version_token >> 16)
+    {
+        case WINED3D_SM4_PS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+            break;
+
+        case WINED3D_SM4_VS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+            break;
+
+        case WINED3D_SM4_GS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
+            break;
+
+        default:
+            FIXME("Unrecognized shader type %#x\n", version_token >> 16);
+    }
+    priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
+    priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
+
+    *shader_version = priv->shader_version;
+}
+
+static void shader_sm4_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins,
+        UINT *param_size)
+{
+    const struct wined3d_sm4_opcode_info *opcode_info;
+    DWORD token = *(*ptr)++;
+    DWORD opcode = token & WINED3D_SM4_OPCODE_MASK;
+
+    *param_size = ((token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
+
+    opcode_info = get_opcode_info(opcode);
+    if (!opcode_info)
+    {
+        FIXME("Unrecognized opcode %#x, token 0x%08x\n", opcode, token);
+        ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+        return;
+    }
+
+    ins->handler_idx = opcode_info->handler_idx;
+    ins->flags = 0;
+    ins->coissue = 0;
+    ins->predicate = 0;
+    ins->dst_count = opcode_info->dst_count;
+    ins->src_count = opcode_info->src_count;
+}
+
+static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+        struct wined3d_shader_src_param *src_rel_addr)
+{
+    struct wined3d_sm4_data *priv = data;
+    DWORD token = *(*ptr)++;
+    enum wined3d_sm4_register_type register_type;
+
+    register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
+    if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
+    {
+        FIXME("Unhandled register type %#x\n", register_type);
+        src_param->reg.type = WINED3DSPR_TEMP;
+    }
+    else
+    {
+        src_param->reg.type = register_type_table[register_type];
+    }
+
+    if (register_type == WINED3D_SM4_RT_IMMCONST)
+    {
+        enum wined3d_sm4_immconst_type immconst_type =
+                (token & WINED3D_SM4_IMMCONST_TYPE_MASK) >> WINED3D_SM4_IMMCONST_TYPE_SHIFT;
+        src_param->swizzle = WINED3DSP_NOSWIZZLE;
+
+        switch(immconst_type)
+        {
+            case WINED3D_SM4_IMMCONST_FLOAT:
+                src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT;
+                memcpy(src_param->reg.immconst_data, *ptr, 1 * sizeof(DWORD));
+                *ptr += 1;
+                break;
+
+            case WINED3D_SM4_IMMCONST_FLOAT4:
+                src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT4;
+                memcpy(src_param->reg.immconst_data, *ptr, 4 * sizeof(DWORD));
+                *ptr += 4;
+                break;
+
+            default:
+                FIXME("Unhandled immediate constant type %#x\n", immconst_type);
+                break;
+        }
+    }
+    else
+    {
+        src_param->reg.idx = *(*ptr)++;
+        src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
+    }
+
+    src_param->modifiers = 0;
+    src_param->reg.rel_addr = NULL;
+
+    map_register(priv, &src_param->reg);
+}
+
+static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+        struct wined3d_shader_src_param *dst_rel_addr)
+{
+    struct wined3d_sm4_data *priv = data;
+    DWORD token = *(*ptr)++;
+    UINT register_idx = *(*ptr)++;
+    enum wined3d_sm4_register_type register_type;
+
+    register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
+    if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
+    {
+        FIXME("Unhandled register type %#x\n", register_type);
+        dst_param->reg.type = WINED3DSPR_TEMP;
+    }
+    else
+    {
+        dst_param->reg.type = register_type_table[register_type];
+    }
+
+    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->reg.rel_addr = NULL;
+
+    map_register(priv, &dst_param->reg);
+}
+
+static void shader_sm4_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
+{
+    FIXME("ptr %p, semantic %p stub!\n", ptr, semantic);
+}
+
+static void shader_sm4_read_comment(const DWORD **ptr, const char **comment)
+{
+    FIXME("ptr %p, comment %p stub!\n", ptr, comment);
+    *comment = NULL;
+}
+
+static BOOL shader_sm4_is_end(void *data, const DWORD **ptr)
+{
+    struct wined3d_sm4_data *priv = data;
+    return *ptr == priv->end;
+}
+
+const struct wined3d_shader_frontend sm4_shader_frontend =
+{
+    shader_sm4_init,
+    shader_sm4_free,
+    shader_sm4_read_header,
+    shader_sm4_read_opcode,
+    shader_sm4_read_src_param,
+    shader_sm4_read_dst_param,
+    shader_sm4_read_semantic,
+    shader_sm4_read_comment,
+    shader_sm4_is_end,
+};
index 05e52b0..ad1593c 100644 (file)
@@ -1503,14 +1503,25 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
 }
 
 static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
 }
 
 static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    BOOL warned = FALSE;
     /* TODO: NV_POINT_SPRITE */
     /* TODO: NV_POINT_SPRITE */
-    if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
-        TRACE("Point sprites not supported\n");
+    if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
+        /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
+        FIXME("Point sprites not supported\n");
+        warned = TRUE;
     }
 }
 
 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
     }
 }
 
 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(use_ps(stateblock) || stateblock->lowest_disabled_stage > GL_LIMITS(point_sprite_units)) {
+                FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
+                warned = TRUE;
+            }
+        }
+
         glEnable(GL_POINT_SPRITE_ARB);
         checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
     } else {
         glEnable(GL_POINT_SPRITE_ARB);
         checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
     } else {
@@ -3913,7 +3924,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
             if (stream_info->elements[i].buffer_object)
             {
                 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
             if (stream_info->elements[i].buffer_object)
             {
                 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
-                ptr += (long) vb->resource.allocatedMemory;
+                ptr += (long) buffer_get_sysmem(vb);
             }
 
             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
             }
 
             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
index 35ba9a4..9e9d55c 100644 (file)
@@ -1795,6 +1795,22 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             *target_bpp = 6;
             break;
 
             *target_bpp = 6;
             break;
 
+        case WINED3DFMT_R16G16_FLOAT:
+            *convert = CONVERT_R16G16F;
+            *format = GL_RGB;
+            *internal = GL_RGB16F_ARB;
+            *type = GL_HALF_FLOAT_ARB;
+            *target_bpp = 6;
+            break;
+
+        case WINED3DFMT_R32G32_FLOAT:
+            *convert = CONVERT_R32G32F;
+            *format = GL_RGB;
+            *internal = GL_RGB32F_ARB;
+            *type = GL_FLOAT;
+            *target_bpp = 12;
+            break;
+
         default:
             break;
     }
         default:
             break;
     }
@@ -2123,6 +2139,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
         }
 
         case CONVERT_G16R16:
         }
 
         case CONVERT_G16R16:
+        case CONVERT_R16G16F:
         {
             unsigned int x, y;
             const WORD *Source;
         {
             unsigned int x, y;
             const WORD *Source;
@@ -2136,6 +2153,9 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
                     WORD red = (*Source++);
                     Dest[0] = green;
                     Dest[1] = red;
                     WORD red = (*Source++);
                     Dest[0] = green;
                     Dest[1] = red;
+                    /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
+                     * shader overwrites it anyway
+                     */
                     Dest[2] = 0xffff;
                     Dest += 3;
                 }
                     Dest[2] = 0xffff;
                     Dest += 3;
                 }
@@ -2143,6 +2163,26 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
             break;
         }
 
             break;
         }
 
+        case CONVERT_R32G32F:
+        {
+            unsigned int x, y;
+            const float *Source;
+            float *Dest;
+            for(y = 0; y < height; y++) {
+                Source = (const float *)(src + y * pitch);
+                Dest = (float *) (dst + y * outpitch);
+                for (x = 0; x < width; x++ ) {
+                    float green = (*Source++);
+                    float red = (*Source++);
+                    Dest[0] = green;
+                    Dest[1] = red;
+                    Dest[2] = 1.0;
+                    Dest += 3;
+                }
+            }
+            break;
+        }
+
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
index 4b1629d..d487f80 100644 (file)
@@ -781,22 +781,11 @@ static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source,
         return NULL;
     }
 
         return NULL;
     }
 
-    IWineD3DDevice_CreateSurface((IWineD3DDevice *) source->resource.wineD3DDevice,
-                                 source->currentDesc.Width,
-                                 source->currentDesc.Height,
-                                 to_fmt,
-                                 TRUE,  /* lockable */
-                                 TRUE,  /* discard  */
-                                 0,     /* level */
-                                 &ret,
-                                 WINED3DRTYPE_SURFACE,
-                                 0,     /* usage */
-                                 WINED3DPOOL_SCRATCH,
-                                 WINED3DMULTISAMPLE_NONE,   /* TODO: Multisampled conversion */
-                                 0,     /* MultiSampleQuality */
-                                 NULL,  /* SharedHandle */
-                                 IWineD3DSurface_GetImplType((IWineD3DSurface *) source),
-                                 NULL); /* parent */
+    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");
         return NULL;
     if(!ret) {
         ERR("Failed to create a destination surface for conversion\n");
         return NULL;
index 0ed350e..0ad65e0 100644 (file)
@@ -130,7 +130,7 @@ IWineGDISurfaceImpl_LockRect(IWineD3DSurface *iface,
     /* Already locked? */
     if(This->Flags & SFLAG_LOCKED)
     {
     /* Already locked? */
     if(This->Flags & SFLAG_LOCKED)
     {
-        ERR("(%p) Surface already locked\n", This);
+        WARN("(%p) Surface already locked\n", This);
         /* What should I return here? */
         return WINED3DERR_INVALIDCALL;
     }
         /* What should I return here? */
         return WINED3DERR_INVALIDCALL;
     }
index 7eb3d59..d697372 100644 (file)
@@ -651,15 +651,15 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info)
         gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
     }
 
         gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
     }
 
-    if (GL_SUPPORT(NV_HALF_FLOAT))
+    if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX))
     {
         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
     {
         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
-        gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
+        gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
 
         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
 
         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
-        gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV;
+        gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT;
     }
 }
 
     }
 }
 
index 0e41494..2c2b763 100644 (file)
@@ -261,7 +261,7 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
 
         if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
         {
 
         if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
         {
-            if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE;
+            if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) This->half_float_conv_needed = TRUE;
         }
     }
 
         }
     }
 
index fdd8cd8..7dba4e3 100644 (file)
@@ -34,134 +34,71 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 
 #define GLINFO_LOCATION ((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info
 
 
 #define GLINFO_LOCATION ((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info
 
-/* TODO: Vertex and Pixel shaders are almost identical, the only exception being the way that some of the data is looked up or the availability of some of the data i.e. some instructions are only valid for pshaders and some for vshaders
-because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't surprise me if the program can be cross compiled using a large body of shared code */
-
-CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
-    /* This table is not order or position dependent. */
-
-    /* Arithmetic */
-    {WINED3DSIO_NOP,     "nop",     0, 0, WINED3DSIH_NOP,     0,                      0                     },
-    {WINED3DSIO_MOV,     "mov",     1, 2, WINED3DSIH_MOV,     0,                      0                     },
-    {WINED3DSIO_MOVA,    "mova",    1, 2, WINED3DSIH_MOVA,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ADD,     "add",     1, 3, WINED3DSIH_ADD,     0,                      0                     },
-    {WINED3DSIO_SUB,     "sub",     1, 3, WINED3DSIH_SUB,     0,                      0                     },
-    {WINED3DSIO_MAD,     "mad",     1, 4, WINED3DSIH_MAD,     0,                      0                     },
-    {WINED3DSIO_MUL,     "mul",     1, 3, WINED3DSIH_MUL,     0,                      0                     },
-    {WINED3DSIO_RCP,     "rcp",     1, 2, WINED3DSIH_RCP,     0,                      0                     },
-    {WINED3DSIO_RSQ,     "rsq",     1, 2, WINED3DSIH_RSQ,     0,                      0                     },
-    {WINED3DSIO_DP3,     "dp3",     1, 3, WINED3DSIH_DP3,     0,                      0                     },
-    {WINED3DSIO_DP4,     "dp4",     1, 3, WINED3DSIH_DP4,     0,                      0                     },
-    {WINED3DSIO_MIN,     "min",     1, 3, WINED3DSIH_MIN,     0,                      0                     },
-    {WINED3DSIO_MAX,     "max",     1, 3, WINED3DSIH_MAX,     0,                      0                     },
-    {WINED3DSIO_SLT,     "slt",     1, 3, WINED3DSIH_SLT,     0,                      0                     },
-    {WINED3DSIO_SGE,     "sge",     1, 3, WINED3DSIH_SGE,     0,                      0                     },
-    {WINED3DSIO_ABS,     "abs",     1, 2, WINED3DSIH_ABS,     0,                      0                     },
-    {WINED3DSIO_EXP,     "exp",     1, 2, WINED3DSIH_EXP,     0,                      0                     },
-    {WINED3DSIO_LOG,     "log",     1, 2, WINED3DSIH_LOG,     0,                      0                     },
-    {WINED3DSIO_EXPP,    "expp",    1, 2, WINED3DSIH_EXPP,    0,                      0                     },
-    {WINED3DSIO_LOGP,    "logp",    1, 2, WINED3DSIH_LOGP,    0,                      0                     },
-    {WINED3DSIO_LIT,     "lit",     1, 2, WINED3DSIH_LIT,     0,                      0                     },
-    {WINED3DSIO_DST,     "dst",     1, 3, WINED3DSIH_DST,     0,                      0                     },
-    {WINED3DSIO_LRP,     "lrp",     1, 4, WINED3DSIH_LRP,     0,                      0                     },
-    {WINED3DSIO_FRC,     "frc",     1, 2, WINED3DSIH_FRC,     0,                      0                     },
-    {WINED3DSIO_POW,     "pow",     1, 3, WINED3DSIH_POW,     0,                      0                     },
-    {WINED3DSIO_CRS,     "crs",     1, 3, WINED3DSIH_CRS,     0,                      0                     },
-    /* TODO: sng can possibly be performed as
-        RCP tmp, vec
-        MUL out, tmp, vec*/
-    {WINED3DSIO_SGN,     "sgn",     1, 2, WINED3DSIH_SGN,     0,                      0                     },
-    {WINED3DSIO_NRM,     "nrm",     1, 2, WINED3DSIH_NRM,     0,                      0                     },
-    {WINED3DSIO_SINCOS,  "sincos",  1, 4, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
-    {WINED3DSIO_SINCOS,  "sincos",  1, 2, WINED3DSIH_SINCOS,  WINED3DVS_VERSION(3,0), -1                    },
-    /* Matrix */
-    {WINED3DSIO_M4x4,    "m4x4",    1, 3, WINED3DSIH_M4x4,    0,                      0                     },
-    {WINED3DSIO_M4x3,    "m4x3",    1, 3, WINED3DSIH_M4x3,    0,                      0                     },
-    {WINED3DSIO_M3x4,    "m3x4",    1, 3, WINED3DSIH_M3x4,    0,                      0                     },
-    {WINED3DSIO_M3x3,    "m3x3",    1, 3, WINED3DSIH_M3x3,    0,                      0                     },
-    {WINED3DSIO_M3x2,    "m3x2",    1, 3, WINED3DSIH_M3x2,    0,                      0                     },
-    /* Declare registers */
-    {WINED3DSIO_DCL,     "dcl",     0, 2, WINED3DSIH_DCL,     0,                      0                     },
-    /* Constant definitions */
-    {WINED3DSIO_DEF,     "def",     1, 5, WINED3DSIH_DEF,     0,                      0                     },
-    {WINED3DSIO_DEFB,    "defb",    1, 2, WINED3DSIH_DEFB,    0,                      0                     },
-    {WINED3DSIO_DEFI,    "defi",    1, 5, WINED3DSIH_DEFI,    0,                      0                     },
-    /* Flow control - requires GLSL or software shaders */
-    {WINED3DSIO_REP ,    "rep",     0, 1, WINED3DSIH_REP,     WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDREP,  "endrep",  0, 0, WINED3DSIH_ENDREP,  WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_IF,      "if",      0, 1, WINED3DSIH_IF,      WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_IFC,     "ifc",     0, 2, WINED3DSIH_IFC,     WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_ELSE,    "else",    0, 0, WINED3DSIH_ELSE,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDIF,   "endif",   0, 0, WINED3DSIH_ENDIF,   WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_BREAK,   "break",   0, 0, WINED3DSIH_BREAK,   WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKC,  "breakc",  0, 2, WINED3DSIH_BREAKC,  WINED3DVS_VERSION(2,1), -1                    },
-    {WINED3DSIO_BREAKP,  "breakp",  0, 1, WINED3DSIH_BREAKP,  0,                      0                     },
-    {WINED3DSIO_CALL,    "call",    0, 1, WINED3DSIH_CALL,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_CALLNZ,  "callnz",  0, 2, WINED3DSIH_CALLNZ,  WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_LOOP,    "loop",    0, 2, WINED3DSIH_LOOP,    WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_RET,     "ret",     0, 0, WINED3DSIH_RET,     WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_ENDLOOP, "endloop", 0, 0, WINED3DSIH_ENDLOOP, WINED3DVS_VERSION(2,0), -1                    },
-    {WINED3DSIO_LABEL,   "label",   0, 1, WINED3DSIH_LABEL,   WINED3DVS_VERSION(2,0), -1                    },
-
-    {WINED3DSIO_SETP,    "setp",    1, 3, WINED3DSIH_SETP,    0,                      0                     },
-    {WINED3DSIO_TEXLDL,  "texldl",  1, 3, WINED3DSIH_TEXLDL,  WINED3DVS_VERSION(3,0), -1                    },
-    {0,                  NULL,      0, 0, 0,                  0,                      0                     }
-};
+static void vshader_set_limits(IWineD3DVertexShaderImpl *This)
+{
+    DWORD shader_version = WINED3D_SHADER_VERSION(This->baseShader.reg_maps.shader_version.major,
+            This->baseShader.reg_maps.shader_version.minor);
 
 
-static void vshader_set_limits(
-      IWineD3DVertexShaderImpl *This) {
-
-      This->baseShader.limits.texcoord = 0;
-      This->baseShader.limits.attributes = 16;
-      This->baseShader.limits.packed_input = 0;
-
-      /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
-      This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
-
-      switch (This->baseShader.reg_maps.shader_version)
-      {
-          case WINED3DVS_VERSION(1,0):
-          case WINED3DVS_VERSION(1,1):
-                   This->baseShader.limits.temporary = 12;
-                   This->baseShader.limits.constant_bool = 0;
-                   This->baseShader.limits.constant_int = 0;
-                   This->baseShader.limits.address = 1;
-                   This->baseShader.limits.packed_output = 0;
-                   This->baseShader.limits.sampler = 0;
-                   This->baseShader.limits.label = 0;
-                   break;
-      
-          case WINED3DVS_VERSION(2,0):
-          case WINED3DVS_VERSION(2,1):
-                   This->baseShader.limits.temporary = 12;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.address = 1;
-                   This->baseShader.limits.packed_output = 0;
-                   This->baseShader.limits.sampler = 0;
-                   This->baseShader.limits.label = 16;
-                   break;
-
-          case WINED3DVS_VERSION(3,0):
-                   This->baseShader.limits.temporary = 32;
-                   This->baseShader.limits.constant_bool = 32;
-                   This->baseShader.limits.constant_int = 32;
-                   This->baseShader.limits.address = 1;
-                   This->baseShader.limits.packed_output = 12;
-                   This->baseShader.limits.sampler = 4;
-                   This->baseShader.limits.label = 16; /* FIXME: 2048 */
-                   break;
-
-          default: This->baseShader.limits.temporary = 12;
-                   This->baseShader.limits.constant_bool = 16;
-                   This->baseShader.limits.constant_int = 16;
-                   This->baseShader.limits.address = 1;
-                   This->baseShader.limits.packed_output = 0;
-                   This->baseShader.limits.sampler = 0;
-                   This->baseShader.limits.label = 16;
-                   FIXME("Unrecognized vertex shader version %#x\n",
-                           This->baseShader.reg_maps.shader_version);
-      }
+    This->baseShader.limits.texcoord = 0;
+    This->baseShader.limits.attributes = 16;
+    This->baseShader.limits.packed_input = 0;
+
+    switch (shader_version)
+    {
+        case WINED3D_SHADER_VERSION(1,0):
+        case WINED3D_SHADER_VERSION(1,1):
+            This->baseShader.limits.temporary = 12;
+            This->baseShader.limits.constant_bool = 0;
+            This->baseShader.limits.constant_int = 0;
+            This->baseShader.limits.address = 1;
+            This->baseShader.limits.packed_output = 0;
+            This->baseShader.limits.sampler = 0;
+            This->baseShader.limits.label = 0;
+            /* TODO: vs_1_1 has a minimum of 96 constants. What happens if a vs_1_1 shader is used
+             * on a vs_3_0 capable card that has 256 constants? */
+            This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+            break;
+
+        case WINED3D_SHADER_VERSION(2,0):
+        case WINED3D_SHADER_VERSION(2,1):
+            This->baseShader.limits.temporary = 12;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.address = 1;
+            This->baseShader.limits.packed_output = 0;
+            This->baseShader.limits.sampler = 0;
+            This->baseShader.limits.label = 16;
+            This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+            break;
+
+        case WINED3D_SHADER_VERSION(3,0):
+            This->baseShader.limits.temporary = 32;
+            This->baseShader.limits.constant_bool = 32;
+            This->baseShader.limits.constant_int = 32;
+            This->baseShader.limits.address = 1;
+            This->baseShader.limits.packed_output = 12;
+            This->baseShader.limits.sampler = 4;
+            This->baseShader.limits.label = 16; /* FIXME: 2048 */
+            /* DX10 cards on Windows advertise a d3d9 constant limit of 256 even though they are capable
+             * of supporting much more(GL drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+             * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 shaders to 256.s
+             * use constant buffers */
+            This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+            break;
+
+        default:
+            This->baseShader.limits.temporary = 12;
+            This->baseShader.limits.constant_bool = 16;
+            This->baseShader.limits.constant_int = 16;
+            This->baseShader.limits.address = 1;
+            This->baseShader.limits.packed_output = 0;
+            This->baseShader.limits.sampler = 0;
+            This->baseShader.limits.label = 16;
+            This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
+            FIXME("Unrecognized vertex shader version %u.%u\n",
+                    This->baseShader.reg_maps.shader_version.major,
+                    This->baseShader.reg_maps.shader_version.minor);
+    }
 }
 
 /* This is an internal function,
 }
 
 /* This is an internal function,
@@ -176,13 +113,12 @@ static void vshader_set_input(
 
     This->semantics_in[regnum].usage = usage;
     This->semantics_in[regnum].usage_idx = usage_idx;
 
     This->semantics_in[regnum].usage = usage;
     This->semantics_in[regnum].usage_idx = usage_idx;
-    This->semantics_in[regnum].reg.register_type = WINED3DSPR_INPUT;
-    This->semantics_in[regnum].reg.register_idx = regnum;
+    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.write_mask = WINED3DSP_WRITEMASK_ALL;
     This->semantics_in[regnum].reg.modifiers = 0;
     This->semantics_in[regnum].reg.shift = 0;
-    This->semantics_in[regnum].reg.has_rel_addr = FALSE;
-    This->semantics_in[regnum].reg.addr_token = 0;
+    This->semantics_in[regnum].reg.reg.rel_addr = NULL;
 }
 
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
 }
 
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
@@ -307,17 +243,33 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
  * shader is first used. The reason for this is that we need the vertex
  * declaration the shader will be used with in order to determine if
  * the data in a register is of type D3DCOLOR, and needs swizzling. */
  * shader is first used. The reason for this is that we need the vertex
  * declaration the shader will be used with in order to determine if
  * the data in a register is of type D3DCOLOR, and needs swizzling. */
-static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
-
+static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
+        const DWORD *pFunction, const struct wined3d_shader_signature *output_signature)
+{
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
     IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
+    const struct wined3d_shader_frontend *fe;
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
     HRESULT hr;
     shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
 
     TRACE("(%p) : pFunction %p\n", iface, pFunction);
 
+    fe = shader_select_frontend(*pFunction);
+    if (!fe)
+    {
+        FIXME("Unable to find frontend for shader.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+    This->baseShader.frontend = fe;
+    This->baseShader.frontend_data = fe->shader_init(pFunction, output_signature);
+    if (!This->baseShader.frontend_data)
+    {
+        FIXME("Failed to initialize frontend.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
+
     /* First pass: trace shader */
     /* First pass: trace shader */
-    if (TRACE_ON(d3d_shader)) shader_trace_init(pFunction, This->baseShader.shader_ins);
+    if (TRACE_ON(d3d_shader)) shader_trace_init(fe, This->baseShader.frontend_data, pFunction);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
 
     /* Initialize immediate constant lists */
     list_init(&This->baseShader.constantsF);
@@ -327,15 +279,13 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     /* Second pass: figure out registers used, semantics, etc.. */
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
     /* Second pass: figure out registers used, semantics, etc.. */
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
-    memset(reg_maps, 0, sizeof(shader_reg_maps));
-    hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
-            This->semantics_in, This->semantics_out, pFunction);
+    hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
+            reg_maps, This->semantics_in, This->semantics_out, pFunction,
+            GL_LIMITS(vshader_constantsF));
     if (hr != WINED3D_OK) return hr;
 
     vshader_set_limits(This);
 
     if (hr != WINED3D_OK) return hr;
 
     vshader_set_limits(This);
 
-    This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
-
     if(deviceImpl->vs_selected_mode == SHADER_ARB &&
        (GLINFO_LOCATION).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) {
index 9d0f789..d08d32e 100644 (file)
@@ -33,6 +33,8 @@
        <file>pixelshader.c</file>
        <file>query.c</file>
        <file>resource.c</file>
        <file>pixelshader.c</file>
        <file>query.c</file>
        <file>resource.c</file>
+       <file>shader_sm1.c</file>
+       <file>shader_sm4.c</file>
        <file>state.c</file>
        <file>stateblock.c</file>
        <file>surface_base.c</file>
        <file>state.c</file>
        <file>stateblock.c</file>
        <file>surface_base.c</file>
index cc76035..1a9c925 100644 (file)
@@ -2537,6 +2537,12 @@ typedef void (WINE_GLAPI * PGLFNGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint
 #define GL_DECR_WRAP_EXT                  0x8508
 #endif
 
 #define GL_DECR_WRAP_EXT                  0x8508
 #endif
 
+/* GL_ARB_half_float_vertex */
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex
+/* No _ARB, see extension spec */
+#define GL_HALF_FLOAT                     0x140B
+#endif
 /* GL_NV_half_float */
 #ifndef GL_NV_half_float
 #define GL_NV_half_float 1
 /* GL_NV_half_float */
 #ifndef GL_NV_half_float
 #define GL_NV_half_float 1
@@ -2895,7 +2901,7 @@ typedef void (WINE_GLAPI * PGLFNGETFENCEIVNVPROC) (GLuint, GLenum, GLint *);
 #ifndef GL_APPLE_fence
 #define GL_APPLE_fence 1
 #define GL_DRAW_PIXELS_APPLE                0x8A0A
 #ifndef GL_APPLE_fence
 #define GL_APPLE_fence 1
 #define GL_DRAW_PIXELS_APPLE                0x8A0A
-#define GL_FENCE_APPLE                      0x84F3
+#define GL_FENCE_APPLE                      0x8A0B
 #endif
 typedef void (WINE_GLAPI * PGLFNGENFENCESAPPLEPROC) (GLsizei, GLuint *);
 typedef void (WINE_GLAPI * PGLFNDELETEFENCESAPPLEPROC) (GLuint, const GLuint *);
 #endif
 typedef void (WINE_GLAPI * PGLFNGENFENCESAPPLEPROC) (GLsizei, GLuint *);
 typedef void (WINE_GLAPI * PGLFNDELETEFENCESAPPLEPROC) (GLuint, const GLuint *);
@@ -3397,6 +3403,8 @@ typedef enum _GL_SupportedExt {
   ARB_VERTEX_BUFFER_OBJECT,
   ARB_VERTEX_SHADER,
   ARB_SHADER_OBJECTS,
   ARB_VERTEX_BUFFER_OBJECT,
   ARB_VERTEX_SHADER,
   ARB_SHADER_OBJECTS,
+  ARB_SHADER_TEXTURE_LOD,
+  ARB_HALF_FLOAT_VERTEX,
   /* EXT */
   EXT_BLEND_COLOR,
   EXT_BLEND_MINMAX,
   /* EXT */
   EXT_BLEND_COLOR,
   EXT_BLEND_MINMAX,
@@ -3925,6 +3933,7 @@ typedef struct _WineD3D_GL_Info {
   UINT   max_texture_size;
   UINT   max_texture3d_size;
   float  max_pointsize, max_pointsizemin;
   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;
   UINT   max_blends;
   UINT   max_anisotropy;
   UINT   max_glsl_varyings;
@@ -3951,6 +3960,7 @@ typedef struct _WineD3D_GL_Info {
 
   BOOL arb_vs_offset_limit;
   BOOL set_texcoord_w;
 
   BOOL arb_vs_offset_limit;
   BOOL set_texcoord_w;
+  DWORD reserved_glsl_constants;
 
   BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
 
 
   BOOL supported[OPENGL_SUPPORTED_EXT_END + 1];
 
@@ -3963,4 +3973,10 @@ typedef struct _WineD3D_GL_Info {
 } WineD3D_GL_Info;
 #undef USE_GL_FUNC
 
 } WineD3D_GL_Info;
 #undef USE_GL_FUNC
 
+struct driver_quirk {
+    BOOL        (*match)(const WineD3D_GL_Info *gl_info);
+    void        (*apply)(WineD3D_GL_Info *gl_info);
+    const char  *description;
+};
+
 #endif /* __WINE_WINED3D_GL */
 #endif /* __WINE_WINED3D_GL */
index 566e2a6..303fb70 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2002-2003 The wine-d3d team
  * Copyright 2002-2003 Raphael Junqueira
  *
  * Copyright 2002-2003 The wine-d3d team
  * Copyright 2002-2003 Raphael Junqueira
- * Copyright 2004 Jason Edmeades
+ * Copyright 2002-2003, 2004 Jason Edmeades
  * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
  * Copyright 2005 Oliver Stieber
  *
  * This library is free software; you can redistribute it and/or
@@ -38,7 +38,6 @@
 #include "wine/unicode.h"
 
 #include "objbase.h"
 #include "wine/unicode.h"
 
 #include "objbase.h"
-#include "wined3d_private_types.h"
 #include "wine/wined3d.h"
 #include "wined3d_gl.h"
 #include "wine/list.h"
 #include "wine/wined3d.h"
 #include "wined3d_gl.h"
 #include "wine/list.h"
@@ -169,10 +168,6 @@ void hash_table_remove(struct hash_table_t *table, void *key);
 #define MAX_COMBINED_SAMPLERS   (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
 #define MAX_ACTIVE_LIGHTS       8
 #define MAX_CLIPPLANES          WINED3DMAXUSERCLIPPLANES
 #define MAX_COMBINED_SAMPLERS   (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
 #define MAX_ACTIVE_LIGHTS       8
 #define MAX_CLIPPLANES          WINED3DMAXUSERCLIPPLANES
-#define MAX_LEVELS              256
-
-#define MAX_CONST_I 16
-#define MAX_CONST_B 16
 
 /* Used for CreateStateBlock */
 #define NUM_SAVEDPIXELSTATES_R     35
 
 /* Used for CreateStateBlock */
 #define NUM_SAVEDPIXELSTATES_R     35
@@ -296,6 +291,204 @@ typedef struct wined3d_settings_s {
 
 extern wined3d_settings_t wined3d_settings;
 
 
 extern wined3d_settings_t wined3d_settings;
 
+typedef enum _WINED3DSAMPLER_TEXTURE_TYPE
+{
+    WINED3DSTT_UNKNOWN = 0,
+    WINED3DSTT_1D = 1,
+    WINED3DSTT_2D = 2,
+    WINED3DSTT_CUBE = 3,
+    WINED3DSTT_VOLUME = 4,
+} WINED3DSAMPLER_TEXTURE_TYPE;
+
+typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE
+{
+    WINED3DSPR_TEMP = 0,
+    WINED3DSPR_INPUT = 1,
+    WINED3DSPR_CONST = 2,
+    WINED3DSPR_ADDR = 3,
+    WINED3DSPR_TEXTURE = 3,
+    WINED3DSPR_RASTOUT = 4,
+    WINED3DSPR_ATTROUT = 5,
+    WINED3DSPR_TEXCRDOUT = 6,
+    WINED3DSPR_OUTPUT = 6,
+    WINED3DSPR_CONSTINT = 7,
+    WINED3DSPR_COLOROUT = 8,
+    WINED3DSPR_DEPTHOUT = 9,
+    WINED3DSPR_SAMPLER = 10,
+    WINED3DSPR_CONST2 = 11,
+    WINED3DSPR_CONST3 = 12,
+    WINED3DSPR_CONST4 = 13,
+    WINED3DSPR_CONSTBOOL = 14,
+    WINED3DSPR_LOOP = 15,
+    WINED3DSPR_TEMPFLOAT16 = 16,
+    WINED3DSPR_MISCTYPE = 17,
+    WINED3DSPR_LABEL = 18,
+    WINED3DSPR_PREDICATE = 19,
+    WINED3DSPR_IMMCONST,
+} WINED3DSHADER_PARAM_REGISTER_TYPE;
+
+enum wined3d_immconst_type
+{
+    WINED3D_IMMCONST_FLOAT,
+    WINED3D_IMMCONST_FLOAT4,
+};
+
+typedef enum _WINED3DVS_RASTOUT_OFFSETS
+{
+    WINED3DSRO_POSITION = 0,
+    WINED3DSRO_FOG = 1,
+    WINED3DSRO_POINT_SIZE = 2,
+} WINED3DVS_RASTOUT_OFFSETS;
+
+#define WINED3DSP_NOSWIZZLE (0 | (1 << 2) | (2 << 4) | (3 << 6))
+
+typedef enum _WINED3DSHADER_PARAM_SRCMOD_TYPE
+{
+    WINED3DSPSM_NONE = 0,
+    WINED3DSPSM_NEG = 1,
+    WINED3DSPSM_BIAS = 2,
+    WINED3DSPSM_BIASNEG = 3,
+    WINED3DSPSM_SIGN = 4,
+    WINED3DSPSM_SIGNNEG = 5,
+    WINED3DSPSM_COMP = 6,
+    WINED3DSPSM_X2 = 7,
+    WINED3DSPSM_X2NEG = 8,
+    WINED3DSPSM_DZ = 9,
+    WINED3DSPSM_DW = 10,
+    WINED3DSPSM_ABS = 11,
+    WINED3DSPSM_ABSNEG = 12,
+    WINED3DSPSM_NOT = 13,
+} WINED3DSHADER_PARAM_SRCMOD_TYPE;
+
+#define WINED3DSP_WRITEMASK_0   0x1 /* .x r */
+#define WINED3DSP_WRITEMASK_1   0x2 /* .y g */
+#define WINED3DSP_WRITEMASK_2   0x4 /* .z b */
+#define WINED3DSP_WRITEMASK_3   0x8 /* .w a */
+#define WINED3DSP_WRITEMASK_ALL 0xf /* all */
+
+typedef enum _WINED3DSHADER_PARAM_DSTMOD_TYPE
+{
+    WINED3DSPDM_NONE = 0,
+    WINED3DSPDM_SATURATE = 1,
+    WINED3DSPDM_PARTIALPRECISION = 2,
+    WINED3DSPDM_MSAMPCENTROID = 4,
+} WINED3DSHADER_PARAM_DSTMOD_TYPE;
+
+typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE
+{
+    WINED3DSIO_NOP = 0,
+    WINED3DSIO_MOV = 1,
+    WINED3DSIO_ADD = 2,
+    WINED3DSIO_SUB = 3,
+    WINED3DSIO_MAD = 4,
+    WINED3DSIO_MUL = 5,
+    WINED3DSIO_RCP = 6,
+    WINED3DSIO_RSQ = 7,
+    WINED3DSIO_DP3 = 8,
+    WINED3DSIO_DP4 = 9,
+    WINED3DSIO_MIN = 10,
+    WINED3DSIO_MAX = 11,
+    WINED3DSIO_SLT = 12,
+    WINED3DSIO_SGE = 13,
+    WINED3DSIO_EXP = 14,
+    WINED3DSIO_LOG = 15,
+    WINED3DSIO_LIT = 16,
+    WINED3DSIO_DST = 17,
+    WINED3DSIO_LRP = 18,
+    WINED3DSIO_FRC = 19,
+    WINED3DSIO_M4x4 = 20,
+    WINED3DSIO_M4x3 = 21,
+    WINED3DSIO_M3x4 = 22,
+    WINED3DSIO_M3x3 = 23,
+    WINED3DSIO_M3x2 = 24,
+    WINED3DSIO_CALL = 25,
+    WINED3DSIO_CALLNZ = 26,
+    WINED3DSIO_LOOP = 27,
+    WINED3DSIO_RET = 28,
+    WINED3DSIO_ENDLOOP = 29,
+    WINED3DSIO_LABEL = 30,
+    WINED3DSIO_DCL = 31,
+    WINED3DSIO_POW = 32,
+    WINED3DSIO_CRS = 33,
+    WINED3DSIO_SGN = 34,
+    WINED3DSIO_ABS = 35,
+    WINED3DSIO_NRM = 36,
+    WINED3DSIO_SINCOS = 37,
+    WINED3DSIO_REP = 38,
+    WINED3DSIO_ENDREP = 39,
+    WINED3DSIO_IF = 40,
+    WINED3DSIO_IFC = 41,
+    WINED3DSIO_ELSE = 42,
+    WINED3DSIO_ENDIF = 43,
+    WINED3DSIO_BREAK = 44,
+    WINED3DSIO_BREAKC = 45,
+    WINED3DSIO_MOVA = 46,
+    WINED3DSIO_DEFB = 47,
+    WINED3DSIO_DEFI = 48,
+
+    WINED3DSIO_TEXCOORD = 64,
+    WINED3DSIO_TEXKILL = 65,
+    WINED3DSIO_TEX = 66,
+    WINED3DSIO_TEXBEM = 67,
+    WINED3DSIO_TEXBEML = 68,
+    WINED3DSIO_TEXREG2AR = 69,
+    WINED3DSIO_TEXREG2GB = 70,
+    WINED3DSIO_TEXM3x2PAD = 71,
+    WINED3DSIO_TEXM3x2TEX = 72,
+    WINED3DSIO_TEXM3x3PAD = 73,
+    WINED3DSIO_TEXM3x3TEX = 74,
+    WINED3DSIO_TEXM3x3DIFF = 75,
+    WINED3DSIO_TEXM3x3SPEC = 76,
+    WINED3DSIO_TEXM3x3VSPEC = 77,
+    WINED3DSIO_EXPP = 78,
+    WINED3DSIO_LOGP = 79,
+    WINED3DSIO_CND = 80,
+    WINED3DSIO_DEF = 81,
+    WINED3DSIO_TEXREG2RGB = 82,
+    WINED3DSIO_TEXDP3TEX = 83,
+    WINED3DSIO_TEXM3x2DEPTH = 84,
+    WINED3DSIO_TEXDP3 = 85,
+    WINED3DSIO_TEXM3x3 = 86,
+    WINED3DSIO_TEXDEPTH = 87,
+    WINED3DSIO_CMP = 88,
+    WINED3DSIO_BEM = 89,
+    WINED3DSIO_DP2ADD = 90,
+    WINED3DSIO_DSX = 91,
+    WINED3DSIO_DSY = 92,
+    WINED3DSIO_TEXLDD = 93,
+    WINED3DSIO_SETP = 94,
+    WINED3DSIO_TEXLDL = 95,
+    WINED3DSIO_BREAKP = 96,
+
+    WINED3DSIO_PHASE = 0xfffd,
+    WINED3DSIO_COMMENT = 0xfffe,
+    WINED3DSIO_END = 0Xffff,
+} WINED3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
+#define WINED3DSI_TEXLD_PROJECT 1
+#define WINED3DSI_TEXLD_BIAS    2
+
+typedef enum COMPARISON_TYPE
+{
+    COMPARISON_GT = 1,
+    COMPARISON_EQ = 2,
+    COMPARISON_GE = 3,
+    COMPARISON_LT = 4,
+    COMPARISON_NE = 5,
+    COMPARISON_LE = 6,
+} COMPARISON_TYPE;
+
+#define WINED3D_SM1_VS  0xfffe
+#define WINED3D_SM1_PS  0xffff
+#define WINED3D_SM4_PS  0x0000
+#define WINED3D_SM4_VS  0x0001
+#define WINED3D_SM4_GS  0x0002
+
+/* Shader version tokens, and shader end tokens */
+#define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor))
+#define WINED3DVS_VERSION(major, minor) ((WINED3D_SM1_VS << 16) | ((major) << 8) | (minor))
+
 /* Shader backends */
 
 /* TODO: Make this dynamic, based on shader limits ? */
 /* Shader backends */
 
 /* TODO: Make this dynamic, based on shader limits ? */
@@ -408,9 +601,25 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_TABLE_SIZE
 };
 
     WINED3DSIH_TABLE_SIZE
 };
 
+enum wined3d_shader_type
+{
+    WINED3D_SHADER_TYPE_PIXEL,
+    WINED3D_SHADER_TYPE_VERTEX,
+    WINED3D_SHADER_TYPE_GEOMETRY,
+};
+
+struct wined3d_shader_version
+{
+    enum wined3d_shader_type type;
+    BYTE major;
+    BYTE minor;
+};
+
+#define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
+
 typedef struct shader_reg_maps
 {
 typedef struct shader_reg_maps
 {
-    DWORD shader_version;
+    struct wined3d_shader_version shader_version;
     char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
     char temporary[MAX_REG_TEMP];           /* pixel, vertex */
     char address[MAX_REG_ADDR];             /* vertex */
     char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
     char temporary[MAX_REG_TEMP];           /* pixel, vertex */
     char address[MAX_REG_ADDR];             /* vertex */
@@ -418,13 +627,14 @@ typedef struct shader_reg_maps
     char packed_output[MAX_REG_OUTPUT];     /* vertex >= 3.0 */
     char attributes[MAX_ATTRIBS];           /* vertex */
     char labels[MAX_LABELS];                /* pixel, vertex */
     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 texcoord_mask[MAX_REG_TEXCRD];    /* vertex < 3.0 */
+    WORD integer_constants;                 /* MAX_CONST_I, 16 */
+    WORD boolean_constants;                 /* MAX_CONST_B, 16 */
 
 
-    /* Sampler usage tokens
-     * Use 0 as default (bit 31 is always 1 on a valid token) */
-    DWORD samplers[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
     BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
     BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
-    char usesnrm, vpos, usesdsy;
+    char usesnrm, vpos, usesdsy, usestexldd;
     char usesrelconstF;
 
     /* Whether or not loops are used in this shader, and nesting depth */
     char usesrelconstF;
 
     /* Whether or not loops are used in this shader, and nesting depth */
@@ -435,51 +645,76 @@ typedef struct shader_reg_maps
 
 } shader_reg_maps;
 
 
 } shader_reg_maps;
 
-typedef struct SHADER_OPCODE
+struct wined3d_shader_context
 {
 {
-    unsigned int opcode;
-    const char *name;
-    char dst_token;
-    CONST UINT num_params;
-    enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
-    DWORD min_version;
-    DWORD max_version;
-} SHADER_OPCODE;
+    IWineD3DBaseShader *shader;
+    const struct shader_reg_maps *reg_maps;
+    SHADER_BUFFER *buffer;
+};
+
+struct wined3d_shader_register
+{
+    WINED3DSHADER_PARAM_REGISTER_TYPE type;
+    UINT idx;
+    const struct wined3d_shader_src_param *rel_addr;
+    enum wined3d_immconst_type immconst_type;
+    DWORD immconst_data[4];
+};
 
 struct wined3d_shader_dst_param
 {
 
 struct wined3d_shader_dst_param
 {
-    WINED3DSHADER_PARAM_REGISTER_TYPE register_type;
-    UINT register_idx;
+    struct wined3d_shader_register reg;
     DWORD write_mask;
     DWORD modifiers;
     DWORD shift;
     DWORD write_mask;
     DWORD modifiers;
     DWORD shift;
-    BOOL has_rel_addr;
-    DWORD addr_token;
+};
+
+struct wined3d_shader_src_param
+{
+    struct wined3d_shader_register reg;
+    DWORD swizzle;
+    DWORD modifiers;
 };
 
 struct wined3d_shader_instruction
 {
 };
 
 struct wined3d_shader_instruction
 {
-    IWineD3DBaseShader *shader;
-    const shader_reg_maps *reg_maps;
+    const struct wined3d_shader_context *ctx;
     enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
     DWORD flags;
     BOOL coissue;
     DWORD predicate;
     enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
     DWORD flags;
     BOOL coissue;
     DWORD predicate;
-    DWORD src[4];
-    DWORD src_addr[4];
-    SHADER_BUFFER *buffer;
     UINT dst_count;
     const struct wined3d_shader_dst_param *dst;
     UINT src_count;
     UINT dst_count;
     const struct wined3d_shader_dst_param *dst;
     UINT src_count;
+    const struct wined3d_shader_src_param *src;
 };
 
 struct wined3d_shader_semantic
 {
     WINED3DDECLUSAGE usage;
     UINT usage_idx;
 };
 
 struct wined3d_shader_semantic
 {
     WINED3DDECLUSAGE usage;
     UINT usage_idx;
+    WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
     struct wined3d_shader_dst_param reg;
 };
 
     struct wined3d_shader_dst_param reg;
 };
 
+struct wined3d_shader_frontend
+{
+    void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
+    void (*shader_free)(void *data);
+    void (*shader_read_header)(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version);
+    void (*shader_read_opcode)(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins, UINT *param_size);
+    void (*shader_read_src_param)(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+            struct wined3d_shader_src_param *src_rel_addr);
+    void (*shader_read_dst_param)(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
+            struct wined3d_shader_src_param *dst_rel_addr);
+    void (*shader_read_semantic)(const DWORD **ptr, struct wined3d_shader_semantic *semantic);
+    void (*shader_read_comment)(const DWORD **ptr, const char **comment);
+    BOOL (*shader_is_end)(void *data, const DWORD **ptr);
+};
+
+extern const struct wined3d_shader_frontend sm1_shader_frontend;
+extern const struct wined3d_shader_frontend sm4_shader_frontend;
+
 typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
 
 struct shader_caps {
 typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
 
 struct shader_caps {
@@ -568,10 +803,13 @@ typedef struct {
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
     BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
-    GLuint (*shader_generate_pshader)(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, const struct ps_compile_args *args);
-    GLuint (*shader_generate_vshader)(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args);
+    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_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;
 
 extern const shader_backend_t glsl_shader_backend;
 } shader_backend_t;
 
 extern const shader_backend_t glsl_shader_backend;
@@ -624,8 +862,7 @@ extern int num_lock;
 
 /* DirectX Device Limits */
 /* --------------------- */
 
 /* DirectX Device Limits */
 /* --------------------- */
-#define MAX_LEVELS  256  /* Maximum number of mipmap levels. Guessed at 256 */
-
+#define MAX_MIP_LEVELS 32  /* Maximum number of mipmap levels. */
 #define MAX_STREAMS  16  /* Maximum possible streams - used for fixed size arrays
                             See MaxStreams in MSDN under GetDeviceCaps */
 #define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */
 #define MAX_STREAMS  16  /* Maximum possible streams - used for fixed size arrays
                             See MaxStreams in MSDN under GetDeviceCaps */
 #define HIGHEST_TRANSFORMSTATE WINED3DTS_WORLDMATRIX(255) /* Highest value in WINED3DTRANSFORMSTATETYPE */
@@ -1185,6 +1422,9 @@ void dumpResources(struct list *list);
  */
 #define WINED3D_UNMAPPED_STAGE ~0U
 
  */
 #define WINED3D_UNMAPPED_STAGE ~0U
 
+/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
+#define WINED3DCREATE_MULTITHREADED 0x00000004
+
 struct IWineD3DDeviceImpl
 {
     /* IUnknown fields      */
 struct IWineD3DDeviceImpl
 {
     /* IUnknown fields      */
@@ -1509,7 +1749,7 @@ typedef struct IWineD3DTextureImpl
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DTexture */
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DTexture */
-    IWineD3DSurface          *surfaces[MAX_LEVELS];
+    IWineD3DSurface          *surfaces[MAX_MIP_LEVELS];
     UINT                      target;
     BOOL                      cond_np2;
 
     UINT                      target;
     BOOL                      cond_np2;
 
@@ -1528,7 +1768,7 @@ typedef struct IWineD3DCubeTextureImpl
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DCubeTexture */
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DCubeTexture */
-    IWineD3DSurface          *surfaces[6][MAX_LEVELS];
+    IWineD3DSurface          *surfaces[6][MAX_MIP_LEVELS];
 } IWineD3DCubeTextureImpl;
 
 extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
 } IWineD3DCubeTextureImpl;
 
 extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl;
@@ -1574,7 +1814,7 @@ typedef struct IWineD3DVolumeTextureImpl
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DVolumeTexture */
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DVolumeTexture */
-    IWineD3DVolume           *volumes[MAX_LEVELS];
+    IWineD3DVolume           *volumes[MAX_MIP_LEVELS];
 } IWineD3DVolumeTextureImpl;
 
 extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
 } IWineD3DVolumeTextureImpl;
 
 extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl;
@@ -1818,6 +2058,8 @@ typedef enum {
     CONVERT_V16U16,
     CONVERT_A4L4,
     CONVERT_G16R16,
     CONVERT_V16U16,
     CONVERT_A4L4,
     CONVERT_G16R16,
+    CONVERT_R16G16F,
+    CONVERT_R32G32F,
 } 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);
@@ -2236,6 +2478,7 @@ BOOL getDepthStencilBits(const struct GlPixelFormatDesc *format_desc, short *dep
 /* Math utils */
 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
 UINT wined3d_log2i(UINT32 x);
 /* Math utils */
 void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED3DMATRIX *src2);
 UINT wined3d_log2i(UINT32 x);
+unsigned int count_bits(unsigned int mask);
 
 typedef struct local_constant {
     struct list entry;
 
 typedef struct local_constant {
     struct list entry;
@@ -2243,19 +2486,6 @@ typedef struct local_constant {
     DWORD value[4];
 } local_constant;
 
     DWORD value[4];
 } local_constant;
 
-/* Undocumented opcode controls */
-#define INST_CONTROLS_SHIFT 16
-#define INST_CONTROLS_MASK 0x00ff0000
-
-typedef enum COMPARISON_TYPE {
-    COMPARISON_GT = 1,
-    COMPARISON_EQ = 2,
-    COMPARISON_GE = 3,
-    COMPARISON_LT = 4,
-    COMPARISON_NE = 5,
-    COMPARISON_LE = 6
-} COMPARISON_TYPE;
-
 typedef struct SHADER_LIMITS {
     unsigned int temporary;
     unsigned int texcoord;
 typedef struct SHADER_LIMITS {
     unsigned int temporary;
     unsigned int texcoord;
@@ -2290,8 +2520,6 @@ extern int shader_addline(
     const char* fmt, ...) PRINTF_ATTR(2,3);
 int shader_vaddline(SHADER_BUFFER *buffer, const char *fmt, va_list args);
 
     const char* fmt, ...) PRINTF_ATTR(2,3);
 int shader_vaddline(SHADER_BUFFER *buffer, const char *fmt, va_list args);
 
-const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *shader_ins, DWORD shader_version, DWORD code);
-
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
     IWineD3DVertexShader* iface,
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
     IWineD3DVertexShader* iface,
@@ -2300,9 +2528,6 @@ extern BOOL vshader_get_input(
 
 extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
 
 
 extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object);
 
-/* GLSL helper functions */
-extern void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins);
-
 /*****************************************************************************
  * IDirect3DBaseShader implementation structure
  */
 /*****************************************************************************
  * IDirect3DBaseShader implementation structure
  */
@@ -2311,15 +2536,12 @@ typedef struct IWineD3DBaseShaderClass
     LONG                            ref;
     SHADER_LIMITS                   limits;
     SHADER_PARSE_STATE              parse_state;
     LONG                            ref;
     SHADER_LIMITS                   limits;
     SHADER_PARSE_STATE              parse_state;
-    CONST SHADER_OPCODE             *shader_ins;
     DWORD                          *function;
     UINT                            functionLength;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
     DWORD                          *function;
     UINT                            functionLength;
     UINT                            cur_loop_depth, cur_loop_regno;
     BOOL                            load_local_constsF;
-    BOOL                            uses_bool_consts, uses_int_consts;
-
-    /* Type of shader backend */
-    int shader_mode;
+    const struct wined3d_shader_frontend *frontend;
+    void *frontend_data;
 
     /* Programs this shader is linked with */
     struct list linked_programs;
 
     /* Programs this shader is linked with */
     struct list linked_programs;
@@ -2347,44 +2569,36 @@ typedef struct IWineD3DBaseShaderImpl {
 void shader_buffer_init(struct SHADER_BUFFER *buffer);
 void shader_buffer_free(struct SHADER_BUFFER *buffer);
 void shader_cleanup(IWineD3DBaseShader *iface);
 void shader_buffer_init(struct SHADER_BUFFER *buffer);
 void shader_buffer_free(struct SHADER_BUFFER *buffer);
 void shader_cleanup(IWineD3DBaseShader *iface);
-HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
-        struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
-        const DWORD *byte_code);
-void shader_init(struct IWineD3DBaseShaderClass *shader,
-        IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
-void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
-
-extern void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+        const struct wined3d_shader_version *shader_version);
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+        const struct wined3d_shader_version *shader_version);
+void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
-
-static inline int shader_get_regtype(const DWORD param) {
-    return (((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) |
-            ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2));
-}
-
-static inline int shader_get_writemask(const DWORD param) {
-    return param & WINED3DSP_WRITEMASK_ALL;
-}
-
-static inline BOOL shader_is_pshader_version(DWORD token) {
-    return 0xFFFF0000 == (token & 0xFFFF0000);
-}
-
-static inline BOOL shader_is_vshader_version(DWORD token) {
-    return 0xFFFE0000 == (token & 0xFFFF0000);
+HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
+        struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
+        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size);
+void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
+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);
+
+static inline BOOL shader_is_pshader_version(enum wined3d_shader_type type)
+{
+    return type == WINED3D_SHADER_TYPE_PIXEL;
 }
 
 }
 
-static inline BOOL shader_is_comment(DWORD token) {
-    return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK);
+static inline BOOL shader_is_vshader_version(enum wined3d_shader_type type)
+{
+    return type == WINED3D_SHADER_TYPE_VERTEX;
 }
 
 }
 
-static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx)
+static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
 {
 {
-    switch (register_type)
+    switch (reg->type)
     {
         case WINED3DSPR_RASTOUT:
             /* oFog & oPts */
     {
         case WINED3DSPR_RASTOUT:
             /* oFog & oPts */
-            if (register_idx != 0) return TRUE;
+            if (reg->idx != 0) return TRUE;
             /* oPos */
             return FALSE;
 
             /* oPos */
             return FALSE;
 
@@ -2395,7 +2609,7 @@ static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_t
             return TRUE;
 
         case WINED3DSPR_MISCTYPE:
             return TRUE;
 
         case WINED3DSPR_MISCTYPE:
-            switch(register_idx)
+            switch(reg->idx)
             {
                 case 0: /* vPos */
                     return FALSE;
             {
                 case 0: /* vPos */
                     return FALSE;
@@ -2405,6 +2619,15 @@ static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_t
                     return FALSE;
             }
 
                     return FALSE;
             }
 
+        case WINED3DSPR_IMMCONST:
+            switch(reg->immconst_type)
+            {
+                case WINED3D_IMMCONST_FLOAT:
+                    return TRUE;
+                default:
+                    return FALSE;
+            }
+
         default:
             return FALSE;
     }
         default:
             return FALSE;
     }
@@ -2457,7 +2680,6 @@ typedef struct IWineD3DVertexShaderImpl {
 
     const struct vs_compile_args    *cur_args;
 } IWineD3DVertexShaderImpl;
 
     const struct vs_compile_args    *cur_args;
 } IWineD3DVertexShaderImpl;
-extern const SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[];
 extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
 
 void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args);
 extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl;
 
 void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args);
@@ -2500,7 +2722,6 @@ typedef struct IWineD3DPixelShaderImpl {
     const struct ps_compile_args *cur_args;
 } IWineD3DPixelShaderImpl;
 
     const struct ps_compile_args *cur_args;
 } IWineD3DPixelShaderImpl;
 
-extern const SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[];
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
 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);
 extern const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl;
 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);
@@ -2543,6 +2764,14 @@ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth);
  * Pixel format management
  */
 
  * Pixel format management
  */
 
+/* WineD3D pixel format flags */
+#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1
+#define WINED3DFMT_FLAG_FILTERING                0x2
+#define WINED3DFMT_FLAG_DEPTH                    0x4
+#define WINED3DFMT_FLAG_STENCIL                  0x8
+#define WINED3DFMT_FLAG_RENDERTARGET             0x10
+#define WINED3DFMT_FLAG_FOURCC                   0x20
+
 struct GlPixelFormatDesc
 {
     WINED3DFORMAT format;
 struct GlPixelFormatDesc
 {
     WINED3DFORMAT format;
diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private_types.h b/reactos/dll/directx/wine/wined3d/wined3d_private_types.h
deleted file mode 100644 (file)
index 2d9ae03..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Direct3D wine internal header: D3D equivalent types
- *
- * Copyright 2002-2003 Jason Edmeades
- * Copyright 2002-2003 Raphael Junqueira
- * 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
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifndef __WINE_WINED3D_TYPES_INTERNAL_H
-#define __WINE_WINED3D_TYPES_INTERNAL_H
-
-/* WineD3D pixel format flags */
-#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x1
-#define WINED3DFMT_FLAG_FILTERING                0x2
-#define WINED3DFMT_FLAG_DEPTH                    0x4
-#define WINED3DFMT_FLAG_STENCIL                  0x8
-#define WINED3DFMT_FLAG_RENDERTARGET             0x10
-#define WINED3DFMT_FLAG_FOURCC                   0x20
-
-/** DCL usage masks **/
-#define WINED3DSP_DCL_USAGE_SHIFT 0
-#define WINED3DSP_DCL_USAGE_MASK  0x0000000f
-#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
-#define WINED3DSP_DCL_USAGEINDEX_MASK  0x000f0000
-
-/** DCL sampler texture type **/
-#define WINED3DSP_TEXTURETYPE_SHIFT 27
-#define WINED3DSP_TEXTURETYPE_MASK  0x78000000
-
-typedef enum _WINED3DSAMPLER_TEXTURE_TYPE {
-  WINED3DSTT_UNKNOWN      = 0 << WINED3DSP_TEXTURETYPE_SHIFT,
-  WINED3DSTT_1D           = 1 << WINED3DSP_TEXTURETYPE_SHIFT,
-  WINED3DSTT_2D           = 2 << WINED3DSP_TEXTURETYPE_SHIFT,
-  WINED3DSTT_CUBE         = 3 << WINED3DSP_TEXTURETYPE_SHIFT,
-  WINED3DSTT_VOLUME       = 4 << WINED3DSP_TEXTURETYPE_SHIFT,
-
-  WINED3DSTT_FORCE_DWORD  = 0x7FFFFFFF
-} WINED3DSAMPLER_TEXTURE_TYPE;
-
-/** Register number mask **/
-#define WINED3DSP_REGNUM_MASK        0x000007FF
-
-/** Register type masks  **/
-#define WINED3DSP_REGTYPE_SHIFT      28
-#define WINED3DSP_REGTYPE_SHIFT2     8
-#define WINED3DSP_REGTYPE_MASK       (0x7 << WINED3DSP_REGTYPE_SHIFT)
-#define WINED3DSP_REGTYPE_MASK2      0x00001800
-
-/** Register types **/
-typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE {
-  WINED3DSPR_TEMP         =  0, 
-  WINED3DSPR_INPUT        =  1,
-  WINED3DSPR_CONST        =  2,
-  WINED3DSPR_ADDR         =  3,
-  WINED3DSPR_TEXTURE      =  3,
-  WINED3DSPR_RASTOUT      =  4,
-  WINED3DSPR_ATTROUT      =  5,
-  WINED3DSPR_TEXCRDOUT    =  6,
-  WINED3DSPR_OUTPUT       =  6,
-  WINED3DSPR_CONSTINT     =  7,
-  WINED3DSPR_COLOROUT     =  8,
-  WINED3DSPR_DEPTHOUT     =  9,
-  WINED3DSPR_SAMPLER      = 10,
-  WINED3DSPR_CONST2       = 11,
-  WINED3DSPR_CONST3       = 12,
-  WINED3DSPR_CONST4       = 13,
-  WINED3DSPR_CONSTBOOL    = 14,
-  WINED3DSPR_LOOP         = 15,
-  WINED3DSPR_TEMPFLOAT16  = 16,
-  WINED3DSPR_MISCTYPE     = 17,
-  WINED3DSPR_LABEL        = 18,
-  WINED3DSPR_PREDICATE    = 19,
-
-  WINED3DSPR_FORCE_DWORD  = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_REGISTER_TYPE;
-
-/* RASTOUT register offsets */
-typedef enum _WINED3DVS_RASTOUT_OFFSETS {
-  WINED3DSRO_POSITION     = 0,
-  WINED3DSRO_FOG          = 1,
-  WINED3DSRO_POINT_SIZE   = 2,
-
-  WINED3DSRO_FORCE_DWORD  = 0x7FFFFFFF
-} WINED3DVS_RASTOUT_OFFSETS;
-
-/** Source register modifiers **/
-#define WINED3DVS_SWIZZLE_SHIFT      16
-#define WINED3DVS_SWIZZLE_MASK       (0xFF << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DSP_SWIZZLE_SHIFT      16
-#define WINED3DSP_SWIZZLE_MASK       (0xFF << WINED3DSP_SWIZZLE_SHIFT)
-
-#define WINED3DVS_X_X       (0 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_Y       (1 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_Z       (2 << WINED3DVS_SWIZZLE_SHIFT)
-#define WINED3DVS_X_W       (3 << WINED3DVS_SWIZZLE_SHIFT)
-
-#define WINED3DVS_Y_X       (0 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_Y       (1 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_Z       (2 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-#define WINED3DVS_Y_W       (3 << (WINED3DVS_SWIZZLE_SHIFT + 2))
-
-#define WINED3DVS_Z_X       (0 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_Y       (1 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_Z       (2 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-#define WINED3DVS_Z_W       (3 << (WINED3DVS_SWIZZLE_SHIFT + 4))
-
-#define WINED3DVS_W_X       (0 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_Y       (1 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_Z       (2 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-#define WINED3DVS_W_W       (3 << (WINED3DVS_SWIZZLE_SHIFT + 6))
-
-#define WINED3DVS_NOSWIZZLE (WINED3DVS_X_X | WINED3DVS_Y_Y | WINED3DVS_Z_Z | WINED3DVS_W_W)
-
-#define WINED3DSP_NOSWIZZLE \
-    ((0 << (WINED3DSP_SWIZZLE_SHIFT + 0)) | (1 << (WINED3DSP_SWIZZLE_SHIFT + 2)) | \
-     (2 << (WINED3DSP_SWIZZLE_SHIFT + 4)) | (3 << (WINED3DSP_SWIZZLE_SHIFT + 6)))
-
-#define WINED3DSP_SRCMOD_SHIFT      24
-#define WINED3DSP_SRCMOD_MASK       (0xF << WINED3DSP_SRCMOD_SHIFT)
-
-typedef enum _WINED3DSHADER_PARAM_SRCMOD_TYPE {
-  WINED3DSPSM_NONE         =  0 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_NEG          =  1 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_BIAS         =  2 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_BIASNEG      =  3 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_SIGN         =  4 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_SIGNNEG      =  5 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_COMP         =  6 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_X2           =  7 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_X2NEG        =  8 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_DZ           =  9 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_DW           = 10 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_ABS          = 11 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_ABSNEG       = 12 << WINED3DSP_SRCMOD_SHIFT,
-  WINED3DSPSM_NOT          = 13 << WINED3DSP_SRCMOD_SHIFT,
-
-  WINED3DSPSM_FORCE_DWORD  = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_SRCMOD_TYPE;
-
-/** Destination register modifiers **/
-#define WINED3DSP_WRITEMASK_0       0x00010000 /* .x r */
-#define WINED3DSP_WRITEMASK_1       0x00020000 /* .y g */
-#define WINED3DSP_WRITEMASK_2       0x00040000 /* .z b */
-#define WINED3DSP_WRITEMASK_3       0x00080000 /* .w a */
-#define WINED3DSP_WRITEMASK_ALL     0x000F0000 /* all */
-
-#define WINED3DSP_DSTMOD_SHIFT      20
-#define WINED3DSP_DSTMOD_MASK       (0xF << WINED3DSP_DSTMOD_SHIFT)
-
-typedef enum _WINED3DSHADER_PARAM_DSTMOD_TYPE {
-  WINED3DSPDM_NONE             = 0 << WINED3DSP_DSTMOD_SHIFT,
-  WINED3DSPDM_SATURATE         = 1 << WINED3DSP_DSTMOD_SHIFT,
-  WINED3DSPDM_PARTIALPRECISION = 2 << WINED3DSP_DSTMOD_SHIFT,
-  WINED3DSPDM_MSAMPCENTROID    = 4 << WINED3DSP_DSTMOD_SHIFT,
-
-  WINED3DSPDM_FORCE_DWORD  = 0x7FFFFFFF
-} WINED3DSHADER_PARAM_DSTMOD_TYPE;
-
-#define WINED3DSP_DSTSHIFT_SHIFT     24
-#define WINED3DSP_DSTSHIFT_MASK      (0xF << WINED3DSP_DSTSHIFT_SHIFT)
-
-/** Register addressing modes **/
-#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
-#define WINED3DSHADER_ADDRESSMODE_MASK  (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
-
-typedef enum _WINED3DSHADER_ADDRESSMODE_TYPE {
-  WINED3DSHADER_ADDRMODE_ABSOLUTE    = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
-  WINED3DSHADER_ADDRMODE_RELATIVE    = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
-
-  WINED3DSHADER_ADDRMODE_FORCE_DWORD = 0x7FFFFFFF
-} WINED3DSHADER_ADDRESSMODE_TYPE;
-
-/** Opcode types */
-typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE {
-  WINED3DSIO_NOP          =  0,
-  WINED3DSIO_MOV          =  1,
-  WINED3DSIO_ADD          =  2,
-  WINED3DSIO_SUB          =  3,
-  WINED3DSIO_MAD          =  4,
-  WINED3DSIO_MUL          =  5,
-  WINED3DSIO_RCP          =  6,
-  WINED3DSIO_RSQ          =  7,
-  WINED3DSIO_DP3          =  8,
-  WINED3DSIO_DP4          =  9,
-  WINED3DSIO_MIN          = 10,
-  WINED3DSIO_MAX          = 11,
-  WINED3DSIO_SLT          = 12,
-  WINED3DSIO_SGE          = 13,
-  WINED3DSIO_EXP          = 14,
-  WINED3DSIO_LOG          = 15,
-  WINED3DSIO_LIT          = 16,
-  WINED3DSIO_DST          = 17,
-  WINED3DSIO_LRP          = 18,
-  WINED3DSIO_FRC          = 19,
-  WINED3DSIO_M4x4         = 20,
-  WINED3DSIO_M4x3         = 21,
-  WINED3DSIO_M3x4         = 22,
-  WINED3DSIO_M3x3         = 23,
-  WINED3DSIO_M3x2         = 24,
-  WINED3DSIO_CALL         = 25,
-  WINED3DSIO_CALLNZ       = 26,
-  WINED3DSIO_LOOP         = 27,
-  WINED3DSIO_RET          = 28,
-  WINED3DSIO_ENDLOOP      = 29,
-  WINED3DSIO_LABEL        = 30,
-  WINED3DSIO_DCL          = 31,
-  WINED3DSIO_POW          = 32,
-  WINED3DSIO_CRS          = 33,
-  WINED3DSIO_SGN          = 34,
-  WINED3DSIO_ABS          = 35,
-  WINED3DSIO_NRM          = 36,
-  WINED3DSIO_SINCOS       = 37,
-  WINED3DSIO_REP          = 38,
-  WINED3DSIO_ENDREP       = 39,
-  WINED3DSIO_IF           = 40,
-  WINED3DSIO_IFC          = 41,
-  WINED3DSIO_ELSE         = 42,
-  WINED3DSIO_ENDIF        = 43,
-  WINED3DSIO_BREAK        = 44,
-  WINED3DSIO_BREAKC       = 45,
-  WINED3DSIO_MOVA         = 46,
-  WINED3DSIO_DEFB         = 47,
-  WINED3DSIO_DEFI         = 48,
-
-  WINED3DSIO_TEXCOORD     = 64,
-  WINED3DSIO_TEXKILL      = 65,
-  WINED3DSIO_TEX          = 66,
-  WINED3DSIO_TEXBEM       = 67,
-  WINED3DSIO_TEXBEML      = 68,
-  WINED3DSIO_TEXREG2AR    = 69,
-  WINED3DSIO_TEXREG2GB    = 70,
-  WINED3DSIO_TEXM3x2PAD   = 71,
-  WINED3DSIO_TEXM3x2TEX   = 72,
-  WINED3DSIO_TEXM3x3PAD   = 73,
-  WINED3DSIO_TEXM3x3TEX   = 74,
-  WINED3DSIO_TEXM3x3DIFF  = 75,
-  WINED3DSIO_TEXM3x3SPEC  = 76,
-  WINED3DSIO_TEXM3x3VSPEC = 77,
-  WINED3DSIO_EXPP         = 78,
-  WINED3DSIO_LOGP         = 79,
-  WINED3DSIO_CND          = 80,
-  WINED3DSIO_DEF          = 81,
-  WINED3DSIO_TEXREG2RGB   = 82,
-  WINED3DSIO_TEXDP3TEX    = 83,
-  WINED3DSIO_TEXM3x2DEPTH = 84,
-  WINED3DSIO_TEXDP3       = 85,
-  WINED3DSIO_TEXM3x3      = 86,
-  WINED3DSIO_TEXDEPTH     = 87,
-  WINED3DSIO_CMP          = 88,
-  WINED3DSIO_BEM          = 89,
-  WINED3DSIO_DP2ADD       = 90,
-  WINED3DSIO_DSX          = 91,
-  WINED3DSIO_DSY          = 92,
-  WINED3DSIO_TEXLDD       = 93,
-  WINED3DSIO_SETP         = 94,
-  WINED3DSIO_TEXLDL       = 95,
-  WINED3DSIO_BREAKP       = 96,
-
-  WINED3DSIO_PHASE        = 0xFFFD,
-  WINED3DSIO_COMMENT      = 0xFFFE,
-  WINED3DSIO_END          = 0XFFFF,
-
-  WINED3DSIO_FORCE_DWORD  = 0X7FFFFFFF /** for 32-bit alignment */
-} WINED3DSHADER_INSTRUCTION_OPCODE_TYPE;
-
-/** opcode-related masks **/
-
-#define WINED3D_OPCODESPECIFICCONTROL_MASK  0x00ff0000
-#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16
-
-#define WINED3DSI_OPCODE_MASK       0x0000FFFF
-#define WINED3DSI_INSTLENGTH_MASK   0x0F000000
-#define WINED3DSI_INSTLENGTH_SHIFT  24
-
-#define WINED3DSI_COISSUE 0x40000000
-
-#define WINED3DSI_COMMENTSIZE_SHIFT 16
-#define WINED3DSI_COMMENTSIZE_MASK (0x7FFF << WINED3DSI_COMMENTSIZE_SHIFT)
-#define WINED3DSHADER_COMMENT(commentSize) \
-  ((((commentSize) << WINED3DSI_COMMENTSIZE_SHIFT) & WINED3DSI_COMMENTSIZE_MASK) | WINED3DSIO_COMMENT)
-
-#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
-
-/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
-#define WINED3DSI_TEXLD_PROJECT 0x00010000
-#define WINED3DSI_TEXLD_BIAS    0x00020000
-
-/** Shader version tokens, and shader end tokens **/
-
-#define WINED3DPS_VERSION(major, minor) (0xFFFF0000 | ((major) << 8) | (minor))
-#define WINED3DVS_VERSION(major, minor) (0xFFFE0000 | ((major) << 8) | (minor))
-#define WINED3DSHADER_VERSION_MAJOR(version) (((version) >> 8) & 0xFF)
-#define WINED3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
-#define WINED3DPS_END() 0x0000FFFF
-#define WINED3DVS_END() 0x0000FFFF
-
-/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
-#define WINED3DCREATE_MULTITHREADED                 0x00000004
-
-#endif
index b8691a7..3845ded 100644 (file)
@@ -848,6 +848,19 @@ typedef enum _WINED3DSURFTYPE
     SURFACE_GDI,                                    /* User surface. No 3D, DirectDraw rendering with GDI */
 } WINED3DSURFTYPE;
 
     SURFACE_GDI,                                    /* User surface. No 3D, DirectDraw rendering with GDI */
 } WINED3DSURFTYPE;
 
+enum wined3d_sysval_semantic
+{
+    WINED3D_SV_DEPTH = 0xffffffff,
+    WINED3D_SV_TARGET0 = 0,
+    WINED3D_SV_TARGET1 = 1,
+    WINED3D_SV_TARGET2 = 2,
+    WINED3D_SV_TARGET3 = 3,
+    WINED3D_SV_TARGET4 = 4,
+    WINED3D_SV_TARGET5 = 5,
+    WINED3D_SV_TARGET6 = 6,
+    WINED3D_SV_TARGET7 = 7,
+};
+
 const UINT WINED3DCOLORWRITEENABLE_RED                          = (1<<0);
 const UINT WINED3DCOLORWRITEENABLE_GREEN                        = (1<<1);
 const UINT WINED3DCOLORWRITEENABLE_BLUE                         = (1<<2);
 const UINT WINED3DCOLORWRITEENABLE_RED                          = (1<<0);
 const UINT WINED3DCOLORWRITEENABLE_GREEN                        = (1<<1);
 const UINT WINED3DCOLORWRITEENABLE_BLUE                         = (1<<2);
@@ -2117,6 +2130,23 @@ struct wined3d_buffer_desc
     UINT misc_flags;
 };
 
     UINT misc_flags;
 };
 
+struct wined3d_shader_signature_element
+{
+    const char *semantic_name;
+    UINT semantic_idx;
+    enum wined3d_sysval_semantic sysval_semantic;
+    DWORD component_type;
+    UINT register_idx;
+    DWORD mask;
+};
+
+struct wined3d_shader_signature
+{
+    UINT element_count;
+    struct wined3d_shader_signature_element *elements;
+    char *string_data;
+};
+
 interface IWineD3DResource;
 interface IWineD3DSurface;
 interface IWineD3DVolume;
 interface IWineD3DResource;
 interface IWineD3DSurface;
 interface IWineD3DVolume;
@@ -2222,8 +2252,8 @@ interface IWineD3D : IWineD3DBase
     );
     HRESULT EnumAdapterModes(
         [in] UINT adapter_idx,
     );
     HRESULT EnumAdapterModes(
         [in] UINT adapter_idx,
-        [in] UINT mode_idx,
         [in] WINED3DFORMAT format,
         [in] WINED3DFORMAT format,
+        [in] UINT mode_idx,
         [out] WINED3DDISPLAYMODE *mode
     );
     HRESULT GetAdapterDisplayMode(
         [out] WINED3DDISPLAYMODE *mode
     );
     HRESULT GetAdapterDisplayMode(
@@ -2823,7 +2853,8 @@ interface IWineD3DBuffer : IWineD3DResource
 interface IWineD3DBaseShader : IWineD3DBase
 {
     HRESULT SetFunction(
 interface IWineD3DBaseShader : IWineD3DBase
 {
     HRESULT SetFunction(
-        [in] const DWORD *function
+        [in] const DWORD *function,
+        [in] const struct wined3d_shader_signature *output_signature
     );
 }
 
     );
 }
 
@@ -2886,7 +2917,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] DWORD fvf,
         [in] WINED3DPOOL pool,
         [out] IWineD3DBuffer **vertex_buffer,
         [in] DWORD fvf,
         [in] WINED3DPOOL pool,
         [out] IWineD3DBuffer **vertex_buffer,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateIndexBuffer(
         [in] IUnknown *parent
     );
     HRESULT CreateIndexBuffer(
@@ -2894,7 +2924,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] DWORD usage,
         [in] WINED3DPOOL pool,
         [out] IWineD3DBuffer **index_buffer,
         [in] DWORD usage,
         [in] WINED3DPOOL pool,
         [out] IWineD3DBuffer **index_buffer,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateStateBlock(
         [in] IUnknown *parent
     );
     HRESULT CreateStateBlock(
@@ -2915,7 +2944,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DPOOL pool,
         [in] WINED3DMULTISAMPLE_TYPE multisample_type,
         [in] DWORD multisample_quality,
         [in] WINED3DPOOL pool,
         [in] WINED3DMULTISAMPLE_TYPE multisample_type,
         [in] DWORD multisample_quality,
-        [in] HANDLE *shared_handle,
         [in] WINED3DSURFTYPE surface_type,
         [in] IUnknown *parent
     );
         [in] WINED3DSURFTYPE surface_type,
         [in] IUnknown *parent
     );
@@ -2932,7 +2960,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DTexture **texture,
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DTexture **texture,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateVolumeTexture(
         [in] IUnknown *parent
     );
     HRESULT CreateVolumeTexture(
@@ -2944,7 +2971,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolumeTexture **texture,
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolumeTexture **texture,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateVolume(
         [in] IUnknown *parent
     );
     HRESULT CreateVolume(
@@ -2955,7 +2981,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolume **volume,
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DVolume **volume,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateCubeTexture(
         [in] IUnknown *parent
     );
     HRESULT CreateCubeTexture(
@@ -2965,7 +2990,6 @@ interface IWineD3DDevice : IWineD3DBase
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DCubeTexture **texture,
         [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
         [out] IWineD3DCubeTexture **texture,
-        [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
     HRESULT CreateQuery(
         [in] IUnknown *parent
     );
     HRESULT CreateQuery(
@@ -2998,6 +3022,7 @@ interface IWineD3DDevice : IWineD3DBase
     );
     HRESULT CreatePixelShader(
         [in] const DWORD *function,
     );
     HRESULT CreatePixelShader(
         [in] const DWORD *function,
+        [in] const struct wined3d_shader_signature *output_signature,
         [out] IWineD3DPixelShader **shader,
         [in] IUnknown *parent
     );
         [out] IWineD3DPixelShader **shader,
         [in] IUnknown *parent
     );