From b3563daca2faf773fb9c204a423697271484b626 Mon Sep 17 00:00:00 2001 From: Oliver Stieber Date: Wed, 28 Sep 2005 10:13:00 +0000 Subject: [PATCH] Implement state tracking for pixel shader constants. --- dlls/wined3d/device.c | 108 ++++++++++++++++++++++----------- dlls/wined3d/stateblock.c | 49 ++++++++++++--- dlls/wined3d/wined3d_private.h | 21 ++++--- 3 files changed, 125 insertions(+), 53 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a07a28875a6..fb887279cab 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -539,13 +539,13 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3 TRACE("PIXELSTATE => Pretend all pixel shates have changed\n"); memset(&object->changed, FALSE, sizeof(This->stateBlock->changed)); + object->changed.pixelShader = TRUE; -#if 0 /* TODO: Pixel Shader Constants */ + /* Pixel Shader Constants */ for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { object->changed.pixelShaderConstants[i] = TRUE; } -#endif for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { object->changed.renderState[SavedPixelStates_R[i]] = TRUE; } @@ -565,8 +565,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3 TRACE("VERTEXSTATE => Pretend all vertex shates have changed\n"); memset(&object->changed, FALSE, sizeof(This->stateBlock->changed)); - /* TODO: Vertex Shader Constants */ + object->changed.vertexShader = TRUE; + + /* Vertex Shader Constants */ for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) { object->changed.vertexShaderConstants[i] = TRUE; } @@ -3867,7 +3869,6 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, IWineD3D 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; @@ -3902,8 +3903,6 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, IWineD3D IUnknown_Release(parent); /* and once for the ref */ } - - return D3D_OK; } @@ -3924,7 +3923,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShader(IWineD3DDevice *iface, IWineD3D } #define GET_SHADER_CONSTANT(_pixelshaderconstant, _count, _sizecount) \ -int count = min(_count, MAX_PSHADER_CONSTANTS - (StartRegister + 1)); \ +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)); \ @@ -3941,68 +3940,109 @@ This->updateStateBlock->set.pixelShader = TRUE; HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, CONST BOOL *pConstantData, UINT BoolCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; + int i; + SET_SHADER_CONSTANT(pixelShaderConstantB, BoolCount, 1); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + + /* populate the bitmap that says which constant type we should load */ + for (i = StartRegister; i < BoolCount + StartRegister; ++i) { + This->updateStateBlock->changed.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->set.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->pixelShaderConstantT[i] = WINESHADERCNST_BOOL; + TRACE("(%p) : Setting psb %d to %d\n", This->updateStateBlock, i, pConstantData[i - StartRegister]); } + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, BOOL *pConstantData, UINT BoolCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; - GET_SHADER_CONSTANT(pixelShaderConstantB, BoolCount, 1); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + int i, count; + + /* populate the bitmap that says which constant type we should load */ + for (i = StartRegister; i < BoolCount + StartRegister; ++i) { + This->updateStateBlock->changed.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->set.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->pixelShaderConstantT[i] = WINESHADERCNST_BOOL; + TRACE("(%p) : Setting psb %d to %d\n", This->updateStateBlock, i, pConstantData[i - StartRegister]); } + + GET_SHADER_CONSTANT(pixelShaderConstantB, BoolCount, 1); + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; + int i; + SET_SHADER_CONSTANT(pixelShaderConstantI, Vector4iCount, 4); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + + /* populate the bitmap that says which constant type we should load */ + for (i = StartRegister; i < Vector4iCount + StartRegister; ++i) { + This->updateStateBlock->changed.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->set.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->pixelShaderConstantT[i] = WINESHADERCNST_INTEGER; + TRACE("(%p) : Setting psb %d to %d\n", This->updateStateBlock, i, pConstantData[i - StartRegister]); } + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, int *pConstantData, UINT Vector4iCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; - GET_SHADER_CONSTANT(pixelShaderConstantI, Vector4iCount, 4); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + int i, count; + + /* verify that the requested shader constant was populated with a integer */ + for (i = StartRegister; i < Vector4iCount; ++i) { + if (WINESHADERCNST_INTEGER != This->updateStateBlock->pixelShaderConstantT[i]) { + + /* the constant for this register isn't a integer */ + WARN("(%p) : Caller requested a integer where stateblock (%p) entry is a %s. Returning D3DERR_INVALIDCALL\n", This, This->updateStateBlock, + WINESHADERCNST_BOOL == This->updateStateBlock->vertexShaderConstantT[i] ? "boolean" : "float"); + return D3DERR_INVALIDCALL; + } } + + GET_SHADER_CONSTANT(pixelShaderConstantI, Vector4iCount, 4); + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; + int i; SET_SHADER_CONSTANT(pixelShaderConstantF, Vector4fCount, 4); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + + /* populate the bitmap that says which constant type we should load */ + for (i = StartRegister; i < Vector4fCount + StartRegister; ++i) { + This->updateStateBlock->changed.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->set.pixelShaderConstants[i] = TRUE; + This->updateStateBlock->pixelShaderConstantT[i] = WINESHADERCNST_FLOAT; + TRACE("(%p) : Setting psb %d to %f\n", This->updateStateBlock, i, pConstantData[i - StartRegister]); } + return D3D_OK; } HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, float *pConstantData, UINT Vector4fCount) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - static BOOL showFixmes = TRUE; - GET_SHADER_CONSTANT(pixelShaderConstantF, Vector4fCount, 4); - if(showFixmes) { - FIXME("(%p) : stub\n", This); - showFixmes = FALSE; + int i, count; + + /* verify that the requested shader constant was populated with a integer */ + for (i = StartRegister; i < Vector4fCount; ++i) { + if (WINESHADERCNST_FLOAT != This->updateStateBlock->pixelShaderConstantT[i]) { + + /* the constant for this register isn't a float */ + WARN("(%p) : Caller requested a integer where stateblock (%p) entry is a %s. Returning D3DERR_INVALIDCALL\n", This, This->updateStateBlock, + WINESHADERCNST_BOOL == This->updateStateBlock->vertexShaderConstantT[i] ? "boolean" : "integer"); + return D3DERR_INVALIDCALL; + } } + + GET_SHADER_CONSTANT(pixelShaderConstantF, Vector4fCount, 4); + return D3D_OK; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 0f40d4043f5..c591f68a14e 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -207,14 +207,28 @@ HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){ src = src->next; } - -#if 0 /*TODO: Pixel shaders*/ - if (This->set.pixelShader && This->pixelShader != pDeviceImpl->stateBlock->pixelShader) { - TRACE("Updating pixel shader to %p\n", pDeviceImpl->stateBlock->pixelShader); + /* Recorded => Only update 'changed' values */ + if (This->pixelShader != targetStateBlock->pixelShader) { This->pixelShader = targetStateBlock->pixelShader; + TRACE("Updating pixrl shader to %p\n", targetStateBlock->pixelShader); + } + + /* Pixel Shader Constants */ + for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { + if (This->set.pixelShaderConstants[i]) { + TRACE("Setting %p from %p %d to %f\n", This, targetStateBlock, i, targetStateBlock->pixelShaderConstantF[i * 4 + 1]); + This->pixelShaderConstantB[i] = targetStateBlock->pixelShaderConstantB[i]; + This->pixelShaderConstantF[i * 4] = targetStateBlock->pixelShaderConstantF[i * 4]; + This->pixelShaderConstantF[i * 4 + 1] = targetStateBlock->pixelShaderConstantF[i * 4 + 1]; + This->pixelShaderConstantF[i * 4 + 2] = targetStateBlock->pixelShaderConstantF[i * 4 + 2]; + This->pixelShaderConstantF[i * 4 + 3] = targetStateBlock->pixelShaderConstantF[i * 4 + 3]; + This->pixelShaderConstantI[i * 4] = targetStateBlock->pixelShaderConstantI[i * 4]; + This->pixelShaderConstantI[i * 4 + 1] = targetStateBlock->pixelShaderConstantI[i * 4 + 1]; + This->pixelShaderConstantI[i * 4 + 2] = targetStateBlock->pixelShaderConstantI[i * 4 + 2]; + This->pixelShaderConstantI[i * 4 + 3] = targetStateBlock->pixelShaderConstantI[i * 4 + 3]; + This->pixelShaderConstantT[i] = targetStateBlock->pixelShaderConstantT[i]; + } } -#endif - /* TODO: Pixel Shader Constants */ /* Others + Render & Texture */ for (i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) { @@ -385,15 +399,30 @@ should really perform a delta so that only the changes get updated*/ } -#if 0 /*TODO: Pixel Shaders*/ if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == D3DSBT_ALL || This->blockType == D3DSBT_PIXELSTATE) { - if (This->set.pixelShader && This->changed.pixelShader) + /* Pixel Shader */ + if (This->set.pixelShader && This->changed.pixelShader) { IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader); + } - /* TODO: Pixel Shader Constants */ + /* Pixel Shader Constants */ + for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) { + if (This->set.pixelShaderConstants[i] && This->changed.pixelShaderConstants[i]) { + switch (This->pixelShaderConstantT[i]) { + case WINESHADERCNST_FLOAT: + IWineD3DDevice_SetPixelShaderConstantF(pDevice, i, This->pixelShaderConstantF + i * 4, 1); + break; + case WINESHADERCNST_BOOL: + IWineD3DDevice_SetPixelShaderConstantB(pDevice, i, This->pixelShaderConstantB + i, 1); + break; + case WINESHADERCNST_INTEGER: + IWineD3DDevice_SetPixelShaderConstantI(pDevice, i, This->pixelShaderConstantI + i * 4, 1); + break; + } + } + } } -#endif if (This->set.fvf && This->changed.fvf) { IWineD3DDevice_SetFVF(pDevice, This->fvf); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2abf3068009..16316166e10 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -873,6 +873,7 @@ typedef struct SAVEDSTATES { BOOL clipplane[MAX_CLIPPLANES]; BOOL vertexDecl; BOOL pixelShader; + BOOL pixelShaderConstants[MAX_PSHADER_CONSTANTS]; BOOL vertexShader; BOOL vertexShaderConstants[MAX_VSHADER_CONSTANTS]; } SAVEDSTATES; @@ -903,7 +904,7 @@ struct IWineD3DStateBlockImpl /* Vertex Shader Declaration */ IWineD3DVertexDeclaration *vertexDecl; - IWineD3DVertexShader *vertexShader; /* @TODO: Replace void * with IWineD3DVertexShader * */ + IWineD3DVertexShader *vertexShader; /* Vertex Shader Constants */ BOOL vertexShaderConstantB[MAX_VSHADER_CONSTANTS]; @@ -942,12 +943,13 @@ struct IWineD3DStateBlockImpl WINED3DMATERIAL material; /* Pixel Shader */ - IWineD3DPixelShader *pixelShader; /* TODO: Replace void * with IWineD3DPixelShader */ + IWineD3DPixelShader *pixelShader; /* Pixel Shader Constants */ BOOL pixelShaderConstantB[MAX_PSHADER_CONSTANTS]; - UINT pixelShaderConstantI[MAX_PSHADER_CONSTANTS * 4]; + INT pixelShaderConstantI[MAX_PSHADER_CONSTANTS * 4]; float pixelShaderConstantF[MAX_PSHADER_CONSTANTS * 4]; + WINESHADERCNST pixelShaderConstantT[MAX_PSHADER_CONSTANTS]; /* TODO: Think about changing this to a char to possibly save a little memory */ /* Indexed Vertex Blending */ D3DVERTEXBLENDFLAGS vertex_blend; @@ -1172,21 +1174,22 @@ extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl; * IDirect3DPixelShader implementation structure */ typedef struct IWineD3DPixelShaderImpl { - /* IUnknown parts*/ + /* IUnknown parts */ const IWineD3DPixelShaderVtbl *lpVtbl; LONG ref; /* Note: Ref counting not required */ - + IUnknown *parent; IWineD3DDeviceImpl *wineD3DDevice; - /* IWineD3DPixelShaderImpl */ CONST DWORD *function; UINT functionLength; - + DWORD version; + + /* run time data */ + PSHADERDATA *data; + #if 0 /* needs reworking */ - /* run time datas */ - PSHADERDATA* data; PSHADERINPUTDATA input; PSHADEROUTPUTDATA output; #endif