1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-05 19:46:15 +01:00

[dxvk] Implement separate code path for clear-only render passes

Allows more clears to overlap with non-rendering commands
in case the app calls OMSetRenderTargets prior to the clear.
Also fixes a bug where we might accidentally use the wrong
set of color attachments to set up render pass operations.
This commit is contained in:
Philip Rebohle 2019-01-22 22:33:18 +01:00
parent 8cfb7936ed
commit df7573f332
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 56 additions and 8 deletions

View File

@ -97,13 +97,13 @@ namespace dxvk {
void DxvkContext::bindRenderTargets(
const DxvkRenderTargets& targets,
bool spill) {
m_state.om.renderTargets = targets;
// If necessary, perform clears on the active render targets
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
this->startRenderPass();
this->clearRenderPass();
// Set up default render pass ops
m_state.om.renderTargets = targets;
this->resetRenderPassOps(
m_state.om.renderTargets,
m_state.om.renderPassOps);
@ -2407,7 +2407,7 @@ namespace dxvk {
void DxvkContext::spillRenderPass() {
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
this->startRenderPass();
this->clearRenderPass();
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
@ -2425,6 +2425,52 @@ namespace dxvk {
}
void DxvkContext::clearRenderPass() {
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets)) {
m_flags.clr(DxvkContextFlag::GpClearRenderTargets);
bool flushBarriers = false;
for (uint32_t i = 0; i < m_state.om.framebuffer->numAttachments(); i++) {
const DxvkAttachment& attachment = m_state.om.framebuffer->getAttachment(i);
flushBarriers |= m_barriers.isImageDirty(
attachment.view->image(),
attachment.view->subresources(),
DxvkAccess::Write);
}
if (flushBarriers)
m_barriers.recordCommands(m_cmd);
this->renderPassBindFramebuffer(
m_state.om.framebuffer,
m_state.om.renderPassOps,
m_state.om.clearValues.size(),
m_state.om.clearValues.data());
this->resetRenderPassOps(
m_state.om.renderTargets,
m_state.om.renderPassOps);
this->renderPassUnbindFramebuffer();
for (uint32_t i = 0; i < m_state.om.framebuffer->numAttachments(); i++) {
const DxvkAttachment& attachment = m_state.om.framebuffer->getAttachment(i);
m_barriers.accessImage(
attachment.view->image(),
attachment.view->subresources(),
attachment.view->imageInfo().layout,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0,
attachment.view->imageInfo().layout,
attachment.view->imageInfo().stages,
attachment.view->imageInfo().access);
}
}
}
void DxvkContext::renderPassBindFramebuffer(
const Rc<DxvkFramebuffer>& framebuffer,
const DxvkRenderPassOps& ops,
@ -3147,11 +3193,12 @@ namespace dxvk {
void DxvkContext::commitComputeState() {
if (m_flags.any(
DxvkContextFlag::GpRenderPassBound,
DxvkContextFlag::GpClearRenderTargets))
if (m_flags.test(DxvkContextFlag::GpRenderPassBound))
this->spillRenderPass();
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
this->clearRenderPass();
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline))
this->updateComputePipeline();

View File

@ -844,6 +844,7 @@ namespace dxvk {
void startRenderPass();
void spillRenderPass();
void clearRenderPass();
void renderPassBindFramebuffer(
const Rc<DxvkFramebuffer>& framebuffer,