summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2023-08-17 13:01:52 +0200
committerMike Krus <mike.krus@kdab.com>2023-11-09 09:18:30 +0000
commitf1a60664d4fed11e1b1e135fcff92e728d1aa959 (patch)
tree9283bbdfa286ba3cdb050acf9fdd5b12e9fe3d13
parentca30b206ccbd93f2304bbfa630a267d3e3ce14fb (diff)
RHIRenderer: handle RenderTargets that target Left/Right backbuffers
When defining a RenderTarget with an attachment that targets Left or Right, we essentially skip texture creation for the RenderTarget and simply have is use the swapchain instead. Change-Id: I07d6c168afbc4a7b5e7515c263243e65531e117f Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/renderers/rhi/renderer/renderer.cpp56
-rw-r--r--src/plugins/renderers/rhi/renderer/rhirendertarget_p.h13
2 files changed, 56 insertions, 13 deletions
diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp
index 95c40ac07..c3fb610f5 100644
--- a/src/plugins/renderers/rhi/renderer/renderer.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderer.cpp
@@ -1141,9 +1141,17 @@ void Renderer::createRenderTarget(RenderTarget *target)
}
};
+ RHIRenderTarget::BackBuffer backBuffer = RHIRenderTarget::BackBuffer::None;
+
// Look up attachments to populate the RT description
// Attachments are sorted by attachment point (Color0 is first)
for (const Attachment &attachment : pack.attachments()) {
+
+ if (attachment.m_point == QRenderTargetOutput::Left || attachment.m_point == QRenderTargetOutput::Right) {
+ backBuffer = attachment.m_point == QRenderTargetOutput::Left ? RHIRenderTarget::BackBuffer::Left : RHIRenderTarget::BackBuffer::Right;
+ break;
+ }
+
RHITexture *tex = texman->lookupResource(attachment.m_textureUuid);
if (tex && tex->getRhiTexture()) {
auto rhiTex = tex->getRhiTexture();
@@ -1183,6 +1191,12 @@ void Renderer::createRenderTarget(RenderTarget *target)
}
}
+ rhiTarget->backBuffer = backBuffer;
+ // If we are targeting one of the back buffers directly, don't create an offscreen RT
+ if (backBuffer != RHIRenderTarget::BackBuffer::None)
+ return;
+
+ // Otherwise, create QRhiRenderBuffer and associated resources
if (targetSize.width() <= 0 || targetSize.height() <= 0) {
cleanAllocatedResources();
return;
@@ -1232,6 +1246,12 @@ bool Renderer::setupRenderTarget(RenderView *rv,
const auto &managers = *nodeManagers();
auto &renderTargetManager = *managers.renderTargetManager();
+ auto useSwapchainForPipeline = [&]() {
+ Q_ASSERT(swapchain);
+ rhiPipeline->setRenderPassDescriptor(swapchain->renderPassDescriptor());
+ rhiPipeline->setSampleCount(swapchain->sampleCount());
+ };
+
auto *renderTarget = renderTargetManager.lookupResource(rv->renderTargetId());
if (renderTarget) {
// Render to texture
@@ -1239,14 +1259,25 @@ bool Renderer::setupRenderTarget(RenderView *rv,
RHIRenderTargetManager *rhiRenderTargetManager = m_RHIResourceManagers->rhiRenderTargetManager();
RHIRenderTarget *rhiTarget = rhiRenderTargetManager->lookupResource(renderTargetId);
- if (!rhiTarget || !rhiTarget->renderTarget) {
+ if (!rhiTarget) {
qWarning(Backend) << "Invalid RenderTarget " << renderTargetId << " for Pipeline";
return false;
}
- rhiPipeline->setRenderPassDescriptor(rhiTarget->renderPassDescriptor);
- rhiPipeline->setSampleCount(rhiTarget->renderTarget->sampleCount());
+ // The RenderTarget we reference might actually be referencing a swapchain back buffer
+ if (rhiTarget->backBuffer != RHIRenderTarget::BackBuffer::None) {
+ // Render to the default framebuffer on our swapchain
+ useSwapchainForPipeline();
+ } else {
+ if (!rhiTarget->renderTarget) {
+ qWarning(Backend) << "Invalid RenderTarget " << renderTargetId << " for Pipeline";
+ return false;
+ }
+ rhiPipeline->setRenderPassDescriptor(rhiTarget->renderPassDescriptor);
+ rhiPipeline->setSampleCount(rhiTarget->renderTarget->sampleCount());
+ }
return true;
+
} else if (m_submissionContext->defaultRenderTarget()) {
// Use default RenderTarget if set Default FBO set by Scene3D
QRhiRenderTarget *defaultTarget = m_submissionContext->defaultRenderTarget();;
@@ -1254,10 +1285,8 @@ bool Renderer::setupRenderTarget(RenderView *rv,
rhiPipeline->setSampleCount(defaultTarget->sampleCount());
return true;
} else {
- Q_ASSERT(swapchain);
// Render to the default framebuffer on our swapchain
- rhiPipeline->setRenderPassDescriptor(swapchain->renderPassDescriptor());
- rhiPipeline->setSampleCount(swapchain->sampleCount());
+ useSwapchainForPipeline();
return true;
}
}
@@ -2640,12 +2669,19 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
auto &renderTargetManager = *managers.rhiRenderTargetManager();
auto *renderTarget = renderTargetManager.lookupResource(passInfo.renderTargetId);
- if (renderTarget)
- rhiRenderTarget = renderTarget->renderTarget;
- else if (m_submissionContext->defaultRenderTarget())
+ if (renderTarget) {
+ // Is our RenderTarget targeting offscreen attachments?
+ if (renderTarget->backBuffer == RHIRenderTarget::BackBuffer::None)
+ rhiRenderTarget = renderTarget->renderTarget;
+ else // Or one of the back buffers?
+ rhiRenderTarget = m_submissionContext->currentSwapChain()->currentFrameRenderTarget(renderTarget->backBuffer == RHIRenderTarget::BackBuffer::Left
+ ? QRhiSwapChain::LeftBuffer
+ : QRhiSwapChain::RightBuffer);
+ } else if (m_submissionContext->defaultRenderTarget()) {
rhiRenderTarget = m_submissionContext->defaultRenderTarget();
- else
+ } else {
rhiRenderTarget = m_submissionContext->currentSwapChain()->currentFrameRenderTarget();
+ }
}
auto executeDrawRenderView = [&] (RenderView* rv) {
diff --git a/src/plugins/renderers/rhi/renderer/rhirendertarget_p.h b/src/plugins/renderers/rhi/renderer/rhirendertarget_p.h
index 0c958b315..f699db687 100644
--- a/src/plugins/renderers/rhi/renderer/rhirendertarget_p.h
+++ b/src/plugins/renderers/rhi/renderer/rhirendertarget_p.h
@@ -30,9 +30,16 @@ struct RHIRenderTarget {
// Note: only used when rendering to a FBO
// as we don't want to remove the default framebuffer's rendertarget
// TODO: at some point separate render target and graphics pipeline as the former can be reused
- QRhiRenderTarget *renderTarget{};
- QRhiRenderPassDescriptor *renderPassDescriptor{};
- QRhiRenderBuffer *depthStencilBuffer{};
+ QRhiRenderTarget *renderTarget{ nullptr };
+ QRhiRenderPassDescriptor *renderPassDescriptor{ nullptr };
+ QRhiRenderBuffer *depthStencilBuffer{ nullptr };
+
+ enum class BackBuffer {
+ None,
+ Left,
+ Right,
+ };
+ BackBuffer backBuffer{ BackBuffer::None };
~RHIRenderTarget();
void cleanup();