- sync wined3d, d3d8, d3d9, ddraw with Wine 1.1.21

svn path=/trunk/; revision=40924
This commit is contained in:
Kamil Hornicek 2009-05-15 09:33:59 +00:00
parent b3c26a404a
commit de0f2fe886
41 changed files with 3700 additions and 2645 deletions

View file

@ -601,6 +601,8 @@ struct IDirect3DVertexShader8Impl {
IWineD3DVertexShader *wineD3DVertexShader;
};
#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256
/* ------------------------ */
/* IDirect3DPixelShaderImpl */

View file

@ -359,6 +359,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
}
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);

View file

@ -265,6 +265,7 @@ static HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Ada
if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
}
pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
TRACE("(%p) returning %p\n", This, pCaps);
return hrc;

View file

@ -365,8 +365,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac
object->ref = 1;
EnterCriticalSection(&d3d9_cs);
hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
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){

View file

@ -497,6 +497,8 @@ typedef struct IDirect3DVertexShader9Impl {
LPDIRECT3DDEVICE9EX parentDevice;
} IDirect3DVertexShader9Impl;
#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
/* --------------------- */
/* IDirect3DPixelShader9 */
/* --------------------- */

View file

@ -678,8 +678,8 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
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);

View file

@ -311,6 +311,8 @@ void filter_caps(D3DCAPS9* pCaps)
D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP |
D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP |
D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
}
static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) {

View file

@ -245,8 +245,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
TRACE("Calling wined3d create index buffer\n");
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
(WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
pSharedHandle, (IUnknown *)object);
(WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, (IUnknown *)object);
LeaveCriticalSection(&d3d9_cs);
if (hrc != D3D_OK) {

View file

@ -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) {

View file

@ -358,7 +358,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
object->ref = 1;
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
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)) {

View file

@ -248,8 +248,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface
object->fvf = FVF;
EnterCriticalSection(&d3d9_cs);
hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
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) {

View file

@ -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);

View file

@ -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);

View file

@ -1,58 +0,0 @@
/* A few helpful macros for implementing COM objects.
*
* Copyright 2000 TransGaming Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _DDCOMIMPL_H_
#define _DDCOMIMPL_H_
#include <stddef.h>
/* Generates the name for a vtable pointer for a given interface. */
/* The canonical name for a single interface is "lpVtbl". */
#define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface
#define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)
/* Declares a vtable pointer field in an implementation. */
#define ICOM_VFIELD_MULTI(iface) \
iface ICOM_VFIELD_MULTI_NAME(iface)
/* Returns the offset of a vtable pointer within an implementation object. */
#define ICOM_VFIELD_OFFSET(impltype, iface) \
offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))
/* Given an interface pointer, returns the implementation pointer. */
#define ICOM_OBJECT(impltype, ifacename, ifaceptr) \
(impltype*)((ifaceptr) == NULL ? NULL \
: (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))
#define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \
impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)
/* Given an object and interface name, returns a pointer to that interface. */
#define ICOM_INTERFACE(implobj, iface) \
(implobj == NULL ? NULL :&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
#define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
do { \
(implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \
} while (0)
#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr) \
ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
#endif /* _DDCOMIMPL_H_ */

View file

@ -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;
}

View file

@ -4356,8 +4356,6 @@ Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
* The return value consist of a combination of D3DCLIP_* flags, or it's
* 0 if the sphere is completely visible(according to the SDK, not checked)
*
* 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)

View file

@ -824,8 +824,7 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
* takes the pointer and avoids the memcpy
*/
hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
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);

View file

@ -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<<lpDirect3DLightImpl->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;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -895,12 +895,10 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
}
}
if(GL_SUPPORT(ARB_POINT_SPRITE)) {
for(s = 0; s < GL_LIMITS(textures); s++) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
}
for(s = 0; s < GL_LIMITS(point_sprite_units); s++) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
}
LEAVE_GL();

View file

@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
{
WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
buffer_object = 0;
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 */

View file

@ -91,6 +91,8 @@ static const struct {
{"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
{"GL_ARB_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 {

View file

@ -370,6 +370,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format
* byte float according to the IEEE standard
*/
if (GL_SUPPORT(NV_HALF_FLOAT)) {
/* 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);

File diff suppressed because it is too large Load diff

View file

@ -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)
{

View file

@ -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,
};

View file

@ -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,
};

View file

@ -1503,14 +1503,25 @@ static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
}
static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -651,15 +651,15 @@ static void apply_format_fixups(WineD3D_GL_Info *gl_info)
gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
}
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;
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -33,6 +33,8 @@
<file>pixelshader.c</file>
<file>query.c</file>
<file>resource.c</file>
<file>shader_sm1.c</file>
<file>shader_sm4.c</file>
<file>state.c</file>
<file>stateblock.c</file>
<file>surface_base.c</file>

View file

@ -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 */

View file

@ -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;

View file

@ -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

View file

@ -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
);