summaryrefslogtreecommitdiffstats
path: root/src/plugins/renderers/rhi/renderer/renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/renderers/rhi/renderer/renderer.cpp')
-rw-r--r--src/plugins/renderers/rhi/renderer/renderer.cpp178
1 files changed, 117 insertions, 61 deletions
diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp
index 45485a6c7..4a25bb464 100644
--- a/src/plugins/renderers/rhi/renderer/renderer.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderer.cpp
@@ -93,8 +93,6 @@
QT_BEGIN_NAMESPACE
-using namespace Qt3DCore;
-
namespace Qt3DRender {
namespace Render {
namespace Rhi {
@@ -336,7 +334,7 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_computableEntityFilterJob->setManager(m_nodesManager->renderNodesManager());
}
-void Renderer::setServices(QServiceLocator *services)
+void Renderer::setServices(Qt3DCore::QServiceLocator *services)
{
m_services = services;
@@ -613,12 +611,12 @@ void Renderer::render(bool swapBuffers)
// RenderQueue is complete (but that means it may be of size 0)
if (!queueIsEmpty) {
- QTaskLogger submissionStatsPart1(m_services->systemInformation(),
- { JobTypes::FrameSubmissionPart1, 0 },
- QTaskLogger::Submission);
- QTaskLogger submissionStatsPart2(m_services->systemInformation(),
- { JobTypes::FrameSubmissionPart2, 0 },
- QTaskLogger::Submission);
+ Qt3DCore::QTaskLogger submissionStatsPart1(m_services->systemInformation(),
+ { JobTypes::FrameSubmissionPart1, 0 },
+ Qt3DCore::QTaskLogger::Submission);
+ Qt3DCore::QTaskLogger submissionStatsPart2(m_services->systemInformation(),
+ { JobTypes::FrameSubmissionPart2, 0 },
+ Qt3DCore::QTaskLogger::Submission);
std::vector<RHIPassInfo> rhiPassesInfo;
@@ -759,8 +757,8 @@ QSurfaceFormat Renderer::format()
namespace {
std::optional<QRhiVertexInputAttribute::Format> rhiAttributeType(Attribute *attr) {
switch (attr->vertexBaseType()) {
- case QAttribute::Byte:
- case QAttribute::UnsignedByte: {
+ case Qt3DCore::QAttribute::Byte:
+ case Qt3DCore::QAttribute::UnsignedByte: {
if (attr->vertexSize() == 1)
return QRhiVertexInputAttribute::UNormByte;
if (attr->vertexSize() == 2)
@@ -769,7 +767,18 @@ std::optional<QRhiVertexInputAttribute::Format> rhiAttributeType(Attribute *attr
return QRhiVertexInputAttribute::UNormByte4;
break;
}
- case QAttribute::UnsignedInt: {
+ case Qt3DCore::QAttribute::Int: {
+ if (attr->vertexSize() == 1)
+ return QRhiVertexInputAttribute::SInt;
+ if (attr->vertexSize() == 2)
+ return QRhiVertexInputAttribute::SInt2;
+ if (attr->vertexSize() == 3)
+ return QRhiVertexInputAttribute::SInt3;
+ if (attr->vertexSize() == 4)
+ return QRhiVertexInputAttribute::SInt4;
+ break;
+ }
+ case Qt3DCore::QAttribute::UnsignedInt: {
if (attr->vertexSize() == 1)
return QRhiVertexInputAttribute::UInt;
if (attr->vertexSize() == 2)
@@ -780,7 +789,18 @@ std::optional<QRhiVertexInputAttribute::Format> rhiAttributeType(Attribute *attr
return QRhiVertexInputAttribute::UInt4;
break;
}
- case QAttribute::Float: {
+ case Qt3DCore::QAttribute::HalfFloat: {
+ if (attr->vertexSize() == 1)
+ return QRhiVertexInputAttribute::Half;
+ if (attr->vertexSize() == 2)
+ return QRhiVertexInputAttribute::Half2;
+ if (attr->vertexSize() == 3)
+ return QRhiVertexInputAttribute::Half3;
+ if (attr->vertexSize() >= 4)
+ return QRhiVertexInputAttribute::Half4;
+ break;
+ }
+ case Qt3DCore::QAttribute::Float: {
if (attr->vertexSize() == 1)
return QRhiVertexInputAttribute::Float;
if (attr->vertexSize() == 2)
@@ -1143,9 +1163,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();
@@ -1185,6 +1213,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;
@@ -1234,6 +1268,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
@@ -1241,14 +1281,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();;
@@ -1256,10 +1307,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;
}
}
@@ -1442,10 +1491,10 @@ void Renderer::lookForDirtyTextures()
const std::vector<HTexture> &activeTextureHandles = textureManager->activeHandles();
for (const HTexture &handle : activeTextureHandles) {
Texture *texture = textureManager->data(handle);
- const QNodeIdVector imageIds = texture->textureImageIds();
+ const Qt3DCore::QNodeIdVector imageIds = texture->textureImageIds();
// Does the texture reference any of the dirty texture images?
- for (const QNodeId &imageId : imageIds) {
+ for (const Qt3DCore::QNodeId &imageId : imageIds) {
if (dirtyImageIds.contains(imageId)) {
texture->addDirtyFlag(Texture::DirtyImageGenerators);
break;
@@ -1475,7 +1524,7 @@ void Renderer::reloadDirtyShaders()
// If api of the renderer matches the one from the technique
if (technique->isCompatibleWithRenderer()) {
const auto passIds = technique->renderPasses();
- for (const QNodeId &passId : passIds) {
+ for (const Qt3DCore::QNodeId &passId : passIds) {
RenderPass *renderPass =
m_nodesManager->renderPassManager()->lookupResource(passId);
HShader shaderHandle =
@@ -1536,7 +1585,7 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager)
static_cast<decltype(frontend)>(manager->lookupNode(s->peerId()));
if (frontend) {
QShaderProgramPrivate *dFrontend =
- static_cast<decltype(dFrontend)>(QNodePrivate::get(frontend));
+ static_cast<decltype(dFrontend)>(Qt3DCore::QNodePrivate::get(frontend));
dFrontend->setStatus(s->status());
dFrontend->setLog(s->log());
s->unsetRequiresFrontendSync();
@@ -1552,7 +1601,7 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager)
continue;
QShaderProgramBuilderPrivate *dBuilder =
- static_cast<decltype(dBuilder)>(QNodePrivate::get(builder));
+ static_cast<decltype(dBuilder)>(Qt3DCore::QNodePrivate::get(builder));
dBuilder->setShaderCode(update.shaderCode, update.shaderType);
}
m_shaderBuilderUpdates.clear();
@@ -1588,7 +1637,7 @@ void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager)
texture->blockNotifications(blocked);
QAbstractTexturePrivate *dTexture =
- static_cast<QAbstractTexturePrivate *>(QNodePrivate::get(texture));
+ static_cast<QAbstractTexturePrivate *>(Qt3DCore::QNodePrivate::get(texture));
dTexture->setStatus(properties.status);
dTexture->setHandleType(pair.first.handleType);
dTexture->setHandle(pair.first.handle);
@@ -1626,7 +1675,7 @@ bool Renderer::prepareGeometryInputBindings(const Geometry *geometry, const RHIS
QHash<int, int> &attributeNameToBinding)
{
// shader requires no attributes
- if (shader->attributes().size() == 0)
+ if (shader->attributes().empty())
return true;
// QRhiVertexInputBinding -> specifies the stride of an attribute,
@@ -1648,7 +1697,7 @@ bool Renderer::prepareGeometryInputBindings(const Geometry *geometry, const RHIS
for (Qt3DCore::QNodeId attribute_id : attributesIds) {
Attribute *attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id);
- if (attrib->attributeType() != QAttribute::VertexAttribute)
+ if (attrib->attributeType() != Qt3DCore::QAttribute::VertexAttribute)
continue;
const int location = locationForAttribute(attrib, shader);
// In case the shader doesn't use the attribute, we would get no
@@ -1662,20 +1711,20 @@ bool Renderer::prepareGeometryInputBindings(const Geometry *geometry, const RHIS
? QRhiVertexInputBinding::PerInstance
: QRhiVertexInputBinding::PerVertex;
- auto getAttributeByteSize = [] (const QAttribute::VertexBaseType type) {
+ auto getAttributeByteSize = [](const Qt3DCore::QAttribute::VertexBaseType type) {
switch (type) {
- case QAttribute::Byte:
- case QAttribute::UnsignedByte:
+ case Qt3DCore::QAttribute::Byte:
+ case Qt3DCore::QAttribute::UnsignedByte:
return 1;
- case QAttribute::Short:
- case QAttribute::UnsignedShort:
- case QAttribute::HalfFloat:
+ case Qt3DCore::QAttribute::Short:
+ case Qt3DCore::QAttribute::UnsignedShort:
+ case Qt3DCore::QAttribute::HalfFloat:
return 2;
- case QAttribute::Int:
- case QAttribute::UnsignedInt:
- case QAttribute::Float:
+ case Qt3DCore::QAttribute::Int:
+ case Qt3DCore::QAttribute::UnsignedInt:
+ case Qt3DCore::QAttribute::Float:
return 4;
- case QAttribute::Double:
+ case Qt3DCore::QAttribute::Double:
return 8;
}
return 0;
@@ -1842,7 +1891,7 @@ void Renderer::updateResources()
// for textures which had not initially specified these information
// (TargetAutomatic...) Gather these information and store them to be distributed by
// a change next frame
- const QNodeIdVector referenceTextureIds = { rhiTextureManager->texNodeIdForRHITexture.value(rhiTexture) };
+ const Qt3DCore::QNodeIdVector referenceTextureIds = { rhiTextureManager->texNodeIdForRHITexture.value(rhiTexture) };
// Store properties and referenceTextureIds
Texture::TextureUpdateInfo updateInfo;
updateInfo.properties = info.properties;
@@ -1964,11 +2013,11 @@ void Renderer::updateTexture(Texture *texture)
// Will make the texture requestUpload
if (dirtyFlags.testFlag(Texture::DirtyImageGenerators)) {
- const QNodeIdVector textureImageIds = texture->textureImageIds();
+ const Qt3DCore::QNodeIdVector textureImageIds = texture->textureImageIds();
std::vector<RHITexture::Image> images;
images.reserve(textureImageIds.size());
// TODO: Move this into RHITexture directly
- for (const QNodeId &textureImageId : textureImageIds) {
+ for (const Qt3DCore::QNodeId &textureImageId : textureImageIds) {
const TextureImage *img =
m_nodesManager->textureImageManager()->lookupResource(textureImageId);
if (img == nullptr) {
@@ -2203,7 +2252,7 @@ void Renderer::jobsDone(Qt3DCore::QAspectManager *manager)
}
// Do we need to notify any texture about property changes?
- if (m_updatedTextureProperties.size() > 0)
+ if (!m_updatedTextureProperties.empty())
sendTextureChangesToFrontend(manager);
sendDisablesToFrontend(manager);
@@ -2224,7 +2273,7 @@ bool Renderer::processKeyEvent(QObject *object, QKeyEvent *event)
}
// Jobs we may have to run even if no rendering will happen
-std::vector<QAspectJobPtr> Renderer::preRenderingJobs()
+std::vector<Qt3DCore::QAspectJobPtr> Renderer::preRenderingJobs()
{
if (m_sendBufferCaptureJob->hasRequests())
return { m_sendBufferCaptureJob };
@@ -2238,10 +2287,10 @@ std::vector<QAspectJobPtr> Renderer::preRenderingJobs()
// for the rendering of the scene
std::vector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
{
- std::vector<QAspectJobPtr> renderBinJobs;
+ std::vector<Qt3DCore::QAspectJobPtr> renderBinJobs;
// Remove previous dependencies
- m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
+ m_cleanupJob->removeDependency(QWeakPointer<Qt3DCore::QAspectJob>());
const bool dirtyParametersForCurrentFrame = m_dirtyBits.marked & AbstractRenderer::ParameterDirty;
const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
@@ -2315,7 +2364,7 @@ std::vector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_updatedDisableSubtreeEnablers.push_back(node->peerId());
}
- int idealThreadCount = QAspectJobManager::idealThreadCount();
+ int idealThreadCount = Qt3DCore::QAspectJobManager::idealThreadCount();
const size_t fgBranchCount = m_frameGraphLeaves.size();
if (fgBranchCount > 1) {
@@ -2379,7 +2428,7 @@ std::vector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
return renderBinJobs;
}
-QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const
+Qt3DCore::QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const
{
return static_cast<Qt3DCore::QAbstractFrameAdvanceService *>(m_vsyncFrameAdvanceService.data());
}
@@ -2404,12 +2453,12 @@ bool Renderer::performCompute(QRhiCommandBuffer *cb, RenderCommand &command)
return true;
}
-static auto rhiIndexFormat(QAttribute::VertexBaseType type)
+static auto rhiIndexFormat(Qt3DCore::QAttribute::VertexBaseType type)
{
switch (type) {
- case QAttribute::VertexBaseType ::UnsignedShort:
+ case Qt3DCore::QAttribute::VertexBaseType ::UnsignedShort:
return QRhiCommandBuffer::IndexUInt16;
- case QAttribute::VertexBaseType ::UnsignedInt:
+ case Qt3DCore::QAttribute::VertexBaseType ::UnsignedInt:
return QRhiCommandBuffer::IndexUInt32;
default:
std::abort();
@@ -2481,7 +2530,7 @@ bool Renderer::uploadBuffersForCommand(RHIGraphicsPipeline* graphicsPipeline, Re
Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attrib->bufferId());
RHIBuffer *hbuf = m_RHIResourceManagers->rhiBufferManager()->lookupResource(buffer->peerId());
switch (attrib->attributeType()) {
- case QAttribute::VertexAttribute: {
+ case Qt3DCore::QAttribute::VertexAttribute: {
if (!hbuf->bind(&*m_submissionContext, RHIBuffer::Type((int)RHIBuffer::Type::ArrayBuffer | (int)RHIBuffer::Type::ShaderStorageBuffer)))
return false;
assert(hbuf->rhiBuffer());
@@ -2494,7 +2543,7 @@ bool Renderer::uploadBuffersForCommand(RHIGraphicsPipeline* graphicsPipeline, Re
command.vertex_input[bindingIndex] = { hbuf->rhiBuffer(), 0 };
break;
}
- case QAttribute::IndexAttribute: {
+ case Qt3DCore::QAttribute::IndexAttribute: {
if (!hbuf->bind(&*m_submissionContext, RHIBuffer::Type::IndexBuffer))
return false;
assert(hbuf->rhiBuffer());
@@ -2503,7 +2552,7 @@ bool Renderer::uploadBuffersForCommand(RHIGraphicsPipeline* graphicsPipeline, Re
command.indexAttribute = attrib;
break;
}
- case QAttribute::DrawIndirectAttribute:
+ case Qt3DCore::QAttribute::DrawIndirectAttribute:
RHI_UNIMPLEMENTED;
break;
}
@@ -2642,12 +2691,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) {
@@ -2707,7 +2763,6 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
// All the RVs in the current passinfo target the same RenderTarget
// A single beginPass should take place, unless Computes RVs are intermingled
- QRhiResourceUpdateBatch *inPassUpdates = nullptr;
static const bool supportsCompute = m_submissionContext->rhi()->isFeatureSupported(QRhi::Compute);
// Per Pass Global States
@@ -2725,6 +2780,7 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
if (supportsCompute) {
if (!inCompute) {
cb->beginComputePass(m_submissionContext->m_currentUpdates);
+ m_submissionContext->m_currentUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch();
inCompute = true;
}
executeComputeRenderView(rv);
@@ -2746,6 +2802,7 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
continue;
}
cb->beginPass(rhiRenderTarget, clearColor, clearDepthStencil, m_submissionContext->m_currentUpdates);
+ m_submissionContext->m_currentUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch();
inDraw = true;
}
@@ -2794,8 +2851,7 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
const QRhiColorAttachment *color0Att = desc.colorAttachmentAt(0);
readbackDesc.setTexture(color0Att->texture());
}
- inPassUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch();
- inPassUpdates->readBackTexture(readbackDesc, readBackResult);
+ m_submissionContext->m_currentUpdates->readBackTexture(readbackDesc, readBackResult);
} else {
qCWarning(Backend) << "Requested capture rectangle is outside framebuffer";
}
@@ -2807,9 +2863,9 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo)
}
if (Q_LIKELY(inDraw))
- cb->endPass(inPassUpdates);
+ cb->endPass(m_submissionContext->m_currentUpdates);
else if (inCompute)
- cb->endComputePass();
+ cb->endComputePass(m_submissionContext->m_currentUpdates);
m_submissionContext->m_currentUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch();