diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index fcb167076cd..59bc35f2c22 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -466,6 +466,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, light->enabledChanged = TRUE; } } + for(j = 1; j <= WINEHIGHEST_RENDER_STATE; j++) { + object->contained_render_states[j - 1] = j; + } + object->num_contained_render_states = WINEHIGHEST_RENDER_STATE; + } else if (Type == WINED3DSBT_PIXELSTATE) { TRACE("PIXELSTATE => Pretend all pixel shates have changed\n"); @@ -480,10 +485,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, object->changed.pixelShaderConstantsB[i] = TRUE; for (i = 0; i < MAX_CONST_I; ++i) object->changed.pixelShaderConstantsI[i] = TRUE; - + for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { object->changed.renderState[SavedPixelStates_R[i]] = TRUE; + object->contained_render_states[i] = SavedPixelStates_R[i]; } + object->num_contained_render_states = NUM_SAVEDPIXELSTATES_R; for (j = 0; j < MAX_TEXTURES; j++) { for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) { object->changed.textureState[j][SavedPixelStates_T[i]] = TRUE; @@ -510,10 +517,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, object->changed.vertexShaderConstantsB[i] = TRUE; for (i = 0; i < MAX_CONST_I; ++i) object->changed.vertexShaderConstantsI[i] = TRUE; - + for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { object->changed.renderState[SavedVertexStates_R[i]] = TRUE; + object->contained_render_states[i] = SavedVertexStates_R[i]; } + object->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R; for (j = 0; j < MAX_TEXTURES; j++) { for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) { object->changed.textureState[j][SavedVertexStates_T[i]] = TRUE; @@ -4301,6 +4310,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_BeginStateBlock(IWineD3DDevice *iface) static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IWineD3DStateBlock** ppStateBlock) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + unsigned int i; + IWineD3DStateBlockImpl *object = This->updateStateBlock; if (!This->isRecordingState) { FIXME("(%p) not recording! returning error\n", This); @@ -4308,7 +4319,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndStateBlock(IWineD3DDevice *iface, IW return WINED3DERR_INVALIDCALL; } - *ppStateBlock = (IWineD3DStateBlock*)This->updateStateBlock; + for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) { + if(object->changed.renderState[i]) { + object->contained_render_states[object->num_contained_render_states] = i; + object->num_contained_render_states++; + } + } + + *ppStateBlock = (IWineD3DStateBlock*) object; This->isRecordingState = FALSE; This->updateStateBlock = This->stateBlock; IWineD3DStateBlock_AddRef((IWineD3DStateBlock*)This->updateStateBlock); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 3fefc2fce3e..79bfe561c19 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -566,12 +566,10 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) } /* Render */ - for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) { - - if (This->changed.renderState[i] && (This->renderState[i] != targetStateBlock->renderState[i])) { - TRACE("Updating renderState %d to %d\n", i, targetStateBlock->renderState[i]); - This->renderState[i] = targetStateBlock->renderState[i]; - } + for (i = 0; i <= This->num_contained_render_states; i++) { + TRACE("Updating renderState %d to %d\n", + This->contained_render_states[i], targetStateBlock->renderState[This->contained_render_states[i]]); + This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]]; } /* Texture states */ @@ -737,12 +735,6 @@ should really perform a delta so that only the changes get updated*/ } } - /* Render */ - for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) { - if (This->changed.renderState[i]) - IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]); - } - /* Texture states */ for (j = 0; j < MAX_TEXTURES; j++) { /* Set The texture first, just in case it resets the states? */ /* TODO: move over to memcpy */ @@ -778,12 +770,6 @@ should really perform a delta so that only the changes get updated*/ } else if (This->blockType == WINED3DSBT_PIXELSTATE) { - for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) { - if (This->changed.renderState[SavedPixelStates_R[i]]) - IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]); - - } - for (j = 0; j < MAX_TEXTURES; j++) { for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) { ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedPixelStates_T[i]] = This->textureState[j][SavedPixelStates_T[i]]; @@ -799,11 +785,6 @@ should really perform a delta so that only the changes get updated*/ } else if (This->blockType == WINED3DSBT_VERTEXSTATE) { - for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) { - if (This->changed.renderState[SavedVertexStates_R[i]]) - IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]); - } - for (j = 0; j < MAX_TEXTURES; j++) { for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) { ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedVertexStates_T[i]] = This->textureState[j][SavedVertexStates_T[i]]; @@ -821,6 +802,13 @@ should really perform a delta so that only the changes get updated*/ } else { FIXME("Unrecognized state block type %d\n", This->blockType); } + + /* Render */ + for (i = 0; i <= This->num_contained_render_states; i++) { + IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i], + This->renderState[This->contained_render_states[i]]); + } + 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++) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 55eabf88f48..b2fe1458207 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1356,6 +1356,10 @@ struct IWineD3DStateBlockImpl /* Scissor test rectangle */ RECT scissorRect; + + /* Contained state management */ + DWORD contained_render_states[WINEHIGHEST_RENDER_STATE + 1]; + unsigned int num_contained_render_states; }; extern void stateblock_savedstates_set(