diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7f8379d0..25de161e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -88,7 +88,6 @@ namespace dxvk { void DxvkContext::bindFramebuffer(const Rc& fb) { if (m_state.om.framebuffer != fb) { this->renderPassEnd(); - m_state.om.framebuffer = fb; if (fb != nullptr) { m_state.gp.state.msSampleCount = fb->sampleCount(); @@ -96,38 +95,22 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } + + m_state.om.framebuffer = fb; } } void DxvkContext::bindRenderTargets(const DxvkRenderTargets& targets) { - bool needsUpdate = false; + bool sameAsCurr = m_state.om.framebuffer != nullptr + && m_state.om.framebuffer->renderTargets().matches(targets); - if (m_state.om.framebuffer != nullptr) { - const DxvkRenderTargets& active = m_state.om.framebuffer->renderTargets(); - - needsUpdate |= active.getDepthTarget().view != targets.getDepthTarget().view - || active.getDepthTarget().layout != targets.getDepthTarget().layout; - - for (uint32_t i = 0; i < MaxNumRenderTargets && !needsUpdate; i++) { - needsUpdate |= active.getColorTarget(i).view != targets.getColorTarget(i).view - || active.getColorTarget(i).layout != targets.getColorTarget(i).layout; - } - } else { - needsUpdate = targets.hasAttachments(); - } - - if (needsUpdate) { + if (!sameAsCurr) { Rc fb = targets.hasAttachments() ? m_device->createFramebuffer(targets) : nullptr; - if (fb != nullptr) { - m_state.gp.state.msSampleCount = fb->sampleCount(); - m_state.gp.state.omRenderPass = fb->renderPass(); - - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); - } + this->bindFramebuffer(fb); } } diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 99f647cf..3d244427 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -71,6 +71,19 @@ namespace dxvk { } + bool DxvkRenderTargets::matches(const DxvkRenderTargets& other) const { + bool equal = m_depthTarget.view == other.m_depthTarget.view + && m_depthTarget.layout == other.m_depthTarget.layout; + + for (uint32_t i = 0; i < MaxNumRenderTargets && equal; i++) { + equal &= m_colorTargets.at(i).view == other.m_colorTargets.at(i).view + && m_colorTargets.at(i).layout == other.m_colorTargets.at(i).layout; + } + + return equal; + } + + DxvkFramebufferSize DxvkRenderTargets::renderTargetSize( const Rc& renderTarget) const { auto extent = renderTarget->mipLevelExtent(0); diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index c0238be2..75f2f579 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -116,6 +116,16 @@ namespace dxvk { */ bool hasAttachments() const; + /** + * \brief Compares two sets of render targets + * + * Checks whether two sets of render targets + * are identical, including the image layout. + * \param [in] other Render target set to compare to + * \returns \c true if the render targets are the same + */ + bool matches(const DxvkRenderTargets& other) const; + private: std::array m_colorTargets;