1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 19:24:11 +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,17 +97,17 @@ 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);
if (m_state.om.framebuffer == nullptr || !m_state.om.framebuffer->hasTargets(targets)) {
// Create a new framebuffer object next
// time we start rendering something
@ -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);
@ -2423,6 +2423,52 @@ namespace dxvk {
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
}
}
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(
@ -3147,10 +3193,11 @@ 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,