Commit 0c2fcf2e authored by Oliver Stieber's avatar Oliver Stieber Committed by Alexandre Julliard

Added support for state management of vertex shader constants via

stateblocks.
parent 489c6b38
...@@ -460,7 +460,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3 ...@@ -460,7 +460,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DStateBlockImpl *object; IWineD3DStateBlockImpl *object;
int i; int i, j;
D3DCREATEOBJECTINSTANCE(object, StateBlock) D3DCREATEOBJECTINSTANCE(object, StateBlock)
object->blockType = Type; object->blockType = Type;
...@@ -495,11 +495,27 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3 ...@@ -495,11 +495,27 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3
TRACE("PIXELSTATE => Pretend all pixel shates have changed\n"); TRACE("PIXELSTATE => Pretend all pixel shates have changed\n");
memset(&object->changed, FALSE, sizeof(This->stateBlock->changed)); memset(&object->changed, FALSE, sizeof(This->stateBlock->changed));
/* TODO: Pixel Shader Constants */
object->changed.pixelShader = TRUE; object->changed.pixelShader = TRUE;
#if 0 /* TODO: 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++) { for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
object->changed.renderState[SavedPixelStates_R[i]] = TRUE; object->changed.renderState[SavedPixelStates_R[i]] = TRUE;
} }
for (j = 0; j < GL_LIMITS(textures); j++) {
for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
object->changed.textureState[j][SavedPixelStates_T[i]] = TRUE;
}
}
for (j = 0 ; j < 16; j++) {
for (i =0; i < NUM_SAVEDPIXELSTATES_S;i++) {
object->changed.samplerState[j][SavedPixelStates_S[i]] = TRUE;
}
}
} else if (Type == WINED3DSBT_VERTEXSTATE) { } else if (Type == WINED3DSBT_VERTEXSTATE) {
...@@ -507,9 +523,22 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3 ...@@ -507,9 +523,22 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, WINED3
memset(&object->changed, FALSE, sizeof(This->stateBlock->changed)); memset(&object->changed, FALSE, sizeof(This->stateBlock->changed));
/* TODO: Vertex Shader Constants */ /* TODO: Vertex Shader Constants */
object->changed.vertexShader = TRUE; object->changed.vertexShader = TRUE;
for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) {
object->changed.vertexShaderConstants[i] = TRUE;
}
for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
object->changed.renderState[SavedVertexStates_R[i]] = TRUE; object->changed.renderState[SavedVertexStates_R[i]] = TRUE;
} }
for (j = 0; j < GL_LIMITS(textures); j++) {
for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
object->changed.textureState[j][SavedVertexStates_T[i]] = TRUE;
}
}
for (j = 0 ; j < 16; j++){
for (i =0; i < NUM_SAVEDVERTEXSTATES_S;i++) {
object->changed.samplerState[j][SavedVertexStates_S[i]] = TRUE;
}
}
/* Duplicate light chain */ /* Duplicate light chain */
{ {
...@@ -3662,9 +3691,8 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShader(IWineD3DDevice *iface, IWineD3 ...@@ -3662,9 +3691,8 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShader(IWineD3DDevice *iface, IWineD3
return D3D_OK; return D3D_OK;
} }
/* FIXME: Vertex shaders don't work properly with stateblocks */
#define GET_SHADER_CONSTANT(_vertexshaderconstant, _count, _sizecount) \ #define GET_SHADER_CONSTANT(_vertexshaderconstant, _count, _sizecount) \
int count = min(_count, MAX_VSHADER_CONSTANTS - (StartRegister + 1)); \ count = min(_count, MAX_VSHADER_CONSTANTS - (StartRegister + 1)); \
if (NULL == pConstantData || count < 0 /* || _count != count */ ) \ if (NULL == pConstantData || count < 0 /* || _count != count */ ) \
return D3DERR_INVALIDCALL; \ return D3DERR_INVALIDCALL; \
memcpy(pConstantData, This->updateStateBlock->_vertexshaderconstant + (StartRegister * _sizecount), count * (sizeof(*pConstantData) * _sizecount)); memcpy(pConstantData, This->updateStateBlock->_vertexshaderconstant + (StartRegister * _sizecount), count * (sizeof(*pConstantData) * _sizecount));
...@@ -3679,103 +3707,111 @@ This->updateStateBlock->set.vertexShader = TRUE; ...@@ -3679,103 +3707,111 @@ This->updateStateBlock->set.vertexShader = TRUE;
HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, CONST BOOL *pConstantData, UINT BoolCount){ HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, CONST BOOL *pConstantData, UINT BoolCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i;
SET_SHADER_CONSTANT(vertexShaderConstantB, BoolCount, 1); SET_SHADER_CONSTANT(vertexShaderConstantB, BoolCount, 1);
#if 0 /* TODO: a bitmasp to say which constant type we should load */
memset(This->updateStateBlock->vsibfBitmap + StartRegister, WINESHADER_CONSTANTB, BoolCount); /* populate the bitmap that says which constant type we should load */
#endif for (i = StartRegister; i < BoolCount + StartRegister; ++i) {
/* clean out the other constants? */ This->updateStateBlock->changed.vertexShaderConstants[i] = TRUE;
if(showFixmes || TRUE) { This->updateStateBlock->set.vertexShaderConstants[i] = TRUE;
FIXME("(%p) : stub\n", This); This->updateStateBlock->vertexShaderConstantT[i] = WINESHADERCNST_BOOL;
showFixmes = FALSE; TRACE("(%p) : Setting vsb %d to %d\n", This->updateStateBlock, i, pConstantData[i - StartRegister]);
} }
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, BOOL *pConstantData, UINT BoolCount){ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantB(IWineD3DDevice *iface, UINT StartRegister, BOOL *pConstantData, UINT BoolCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i, count;
#if 0 /* TODO: a bitmasp to say which constant type we should load */
for (i = 0; i < BoolCount; i++ ) { /* verify that the requested shader constant was populated with a boolean */
if (This->updateStateBlock->vsibfBitmap[StartRegister + i] != WINESHADER_CONSTANTB) { for (i = StartRegister; i < BoolCount; ++i) {
if (This->updateStateBlock->vertexShaderConstantT[i] != WINESHADERCNST_BOOL) {
/* the constant for this register isn't a boolean */ /* the constant for this register isn't a boolean */
WARN("(%p) : Caller requested a boolean where stateblock (%p) entry is a %s. Returning D3DERR_INVALIDCALL\n", This,This->updateStateBlock,
This->updateStateBlock->vertexShaderConstantT[i] == WINESHADERCNST_INTEGER ? "integer" : "float");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
} }
#endif
GET_SHADER_CONSTANT(vertexShaderConstantB, BoolCount, 1); GET_SHADER_CONSTANT(vertexShaderConstantB, BoolCount, 1);
if(showFixmes || TRUE) {
FIXME("(%p) : stub\n", This);
showFixmes = FALSE;
}
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount){ HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i;
#if 0 /* TODO: a bitmasp to say which constant type we should load */
memset(This->updateStateBlock->vsibfBitmap + StartRegister, WINESHADER_CONSTANTI, Vector4iCount);
#endif
SET_SHADER_CONSTANT(vertexShaderConstantI, Vector4iCount, 4); SET_SHADER_CONSTANT(vertexShaderConstantI, Vector4iCount, 4);
/* clean out the other constants? */
if(showFixmes || TRUE) { /* populate the bitmap that says which constant type we should load */
FIXME("(%p) : stub\n", This); for (i = StartRegister; i < StartRegister + Vector4iCount; ++i) {
showFixmes = FALSE; This->updateStateBlock->changed.vertexShaderConstants[i] = TRUE;
This->updateStateBlock->set.vertexShaderConstants[i] = TRUE;
This->updateStateBlock->vertexShaderConstantT[i] = WINESHADERCNST_INTEGER;
TRACE("(%p) : Setting vsi %d to %d\n", This->updateStateBlock, i, pConstantData[i - StartRegister]);
} }
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, int *pConstantData, UINT Vector4iCount){ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantI(IWineD3DDevice *iface, UINT StartRegister, int *pConstantData, UINT Vector4iCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i, count;
#if 0 /* TODO: a bitmap to say which constant type we should load */
for (i = 0; i < Vector4iCount; i++ ) { /* verify that the requested shader constant was populated with a integer */
if (This->updateStateBlock->vsibfBitmap[StartRegister + i] != WINESHADER_CONSTANTI) { for (i = StartRegister; i < Vector4iCount; ++i) {
/* the constant for this register isn't a boolean */ if (This->updateStateBlock->vertexShaderConstantT[i] != WINESHADERCNST_INTEGER) {
/* 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,
This->updateStateBlock->vertexShaderConstantT[i] == WINESHADERCNST_BOOL ? "boolean" : "float");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
} }
#endif
GET_SHADER_CONSTANT(vertexShaderConstantI, Vector4iCount, 4); GET_SHADER_CONSTANT(vertexShaderConstantI, Vector4iCount, 4);
if(showFixmes || TRUE) {
FIXME("(%p) : stub\n", This);
showFixmes = FALSE;
}
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount){ HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i;
#if 0 /* TODO: a bitmasp to say which constant type we should load */
memset(This->updateStateBlock->vsibfBitmap + StartRegister, WINESHADER_CONSTANTF, Vector4fCount);
#endif
SET_SHADER_CONSTANT(vertexShaderConstantF, Vector4fCount, 4); SET_SHADER_CONSTANT(vertexShaderConstantF, Vector4fCount, 4);
/* clean out the other constants? */
if(showFixmes) { /* populate the bitmap that says which constant type we should load */
TRACE("(%p) : ConstantF isn't intergrated properly with the other constants.\n", This); for (i = StartRegister; i < StartRegister + Vector4fCount; ++i) {
showFixmes = FALSE; This->updateStateBlock->changed.vertexShaderConstants[i] = TRUE;
This->updateStateBlock->set.vertexShaderConstants[i] = TRUE;
This->updateStateBlock->vertexShaderConstantT[i] = WINESHADERCNST_FLOAT;
TRACE("(%p) : Setting vsf %d to %f\n", This->updateStateBlock, i, pConstantData[i - StartRegister]);
} }
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, float *pConstantData, UINT Vector4fCount){ HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(IWineD3DDevice *iface, UINT StartRegister, float *pConstantData, UINT Vector4fCount){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
static BOOL showFixmes = TRUE; int i, count;
#if 0 /* TODO: a bitmap to say which constant type we should load */
for (i = 0; i < Vector4fCount; i++ ) { /* verify that the requested shader constant was populated with a float */
if (This->updateStateBlock->vsibfBitmap[StartRegister + i] != WINESHADER_CONSTANTF) { for (i = StartRegister; i < Vector4fCount; ++i) {
/* the constant for this register isn't a boolean */ if (This->updateStateBlock->vertexShaderConstantT[i] != WINESHADERCNST_FLOAT) {
/* the constant for this register isn't a float */
WARN("(%p) : Caller requested a float where stateblock (%p) entry is a %s. Returning D3DERR_INVALIDCALL\n", This, This->updateStateBlock,
This->updateStateBlock->vertexShaderConstantT[i] == WINESHADERCNST_BOOL ? "boolean" : "integer");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
} }
#endif
GET_SHADER_CONSTANT(vertexShaderConstantF, Vector4fCount, 4); GET_SHADER_CONSTANT(vertexShaderConstantF, Vector4fCount, 4);
if(showFixmes) {
TRACE("(%p) : ConstantF isn't intergrated properly with the other constants.\n", This);
showFixmes = FALSE;
}
return D3D_OK; return D3D_OK;
} }
......
...@@ -157,7 +157,22 @@ HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){ ...@@ -157,7 +157,22 @@ HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){
TRACE("Updating vertex shader to %p\n", targetStateBlock->vertexShader); TRACE("Updating vertex shader to %p\n", targetStateBlock->vertexShader);
} }
/* TODO: Vertex Shader Constants */ /* Vertex Shader Constants */
for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) {
if (This->set.vertexShaderConstants[i]) {
TRACE("Setting %p from %p %d to %f\n", This, targetStateBlock, i, targetStateBlock->vertexShaderConstantF[i * 4 + 1]);
This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i];
This->vertexShaderConstantF[i * 4] = targetStateBlock->vertexShaderConstantF[i * 4];
This->vertexShaderConstantF[i * 4 + 1] = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
This->vertexShaderConstantF[i * 4 + 2] = targetStateBlock->vertexShaderConstantF[i * 4 + 2];
This->vertexShaderConstantF[i * 4 + 3] = targetStateBlock->vertexShaderConstantF[i * 4 + 3];
This->vertexShaderConstantI[i * 4] = targetStateBlock->vertexShaderConstantI[i * 4];
This->vertexShaderConstantI[i * 4 + 1] = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
This->vertexShaderConstantI[i * 4 + 2] = targetStateBlock->vertexShaderConstantI[i * 4 + 2];
This->vertexShaderConstantI[i * 4 + 3] = targetStateBlock->vertexShaderConstantI[i * 4 + 3];
This->vertexShaderConstantT[i] = targetStateBlock->vertexShaderConstantT[i];
}
}
/* Lights... For a recorded state block, we just had a chain of actions to perform, /* Lights... For a recorded state block, we just had a chain of actions to perform,
so we need to walk that chain and update any actions which differ */ so we need to walk that chain and update any actions which differ */
...@@ -346,14 +361,26 @@ should really perform a delta so that only the changes get updated*/ ...@@ -346,14 +361,26 @@ should really perform a delta so that only the changes get updated*/
toDo = toDo->next; toDo = toDo->next;
} }
/* Vertex Shader */
if (This->set.vertexShader && This->changed.vertexShader) { if (This->set.vertexShader && This->changed.vertexShader) {
IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader); IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
/* TODO: Vertex Shader Constants */ }
#if 0 /* FIXME: This isn't the correct place to set vs constants (The Fur demo fails) */
IWineD3DDevice_SetVertexShaderConstantB(pDevice, 0 , This->vertexShaderConstantB , MAX_VSHADER_CONSTANTS); /* Vertex Shader Constants */
IWineD3DDevice_SetVertexShaderConstantI(pDevice, 0 , This->vertexShaderConstantI , MAX_VSHADER_CONSTANTS); for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) {
IWineD3DDevice_SetVertexShaderConstantF(pDevice, 0 , This->vertexShaderConstantF , MAX_VSHADER_CONSTANTS); if (This->set.vertexShaderConstants[i] && This->changed.vertexShaderConstants[i]) {
#endif switch (This->vertexShaderConstantT[i]) {
case WINESHADERCNST_FLOAT:
IWineD3DDevice_SetVertexShaderConstantF(pDevice, i, This->vertexShaderConstantF + i * 4, 1);
break;
case WINESHADERCNST_BOOL:
IWineD3DDevice_SetVertexShaderConstantB(pDevice, i, This->vertexShaderConstantB + i, 1);
break;
case WINESHADERCNST_INTEGER:
IWineD3DDevice_SetVertexShaderConstantI(pDevice, i, This->vertexShaderConstantI + i * 4, 1);
break;
}
}
} }
} }
......
...@@ -866,8 +866,15 @@ typedef struct SAVEDSTATES { ...@@ -866,8 +866,15 @@ typedef struct SAVEDSTATES {
BOOL vertexDecl; BOOL vertexDecl;
BOOL pixelShader; BOOL pixelShader;
BOOL vertexShader; BOOL vertexShader;
BOOL vertexShaderConstants[MAX_VSHADER_CONSTANTS];
} SAVEDSTATES; } SAVEDSTATES;
typedef enum {
WINESHADERCNST_FLOAT = 0,
WINESHADERCNST_INTEGER = 1,
WINESHADERCNST_BOOL = 2
} WINESHADERCNST;
struct IWineD3DStateBlockImpl struct IWineD3DStateBlockImpl
{ {
/* IUnknown fields */ /* IUnknown fields */
...@@ -894,8 +901,9 @@ struct IWineD3DStateBlockImpl ...@@ -894,8 +901,9 @@ struct IWineD3DStateBlockImpl
BOOL vertexShaderConstantB[MAX_VSHADER_CONSTANTS]; BOOL vertexShaderConstantB[MAX_VSHADER_CONSTANTS];
INT vertexShaderConstantI[MAX_VSHADER_CONSTANTS * 4]; INT vertexShaderConstantI[MAX_VSHADER_CONSTANTS * 4];
float vertexShaderConstantF[MAX_VSHADER_CONSTANTS * 4]; float vertexShaderConstantF[MAX_VSHADER_CONSTANTS * 4];
WINESHADERCNST vertexShaderConstantT[MAX_VSHADER_CONSTANTS]; /* TODO: Think about changing this to a char to possibly save a little memory */
BOOL softwareVertexProcessing; BOOL softwareVertexProcessing;
/* Stream Source */ /* Stream Source */
BOOL streamIsUP; BOOL streamIsUP;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment