diff --git a/src/d3d11/d3d11_context_impl.cpp b/src/d3d11/d3d11_context_impl.cpp index 6d3595207..795cbbe43 100644 --- a/src/d3d11/d3d11_context_impl.cpp +++ b/src/d3d11/d3d11_context_impl.cpp @@ -1884,7 +1884,26 @@ template class MTLD3D11DeviceContextImplBase : p void STDMETHODCALLTYPE SwapDeviceContextState(ID3DDeviceContextState *pState, ID3DDeviceContextState **ppPreviousState) override { - UNIMPLEMENTED("SwapDeviceContextState"); + // Callers (e.g. Direct2D interop) swap their own pipeline state in and the + // application's state out around a render pass. Save the current pipeline + // state into the returned previous-state token, then activate the incoming + // token's saved state. + if (!pState) { + if (ppPreviousState) + *ppPreviousState = nullptr; + return; + } + std::lock_guard lock(mutex); + auto incoming = static_cast(pState); + if (ppPreviousState) { + auto previous = new MTLD3D11DeviceContextState(device); + previous->saved_state = std::move(state_); + *ppPreviousState = ref(previous); + } + state_ = std::move(incoming->saved_state); + incoming->saved_state = {}; + ResetEncodingContextState(); + InvalidateRenderPipeline(); } void diff --git a/src/d3d11/d3d11_context_state.hpp b/src/d3d11/d3d11_context_state.hpp index 3484bda07..cb1bcb9bb 100644 --- a/src/d3d11/d3d11_context_state.hpp +++ b/src/d3d11/d3d11_context_state.hpp @@ -211,6 +211,11 @@ class MTLD3D11DeviceContextState return E_NOINTERFACE; } + + // Saved pipeline state for SwapDeviceContextState. A newly created token + // carries default (empty) state, giving the caller a clean context to render + // into; swapping back restores the previously saved state. + D3D11ContextState saved_state = {}; }; } // namespace dxmt \ No newline at end of file