Implement state tracking for pixel shader constants.

This commit is contained in:
Oliver Stieber 2005-09-28 10:13:00 +00:00 committed by Alexandre Julliard
parent 60a52559ac
commit b3563daca2
3 changed files with 125 additions and 53 deletions

View File

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

View File

@ -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 */
}
#endif
/* 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;
}
}
}
}
if (This->set.fvf && This->changed.fvf) {
IWineD3DDevice_SetFVF(pDevice, This->fvf);

View File

@ -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;
@ -1179,14 +1181,15 @@ typedef struct IWineD3DPixelShaderImpl {
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