Commit 762af471 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Move WINED3DTSS_COLOROP to the state table.

parent 251f1eea
......@@ -3684,6 +3684,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, I
}
if (NULL != oldShader) {
IWineD3DPixelShader_Release(oldShader);
if(pShader == NULL) {
/* Fixed function pipeline color args conflict with pixel shader setup, so we do not apply them when a pshader is
* bound. Due to that we have to reapply all color ops when disabling pixel shaders.
* When pixel shaders are handled by the state table too, the pshader function will take care for that, and this
* will also handle draw -> SetPixelShader(NULL) -> SetPixelShader(!= NULL) -> draw cases better
*/
int i;
for(i = 0; i < MAX_TEXTURES; i++) {
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
}
}
}
TRACE("(%p) : setting pShader(%p)\n", This, pShader);
......@@ -4482,6 +4493,7 @@ static void WINAPI IWineD3DDeviceImpl_ApplyTextureUnitState(IWineD3DDevice *ifac
*****/
static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD oldColorOp = This->updateStateBlock->textureState[Stage][WINED3DTSS_COLOROP];
/* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
......@@ -4497,6 +4509,59 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if
This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
This->updateStateBlock->textureState[Stage][Type] = Value;
if (This->isRecordingState) {
TRACE("Recording... not performing anything\n");
return WINED3D_OK;
}
if(Stage > This->stateBlock->lowest_disabled_stage &&
StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) {
/* Colorop change above lowest disabled stage? That won't change anything in the gl setup
* Changes in other states are important on disabled stages too
*/
return WINED3D_OK;
}
if(Type == WINED3DTSS_COLOROP) {
int i;
if(Value == WINED3DTOP_DISABLE && oldColorOp != WINED3DTOP_DISABLE) {
/* Previously enabled stage disabled now. Make sure to dirtify all enabled stages above Stage,
* they have to be disabled
*
* The current stage is dirtified below.
*/
for(i = Stage + 1; i < This->stateBlock->lowest_disabled_stage; i++) {
TRACE("Additionally dirtifying stage %d\n", i);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
}
This->stateBlock->lowest_disabled_stage = Stage;
TRACE("New lowest disabled: %d\n", Stage);
} else if(Value != WINED3DTOP_DISABLE && oldColorOp == WINED3DTOP_DISABLE) {
/* Previously disabled stage enabled. Stages above it may need enabling
* stage must be lowest_disabled_stage here, if it's bigger success is returned above,
* and stages below the lowest disabled stage can't be enabled(because they are enabled already).
*
* Again stage Stage doesn't need to be dirtified here, it is handled below.
*/
for(i = Stage + 1; i < GL_LIMITS(texture_stages); i++) {
if(This->updateStateBlock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
break;
}
TRACE("Additionally dirtifying stage %d due to enable\n", i);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
}
This->stateBlock->lowest_disabled_stage = i;
TRACE("New lowest disabled: %d\n", i);
}
if(GL_SUPPORT(NV_REGISTER_COMBINERS) && !This->stateBlock->pixelShader) {
/* TODO: Built a stage -> texture unit mapping for register combiners */
}
}
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, Type));
return WINED3D_OK;
}
......@@ -4561,10 +4626,19 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
*******************************/
if (NULL != This->updateStateBlock->textures[Stage]) {
IWineD3DBaseTexture_AddRef(This->updateStateBlock->textures[Stage]);
if(oldTexture == NULL) {
/* The source arguments for color and alpha ops have different meanings when a NULL texture is bound,
* so the COLOROP has to be dirtified.(Alphaop is not in the state table yet)
*/
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_COLOROP));
}
}
if (NULL != oldTexture) {
IWineD3DBaseTexture_Release(oldTexture);
if(pTexture == NULL) {
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(Stage, WINED3DTSS_COLOROP));
}
}
/* Color keying is affected by the texture. Temporarily mark the color key state (=alpha test)
......
......@@ -1900,7 +1900,6 @@ static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
* corresponds to MaxTextureBlendStages in the caps. */
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
glEnable(GL_REGISTER_COMBINERS_NV);
D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[WINED3DRS_TEXTUREFACTOR], constant_color);
GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &constant_color[0]));
}
......@@ -1924,7 +1923,7 @@ static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
}
if (This->stateBlock->textures[i]) {
/* Enable the correct target. */
/* Enable the correct target. This has to stay here until samplers are moved over to the state table */
glDisable(GL_TEXTURE_1D);
This->stateBlock->textureDimensions[i] = IWineD3DBaseTexture_GetTextureDimensions(This->stateBlock->textures[i]);
switch(This->stateBlock->textureDimensions[i]) {
......@@ -1967,11 +1966,6 @@ static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
/** these ops apply to the texture unit, so they are preserved between texture changes, but for now brute force and reapply all
dx9_1pass_emboss_bump_mapping and dx9_2pass_emboss_bump_mapping are good texts to make sure the states are being applied when needed **/
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
set_tex_op_nvrc((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG1],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG2],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG0],
texture_idx);
/* alphaop */
set_tex_op_nvrc((IWineD3DDevice *)This, TRUE, i, This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG1],
......@@ -1979,10 +1973,6 @@ static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG0],
texture_idx);
} else {
set_tex_op((IWineD3DDevice *)This, FALSE, i, This->stateBlock->textureState[i][WINED3DTSS_COLOROP],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG1],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG2],
This->stateBlock->textureState[i][WINED3DTSS_COLORARG0]);
/* alphaop */
set_tex_op((IWineD3DDevice *)This, TRUE, i, This->stateBlock->textureState[i][WINED3DTSS_ALPHAOP],
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG1],
......@@ -1990,24 +1980,6 @@ static void drawPrimitiveUploadTextures(IWineD3DDeviceImpl* This) {
This->stateBlock->textureState[i][WINED3DTSS_ALPHAARG0]);
}
}
/* If we're using register combiners, set the amount of *used* combiners.
* Ie, the number of stages below the first stage to have a color op of
* WINED3DTOP_DISABLE. */
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
/* NUM_GENERAL_COMBINERS_NV should be > 0 */
if (!i) glDisable(GL_REGISTER_COMBINERS_NV);
else GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, i));
}
/* Disable the remaining texture units. */
for (i = current_sampler; i < GL_LIMITS(textures); ++i) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
}
static void check_fbo_status(IWineD3DDevice *iface) {
......
......@@ -737,6 +737,8 @@ should really perform a delta so that only the changes get updated*/
((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][i] = This->textureState[j][i];
((IWineD3DDeviceImpl *)pDevice)->stateBlock->set.textureState[j][i] = TRUE;
((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[j][i] = TRUE;
/* TODO: Record a display list to apply all gl states. For now apply by brute force */
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(j, i));
}
}
}
......@@ -768,6 +770,7 @@ should really perform a delta so that only the changes get updated*/
for (j = 0; j < GL_LIMITS(texture_stages); j++) {
for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedPixelStates_T[i]] = This->textureState[j][SavedPixelStates_T[i]];
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(j, SavedPixelStates_T[i]));
}
}
......@@ -787,6 +790,7 @@ should really perform a delta so that only the changes get updated*/
for (j = 0; j < GL_LIMITS(texture_stages); j++) {
for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedVertexStates_T[i]] = This->textureState[j][SavedVertexStates_T[i]];
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(j, SavedVertexStates_T[i]));
}
}
......@@ -801,6 +805,13 @@ should really perform a delta so that only the changes get updated*/
FIXME("Unrecognized state block type %d\n", This->blockType);
}
stateblock_savedstates_copy(iface, &((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed);
((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;
for(j = 0; j < MAX_TEXTURES - 1; j++) {
if(((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][D3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = j;
break;
}
}
TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
return WINED3D_OK;
......@@ -1002,6 +1013,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
This->textureState[i][WINED3DTSS_ALPHAARG0 ] = WINED3DTA_CURRENT;
This->textureState[i][WINED3DTSS_RESULTARG ] = WINED3DTA_CURRENT;
}
This->lowest_disabled_stage = 1;
/* Sampler states*/
for (i = 0 ; i < GL_LIMITS(sampler_stages); i++) {
......
......@@ -1203,6 +1203,7 @@ struct IWineD3DStateBlockImpl
/* Texture State Stage */
DWORD textureState[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
DWORD lowest_disabled_stage;
/* Sampler States */
DWORD samplerState[MAX_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
......
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