mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +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);
|
this->flushClears(true);
|
||||||
|
|
||||||
m_flags.set(DxvkContextFlag::GpRenderPassBound);
|
m_flags.set(DxvkContextFlag::GpRenderPassBound);
|
||||||
|
m_flags.clr(DxvkContextFlag::GpRenderPassSuspended);
|
||||||
|
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
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)) {
|
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
|
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
|
||||||
|
|
||||||
@ -3423,14 +3424,25 @@ namespace dxvk {
|
|||||||
m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS);
|
m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS);
|
||||||
|
|
||||||
this->renderPassUnbindFramebuffer();
|
this->renderPassUnbindFramebuffer();
|
||||||
this->transitionRenderTargetLayouts(m_gfxBarriers);
|
|
||||||
|
if (suspend)
|
||||||
|
m_flags.set(DxvkContextFlag::GpRenderPassSuspended);
|
||||||
|
else
|
||||||
|
this->transitionRenderTargetLayouts(m_gfxBarriers);
|
||||||
|
|
||||||
m_gfxBarriers.recordCommands(m_cmd);
|
m_gfxBarriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
this->unbindGraphicsPipeline();
|
this->unbindGraphicsPipeline();
|
||||||
|
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
|
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
|
// Execute deferred clears if necessary
|
||||||
this->flushClears(false);
|
this->flushClears(false);
|
||||||
}
|
}
|
||||||
@ -3958,7 +3970,7 @@ namespace dxvk {
|
|||||||
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
|
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
||||||
|
|
||||||
this->spillRenderPass(false);
|
this->spillRenderPass(true);
|
||||||
|
|
||||||
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
|
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
|
||||||
this->updateRenderTargetLayouts(fb, m_state.om.framebuffer);
|
this->updateRenderTargetLayouts(fb, m_state.om.framebuffer);
|
||||||
@ -4009,16 +4021,7 @@ namespace dxvk {
|
|||||||
const DxvkAttachment& color = m_state.om.framebuffer->getColorTarget(i);
|
const DxvkAttachment& color = m_state.om.framebuffer->getColorTarget(i);
|
||||||
|
|
||||||
if (color.view != nullptr) {
|
if (color.view != nullptr) {
|
||||||
barriers.accessImage(
|
this->transitionColorAttachment(barriers, color, m_rtLayouts.color[i]);
|
||||||
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);
|
|
||||||
|
|
||||||
m_rtLayouts.color[i] = color.view->imageInfo().layout;
|
m_rtLayouts.color[i] = color.view->imageInfo().layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4026,23 +4029,44 @@ namespace dxvk {
|
|||||||
const DxvkAttachment& depth = m_state.om.framebuffer->getDepthTarget();
|
const DxvkAttachment& depth = m_state.om.framebuffer->getDepthTarget();
|
||||||
|
|
||||||
if (depth.view != nullptr) {
|
if (depth.view != nullptr) {
|
||||||
barriers.accessImage(
|
this->transitionDepthAttachment(barriers, depth, m_rtLayouts.depth);
|
||||||
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);
|
|
||||||
|
|
||||||
m_rtLayouts.depth = depth.view->imageInfo().layout;
|
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(
|
void DxvkContext::updateRenderTargetLayouts(
|
||||||
const Rc<DxvkFramebuffer>& newFb,
|
const Rc<DxvkFramebuffer>& newFb,
|
||||||
const Rc<DxvkFramebuffer>& oldFb) {
|
const Rc<DxvkFramebuffer>& oldFb) {
|
||||||
@ -4076,6 +4100,9 @@ namespace dxvk {
|
|||||||
if (found)
|
if (found)
|
||||||
layouts.color[j] = m_rtLayouts.color[i];
|
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)
|
if (found)
|
||||||
layouts.depth = m_rtLayouts.depth;
|
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);
|
bool useRenderPass);
|
||||||
|
|
||||||
void startRenderPass();
|
void startRenderPass();
|
||||||
void spillRenderPass(bool flushClears = true);
|
void spillRenderPass(bool suspend = false);
|
||||||
|
|
||||||
void renderPassBindFramebuffer(
|
void renderPassBindFramebuffer(
|
||||||
const Rc<DxvkFramebuffer>& framebuffer,
|
const Rc<DxvkFramebuffer>& framebuffer,
|
||||||
@ -1148,6 +1148,16 @@ namespace dxvk {
|
|||||||
void transitionRenderTargetLayouts(
|
void transitionRenderTargetLayouts(
|
||||||
DxvkBarrierSet& barriers);
|
DxvkBarrierSet& barriers);
|
||||||
|
|
||||||
|
void transitionColorAttachment(
|
||||||
|
DxvkBarrierSet& barriers,
|
||||||
|
const DxvkAttachment& attachment,
|
||||||
|
VkImageLayout oldLayout);
|
||||||
|
|
||||||
|
void transitionDepthAttachment(
|
||||||
|
DxvkBarrierSet& barriers,
|
||||||
|
const DxvkAttachment& attachment,
|
||||||
|
VkImageLayout oldLayout);
|
||||||
|
|
||||||
void updateRenderTargetLayouts(
|
void updateRenderTargetLayouts(
|
||||||
const Rc<DxvkFramebuffer>& newFb,
|
const Rc<DxvkFramebuffer>& newFb,
|
||||||
const Rc<DxvkFramebuffer>& oldFb);
|
const Rc<DxvkFramebuffer>& oldFb);
|
||||||
|
@ -22,6 +22,7 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
enum class DxvkContextFlag : uint32_t {
|
enum class DxvkContextFlag : uint32_t {
|
||||||
GpRenderPassBound, ///< Render pass is currently bound
|
GpRenderPassBound, ///< Render pass is currently bound
|
||||||
|
GpRenderPassSuspended, ///< Render pass is currently suspended
|
||||||
GpXfbActive, ///< Transform feedback is enabled
|
GpXfbActive, ///< Transform feedback is enabled
|
||||||
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
|
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
|
||||||
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
||||||
|
Loading…
x
Reference in New Issue
Block a user