From 82ac381919d8d25b866a824e10d20643b378363d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Mar 2018 22:15:41 +0100 Subject: [PATCH] [d3d11] Move framebuffer creation out of OMSetRenderTargets This might be useful when restoring context state. --- src/d3d11/d3d11_context.cpp | 69 ++++++++++++++++++++----------------- src/d3d11/d3d11_context.h | 2 ++ 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 96068123..fec45975 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1767,38 +1767,7 @@ namespace dxvk { m_state.om.depthStencilView = static_cast(pDepthStencilView); - // NOTE According to the Microsoft docs, we are supposed to - // unbind overlapping shader resource views. Since this comes - // with a large performance penalty we'll ignore this until an - // application actually relies on this behaviour. - DxvkRenderTargets attachments; - - // D3D11 doesn't have the concept of a framebuffer object, - // so we'll just create a new one every time the render - // target bindings are updated. Set up the attachments. - if (ppRenderTargetViews != nullptr || pDepthStencilView != nullptr) { - for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { - if (m_state.om.renderTargetViews.at(i) != nullptr) { - attachments.setColorTarget(i, - m_state.om.renderTargetViews.at(i)->GetImageView(), - m_state.om.renderTargetViews.at(i)->GetRenderLayout()); - } - } - - if (m_state.om.depthStencilView != nullptr) { - attachments.setDepthTarget( - m_state.om.depthStencilView->GetImageView(), - m_state.om.depthStencilView->GetRenderLayout()); - } - } - - // Create and bind the framebuffer object to the context - EmitCs([attachments, dev = m_device] (DxvkContext* ctx) { - Rc framebuffer = nullptr; - if (attachments.hasAttachments()) - framebuffer = dev->createFramebuffer(attachments); - ctx->bindFramebuffer(framebuffer); - }); + BindFramebuffer(); } @@ -2075,6 +2044,40 @@ namespace dxvk { } + void D3D11DeviceContext::BindFramebuffer() { + // NOTE According to the Microsoft docs, we are supposed to + // unbind overlapping shader resource views. Since this comes + // with a large performance penalty we'll ignore this until an + // application actually relies on this behaviour. + DxvkRenderTargets attachments; + + // D3D11 doesn't have the concept of a framebuffer object, + // so we'll just create a new one every time the render + // target bindings are updated. Set up the attachments. + for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { + if (m_state.om.renderTargetViews.at(i) != nullptr) { + attachments.setColorTarget(i, + m_state.om.renderTargetViews.at(i)->GetImageView(), + m_state.om.renderTargetViews.at(i)->GetRenderLayout()); + } + } + + if (m_state.om.depthStencilView != nullptr) { + attachments.setDepthTarget( + m_state.om.depthStencilView->GetImageView(), + m_state.om.depthStencilView->GetRenderLayout()); + } + + // Create and bind the framebuffer object to the context + EmitCs([attachments, dev = m_device] (DxvkContext* ctx) { + Rc framebuffer = nullptr; + if (attachments.hasAttachments()) + framebuffer = dev->createFramebuffer(attachments); + ctx->bindFramebuffer(framebuffer); + }); + } + + void D3D11DeviceContext::BindConstantBuffers( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings, @@ -2323,6 +2326,8 @@ namespace dxvk { void D3D11DeviceContext::RestoreState() { Logger::err("D3D11DeviceContext::RestoreState: Not implemented"); + + BindFramebuffer(); } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index e7f6e640..61437cc8 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -527,6 +527,8 @@ namespace dxvk { D3D11ContextState m_state; uint64_t m_drawCount = 0; + void BindFramebuffer(); + void BindConstantBuffers( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings,