diff --git a/reactos/dll/directx/wine/d3d8/d3d8_private.h b/reactos/dll/directx/wine/d3d8/d3d8_private.h index c9afe173ab9..c38d8cc8b30 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_private.h +++ b/reactos/dll/directx/wine/d3d8/d3d8_private.h @@ -601,6 +601,8 @@ struct IDirect3DVertexShader8Impl { IWineD3DVertexShader *wineD3DVertexShader; }; +#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256 + /* ------------------------ */ /* IDirect3DPixelShaderImpl */ diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 985557c8d78..206697d99d4 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -359,6 +359,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface 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; @@ -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, - 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)) { @@ -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, - 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) { @@ -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, - 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){ @@ -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, - 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; @@ -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, - (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, - NULL, (IUnknown *)object); + (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object); 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, - (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 */ @@ -2000,6 +1999,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV 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); @@ -2011,6 +2016,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV 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); @@ -2155,7 +2166,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i EnterCriticalSection(&d3d8_cs); hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, - &object->wineD3DPixelShader, (IUnknown *)object); + NULL, &object->wineD3DPixelShader, (IUnknown *)object); 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, - 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); diff --git a/reactos/dll/directx/wine/d3d8/directx.c b/reactos/dll/directx/wine/d3d8/directx.c index 64fc3605d43..d39d3d64768 100644 --- a/reactos/dll/directx/wine/d3d8/directx.c +++ b/reactos/dll/directx/wine/d3d8/directx.c @@ -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); } + pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); TRACE("(%p) returning %p\n", This, pCaps); return hrc; diff --git a/reactos/dll/directx/wine/d3d9/cubetexture.c b/reactos/dll/directx/wine/d3d9/cubetexture.c index c4b4860bfa2..bbd171ea62a 100644 --- a/reactos/dll/directx/wine/d3d9/cubetexture.c +++ b/reactos/dll/directx/wine/d3d9/cubetexture.c @@ -365,8 +365,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac 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){ diff --git a/reactos/dll/directx/wine/d3d9/d3d9_private.h b/reactos/dll/directx/wine/d3d9/d3d9_private.h index 25b6ae2434a..7e439749a7b 100644 --- a/reactos/dll/directx/wine/d3d9/d3d9_private.h +++ b/reactos/dll/directx/wine/d3d9/d3d9_private.h @@ -497,6 +497,8 @@ typedef struct IDirect3DVertexShader9Impl { LPDIRECT3DDEVICE9EX parentDevice; } IDirect3DVertexShader9Impl; +#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 + /* --------------------- */ /* IDirect3DPixelShader9 */ /* --------------------- */ diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index 8d88e5227bd..e5ca4c4afd0 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -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), - 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) { @@ -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, - 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); diff --git a/reactos/dll/directx/wine/d3d9/directx.c b/reactos/dll/directx/wine/d3d9/directx.c index 229368afb80..e9547a764e4 100644 --- a/reactos/dll/directx/wine/d3d9/directx.c +++ b/reactos/dll/directx/wine/d3d9/directx.c @@ -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; + + pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst); } static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { diff --git a/reactos/dll/directx/wine/d3d9/indexbuffer.c b/reactos/dll/directx/wine/d3d9/indexbuffer.c index 161ff643cd7..8802bd19780 100644 --- a/reactos/dll/directx/wine/d3d9/indexbuffer.c +++ b/reactos/dll/directx/wine/d3d9/indexbuffer.c @@ -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, - (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, - pSharedHandle, (IUnknown *)object); + (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object); LeaveCriticalSection(&d3d9_cs); if (hrc != D3D_OK) { diff --git a/reactos/dll/directx/wine/d3d9/pixelshader.c b/reactos/dll/directx/wine/d3d9/pixelshader.c index 9c528d9dba4..3939f5977a8 100644 --- a/reactos/dll/directx/wine/d3d9/pixelshader.c +++ b/reactos/dll/directx/wine/d3d9/pixelshader.c @@ -128,7 +128,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(LPDIRECT3DDEVICE9EX iface, 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) { diff --git a/reactos/dll/directx/wine/d3d9/texture.c b/reactos/dll/directx/wine/d3d9/texture.c index e1283508a80..f0a9c38ad7e 100644 --- a/reactos/dll/directx/wine/d3d9/texture.c +++ b/reactos/dll/directx/wine/d3d9/texture.c @@ -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, - 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)) { diff --git a/reactos/dll/directx/wine/d3d9/vertexbuffer.c b/reactos/dll/directx/wine/d3d9/vertexbuffer.c index 8c65a885df6..501db41439b 100644 --- a/reactos/dll/directx/wine/d3d9/vertexbuffer.c +++ b/reactos/dll/directx/wine/d3d9/vertexbuffer.c @@ -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, - 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) { diff --git a/reactos/dll/directx/wine/d3d9/vertexshader.c b/reactos/dll/directx/wine/d3d9/vertexshader.c index 6478b68656f..fd2837d53be 100644 --- a/reactos/dll/directx/wine/d3d9/vertexshader.c +++ b/reactos/dll/directx/wine/d3d9/vertexshader.c @@ -192,6 +192,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX 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); @@ -202,6 +208,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX 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); diff --git a/reactos/dll/directx/wine/d3d9/volumetexture.c b/reactos/dll/directx/wine/d3d9/volumetexture.c index 81327cd92ee..07b686fe5a4 100644 --- a/reactos/dll/directx/wine/d3d9/volumetexture.c +++ b/reactos/dll/directx/wine/d3d9/volumetexture.c @@ -431,8 +431,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX if 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); diff --git a/reactos/dll/directx/wine/ddraw/ddcomimpl.h b/reactos/dll/directx/wine/ddraw/ddcomimpl.h deleted file mode 100644 index 553d29fccf5..00000000000 --- a/reactos/dll/directx/wine/ddraw/ddcomimpl.h +++ /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 - -/* 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_ */ diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c index 5e2717edc7b..7011afa4004 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw.c +++ b/reactos/dll/directx/wine/ddraw/ddraw.c @@ -1727,20 +1727,9 @@ IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, } /* Create the new surface */ - hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, - Width, Height, Format, - TRUE /* Lockable */, - FALSE /* Discard */, - surfImpl->mipmap_level, - &surfImpl->WineD3DSurface, - 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; @@ -2036,21 +2025,9 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, } /* 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) { @@ -2725,15 +2702,13 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, */ 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, - 0 /* usage */, Format, Pool, (IWineD3DTexture **) &object->wineD3DTexture, - 0 /* SharedHandle */, (IUnknown *)object); + 0 /* usage */, Format, Pool, (IWineD3DTexture **)&object->wineD3DTexture, (IUnknown *)object); } This->tex_root = NULL; } diff --git a/reactos/dll/directx/wine/ddraw/device.c b/reactos/dll/directx/wine/ddraw/device.c index 7c8e222204e..3b7778f69b6 100644 --- a/reactos/dll/directx/wine/ddraw/device.c +++ b/reactos/dll/directx/wine/ddraw/device.c @@ -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) * - * Sounds like an overdose of math ;) - * * Version 3 and 7 * * Params: @@ -4368,7 +4366,7 @@ Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface, * 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) diff --git a/reactos/dll/directx/wine/ddraw/direct3d.c b/reactos/dll/directx/wine/ddraw/direct3d.c index aeba55b5596..9ce0d3664af 100644 --- a/reactos/dll/directx/wine/ddraw/direct3d.c +++ b/reactos/dll/directx/wine/ddraw/direct3d.c @@ -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 */, - WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, - &object->indexbuffer, 0 /* Handle */, (IUnknown *)IndexBufferParent); + WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, (IUnknown *)IndexBufferParent); if(FAILED(hr)) { @@ -1021,13 +1020,10 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface, 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); diff --git a/reactos/dll/directx/wine/ddraw/viewport.c b/reactos/dll/directx/wine/ddraw/viewport.c index 30d5e1821eb..c6e346e2294 100644 --- a/reactos/dll/directx/wine/ddraw/viewport.c +++ b/reactos/dll/directx/wine/ddraw/viewport.c @@ -751,6 +751,7 @@ IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface, /* 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; @@ -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; + IDirect3DLight_Release( (IDirect3DLight *)cur_light ); This->num_lights--; This->map_lights &= ~(1<dwLightIndex); LeaveCriticalSection(&ddraw_cs); @@ -871,6 +873,9 @@ IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface, break; } + if (*lplpDirect3DLight) + IDirect3DLight_AddRef(*lplpDirect3DLight); + LeaveCriticalSection(&ddraw_cs); return *lplpDirect3DLight ? D3D_OK : DDERR_INVALIDPARAMS; diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index b5b5ad445e0..56ee162e232 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -10,6 +10,7 @@ * 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 @@ -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) { - DWORD shader_version = This->baseShader.reg_maps.shader_version; 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] */ - 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++) { @@ -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); } +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, - 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; - 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)); @@ -343,25 +363,19 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh } 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 */ - 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, - 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 */ - 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++) { - 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); } } @@ -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; - 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'; @@ -426,7 +443,8 @@ static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *i *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. */ @@ -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 */ - 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; @@ -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 ((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]; @@ -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; - 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; @@ -498,7 +516,7 @@ static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADE } 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); @@ -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; - 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); @@ -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) { - 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; - IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader; + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader; 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"; } - 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"); @@ -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); } - 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]); } } -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; + SHADER_BUFFER *buffer = ins->ctx->buffer; /* 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; @@ -782,23 +779,15 @@ static void pshader_gen_input_modifier_line ( 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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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]; - DWORD sampler_code = dst->register_idx; + DWORD sampler_code = dst->reg.idx; 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); - 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 */ @@ -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]; - 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; - DWORD shift = dst->shift; 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 */ - 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) */ - 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 */ - 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 { @@ -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]); } - 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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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 */ - 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) */ - 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]); - - if (shift != 0) - pshader_gen_output_modifier_line(buffer, FALSE, dst_wmask, shift, dst_name); } /** 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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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; - 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); - 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]); - - 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) { - SHADER_BUFFER *buffer = ins->buffer; - const DWORD *src = ins->src; + SHADER_BUFFER *buffer = ins->ctx->buffer; const char *instruction; - char arguments[256]; + char arguments[256], dst_str[50]; unsigned int i; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; + const char *modifier; switch (ins->handler_idx) { @@ -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_NOP: instruction = "NOP"; 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; } - if (shader_is_pshader_version(ins->reg_maps->shader_version)) + /* All instructions handled by this function have a destination parameter */ + if(dst->modifiers & WINED3DSPDM_SATURATE) modifier = "_SAT"; + else modifier = ""; + + /* Note that shader_arb_add_dst_param() adds spaces. */ + arguments[0] = '\0'; + shader_arb_get_dst_param(ins, dst, dst_str); + for (i = 0; i < ins->src_count; ++i) { - /* 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); - - 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); + 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) { - 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) { - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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) { - 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"); } @@ -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 - * 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); } } @@ -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]; - DWORD shader_version = ins->reg_maps->shader_version; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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) */ - 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); @@ -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 */ - 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) { - 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; - - 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]; @@ -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 */ - 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. */ - if (shader_version < WINED3DPS_VERSION(1,4)) + if (shader_version < WINED3D_SHADER_VERSION(1,4)) 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. */ - 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 - 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 */ - if (shader_version < WINED3DPS_VERSION(1,4)) + if (shader_version < WINED3D_SHADER_VERSION(1,4)) { 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; } } - 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) { @@ -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]; - 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); - 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]; - 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) { - 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; - 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); - 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; @@ -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) { - 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); - 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); @@ -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) { - 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); - 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) { - 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; - 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 */ - 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 */ - 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 @@ -1292,6 +1201,8 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) } 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); @@ -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) { - 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]; - 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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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); - 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); @@ -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) { - 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]; - 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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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]; - 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 */ @@ -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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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]; - 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 */ @@ -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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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. @@ -1452,12 +1364,12 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins) * * 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, "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); @@ -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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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 */ - 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 @@ -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) { - 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]; - 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); @@ -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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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); - 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 */ } @@ -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]; - 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; - 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); - 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 */ @@ -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) { - 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]; - 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 @@ -1588,21 +1500,18 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) { 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 */ - 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.src = tmp_src; 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_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; - tmp_ins.src[1] = ins->src[1]+i; 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) { @@ -1657,44 +1567,42 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) 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 */ - 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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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; - 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); - 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); - - 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) @@ -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]; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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; - 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); - 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); - - 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) @@ -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; - 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; @@ -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 */ - 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 */ - 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 */ - 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 */ @@ -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 */ } -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; - 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; + DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This); /* 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; @@ -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"); - if (shader_version < WINED3DPS_VERSION(2,0)) { + if (reg_maps->shader_version.major < 2) + { 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 */ - 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 */ - 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"); @@ -2063,18 +1970,21 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF } /* 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; - GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst->idx, value)); + GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value)); checkGLcall("glProgramLocalParameter4fvARB"); } + HeapFree(GetProcessHeap(), 0, lconst_map); } return retval; } -static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUFFER *buffer, const struct vs_compile_args *args) { +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; @@ -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; + DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This); /* 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_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); @@ -2126,7 +2037,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU } /* 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), @@ -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) { - shader_addline(buffer, "MOV result.fogcoord, 0.0;\n"); + shader_addline(buffer, "MOV result.fogcoord, helper_const.w;\n"); } /* Write the final position. @@ -2178,13 +2089,15 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface, SHADER_BU 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; - 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; } @@ -2228,6 +2141,30 @@ static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup) 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, @@ -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_NOP */ shader_hw_map2gl, + /* WINED3DSIH_NOP */ shader_hw_nop, /* 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_RSQ */ vshader_hw_rsq_rcp, + /* WINED3DSIH_RSQ */ shader_hw_rsq_rcp, /* 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_add_instruction_modifiers, }; /* 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 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) */ diff --git a/reactos/dll/directx/wine/wined3d/baseshader.c b/reactos/dll/directx/wine/wined3d/baseshader.c index 08415c21035..8b8aef4d15a 100644 --- a/reactos/dll/directx/wine/wined3d/baseshader.c +++ b/reactos/dll/directx/wine/wined3d/baseshader.c @@ -7,6 +7,7 @@ * 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 @@ -31,7 +32,111 @@ 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) || @@ -95,107 +200,27 @@ int shader_addline(SHADER_BUFFER* buffer, const char *format, ...) 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->shader_ins = instruction_table; list_init(&shader->linked_programs); } -const SHADER_OPCODE *shader_get_opcode(const SHADER_OPCODE *opcode_table, DWORD shader_version, DWORD code) -{ - DWORD i = 0; - - /** TODO: use dichotomic search */ - while (opcode_table[i].name) - { - 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; -} - -/* 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 */ - - char rel_token = WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2 && - ((*pToken & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE); - - *param = *pToken; - *addr_token = rel_token? *(pToken + 1): 0; - return rel_token? 2:1; -} - -/* 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) -{ - /* 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; -} - -/* 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) -{ - int tokens_read = 0; - int i = 0; - - /* TODO: Think of a good name for 0x80000000 and replace it with a constant */ - while (*pToken & 0x80000000) { - - DWORD param, addr_token; - tokens_read += shader_get_param(pToken, shader_version, ¶m, &addr_token); - pToken += tokens_read; - - 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; - } - 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 int shader_get_float_offset(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx) { - 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; + switch (register_type) + { + 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", regtype); - return regnum; - } + FIXME("Unsupported register type: %d\n", register_type); + return register_idx; + } } static void shader_delete_constant_list(struct list* clist) { @@ -212,36 +237,127 @@ static void shader_delete_constant_list(struct list* clist) { list_init(clist); } -static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst) +static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit) { - 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; + DWORD idx, shift; + idx = bit >> 5; + shift = bit & 0x1f; + bitmap[idx] |= (1 << shift); +} + +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) +{ + 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; + + case WINED3DSPR_CONSTINT: + reg_maps->integer_constants |= (1 << register_idx); + break; + + case WINED3DSPR_CONSTBOOL: + reg_maps->boolean_constants |= (1 << register_idx); + break; + + default: + TRACE("Not recording register of type %#x and idx %u\n", register_type, register_idx); + break; + } +} + +static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param) +{ + switch(instr) + { + case WINED3DSIH_M4x4: + case WINED3DSIH_M3x4: + return param == 1 ? 4 : 1; + + case WINED3DSIH_M4x3: + case WINED3DSIH_M3x3: + return param == 1 ? 3 : 1; + + case WINED3DSIH_M3x2: + return param == 1 ? 2 : 1; + + default: + return 1; + } } /* 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; - 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 */ - 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 @@ -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); - /* The version token is supposed to be the first token */ - if (!shader_is_version_token(*pToken)) - { - FIXME("First token is not a version token, invalid shader.\n"); - return WINED3DERR_INVALIDCALL; - } - reg_maps->shader_version = shader_version = *pToken++; - pshader = shader_is_pshader_version(shader_version); + fe->shader_read_header(fe_data, &pToken, &shader_version); + reg_maps->shader_version = shader_version; + pshader = shader_is_pshader_version(shader_version.type); - while (WINED3DVS_END() != *pToken) { - CONST SHADER_OPCODE* curOpcode; - DWORD opcode_token; + 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; + } + + while (!fe->shader_is_end(fe_data, &pToken)) + { + struct wined3d_shader_instruction ins; + const char *comment; + UINT param_size; /* 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 */ - opcode_token = *pToken++; - curOpcode = shader_get_opcode(shader_ins, shader_version, opcode_token); + fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size); /* 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 */ - } else if (WINED3DSIO_DCL == curOpcode->opcode) { + if (ins.handler_idx == WINED3DSIH_DCL) + { + struct wined3d_shader_semantic semantic; - DWORD usage = *pToken++; - DWORD param = *pToken++; - DWORD regtype = shader_get_regtype(param); - unsigned int regnum = param & WINED3DSP_REGNUM_MASK; + fe->shader_read_semantic(&pToken, &semantic); - /* Vshader: mark attributes used - Pshader: mark 3.0 input registers used, save token */ - if (WINED3DSPR_INPUT == regtype) { + 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; - if (!pshader) - reg_maps->attributes[regnum] = 1; - else - reg_maps->packed_input[regnum] = 1; + /* 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; - 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); + /* Save sampler usage token */ + case WINED3DSPR_SAMPLER: + reg_maps->sampler_type[semantic.reg.reg.idx] = semantic.sampler_type; + break; - /* 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 (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT)) - reg_maps->fog = 1; - - /* Save sampler usage token */ - } else if (WINED3DSPR_SAMPLER == regtype) - reg_maps->samplers[regnum] = usage; - - } 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; - 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] */ - 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; @@ -340,176 +461,185 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m } 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; - 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; + list_add_head(&This->baseShader.constantsI, &lconst->entry); - pToken += curOpcode->num_params; - - } else if (WINED3DSIO_DEFB == curOpcode->opcode) { + } + 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; - 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 */ - } 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; - 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--; - + } /* 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 */ - } else { + else + { 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 - * 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) */ - limit = (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED)? - curOpcode->num_params + 1: curOpcode->num_params; + if (ins.dst_count) + { + struct wined3d_shader_dst_param dst_param; + struct wined3d_shader_src_param dst_rel_addr; - for (i = 0; i < limit; ++i) { + fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr); - DWORD param, addr_token, reg, regtype; - pToken += shader_get_param(pToken, shader_version, ¶m, &addr_token); - - regtype = shader_get_regtype(param); - reg = param & WINED3DSP_REGNUM_MASK; - - if (WINED3DSPR_TEXTURE == regtype) { /* vs: WINED3DSPR_ADDR */ - - if (pshader) - reg_maps->texcoord[reg] = 1; - else - reg_maps->address[reg] = 1; - } - - 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 if (WINED3DSPR_RASTOUT == regtype && reg == 1) - reg_maps->fog = 1; - - else if (WINED3DSPR_MISCTYPE == regtype && reg == 0 && pshader) - reg_maps->vpos = 1; - - 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; - } - } - reg_maps->usesrelconstF = TRUE; - } - } - else if(WINED3DSPR_CONSTINT == regtype) { - This->baseShader.uses_int_consts = TRUE; - } - else if(WINED3DSPR_CONSTBOOL == regtype) { - This->baseShader.uses_bool_consts = TRUE; - } - - /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and is used - * in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel shaders because TECRDOUT - * isn't used in them, but future register types might cause issues - */ - else if (WINED3DSPR_TEXCRDOUT == regtype && i == 0 /* Only look at writes */ - && !pshader && WINED3DSHADER_VERSION_MAJOR(shader_version) < 3) + /* 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[reg] |= shader_get_writemask(param); + reg_maps->texcoord_mask[dst_param.reg.type] |= dst_param.write_mask; + } + else + { + shader_record_register_usage(This, reg_maps, dst_param.reg.type, + dst_param.reg.idx, !!dst_param.reg.rel_addr, pshader); + } + + /* Declare 1.X samplers implicitly, based on the destination reg. number */ + if (shader_version.major == 1 + && 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; + + TRACE("Setting fake 2D sampler for 1.x pixelshader\n"); + reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D; + + /* 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; + } + } + } + else if (pshader && ins.handler_idx == WINED3DSIH_BEM) + { + reg_maps->bumpmat[dst_param.reg.idx] = TRUE; + } + } + + 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)) + { + 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); @@ -517,389 +647,395 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m 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"); - 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; - 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 */ - 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("_"); - 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) +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) { - char relative = - ((param & WINED3DSHADER_ADDRESSMODE_MASK) == WINED3DSHADER_ADDRMODE_RELATIVE); + static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"}; + static const char * const misctype_reg_names[] = {"vPos", "vFace"}; + UINT offset = register_idx; - 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 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; - - /* 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: - TRACE("r%u", reg); + TRACE("r"); break; + case WINED3DSPR_INPUT: TRACE("v"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); break; + 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; - 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: - TRACE("%s", rastout_reg_names[reg]); + TRACE("%s", rastout_reg_names[register_idx]); break; + case WINED3DSPR_COLOROUT: - TRACE("oC%u", reg); + TRACE("oC"); break; + case WINED3DSPR_DEPTHOUT: TRACE("oDepth"); break; - case WINED3DSPR_ATTROUT: - TRACE("oD%u", reg); - break; - case WINED3DSPR_TEXCRDOUT: + case WINED3DSPR_ATTROUT: + TRACE("oD"); + break; + + case WINED3DSPR_TEXCRDOUT: /* 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; + case WINED3DSPR_CONSTINT: TRACE("i"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); break; + case WINED3DSPR_CONSTBOOL: TRACE("b"); - shader_dump_arr_entry(param, addr_token, reg, input, shader_version); break; + case WINED3DSPR_LABEL: - TRACE("l%u", reg); + TRACE("l"); break; + case WINED3DSPR_LOOP: TRACE("aL"); break; + case WINED3DSPR_SAMPLER: - TRACE("s%u", reg); + TRACE("s"); break; + 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; + case WINED3DSPR_PREDICATE: - TRACE("p%u", reg); + TRACE("p"); break; + + case WINED3DSPR_IMMCONST: + TRACE("l"); + break; + default: - TRACE("unhandled_rtype(%#x)", regtype); + TRACE("unhandled_rtype(%#x)", register_type); break; - } + } - if (!input) { - /* operand output (for modifiers and shift, see dump_ins_modifiers) */ + if (register_type == WINED3DSPR_IMMCONST) + { + TRACE("("); + switch (immconst_type) + { + case WINED3D_IMMCONST_FLOAT: + TRACE("%.8e", *(float *)immconst_data); + break; - 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]); - } + 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; - } else { - /** operand input */ - DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; + default: + TRACE("", 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; - 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 */ -void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, - const shader_reg_maps* reg_maps, CONST DWORD* pFunction) +void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer, + const shader_reg_maps *reg_maps, const DWORD *pFunction) { 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; - 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_context ctx; const DWORD *pToken = pFunction; - const SHADER_OPCODE *curOpcode; 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.src = src_param; 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 */ - 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 */ - opcode_token = *pToken++; - curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token); + fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size); /* 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 */ - 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 */ - hw_fct = handler_table[curOpcode->handler_idx]; + hw_fct = handler_table[ins.handler_idx]; /* 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; } - ins.handler_idx = curOpcode->handler_idx; - ins.flags = opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK; - ins.coissue = opcode_token & WINED3DSI_COISSUE; - /* 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, ¶m, &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 */ - if (opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED) ins.predicate = *pToken++; + if (ins.predicate) ins.predicate = *pToken++; /* Other source tokens */ - ins.src_count = curOpcode->num_params - curOpcode->dst_token; for (i = 0; i < ins.src_count; ++i) { - DWORD param, addr_token = 0; - pToken += shader_get_param(pToken, shader_version, ¶m, &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. ) */ - /* 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; @@ -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; - default: TRACE("_unhandled_shift(%d)", shift); break; + default: TRACE("_unhandled_shift(%d)", dst->shift); break; } 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) - 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 SHADER_OPCODE* curOpcode = NULL; - DWORD shader_version; - DWORD opcode_token; 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); - while (WINED3DVS_END() != *pToken) + TRACE("%s_%u_%u\n", shader_is_pshader_version(shader_version.type) ? "ps": "vs", + shader_version.major, shader_version.minor); + + while (!fe->shader_is_end(fe_data, &pToken)) { - 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; } - opcode_token = *pToken++; - curOpcode = shader_get_opcode(opcode_table, shader_version, opcode_token); - if (!curOpcode) + fe->shader_read_opcode(fe_data, &pToken, &ins, ¶m_size); + if (ins.handler_idx == WINED3DSIH_TABLE_SIZE) { - int tokens_read; - FIXME("Unrecognized opcode: token=0x%08x\n", opcode_token); - tokens_read = shader_skip_unrecognized(pToken, shader_version); - pToken += tokens_read; + TRACE("Skipping unrecognized instruction.\n"); + pToken += param_size; + continue; + } + + if (ins.handler_idx == WINED3DSIH_DCL) + { + 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 { - 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); + if (ins.dst_count) + { + fe->shader_read_dst_param(fe_data, &pToken, &dst_param, &dst_rel_addr); + } + + /* Print out predication source token first - it follows + * the destination token. */ + if (ins.predicate) + { + fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr); + TRACE("("); + shader_dump_src_param(&src_param, &shader_version); + TRACE(") "); + } + + /* PixWin marks instructions with the coissue flag with a '+' */ + if (ins.coissue) TRACE("+"); + + TRACE("%s", shader_opcode_names[ins.handler_idx]); + + if (ins.handler_idx == WINED3DSIH_IFC + || ins.handler_idx == WINED3DSIH_BREAKC) + { + switch (ins.flags) + { + 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"); + } + + /* We already read the destination token, print it. */ + if (ins.dst_count) + { + shader_dump_ins_modifiers(&dst_param); TRACE(" "); - shader_dump_param(param, 0, 0, shader_version); - pToken += 2; + shader_dump_dst_param(&dst_param, &shader_version); } - else if (curOpcode->opcode == WINED3DSIO_DEF) + + /* Other source tokens */ + for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i) { - 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; + fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr); + TRACE(!i ? " " : ", "); + shader_dump_src_param(&src_param, &shader_version); } - else if (curOpcode->opcode == WINED3DSIO_DEFI) - { - TRACE("defi i%u = %d, %d, %d, %d", *pToken & WINED3DSP_REGNUM_MASK, - *(pToken + 1), - *(pToken + 2), - *(pToken + 3), - *(pToken + 4)); - pToken += 5; - } - else if (curOpcode->opcode == WINED3DSIO_DEFB) - { - TRACE("defb b%u = %s", *pToken & WINED3DSP_REGNUM_MASK, - *(pToken + 1)? "true": "false"); - pToken += 2; - } - 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("+"); - } - - TRACE("%s", curOpcode->name); - - 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, ¶m, &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) - { - pToken++; - } - - /* Other source tokens */ - for (i = curOpcode->dst_token; i < curOpcode->num_params; ++i) - { - tokens_read = shader_get_param(pToken, shader_version, ¶m, &addr_token); - pToken += tokens_read; - - TRACE((i == 0)? " " : ", "); - shader_dump_param(param, addr_token, 1, 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); + 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); + + 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}; @@ -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 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; } -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; } +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) @@ -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_add_instruction_modifiers, }; diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index b68dcf7c6cf..666de8eadc1 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -214,7 +214,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, 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); @@ -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 - * 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 @@ -590,7 +590,8 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) 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)); @@ -951,12 +952,18 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, { 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); } + + 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)); + LEAVE_GL(); } } else @@ -987,12 +994,19 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) 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); } + + 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)); + LEAVE_GL(); + This->resource.allocatedMemory = NULL; } else if (This->flags & WINED3D_BUFFER_HASDESC) diff --git a/reactos/dll/directx/wine/wined3d/context.c b/reactos/dll/directx/wine/wined3d/context.c index a510d2e125b..2c6703f3603 100644 --- a/reactos/dll/directx/wine/wined3d/context.c +++ b/reactos/dll/directx/wine/wined3d/context.c @@ -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(); diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index 1099872ba3b..ec6d3f0422e 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -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; - 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"); @@ -503,7 +503,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, } 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 */ @@ -582,9 +582,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac 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; @@ -897,8 +897,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, 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); @@ -1085,8 +1089,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice * } 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); @@ -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); - 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 */ @@ -1269,8 +1273,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(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); @@ -1391,12 +1395,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa } 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); @@ -1451,8 +1452,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(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); @@ -2343,7 +2344,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac 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; @@ -2353,7 +2354,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac 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); @@ -2365,7 +2366,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac 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; @@ -2382,13 +2386,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface 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); - 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); @@ -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, - 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; @@ -4207,12 +4211,13 @@ static void device_map_fixed_function_samplers(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) { - 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) { @@ -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) { - 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; @@ -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. */ - 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; - if (vshader_sampler_tokens[i]) { + if (vshader_sampler_type[i]) + { 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) { - 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)); @@ -4530,27 +4537,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn 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 @@ -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) { - 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 */ diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index 7c6cc3bad20..9a064bb996e 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -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_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 }, @@ -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); - //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); @@ -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; } - + 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"); @@ -2392,6 +2401,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, /* 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"); @@ -2401,6 +2411,7 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, 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"); @@ -2409,15 +2420,6 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter, 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. @@ -3636,7 +3638,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, 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; } @@ -3851,7 +3853,7 @@ ULONG WINAPI D3DCB_DefaultDestroyVolume(IWineD3DVolume *pVolume) { 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 @@ -3908,6 +3910,8 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) { 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"); @@ -4003,46 +4007,80 @@ static const struct driver_version_information driver_version_table[] = { /* 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; - } - - /* 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_geforce5(const WineD3D_GL_Info *gl_info) { + if(gl_info->gl_vendor == VENDOR_NVIDIA) { + if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) { + return TRUE; } } + return FALSE; +} + +static BOOL match_apple_intel(const WineD3D_GL_Info *gl_info) { + return gl_info->gl_vendor == VENDOR_INTEL && match_apple(gl_info); +} + +static BOOL match_apple_nonr500ati(const WineD3D_GL_Info *gl_info) { + if(!match_apple(gl_info)) return FALSE; + if(gl_info->gl_vendor != VENDOR_ATI) return FALSE; + if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return FALSE; + return TRUE; +} + +static BOOL match_fglrx(const WineD3D_GL_Info *gl_info) { + if(gl_info->gl_vendor != VENDOR_ATI) return FALSE; + if(match_apple(gl_info)) return FALSE; + if(strstr(gl_info->gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers */ + return TRUE; +} + +static void quirk_arb_constants(WineD3D_GL_Info *gl_info) { + TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF); + gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF; + TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL\n", gl_info->ps_arb_constantsF); + gl_info->ps_glsl_constantsF = gl_info->ps_arb_constantsF; +} + +static void quirk_apple_glsl_constants(WineD3D_GL_Info *gl_info) { + quirk_arb_constants(gl_info); + /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms. + * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should + * allow 48 different offsets or other helper immediate values + */ + TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use\n"); + gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12); +} + +/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB + * on more than one texture unit. This means that the d3d9 visual point size test will cause a + * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This + * quirk only enables point sprites on the first texture unit. This keeps point sprites working in + * most games, but avoids the crash + * + * A more sophisticated way would be to find all units that need texture coordinates and enable + * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow + * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though) + * + * Note that disabling the extension entirely does not gain predictability because there is no point + * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension. + */ +static void quirk_one_point_sprite(WineD3D_GL_Info *gl_info) { + if(gl_info->supported[ARB_POINT_SPRITE]) { + TRACE("Limiting point sprites to one texture unit\n"); + gl_info->max_point_sprite_units = 1; + } +} + +static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) { + quirk_arb_constants(gl_info); /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL). @@ -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. */ - 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 @@ -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. */ - 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 */ @@ -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)) { + /* 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 { diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index c96b97586a7..68821b44db0 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -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)) { + /* 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); @@ -379,6 +380,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format 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); diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 61c5701f02c..ca503050646 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -4,6 +4,7 @@ * 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 @@ -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_GRAD 0x8 typedef struct { char reg_name[150]; @@ -51,7 +53,7 @@ typedef struct { typedef struct { char reg_name[150]; - char param_str[100]; + char param_str[200]; } 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. */ - 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); @@ -432,7 +434,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine 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; @@ -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) { - 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]}; @@ -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 */ - 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 */ - 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])); @@ -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 */ - 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 */ - 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. @@ -706,12 +700,11 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s { 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 */ - 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 */ @@ -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; + /* 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) { - 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 { - /* 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); } - 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); - 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) { @@ -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. */ - 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 { @@ -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++) { - 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; @@ -825,7 +849,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s 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 @@ -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); - FIXME("Unrecognized sampler type: %#x\n", stype); + FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]); 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 */ - if (pshader && shader_version >= WINED3DPS_VERSION(3, 0)) + if (pshader && reg_maps->shader_version.major >= 3) { if (use_vs(device->stateBlock)) { @@ -941,8 +966,8 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s ****************************************************************************/ /* 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[] = { @@ -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 */ -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; - 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: @@ -1013,207 +1035,214 @@ static void shader_glsl_gen_modifier ( 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 */ -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" }; - 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; - 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; - 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; - if (rel_addr) + if (reg->rel_addr) { 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 - * 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])", - 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); - } else { + } + else + { 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 - 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'; - - /* 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); - } - } - - } else { - if (shader_constant_is_local(This, register_idx)) + else { - sprintf(register_name, "%cLC%u", prefix, register_idx); - } else { - sprintf(register_name, "%cC[%u]", prefix, register_idx); + if (reg->idx == 0) strcpy(register_name, "gl_Color"); + else strcpy(register_name, "gl_SecondaryColor"); + break; } - } + 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); + case WINED3DSPR_CONST: + { + const char prefix = pshader ? 'P' : 'V'; - 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); + /* 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) + { + /* 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; + + 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 *)®->immconst_data[0], *(float *)®->immconst_data[1], + *(float *)®->immconst_data[2], *(float *)®->immconst_data[3]); + break; + + default: + FIXME("Unhandled immconst type %#x\n", reg->immconst_type); + sprintf(register_name, "", reg->immconst_type); + } + break; + + default: + FIXME("Unhandled register name Type(%d)\n", reg->type); 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; - if (shader_is_scalar(param->register_type, param->register_idx)) + if (shader_is_scalar(¶m->reg)) { 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; } -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. */ - DWORD swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; 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(¶m->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, - 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]; - 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'; - 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. @@ -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'; - 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); } @@ -1333,7 +1363,7 @@ static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const struct wined3d_ } /** 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; @@ -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 */ - 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); } @@ -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 "=="; @@ -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 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"; + } else if(grad) { + sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB"; } 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"; + } 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 if(grad) { + sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB"; } 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"; + } else if(grad) { + sample_function->name = "textureCubeGradARB"; } 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"; + } else if(grad) { + sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB"; } 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) { - 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 { - 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, + const char *dx, const char *dy, 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; - 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"; @@ -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 */ } - 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); - shader_vaddline(ins->buffer, coord_reg_fmt, args); + shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args); 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) { - 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 { - 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) { - 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; @@ -1622,26 +1668,26 @@ static void shader_glsl_arith(const struct wined3d_shader_instruction *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_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); - 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. */ - 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); @@ -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) { - 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; @@ -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; } - 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); @@ -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); - 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) @@ -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) { - 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; @@ -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); - 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); @@ -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) { - 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; @@ -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); - 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); @@ -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) { - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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) { - 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_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); } } @@ -1815,31 +1861,31 @@ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins) { 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]; - 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_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; - 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) { - 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 { - 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; - 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); - 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(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 { - 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) { - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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); - 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); @@ -1889,10 +1935,10 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins) 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); - 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; @@ -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); } - 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) @@ -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. */ - 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 */ - 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); @@ -1942,25 +1989,17 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) 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 { - 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]; @@ -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++) { - 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; @@ -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 */ - 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; - shader_addline(ins->buffer, "tmp0%s = (", mask_char); + shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char); 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; } - 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); - 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 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) { - shader_addline(ins->buffer, "%s /* COISSUE! */);\n", src1_param.param_str); + shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str); } 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; @@ -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++) { - 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; @@ -2056,14 +2100,14 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins) } 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; - 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); } } @@ -2076,11 +2120,11 @@ static void shader_glsl_mad(const struct wined3d_shader_instruction *ins) 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); } @@ -2090,21 +2134,18 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins) { 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 */ - 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.src = tmp_src; 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_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; - tmp_ins.src[1] = ins->src[1] + i; 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; - 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); } @@ -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]; - 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_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; @@ -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 */ - 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); } @@ -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]; - 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_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); } @@ -2250,20 +2293,20 @@ static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins) 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: - 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: - 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): - 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: @@ -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; - 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; - 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. */ - if(regtype == WINED3DSPR_CONSTINT) { + if (ins->src[1].reg.type == WINED3DSPR_CONSTINT) + { 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; } @@ -2305,23 +2348,24 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins) 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_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_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_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); @@ -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) { - 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) { @@ -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) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->shader; + IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; glsl_src_param_t src0_param; + const DWORD *control_values = NULL; + const local_constant *constant; - 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); + /* 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; + } + } + } + + 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++; } @@ -2365,8 +2430,8 @@ static void shader_glsl_if(const struct wined3d_shader_instruction *ins) { 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) @@ -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; - 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) { - shader_addline(ins->buffer, "} else {\n"); + shader_addline(ins->ctx->buffer, "} else {\n"); } 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. */ @@ -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; - 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) { - - 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) { - 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; - 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) { - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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; - 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. */ - 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]; @@ -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; @@ -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; - 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. */ - 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); - 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; - 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; - 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 { - 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); } } } +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) { - 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; - 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); - 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); } - 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 */ - 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", - ins->dst[0].register_idx, dst_mask); + ins->dst[0].reg.idx, dst_mask); } 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]; - 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); - 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); @@ -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); - 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); @@ -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; - 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 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; - 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. @@ -2621,17 +2716,17 @@ static void pshader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins) 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: - 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: - 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; @@ -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; - 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; - 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); - 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) { - 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 { - 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 */ - 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); } @@ -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; - DWORD dstreg = ins->dst[0].register_idx; + DWORD dstreg = ins->dst[0].reg.idx; 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 @@ -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; - 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; - 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); } @@ -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) { - IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->shader; + IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader; 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_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; } @@ -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; - 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; - 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; - 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_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 @@ -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 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; - 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; - 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 */ - 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; } @@ -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 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_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_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; } @@ -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) { - 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; - SHADER_BUFFER *buffer = ins->buffer; + SHADER_BUFFER *buffer = ins->ctx->buffer; 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; - 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); @@ -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_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; } @@ -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) { - 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; - 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; - 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); @@ -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_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; } @@ -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) { - 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; - DWORD sampler_type; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type; 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]; - 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; @@ -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); - 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); @@ -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; - 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_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); } @@ -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; - 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); } @@ -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; - 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; - 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_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); } @@ -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; - 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; - 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_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); } @@ -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; - 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); - 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); } @@ -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); - 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 */ - 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 */ - 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; - 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); - 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) { - 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 { - 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); } } @@ -3281,8 +3370,8 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs 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; @@ -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 - && 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); @@ -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 */ - 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; @@ -3970,7 +4059,9 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) { 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; @@ -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_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 @@ -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 */ - 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 */ - 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 */ - 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)) @@ -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. */ - 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: @@ -4069,7 +4165,9 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU 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; @@ -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_main( (IWineD3DBaseShader*) This, buffer, reg_maps, function); + shader_generate_main((IWineD3DBaseShader*)This, buffer, reg_maps, function); /* 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 @@ -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); - /* 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 @@ -4163,12 +4260,7 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info * 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. @@ -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_TEXLDD */ NULL, + /* WINED3DSIH_TEXLDD */ shader_glsl_texldd, /* 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_add_instruction_modifiers, }; diff --git a/reactos/dll/directx/wine/wined3d/pixelshader.c b/reactos/dll/directx/wine/wined3d/pixelshader.c index d1701f5c1a4..33148c8b9b3 100644 --- a/reactos/dll/directx/wine/wined3d/pixelshader.c +++ b/reactos/dll/directx/wine/wined3d/pixelshader.c @@ -120,192 +120,117 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* 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; - This->baseShader.limits.attributes = 0; - This->baseShader.limits.address = 0; - This->baseShader.limits.packed_output = 0; + 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; - 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 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; - 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; + /* 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 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 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 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; + 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 %#x\n", - This->baseShader.reg_maps.shader_version); - } + 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) { - +static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, + const DWORD *pFunction, const struct wined3d_shader_signature *output_signature) +{ 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; + const struct wined3d_shader_frontend *fe; 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 */ - 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); @@ -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.. */ - 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); @@ -360,8 +285,6 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i 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); @@ -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) { - DWORD shader_version = reg_maps->shader_version; - DWORD *samplers = reg_maps->samplers; + WINED3DSAMPLER_TEXTURE_TYPE *sampler_type = reg_maps->sampler_type; 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 */ - if (!samplers[i]) continue; + if (!sampler_type[i]) continue; 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; } @@ -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 */ - samplers[i] = (1 << 31) | WINED3DSTT_2D; + sampler_type[i] = WINED3DSTT_2D; break; case GL_TEXTURE_3D: - samplers[i] = (1 << 31) | WINED3DSTT_VOLUME; + sampler_type[i] = WINED3DSTT_VOLUME; 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])); - 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++) { - 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; @@ -476,7 +398,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp 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) { diff --git a/reactos/dll/directx/wine/wined3d/shader_sm1.c b/reactos/dll/directx/wine/wined3d/shader_sm1.c new file mode 100644 index 00000000000..a626d52a763 --- /dev/null +++ b/reactos/dll/directx/wine/wined3d/shader_sm1.c @@ -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 index 00000000000..5cc445db69a --- /dev/null +++ b/reactos/dll/directx/wine/wined3d/shader_sm4.c @@ -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, +}; diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 05e52b0fbdd..ad1593c7196 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -1503,14 +1503,25 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, Win } static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { + BOOL warned = FALSE; /* 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]) { + 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 { @@ -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]; - ptr += (long) vb->resource.allocatedMemory; + ptr += (long) buffer_get_sysmem(vb); } if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); diff --git a/reactos/dll/directx/wine/wined3d/surface.c b/reactos/dll/directx/wine/wined3d/surface.c index 35ba9a417e7..9e9d55c5b33 100644 --- a/reactos/dll/directx/wine/wined3d/surface.c +++ b/reactos/dll/directx/wine/wined3d/surface.c @@ -1795,6 +1795,22 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ *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; } @@ -2123,6 +2139,7 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI } case CONVERT_G16R16: + case CONVERT_R16G16F: { 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; + /* Strictly speaking not correct for R16G16F, but it doesn't matter because the + * shader overwrites it anyway + */ Dest[2] = 0xffff; Dest += 3; } @@ -2143,6 +2163,26 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI 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); } diff --git a/reactos/dll/directx/wine/wined3d/surface_base.c b/reactos/dll/directx/wine/wined3d/surface_base.c index 4b1629d5bd3..d487f80e10a 100644 --- a/reactos/dll/directx/wine/wined3d/surface_base.c +++ b/reactos/dll/directx/wine/wined3d/surface_base.c @@ -781,22 +781,11 @@ static IWineD3DSurfaceImpl *surface_convert_format(IWineD3DSurfaceImpl *source, 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; diff --git a/reactos/dll/directx/wine/wined3d/surface_gdi.c b/reactos/dll/directx/wine/wined3d/surface_gdi.c index 0ed350ecee9..0ad65e01a98 100644 --- a/reactos/dll/directx/wine/wined3d/surface_gdi.c +++ b/reactos/dll/directx/wine/wined3d/surface_gdi.c @@ -130,7 +130,7 @@ IWineGDISurfaceImpl_LockRect(IWineD3DSurface *iface, /* 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; } diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 7eb3d595658..d6973725748 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -651,15 +651,15 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info) 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); - 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); - gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT_NV; + gl_info->gl_formats[idx].gl_vtx_type = GL_HALF_FLOAT; } } diff --git a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c index 0e4149479fe..2c2b7634783 100644 --- a/reactos/dll/directx/wine/wined3d/vertexdeclaration.c +++ b/reactos/dll/directx/wine/wined3d/vertexdeclaration.c @@ -261,7 +261,7 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, 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; } } diff --git a/reactos/dll/directx/wine/wined3d/vertexshader.c b/reactos/dll/directx/wine/wined3d/vertexshader.c index fdd8cd8b35e..7dba4e37aaf 100644 --- a/reactos/dll/directx/wine/wined3d/vertexshader.c +++ b/reactos/dll/directx/wine/wined3d/vertexshader.c @@ -34,134 +34,71 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); #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 */ +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); -CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = { - /* This table is not order or position dependent. */ + This->baseShader.limits.texcoord = 0; + This->baseShader.limits.attributes = 16; + This->baseShader.limits.packed_input = 0; - /* 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 }, + 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; - {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 } -}; + 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; -static void vshader_set_limits( - IWineD3DVertexShaderImpl *This) { + 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; - 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); - } + 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, @@ -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].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.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) { @@ -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. */ -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; + const struct wined3d_shader_frontend *fe; 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 */ - 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); @@ -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; - 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); - 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) { diff --git a/reactos/dll/directx/wine/wined3d/wined3d.rbuild b/reactos/dll/directx/wine/wined3d/wined3d.rbuild index 9d0f7896853..d08d32e9cc2 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d.rbuild +++ b/reactos/dll/directx/wine/wined3d/wined3d.rbuild @@ -33,6 +33,8 @@ pixelshader.c query.c resource.c + shader_sm1.c + shader_sm4.c state.c stateblock.c surface_base.c diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index cc760351af8..1a9c9251899 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -2537,6 +2537,12 @@ typedef void (WINE_GLAPI * PGLFNGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint #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 @@ -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 -#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 *); @@ -3397,6 +3403,8 @@ typedef enum _GL_SupportedExt { 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, @@ -3925,6 +3933,7 @@ typedef struct _WineD3D_GL_Info { 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; @@ -3951,6 +3960,7 @@ typedef struct _WineD3D_GL_Info { BOOL arb_vs_offset_limit; BOOL set_texcoord_w; + DWORD reserved_glsl_constants; BOOL supported[OPENGL_SUPPORTED_EXT_END + 1]; @@ -3963,4 +3973,10 @@ typedef struct _WineD3D_GL_Info { } 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 */ diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 566e2a68926..303fb7031f3 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -3,7 +3,7 @@ * * 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 @@ -38,7 +38,6 @@ #include "wine/unicode.h" #include "objbase.h" -#include "wined3d_private_types.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_LEVELS 256 - -#define MAX_CONST_I 16 -#define MAX_CONST_B 16 /* Used for CreateStateBlock */ #define NUM_SAVEDPIXELSTATES_R 35 @@ -296,6 +291,204 @@ typedef struct wined3d_settings_s { 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 ? */ @@ -408,9 +601,25 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER 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 { - 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 */ @@ -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 */ + DWORD *constf; /* pixel, vertex */ 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]; - char usesnrm, vpos, usesdsy; + char usesnrm, vpos, usesdsy, usestexldd; 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; -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 { - WINED3DSHADER_PARAM_REGISTER_TYPE register_type; - UINT register_idx; + struct wined3d_shader_register reg; 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 { - 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; - DWORD src[4]; - DWORD src_addr[4]; - SHADER_BUFFER *buffer; 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; + WINED3DSAMPLER_TEXTURE_TYPE sampler_type; 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 { @@ -568,10 +803,13 @@ typedef struct { 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_add_instruction_modifiers)(const struct wined3d_shader_instruction *ins); } shader_backend_t; extern const shader_backend_t glsl_shader_backend; @@ -624,8 +862,7 @@ extern int num_lock; /* 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 */ @@ -1185,6 +1422,9 @@ void dumpResources(struct list *list); */ #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 */ @@ -1509,7 +1749,7 @@ typedef struct IWineD3DTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DTexture */ - IWineD3DSurface *surfaces[MAX_LEVELS]; + IWineD3DSurface *surfaces[MAX_MIP_LEVELS]; UINT target; BOOL cond_np2; @@ -1528,7 +1768,7 @@ typedef struct IWineD3DCubeTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DCubeTexture */ - IWineD3DSurface *surfaces[6][MAX_LEVELS]; + IWineD3DSurface *surfaces[6][MAX_MIP_LEVELS]; } IWineD3DCubeTextureImpl; extern const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl; @@ -1574,7 +1814,7 @@ typedef struct IWineD3DVolumeTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DVolumeTexture */ - IWineD3DVolume *volumes[MAX_LEVELS]; + IWineD3DVolume *volumes[MAX_MIP_LEVELS]; } IWineD3DVolumeTextureImpl; extern const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl; @@ -1818,6 +2058,8 @@ typedef enum { 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); @@ -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); +unsigned int count_bits(unsigned int mask); typedef struct local_constant { struct list entry; @@ -2243,19 +2486,6 @@ typedef struct 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; @@ -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 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, @@ -2300,9 +2528,6 @@ extern BOOL vshader_get_input( 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 */ @@ -2311,15 +2536,12 @@ typedef struct IWineD3DBaseShaderClass 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; - 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; @@ -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); -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); +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 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); -} - -static inline BOOL shader_is_comment(DWORD token) { - return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK); -} - -static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx) +static inline BOOL shader_is_pshader_version(enum wined3d_shader_type type) { - switch (register_type) + return type == WINED3D_SHADER_TYPE_PIXEL; +} + +static inline BOOL shader_is_vshader_version(enum wined3d_shader_type type) +{ + return type == WINED3D_SHADER_TYPE_VERTEX; +} + +static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) +{ + switch (reg->type) { case WINED3DSPR_RASTOUT: /* oFog & oPts */ - if (register_idx != 0) return TRUE; + if (reg->idx != 0) return TRUE; /* oPos */ return FALSE; @@ -2395,7 +2609,7 @@ static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_t return TRUE; case WINED3DSPR_MISCTYPE: - switch(register_idx) + switch(reg->idx) { case 0: /* vPos */ return FALSE; @@ -2405,6 +2619,15 @@ static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_t return FALSE; } + case WINED3DSPR_IMMCONST: + switch(reg->immconst_type) + { + case WINED3D_IMMCONST_FLOAT: + return TRUE; + default: + return FALSE; + } + default: return FALSE; } @@ -2457,7 +2680,6 @@ typedef struct 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); @@ -2500,7 +2722,6 @@ typedef struct 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); @@ -2543,6 +2764,14 @@ extern WINED3DFORMAT pixelformat_for_depth(DWORD depth); * 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; 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 index 2d9ae033f29..00000000000 --- a/reactos/dll/directx/wine/wined3d/wined3d_private_types.h +++ /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 diff --git a/reactos/include/reactos/wine/wined3d.idl b/reactos/include/reactos/wine/wined3d.idl index b8691a75b0c..3845ded7bb9 100644 --- a/reactos/include/reactos/wine/wined3d.idl +++ b/reactos/include/reactos/wine/wined3d.idl @@ -848,6 +848,19 @@ typedef enum _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); @@ -2117,6 +2130,23 @@ struct wined3d_buffer_desc 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; @@ -2222,8 +2252,8 @@ interface IWineD3D : IWineD3DBase ); HRESULT EnumAdapterModes( [in] UINT adapter_idx, - [in] UINT mode_idx, [in] WINED3DFORMAT format, + [in] UINT mode_idx, [out] WINED3DDISPLAYMODE *mode ); HRESULT GetAdapterDisplayMode( @@ -2823,7 +2853,8 @@ interface IWineD3DBuffer : IWineD3DResource 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] HANDLE *shared_handle, [in] IUnknown *parent ); HRESULT CreateIndexBuffer( @@ -2894,7 +2924,6 @@ interface IWineD3DDevice : IWineD3DBase [in] DWORD usage, [in] WINED3DPOOL pool, [out] IWineD3DBuffer **index_buffer, - [in] HANDLE *shared_handle, [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] HANDLE *shared_handle, [in] WINED3DSURFTYPE surface_type, [in] IUnknown *parent ); @@ -2932,7 +2960,6 @@ interface IWineD3DDevice : IWineD3DBase [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, [out] IWineD3DTexture **texture, - [in] HANDLE *shared_handle, [in] IUnknown *parent ); HRESULT CreateVolumeTexture( @@ -2944,7 +2971,6 @@ interface IWineD3DDevice : IWineD3DBase [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, [out] IWineD3DVolumeTexture **texture, - [in] HANDLE *shared_handle, [in] IUnknown *parent ); HRESULT CreateVolume( @@ -2955,7 +2981,6 @@ interface IWineD3DDevice : IWineD3DBase [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, [out] IWineD3DVolume **volume, - [in] HANDLE *shared_handle, [in] IUnknown *parent ); HRESULT CreateCubeTexture( @@ -2965,7 +2990,6 @@ interface IWineD3DDevice : IWineD3DBase [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, [out] IWineD3DCubeTexture **texture, - [in] HANDLE *shared_handle, [in] IUnknown *parent ); HRESULT CreateQuery( @@ -2998,6 +3022,7 @@ interface IWineD3DDevice : IWineD3DBase ); HRESULT CreatePixelShader( [in] const DWORD *function, + [in] const struct wined3d_shader_signature *output_signature, [out] IWineD3DPixelShader **shader, [in] IUnknown *parent );