mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-13 19:29:14 +01:00
[dxvk] Suspend render pass when updating framebuffer
Saves barriers in case some of the previously bound framebuffer arre reused in the new one.
This commit is contained in:
parent
d3b2db5978
commit
ba698430cb
@ -3388,6 +3388,7 @@ namespace dxvk {
|
||||
this->flushClears(true);
|
||||
|
||||
m_flags.set(DxvkContextFlag::GpRenderPassBound);
|
||||
m_flags.clr(DxvkContextFlag::GpRenderPassSuspended);
|
||||
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
|
||||
@ -3413,7 +3414,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::spillRenderPass(bool flushClears) {
|
||||
void DxvkContext::spillRenderPass(bool suspend) {
|
||||
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
||||
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
|
||||
|
||||
@ -3423,14 +3424,25 @@ namespace dxvk {
|
||||
m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS);
|
||||
|
||||
this->renderPassUnbindFramebuffer();
|
||||
this->transitionRenderTargetLayouts(m_gfxBarriers);
|
||||
|
||||
if (suspend)
|
||||
m_flags.set(DxvkContextFlag::GpRenderPassSuspended);
|
||||
else
|
||||
this->transitionRenderTargetLayouts(m_gfxBarriers);
|
||||
|
||||
m_gfxBarriers.recordCommands(m_cmd);
|
||||
|
||||
this->unbindGraphicsPipeline();
|
||||
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
|
||||
} else if (flushClears) {
|
||||
} else if (!suspend) {
|
||||
// We may end a previously suspended render pass
|
||||
if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) {
|
||||
m_flags.clr(DxvkContextFlag::GpRenderPassSuspended);
|
||||
this->transitionRenderTargetLayouts(m_gfxBarriers);
|
||||
m_gfxBarriers.recordCommands(m_cmd);
|
||||
}
|
||||
|
||||
// Execute deferred clears if necessary
|
||||
this->flushClears(false);
|
||||
}
|
||||
@ -3958,7 +3970,7 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
||||
|
||||
this->spillRenderPass(false);
|
||||
this->spillRenderPass(true);
|
||||
|
||||
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
|
||||
this->updateRenderTargetLayouts(fb, m_state.om.framebuffer);
|
||||
@ -4009,16 +4021,7 @@ namespace dxvk {
|
||||
const DxvkAttachment& color = m_state.om.framebuffer->getColorTarget(i);
|
||||
|
||||
if (color.view != nullptr) {
|
||||
barriers.accessImage(
|
||||
color.view->image(),
|
||||
color.view->subresources(),
|
||||
m_rtLayouts.color[i],
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
color.view->imageInfo().layout,
|
||||
color.view->imageInfo().stages,
|
||||
color.view->imageInfo().access);
|
||||
|
||||
this->transitionColorAttachment(barriers, color, m_rtLayouts.color[i]);
|
||||
m_rtLayouts.color[i] = color.view->imageInfo().layout;
|
||||
}
|
||||
}
|
||||
@ -4026,23 +4029,44 @@ namespace dxvk {
|
||||
const DxvkAttachment& depth = m_state.om.framebuffer->getDepthTarget();
|
||||
|
||||
if (depth.view != nullptr) {
|
||||
barriers.accessImage(
|
||||
depth.view->image(),
|
||||
depth.view->subresources(),
|
||||
m_rtLayouts.depth,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
m_rtLayouts.depth != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
||||
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0,
|
||||
depth.view->imageInfo().layout,
|
||||
depth.view->imageInfo().stages,
|
||||
depth.view->imageInfo().access);
|
||||
|
||||
this->transitionDepthAttachment(barriers, depth, m_rtLayouts.depth);
|
||||
m_rtLayouts.depth = depth.view->imageInfo().layout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::transitionColorAttachment(
|
||||
DxvkBarrierSet& barriers,
|
||||
const DxvkAttachment& attachment,
|
||||
VkImageLayout oldLayout) {
|
||||
barriers.accessImage(
|
||||
attachment.view->image(),
|
||||
attachment.view->subresources(), oldLayout,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
attachment.view->imageInfo().layout,
|
||||
attachment.view->imageInfo().stages,
|
||||
attachment.view->imageInfo().access);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::transitionDepthAttachment(
|
||||
DxvkBarrierSet& barriers,
|
||||
const DxvkAttachment& attachment,
|
||||
VkImageLayout oldLayout) {
|
||||
barriers.accessImage(
|
||||
attachment.view->image(),
|
||||
attachment.view->subresources(), oldLayout,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
oldLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
||||
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : 0,
|
||||
attachment.view->imageInfo().layout,
|
||||
attachment.view->imageInfo().stages,
|
||||
attachment.view->imageInfo().access);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updateRenderTargetLayouts(
|
||||
const Rc<DxvkFramebuffer>& newFb,
|
||||
const Rc<DxvkFramebuffer>& oldFb) {
|
||||
@ -4076,6 +4100,9 @@ namespace dxvk {
|
||||
if (found)
|
||||
layouts.color[j] = m_rtLayouts.color[i];
|
||||
}
|
||||
|
||||
if (!found && m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
||||
this->transitionColorAttachment(m_execBarriers, oldAttachment, m_rtLayouts.color[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4090,6 +4117,8 @@ namespace dxvk {
|
||||
|
||||
if (found)
|
||||
layouts.depth = m_rtLayouts.depth;
|
||||
else if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
||||
this->transitionDepthAttachment(m_execBarriers, oldAttachment, m_rtLayouts.depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1102,7 +1102,7 @@ namespace dxvk {
|
||||
bool useRenderPass);
|
||||
|
||||
void startRenderPass();
|
||||
void spillRenderPass(bool flushClears = true);
|
||||
void spillRenderPass(bool suspend = false);
|
||||
|
||||
void renderPassBindFramebuffer(
|
||||
const Rc<DxvkFramebuffer>& framebuffer,
|
||||
@ -1148,6 +1148,16 @@ namespace dxvk {
|
||||
void transitionRenderTargetLayouts(
|
||||
DxvkBarrierSet& barriers);
|
||||
|
||||
void transitionColorAttachment(
|
||||
DxvkBarrierSet& barriers,
|
||||
const DxvkAttachment& attachment,
|
||||
VkImageLayout oldLayout);
|
||||
|
||||
void transitionDepthAttachment(
|
||||
DxvkBarrierSet& barriers,
|
||||
const DxvkAttachment& attachment,
|
||||
VkImageLayout oldLayout);
|
||||
|
||||
void updateRenderTargetLayouts(
|
||||
const Rc<DxvkFramebuffer>& newFb,
|
||||
const Rc<DxvkFramebuffer>& oldFb);
|
||||
|
@ -22,6 +22,7 @@ namespace dxvk {
|
||||
*/
|
||||
enum class DxvkContextFlag : uint32_t {
|
||||
GpRenderPassBound, ///< Render pass is currently bound
|
||||
GpRenderPassSuspended, ///< Render pass is currently suspended
|
||||
GpXfbActive, ///< Transform feedback is enabled
|
||||
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
|
||||
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
||||
|
Loading…
x
Reference in New Issue
Block a user