summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-12-10 17:13:23 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-12-11 16:15:42 +0000
commit0331dbd1ed89e3aac6c7a1371db5c9b1615f8307 (patch)
tree93f0d76b4d668ae2146d4a75f1de955097fae002
parent7aab0e3b850cc17735ac19ab7a6e7db2bac1cb83 (diff)
Enable BlitFramebuffer with non-output render targets
Task-number: QTBUG-65080 Change-Id: I711f58e67906af048a64eb7d0e2f66c8a96dd14f Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/attachmentpack.cpp13
-rw-r--r--src/render/backend/attachmentpack_p.h4
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp113
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h4
-rw-r--r--src/render/jobs/renderviewjobutils.cpp2
5 files changed, 90 insertions, 46 deletions
diff --git a/src/render/backend/attachmentpack.cpp b/src/render/backend/attachmentpack.cpp
index 9a08fdde4..a2ac8c30c 100644
--- a/src/render/backend/attachmentpack.cpp
+++ b/src/render/backend/attachmentpack.cpp
@@ -50,11 +50,10 @@ AttachmentPack::AttachmentPack()
{
}
-AttachmentPack::AttachmentPack(const RenderTargetSelector *selector, const RenderTarget *target, AttachmentManager *attachmentManager)
+AttachmentPack::AttachmentPack(const RenderTarget *target,
+ AttachmentManager *attachmentManager,
+ const QVector<QRenderTargetOutput::AttachmentPoint> &drawBuffers)
{
- // Cache draw buffers list
- const QVector<QRenderTargetOutput::AttachmentPoint> selectedAttachmentPoints = selector->outputs();
-
// Copy attachments
const auto outputIds = target->renderOutputs();
for (Qt3DCore::QNodeId outputId : outputIds) {
@@ -66,15 +65,15 @@ AttachmentPack::AttachmentPack(const RenderTargetSelector *selector, const Rende
// Create actual DrawBuffers list that is used for glDrawBuffers
// If nothing is specified, use all the attachments as draw buffers
- if (selectedAttachmentPoints.isEmpty()) {
+ if (drawBuffers.isEmpty()) {
m_drawBuffers.reserve(m_attachments.size());
for (const Attachment &attachment : qAsConst(m_attachments))
// only consider Color Attachments
if (attachment.m_point <= QRenderTargetOutput::Color15)
m_drawBuffers.push_back((int) attachment.m_point);
} else {
- m_drawBuffers.reserve(selectedAttachmentPoints.size());
- for (QRenderTargetOutput::AttachmentPoint drawBuffer : selectedAttachmentPoints)
+ m_drawBuffers.reserve(drawBuffers.size());
+ for (QRenderTargetOutput::AttachmentPoint drawBuffer : drawBuffers)
if (drawBuffer <= QRenderTargetOutput::Color15)
m_drawBuffers.push_back((int) drawBuffer);
}
diff --git a/src/render/backend/attachmentpack_p.h b/src/render/backend/attachmentpack_p.h
index 98362149a..a3a2586dd 100644
--- a/src/render/backend/attachmentpack_p.h
+++ b/src/render/backend/attachmentpack_p.h
@@ -84,7 +84,9 @@ class AttachmentPack
{
public:
AttachmentPack();
- AttachmentPack(const RenderTargetSelector *selector, const RenderTarget *target, AttachmentManager *attachmentManager);
+ AttachmentPack(const RenderTarget *target,
+ AttachmentManager *attachmentManager,
+ const QVector<QRenderTargetOutput::AttachmentPoint> &drawBuffers = QVector<QRenderTargetOutput::AttachmentPoint>());
QVector<Attachment> attachments() const { return m_attachments; }
QVector<int> getGlDrawBuffers() const { return m_drawBuffers; }
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 9a20c77e7..f9229f633 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -579,38 +579,11 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId,
// this is the default fbo that some platforms create (iOS), we just register it
// Insert FBO into hash
m_renderTargets.insert(renderTargetNodeId, fboId);
- } else if ((fboId = m_glHelper->createFrameBufferObject()) != 0) {
- // The FBO is created and its attachments are set once
- // Insert FBO into hash
- m_renderTargets.insert(renderTargetNodeId, fboId);
- // Bind FBO
- m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
- bindFrameBufferAttachmentHelper(fboId, attachments);
} else {
- qCritical() << "Failed to create FBO";
+ fboId = createRenderTarget(renderTargetNodeId, attachments);
}
} else {
- fboId = m_renderTargets.value(renderTargetNodeId);
-
- // We need to check if one of the attachment was resized
- bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet?
- if (!needsResize) {
- // render target exists, has attachment been resized?
- GLTextureManager *glTextureManager = m_renderer->nodeManagers()->glTextureManager();
- const QSize s = m_renderTargetsSize[fboId];
- const auto attachments_ = attachments.attachments();
- for (const Attachment &attachment : attachments_) {
- GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid);
- needsResize |= (rTex != nullptr && rTex->size() != s);
- if (attachment.m_point == QRenderTargetOutput::Color0)
- m_renderTargetFormat = rTex->properties().format;
- }
- }
-
- if (needsResize) {
- m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
- bindFrameBufferAttachmentHelper(fboId, attachments);
- }
+ fboId = updateRenderTarget(renderTargetNodeId, attachments, true);
}
}
m_activeFBO = fboId;
@@ -619,6 +592,54 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId,
activateDrawBuffers(attachments);
}
+GLuint GraphicsContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments)
+{
+ const GLuint fboId = m_glHelper->createFrameBufferObject();
+ if (fboId) {
+ // The FBO is created and its attachments are set once
+ // Insert FBO into hash
+ m_renderTargets.insert(renderTargetNodeId, fboId);
+ // Bind FBO
+ m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
+ bindFrameBufferAttachmentHelper(fboId, attachments);
+ } else {
+ qCritical("Failed to create FBO");
+ }
+ return fboId;
+}
+
+GLuint GraphicsContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget)
+{
+ const GLuint fboId = m_renderTargets.value(renderTargetNodeId);
+
+ // We need to check if one of the attachment was resized
+ bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet?
+ if (!needsResize) {
+ // render target exists, has attachment been resized?
+ GLTextureManager *glTextureManager = m_renderer->nodeManagers()->glTextureManager();
+ const QSize s = m_renderTargetsSize[fboId];
+ const auto attachments_ = attachments.attachments();
+ for (const Attachment &attachment : attachments_) {
+ GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid);
+ // ### TODO QTBUG-64757 this check is insufficient since the
+ // texture may have changed to another one with the same size. That
+ // case is not handled atm.
+ needsResize |= (rTex != nullptr && rTex->size() != s);
+ if (isActiveRenderTarget) {
+ if (attachment.m_point == QRenderTargetOutput::Color0)
+ m_renderTargetFormat = rTex->properties().format;
+ }
+ }
+ }
+
+ if (needsResize) {
+ m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
+ bindFrameBufferAttachmentHelper(fboId, attachments);
+ }
+
+ return fboId;
+}
+
void GraphicsContext::bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments)
{
// Set FBO attachments. These are normally textures, except that on Open GL
@@ -1515,20 +1536,39 @@ bool GraphicsContext::hasGLBufferForBuffer(Buffer *buffer)
return (it != m_renderBufferHash.end());
}
-void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTarget,
- Qt3DCore::QNodeId outputRenderTarget,
+void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId,
+ Qt3DCore::QNodeId outputRenderTargetId,
QRect inputRect, QRect outputRect,
uint defaultFboId,
QRenderTargetOutput::AttachmentPoint inputAttachmentPoint,
QRenderTargetOutput::AttachmentPoint outputAttachmentPoint,
QBlitFramebuffer::InterpolationMethod interpolationMethod)
{
- //Find the context side name for the render targets
- const GLuint inputFboId = m_renderTargets[inputRenderTarget];
+ GLuint inputFboId = defaultFboId;
+ bool inputBufferIsDefault = true;
+ if (!inputRenderTargetId.isNull()) {
+ RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(inputRenderTargetId);
+ if (renderTarget) {
+ AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager());
+ if (m_renderTargets.contains(inputRenderTargetId))
+ inputFboId = updateRenderTarget(inputRenderTargetId, attachments, false);
+ else
+ inputFboId = createRenderTarget(inputRenderTargetId, attachments);
+ }
+ inputBufferIsDefault = false;
+ }
+
GLuint outputFboId = defaultFboId;
bool outputBufferIsDefault = true;
- if (!outputRenderTarget.isNull() && m_renderTargets.contains(outputRenderTarget)) {
- outputFboId = m_renderTargets[outputRenderTarget];
+ if (!outputRenderTargetId.isNull()) {
+ RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(outputRenderTargetId);
+ if (renderTarget) {
+ AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager());
+ if (m_renderTargets.contains(outputRenderTargetId))
+ outputFboId = updateRenderTarget(outputRenderTargetId, attachments, false);
+ else
+ outputFboId = createRenderTarget(outputRenderTargetId, attachments);
+ }
outputBufferIsDefault = false;
}
@@ -1552,7 +1592,8 @@ void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTarget,
bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw);
//Bind texture
- readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint);
+ if (!inputBufferIsDefault)
+ readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint);
if (!outputBufferIsDefault)
drawBuffer(GL_COLOR_ATTACHMENT0 + outputAttachmentPoint);
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index b07a11c7e..60d1ec237 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -168,7 +168,7 @@ public:
void releaseBuffer(Qt3DCore::QNodeId bufferId);
bool hasGLBufferForBuffer(Buffer *buffer);
- void blitFramebuffer(Qt3DCore::QNodeId outputRenderTarget, Qt3DCore::QNodeId inputRenderTarget,
+ void blitFramebuffer(Qt3DCore::QNodeId outputRenderTargetId, Qt3DCore::QNodeId inputRenderTargetId,
QRect inputRect,
QRect outputRect, uint defaultFboId,
QRenderTargetOutput::AttachmentPoint inputAttachmentPoint,
@@ -268,6 +268,8 @@ private:
GraphicsHelperInterface *resolveHighestOpenGLFunctions();
+ GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments);
+ GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget);
void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments);
void activateDrawBuffers(const AttachmentPack &attachments);
HGLBuffer createGLBufferFor(Buffer *buffer, GLBuffer::Type type);
diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp
index cf23e572f..1f25a2353 100644
--- a/src/render/jobs/renderviewjobutils.cpp
+++ b/src/render/jobs/renderviewjobutils.cpp
@@ -145,7 +145,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle);
if (renderTarget)
- rv->setAttachmentPack(AttachmentPack(targetSelector, renderTarget, manager->attachmentManager()));
+ rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs()));
}
break;
}