mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-06 04:46:17 +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:
parent
8cfb7936ed
commit
df7573f332
@ -97,17 +97,17 @@ namespace dxvk {
|
|||||||
void DxvkContext::bindRenderTargets(
|
void DxvkContext::bindRenderTargets(
|
||||||
const DxvkRenderTargets& targets,
|
const DxvkRenderTargets& targets,
|
||||||
bool spill) {
|
bool spill) {
|
||||||
m_state.om.renderTargets = targets;
|
|
||||||
|
|
||||||
// If necessary, perform clears on the active render targets
|
// If necessary, perform clears on the active render targets
|
||||||
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
|
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
|
||||||
this->startRenderPass();
|
this->clearRenderPass();
|
||||||
|
|
||||||
// Set up default render pass ops
|
// Set up default render pass ops
|
||||||
|
m_state.om.renderTargets = targets;
|
||||||
|
|
||||||
this->resetRenderPassOps(
|
this->resetRenderPassOps(
|
||||||
m_state.om.renderTargets,
|
m_state.om.renderTargets,
|
||||||
m_state.om.renderPassOps);
|
m_state.om.renderPassOps);
|
||||||
|
|
||||||
if (m_state.om.framebuffer == nullptr || !m_state.om.framebuffer->hasTargets(targets)) {
|
if (m_state.om.framebuffer == nullptr || !m_state.om.framebuffer->hasTargets(targets)) {
|
||||||
// Create a new framebuffer object next
|
// Create a new framebuffer object next
|
||||||
// time we start rendering something
|
// time we start rendering something
|
||||||
@ -2407,7 +2407,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkContext::spillRenderPass() {
|
void DxvkContext::spillRenderPass() {
|
||||||
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
|
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
|
||||||
this->startRenderPass();
|
this->clearRenderPass();
|
||||||
|
|
||||||
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
|
m_flags.clr(DxvkContextFlag::GpRenderPassBound);
|
||||||
@ -2423,6 +2423,52 @@ namespace dxvk {
|
|||||||
m_flags.clr(DxvkContextFlag::GpDirtyXfbCounters);
|
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(
|
void DxvkContext::renderPassBindFramebuffer(
|
||||||
@ -3147,10 +3193,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::commitComputeState() {
|
void DxvkContext::commitComputeState() {
|
||||||
if (m_flags.any(
|
if (m_flags.test(DxvkContextFlag::GpRenderPassBound))
|
||||||
DxvkContextFlag::GpRenderPassBound,
|
|
||||||
DxvkContextFlag::GpClearRenderTargets))
|
|
||||||
this->spillRenderPass();
|
this->spillRenderPass();
|
||||||
|
|
||||||
|
if (m_flags.test(DxvkContextFlag::GpClearRenderTargets))
|
||||||
|
this->clearRenderPass();
|
||||||
|
|
||||||
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline))
|
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline))
|
||||||
this->updateComputePipeline();
|
this->updateComputePipeline();
|
||||||
|
@ -844,6 +844,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void startRenderPass();
|
void startRenderPass();
|
||||||
void spillRenderPass();
|
void spillRenderPass();
|
||||||
|
void clearRenderPass();
|
||||||
|
|
||||||
void renderPassBindFramebuffer(
|
void renderPassBindFramebuffer(
|
||||||
const Rc<DxvkFramebuffer>& framebuffer,
|
const Rc<DxvkFramebuffer>& framebuffer,
|
||||||
|
Loading…
Reference in New Issue
Block a user