From 2af36c646e75d236dde007e56b5b11c53f975317 Mon Sep 17 00:00:00 2001 From: Oliver Stieber Date: Thu, 25 Aug 2005 19:24:21 +0000 Subject: [PATCH] Implemented stubbed out pixel shaders and their states in wined3d. --- dlls/wined3d/Makefile.in | 1 + dlls/wined3d/device.c | 131 ++++++++++++++++++++++++++++++--- dlls/wined3d/pixelshader.c | 122 ++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 8 +- 4 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 dlls/wined3d/pixelshader.c diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index 284ff6193eb..09f22781c37 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ directx.c \ drawprim.c \ indexbuffer.c \ + pixelshader.c \ query.c \ resource.c \ stateblock.c \ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 39ab415db91..51c2da05274 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1465,8 +1465,18 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, CON HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice* iface, CONST DWORD* pFunction, IWineD3DPixelShader** ppPixelShader, IUnknown *parent) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - FIXME("(%p) : Stub\n", This); + IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */ + + D3DCREATEOBJECTINSTANCE(object, PixelShader) +#if 1 + object->function = pFunction; +#else /* TODO: pixel shader set function */ + IWineD3DPixelShaderImpl_SetFuction(*ppPixelShader, pFunction); +#endif + FIXME("(%p) : STUB: Created Pixel shader %p\n", This, ppPixelShader); return D3D_OK; + + } HRESULT WINAPI IWineD3DDeviceImpl_GetDirect3D(IWineD3DDevice* iface, IWineD3D** ppD3D) { @@ -3626,55 +3636,154 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(IWineD3DDevice *iface #undef GET_SHADER_CONSTANT -HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, IWineD3DPixelShader *pShader) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); +HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, IWineD3DPixelShader *pShader) { + IUnknown *parent; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DPixelShader *oldpShader = This->updateStateBlock->pixelShader; + static BOOL showFixmes = TRUE; + + /** FIXME: reference counting? **/ + This->updateStateBlock->pixelShader = pShader; + This->updateStateBlock->changed.pixelShader = TRUE; + This->updateStateBlock->set.pixelShader = TRUE; + + if (pShader == NULL) { + /* clear down the shader */ + TRACE("Clear down the shader\n"); + }else{ + if (showFixmes) { + FIXME("(%p) : stub pShader(%p)\n", This, pShader); + showFixmes = FALSE; + } + } + + /* Handle recording of state blocks */ + if (This->isRecordingState) { + TRACE("Recording... not performing anything\n"); + return D3D_OK; + } + /** + * TODO: merge HAL shaders context switching from prototype + */ + + /* manage reference counting. */ + if (pShader != NULL) { + IWineD3DPixelShader_GetParent(pShader, &parent); /* get parent adds a ref for us*/ + } + + if (oldpShader != NULL) { + IWineD3DPixelShader_GetParent(oldpShader, &parent); + IUnknown_Release(parent); /* once for the getparent */ + IUnknown_Release(parent); /* and once for the ref */ + } + + + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShader(IWineD3DDevice *iface, IWineD3DPixelShader **ppShader) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + + if (ppShader == NULL) { + WARN("(%p) : PShader is NULL, returning INVALIDCALL\n", This); + return D3DERR_INVALIDCALL; + } + + *ppShader = This->updateStateBlock->pixelShader; + if (NULL != ppShader) { + IWineD3DPixelShader_AddRef(*ppShader); + } + TRACE("(%p) : returning %p\n", This, *ppShader); return D3D_OK; } +#define GET_SHADER_CONSTANT(_pixelshaderconstant, _count, _sizecount) \ +int count = min(_count, MAX_PSHADER_CONSTANTS - (StartRegister + 1)); \ +if (NULL == pConstantData || count < 0 /* || _count != count */ ) \ + return D3DERR_INVALIDCALL; \ +memcpy(pConstantData, This->updateStateBlock->_pixelshaderconstant + (StartRegister * _sizecount), count * (sizeof(*pConstantData) * _sizecount)); \ + + +#define SET_SHADER_CONSTANT(_pixelshaderconstant, _count, _sizecount) \ +int count = min(_count, MAX_PSHADER_CONSTANTS - (StartRegister + 1)); \ +if (NULL == pConstantData || count < 0 /* || _count != count */ ) \ + return D3DERR_INVALIDCALL; \ +memcpy(This->updateStateBlock->_pixelshaderconstant + (StartRegister * _sizecount), pConstantData, count * (sizeof(*pConstantData) * _sizecount)); \ +This->updateStateBlock->changed.pixelShader = TRUE; \ +This->updateStateBlock->set.pixelShader = TRUE; + HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, CONST BOOL *pConstantData, UINT BoolCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + SET_SHADER_CONSTANT(pixelShaderConstantB, BoolCount, 1); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; + } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, BOOL *pConstantData, UINT BoolCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + GET_SHADER_CONSTANT(pixelShaderConstantB, BoolCount, 1); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + SET_SHADER_CONSTANT(pixelShaderConstantI, Vector4iCount, 4); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, int *pConstantData, UINT Vector4iCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + GET_SHADER_CONSTANT(pixelShaderConstantI, Vector4iCount, 4); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + SET_SHADER_CONSTANT(pixelShaderConstantF, Vector4fCount, 4); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, float *pConstantData, UINT Vector4fCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - TRACE("(%p) : stub\n", This); + static BOOL showFixmes = TRUE; + GET_SHADER_CONSTANT(pixelShaderConstantF, Vector4fCount, 4); + if(showFixmes) { + FIXME("(%p) : stub\n", This); + showFixmes = FALSE; + } return D3D_OK; } +#undef SET_SHADER_CONSTANT +#undef GET_SHADER_CONSTANT + HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IWineD3DVertexBuffer* pDestBuffer, IWineD3DVertexBuffer* pVertexDecl, DWORD Flags) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; FIXME("(%p) : stub\n", This); diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c new file mode 100644 index 00000000000..ceb616b1cd7 --- /dev/null +++ b/dlls/wined3d/pixelshader.c @@ -0,0 +1,122 @@ +/* + * shaders implementation + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include + +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); + + +/* ******************************************* + IWineD3DPixelShader IUnknown parts follow + ******************************************* */ +HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj) +{ + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IWineD3DPixelShader)) { + IUnknown_AddRef(iface); + *ppobj = This; + return D3D_OK; + } + return E_NOINTERFACE; +} + +ULONG WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface) { + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref); + return InterlockedIncrement(&This->ref); +} + +ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) { + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + ULONG ref; + TRACE("(%p) : Releasing from %ld\n", This, This->ref); + ref = InterlockedDecrement(&This->ref); + if (ref == 0) { + HeapFree(GetProcessHeap(), 0, This); + } + return ref; +} + +/* ******************************************* + IWineD3DPixelShader IWineD3DPixelShader parts follow + ******************************************* */ + +HRESULT WINAPI IWineD3DPixelShaderImpl_GetParent(IWineD3DPixelShader *iface, IUnknown** parent){ + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + + *parent= (IUnknown*) parent; + IUnknown_AddRef(*parent); + TRACE("(%p) : returning %p\n", This, *parent); + return D3D_OK; +} + +HRESULT WINAPI IWineD3DPixelShaderImpl_GetDevice(IWineD3DPixelShader* iface, IWineD3DDevice **pDevice){ + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; + IWineD3DDevice_AddRef((IWineD3DDevice *)This->wineD3DDevice); + *pDevice = (IWineD3DDevice *)This->wineD3DDevice; + TRACE("(%p) returning %p\n", This, *pDevice); + return D3D_OK; +} + + +HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* impl, VOID* pData, UINT* pSizeOfData) { + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)impl; + FIXME("(%p) : pData(%p), pSizeOfData(%p)\n", This, pData, pSizeOfData); + + if (NULL == pData) { + *pSizeOfData = This->functionLength; + return D3D_OK; + } + if (*pSizeOfData < This->functionLength) { + *pSizeOfData = This->functionLength; + return D3DERR_MOREDATA; + } + if (NULL == This->function) { /* no function defined */ + TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData); + (*(DWORD **) pData) = NULL; + } else { + if(This->functionLength == 0){ + + } + TRACE("(%p) : GetFunction copying to %p\n", This, pData); + memcpy(pData, This->function, This->functionLength); + } + return D3D_OK; +} + + + +const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl = +{ + /*** IUnknown methods ***/ + IWineD3DPixelShaderImpl_QueryInterface, + IWineD3DPixelShaderImpl_AddRef, + IWineD3DPixelShaderImpl_Release, + /*** IWineD3DPixelShader methods ***/ + IWineD3DPixelShaderImpl_GetParent, + IWineD3DPixelShaderImpl_GetDevice, + IWineD3DPixelShaderImpl_GetFunction +}; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5fbddc63d28..8325c1129d1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -52,6 +52,7 @@ #define MAX_LEVELS 256 #define MAX_VSHADER_CONSTANTS 96 +#define MAX_PSHADER_CONSTANTS 32 /* Used for CreateStateBlock */ #define NUM_SAVEDPIXELSTATES_R 35 @@ -925,7 +926,12 @@ struct IWineD3DStateBlockImpl WINED3DMATERIAL material; /* Pixel Shader */ - void *pixelShader; /* TODO: Replace void * with IWineD3DPixelShader * */ + IWineD3DPixelShader *pixelShader; /* TODO: Replace void * with IWineD3DPixelShader */ + + /* Pixel Shader Constants */ + BOOL pixelShaderConstantB[MAX_PSHADER_CONSTANTS]; + UINT pixelShaderConstantI[MAX_PSHADER_CONSTANTS * 4]; + float pixelShaderConstantF[MAX_PSHADER_CONSTANTS * 4]; /* Indexed Vertex Blending */ D3DVERTEXBLENDFLAGS vertex_blend;