From 0800d02e5e1a5a83b3dbf8b435beb2da5382d9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 17 Apr 2020 18:15:02 +0200 Subject: rhi: apply clang-format to the whole plug-in Change-Id: I764930b7a59a8e016d451964c14733a966a00ca7 Reviewed-by: Paul Lemire --- .../rhi/graphicshelpers/submissioncontext.cpp | 1113 ++++++++++---------- .../rhi/graphicshelpers/submissioncontext_p.h | 56 +- src/plugins/renderers/rhi/io/rhibuffer.cpp | 64 +- src/plugins/renderers/rhi/io/rhibuffer_p.h | 14 +- .../rhi/jobs/filtercompatibletechniquejob.cpp | 6 +- .../rhi/jobs/materialparametergathererjob.cpp | 25 +- .../rhi/jobs/materialparametergathererjob_p.h | 21 +- .../rhi/jobs/renderviewcommandbuilderjob.cpp | 5 +- .../rhi/jobs/renderviewcommandupdaterjob.cpp | 13 +- .../rhi/jobs/renderviewcommandupdaterjob_p.h | 3 +- .../rhi/jobs/renderviewinitializerjob.cpp | 14 +- .../rhi/jobs/renderviewinitializerjob_p.h | 5 +- .../renderers/rhi/jobs/renderviewjobutils.cpp | 143 +-- .../renderers/rhi/jobs/renderviewjobutils_p.h | 10 +- src/plugins/renderers/rhi/main.cpp | 3 +- .../renderers/rhi/managers/rhiresourcemanagers.cpp | 12 +- .../renderers/rhi/managers/rhiresourcemanagers_p.h | 37 +- .../renderers/rhi/renderer/commandexecuter.cpp | 174 +-- .../renderers/rhi/renderer/rendercommand.cpp | 83 +- .../renderers/rhi/renderer/rendercommand_p.h | 29 +- src/plugins/renderers/rhi/renderer/renderer.cpp | 922 ++++++++-------- src/plugins/renderers/rhi/renderer/renderer_p.h | 71 +- .../renderers/rhi/renderer/renderercache_p.h | 2 +- src/plugins/renderers/rhi/renderer/renderqueue.cpp | 13 +- src/plugins/renderers/rhi/renderer/renderview.cpp | 413 ++++---- src/plugins/renderers/rhi/renderer/renderview_p.h | 218 ++-- .../renderers/rhi/renderer/renderviewbuilder.cpp | 333 +++--- .../renderers/rhi/renderer/renderviewbuilder_p.h | 6 +- .../renderers/rhi/renderer/rhigraphicspipeline.cpp | 14 +- .../renderers/rhi/renderer/rhigraphicspipeline_p.h | 22 +- src/plugins/renderers/rhi/renderer/rhishader.cpp | 377 ++++--- src/plugins/renderers/rhi/renderer/rhishader_p.h | 23 +- .../renderers/rhi/renderer/shaderparameterpack.cpp | 14 +- .../renderers/rhi/renderer/shaderparameterpack_p.h | 54 +- .../renderers/rhi/renderer/shadervariables_p.h | 50 +- .../renderers/rhi/textures/renderbuffer.cpp | 5 +- src/plugins/renderers/rhi/textures/texture.cpp | 444 ++++---- src/plugins/renderers/rhi/textures/texture_p.h | 62 +- 38 files changed, 2580 insertions(+), 2293 deletions(-) diff --git a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp index b2999c287..5b217929c 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp +++ b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp @@ -100,11 +100,11 @@ namespace Qt3DRender { namespace Render { namespace Rhi { -static QHash static_contexts; +static QHash static_contexts; unsigned int nextFreeContextId() noexcept { - for (unsigned int i=0; i < 0xffff; ++i) { + for (unsigned int i = 0; i < 0xffff; ++i) { if (!static_contexts.contains(i)) return i; } @@ -129,32 +129,31 @@ RHIBuffer::Type attributeTypeToGLBufferType(QAttribute::AttributeType type) noex } } -void copyGLFramebufferDataToImage(QImage &img, const uchar *srcData, uint stride, uint width, uint height, QAbstractTexture::TextureFormat format) noexcept +void copyGLFramebufferDataToImage(QImage &img, const uchar *srcData, uint stride, uint width, + uint height, QAbstractTexture::TextureFormat format) noexcept { switch (format) { - case QAbstractTexture::RGBA32F: - { - uchar *srcScanline = const_cast(srcData) + stride * (height - 1); - for (uint i = 0; i < height; ++i) { - uchar *dstScanline = img.scanLine(i); - float *pSrc = reinterpret_cast(srcScanline); - for (uint j = 0; j < width; j++) { - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+2], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+1], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+0], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+3], 1.0f)); - } - srcScanline -= stride; - } - } break; - default: - { - uchar* srcScanline = (uchar *)srcData + stride * (height - 1); - for (uint i = 0; i < height; ++i) { - memcpy(img.scanLine(i), srcScanline, stride); - srcScanline -= stride; + case QAbstractTexture::RGBA32F: { + uchar *srcScanline = const_cast(srcData) + stride * (height - 1); + for (uint i = 0; i < height; ++i) { + uchar *dstScanline = img.scanLine(i); + float *pSrc = reinterpret_cast(srcScanline); + for (uint j = 0; j < width; j++) { + *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4 * j + 2], 1.0f)); + *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4 * j + 1], 1.0f)); + *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4 * j + 0], 1.0f)); + *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4 * j + 3], 1.0f)); } - } break; + srcScanline -= stride; + } + } break; + default: { + uchar *srcScanline = (uchar *)srcData + stride * (height - 1); + for (uint i = 0; i < height; ++i) { + memcpy(img.scanLine(i), srcScanline, stride); + srcScanline -= stride; + } + } break; } } @@ -173,13 +172,13 @@ void applyStateHelper(const BlendEquationArguments *state, QRhiGraphicsPipeline const auto values = state->values(); // We assume a single color attachment - QRhiGraphicsPipeline::TargetBlend targetBlend{}; + QRhiGraphicsPipeline::TargetBlend targetBlend {}; const bool hasTargetBlend = gp->cbeginTargetBlends() != gp->cendTargetBlends(); if (hasTargetBlend) targetBlend = *(gp->cbeginTargetBlends()); - auto getRHIBlendFactor = [] (int arg) { + auto getRHIBlendFactor = [](int arg) { switch (arg) { case QBlendEquationArguments::Zero: return QRhiGraphicsPipeline::Zero; @@ -189,11 +188,11 @@ void applyStateHelper(const BlendEquationArguments *state, QRhiGraphicsPipeline return QRhiGraphicsPipeline::SrcColor; case QBlendEquationArguments::SourceAlpha: return QRhiGraphicsPipeline::SrcAlpha; -// ### Qt 6 Fix values -// case QBlendEquationArguments::Source1Alpha: -// return QRhiGraphicsPipeline::Src1Alpha; -// case QBlendEquationArguments::Source1Color: -// return QRhiGraphicsPipeline::Src1Color; + // ### Qt 6 Fix values + // case QBlendEquationArguments::Source1Alpha: + // return QRhiGraphicsPipeline::Src1Alpha; + // case QBlendEquationArguments::Source1Color: + // return QRhiGraphicsPipeline::Src1Color; case QBlendEquationArguments::DestinationColor: return QRhiGraphicsPipeline::DstColor; case QBlendEquationArguments::DestinationAlpha: @@ -230,13 +229,14 @@ void applyStateHelper(const BlendEquationArguments *state, QRhiGraphicsPipeline targetBlend.dstAlpha = getRHIBlendFactor(std::get<3>(values)); targetBlend.srcColor = getRHIBlendFactor(std::get<0>(values)); targetBlend.dstColor = getRHIBlendFactor(std::get<1>(values)); - gp->setTargetBlends({targetBlend}); + gp->setTargetBlends({ targetBlend }); } void applyStateHelper(const BlendEquation *state, QRhiGraphicsPipeline *gp) noexcept { const auto values = state->values(); - const QBlendEquation::BlendFunction equation = static_cast(std::get<0>(values)); + const QBlendEquation::BlendFunction equation = + static_cast(std::get<0>(values)); // We assume a single color attachment QRhiGraphicsPipeline::TargetBlend targetBlend; @@ -245,7 +245,7 @@ void applyStateHelper(const BlendEquation *state, QRhiGraphicsPipeline *gp) noex if (hasTargetBlend) targetBlend = *(gp->cbeginTargetBlends()); - auto getRHIBlendOp = [] (QBlendEquation::BlendFunction equation) { + auto getRHIBlendOp = [](QBlendEquation::BlendFunction equation) { switch (equation) { case QBlendEquation::Add: return QRhiGraphicsPipeline::Add; @@ -262,10 +262,11 @@ void applyStateHelper(const BlendEquation *state, QRhiGraphicsPipeline *gp) noex targetBlend.enable = true; targetBlend.opAlpha = getRHIBlendOp(equation); - gp->setTargetBlends({targetBlend}); + gp->setTargetBlends({ targetBlend }); } -void applyStateHelper(const MSAAEnabled *state, QRhiGraphicsPipeline *gp, const QSurfaceFormat& format) noexcept +void applyStateHelper(const MSAAEnabled *state, QRhiGraphicsPipeline *gp, + const QSurfaceFormat &format) noexcept { gp->setSampleCount(format.samples()); } @@ -273,7 +274,8 @@ void applyStateHelper(const MSAAEnabled *state, QRhiGraphicsPipeline *gp, const void applyStateHelper(const DepthTest *state, QRhiGraphicsPipeline *gp) noexcept { gp->setDepthTest(true); - const QDepthTest::DepthFunction depthFunc = static_cast(std::get<0>(state->values())); + const QDepthTest::DepthFunction depthFunc = + static_cast(std::get<0>(state->values())); switch (depthFunc) { case QDepthTest::Never: gp->setDepthOp(QRhiGraphicsPipeline::Never); @@ -311,7 +313,8 @@ void applyStateHelper(const NoDepthMask *state, QRhiGraphicsPipeline *gp) noexce void applyStateHelper(const CullFace *state, QRhiGraphicsPipeline *gp) noexcept { const auto values = state->values(); - const QCullFace::CullingMode cullingMode = static_cast(std::get<0>(values)); + const QCullFace::CullingMode cullingMode = + static_cast(std::get<0>(values)); switch (cullingMode) { case QCullFace::NoCulling: gp->setCullMode(QRhiGraphicsPipeline::None); @@ -331,7 +334,8 @@ void applyStateHelper(const CullFace *state, QRhiGraphicsPipeline *gp) noexcept void applyStateHelper(const FrontFace *state, QRhiGraphicsPipeline *gp) noexcept { const auto values = state->values(); - const QFrontFace::WindingDirection cullingMode = static_cast(std::get<0>(values)); + const QFrontFace::WindingDirection cullingMode = + static_cast(std::get<0>(values)); switch (cullingMode) { case QFrontFace::ClockWise: @@ -348,7 +352,7 @@ void applyStateHelper(const StencilTest *state, QRhiGraphicsPipeline *gp) noexce const auto values = state->values(); gp->setStencilTest(true); - auto getCompareOp = [] (int compareOp) { + auto getCompareOp = [](int compareOp) { switch (compareOp) { case QStencilTestArguments::Never: return QRhiGraphicsPipeline::Never; @@ -408,13 +412,13 @@ void applyStateHelper(const ColorMask *state, QRhiGraphicsPipeline *gp) noexcept colorMask |= QRhiGraphicsPipeline::A; targetBlend.colorWrite = colorMask; - gp->setTargetBlends({targetBlend}); + gp->setTargetBlends({ targetBlend }); } void applyStateHelper(const StencilOp *state, QRhiGraphicsPipeline *gp) noexcept { const auto values = state->values(); - auto getRHIStencilOp = [] (int op) { + auto getRHIStencilOp = [](int op) { switch (op) { case QStencilOperationArguments::Zero: return QRhiGraphicsPipeline::StencilZero; @@ -460,39 +464,45 @@ void applyStateHelper(const StencilMask *state, QRhiGraphicsPipeline *gp) noexce static QShader::Stage rhiShaderStage(QShaderProgram::ShaderType type) noexcept { - switch (type) - { - case QShaderProgram::Vertex: return QShader::VertexStage; - case QShaderProgram::Fragment: return QShader::FragmentStage; - case QShaderProgram::TessellationControl: return QShader::TessellationControlStage; - case QShaderProgram::TessellationEvaluation: return QShader::TessellationEvaluationStage; - case QShaderProgram::Geometry: return QShader::GeometryStage; - case QShaderProgram::Compute: return QShader::ComputeStage; - default: std::abort(); + switch (type) { + case QShaderProgram::Vertex: + return QShader::VertexStage; + case QShaderProgram::Fragment: + return QShader::FragmentStage; + case QShaderProgram::TessellationControl: + return QShader::TessellationControlStage; + case QShaderProgram::TessellationEvaluation: + return QShader::TessellationEvaluationStage; + case QShaderProgram::Geometry: + return QShader::GeometryStage; + case QShaderProgram::Compute: + return QShader::ComputeStage; + default: + std::abort(); } } } // anonymous - SubmissionContext::SubmissionContext() - : m_ownCurrent(true) - , m_id(nextFreeContextId()) - , m_surface(nullptr) - , m_activeShader(nullptr) - , m_renderTargetFormat(QAbstractTexture::NoFormat) - , m_material(nullptr) - , m_activeFBO(0) - , m_renderer(nullptr) - , m_uboTempArray(QByteArray(1024, 0)) - , m_initialized(false) - , m_maxTextureUnits(0) - , m_defaultFBO(0) - , m_rhi(nullptr) - , m_currentSwapChain(nullptr) - , m_currentRenderPassDescriptor(nullptr) + : m_ownCurrent(true), + m_id(nextFreeContextId()), + m_surface(nullptr), + m_activeShader(nullptr), + m_renderTargetFormat(QAbstractTexture::NoFormat), + m_material(nullptr), + m_activeFBO(0), + m_renderer(nullptr), + m_uboTempArray(QByteArray(1024, 0)), + m_initialized(false), + m_maxTextureUnits(0), + m_defaultFBO(0), + m_rhi(nullptr), + m_currentSwapChain(nullptr), + m_currentRenderPassDescriptor(nullptr) #ifndef QT_NO_OPENGL - , m_fallbackSurface(nullptr) + , + m_fallbackSurface(nullptr) #endif { static_contexts[m_id] = this; @@ -574,7 +584,7 @@ void SubmissionContext::initialize() params.fallbackSurface = m_fallbackSurface; m_rhi = QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags); #else - qWarning() << "RHI: OpenGL not supported"; + qWarning() << "RHI: OpenGL not supported"; #endif } @@ -585,27 +595,27 @@ void SubmissionContext::resolveRenderTargetFormat() { RHI_UNIMPLEMENTED; -//* const QSurfaceFormat format = m_gl->format(); -//* const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); -//* const uint r = format.redBufferSize(); -//* const uint g = format.greenBufferSize(); -//* const uint b = format.blueBufferSize(); -//* -//* #define RGBA_BITS(r,g,b,a) (r | (g << 6) | (b << 12) | (a << 18)) -//* -//* const uint bits = RGBA_BITS(r,g,b,a); -//* switch (bits) { -//* case RGBA_BITS(8,8,8,8): -//* m_renderTargetFormat = QAbstractTexture::RGBA8_UNorm; -//* break; -//* case RGBA_BITS(8,8,8,0): -//* m_renderTargetFormat = QAbstractTexture::RGB8_UNorm; -//* break; -//* case RGBA_BITS(5,6,5,0): -//* m_renderTargetFormat = QAbstractTexture::R5G6B5; -//* break; -//* } -//* #undef RGBA_BITS + //* const QSurfaceFormat format = m_gl->format(); + //* const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); + //* const uint r = format.redBufferSize(); + //* const uint g = format.greenBufferSize(); + //* const uint b = format.blueBufferSize(); + //* + //* #define RGBA_BITS(r,g,b,a) (r | (g << 6) | (b << 12) | (a << 18)) + //* + //* const uint bits = RGBA_BITS(r,g,b,a); + //* switch (bits) { + //* case RGBA_BITS(8,8,8,8): + //* m_renderTargetFormat = QAbstractTexture::RGBA8_UNorm; + //* break; + //* case RGBA_BITS(8,8,8,0): + //* m_renderTargetFormat = QAbstractTexture::RGB8_UNorm; + //* break; + //* case RGBA_BITS(5,6,5,0): + //* m_renderTargetFormat = QAbstractTexture::R5G6B5; + //* break; + //* } + //* #undef RGBA_BITS } bool SubmissionContext::beginDrawing(QSurface *surface) @@ -659,8 +669,7 @@ bool SubmissionContext::beginDrawing(QSurface *surface) // swapChainInfo->renderBuffer->build(); // Resize swapchain if needed - if (m_surface->size() != swapChain->surfacePixelSize()) - { + if (m_surface->size() != swapChain->surfacePixelSize()) { bool couldRebuild = swapChain->buildOrResize(); if (!couldRebuild) return false; @@ -681,17 +690,18 @@ void SubmissionContext::endDrawing(bool swapBuffers) m_rhi->endFrame(m_currentSwapChain, {}); RHI_UNIMPLEMENTED; -//* if (swapBuffers) -//* m_gl->swapBuffers(m_surface); -//* if (m_ownCurrent) -//* m_gl->doneCurrent(); + //* if (swapBuffers) + //* m_gl->swapBuffers(m_surface); + //* if (m_ownCurrent) + //* m_gl->doneCurrent(); // m_textureContext.endDrawing(); -//* static int i = 0; -//* if (i++ == 10) -//* std::exit(0); + //* static int i = 0; + //* if (i++ == 10) + //* std::exit(0); } -void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId) +void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, + const AttachmentPack &attachments, GLuint defaultFboId) { RHI_UNIMPLEMENTED; GLuint fboId = defaultFboId; // Default FBO @@ -712,247 +722,262 @@ void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeI } } m_activeFBO = fboId; -//* m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw); + //* m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw); // Set active drawBuffers activateDrawBuffers(attachments); } -GLuint SubmissionContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments) +GLuint SubmissionContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, + const AttachmentPack &attachments) { RHI_UNIMPLEMENTED; return 0; -//* 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; + //* 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 SubmissionContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget) +GLuint SubmissionContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, + const AttachmentPack &attachments, + bool isActiveRenderTarget) { RHI_UNIMPLEMENTED; return 0; -//* 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? -//* RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); -//* const QSize s = m_renderTargetsSize[fboId]; -//* const auto attachments_ = attachments.attachments(); -//* for (const Attachment &attachment : attachments_) { -//* RHITexture *rTex = rhiTextureManager->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. -//* if (rTex) { -//* needsResize |= rTex->size() != s; -//* if (isActiveRenderTarget && attachment.m_point == QRenderTargetOutput::Color0) -//* m_renderTargetFormat = rTex->properties().format; -//* } -//* } -//* } -//* -//* if (needsResize) { -//* m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); -//* bindFrameBufferAttachmentHelper(fboId, attachments); -//* } -//* -//* return fboId; + //* 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? + //* RHITextureManager *rhiTextureManager = + //m_renderer->rhiResourceManagers()->rhiTextureManager(); + //* const QSize s = m_renderTargetsSize[fboId]; + //* const auto attachments_ = attachments.attachments(); + //* for (const Attachment &attachment : attachments_) { + //* RHITexture *rTex = rhiTextureManager->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. + //* if (rTex) { + //* needsResize |= rTex->size() != s; + //* if (isActiveRenderTarget && attachment.m_point == + //QRenderTargetOutput::Color0) + //* m_renderTargetFormat = rTex->properties().format; + //* } + //* } + //* } + //* + //* if (needsResize) { + //* m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); + //* bindFrameBufferAttachmentHelper(fboId, attachments); + //* } + //* + //* return fboId; } QSize SubmissionContext::renderTargetSize(const QSize &surfaceSize) const { RHI_UNIMPLEMENTED; return surfaceSize; -//* QSize renderTargetSize{}; -//* if (m_activeFBO != m_defaultFBO) { -//* // For external FBOs we may not have a m_renderTargets entry. -//* if (m_renderTargetsSize.contains(m_activeFBO)) { -//* renderTargetSize = m_renderTargetsSize[m_activeFBO]; -//* } else if (surfaceSize.isValid()) { -//* renderTargetSize = surfaceSize; -//* } else { -//* // External FBO (when used with QtQuick2 Scene3D) -//* -//* // Query FBO color attachment 0 size -//* GLint attachmentObjectType = GL_NONE; -//* GLint attachment0Name = 0; -//* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, -//* GL_COLOR_ATTACHMENT0, -//* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, -//* &attachmentObjectType); -//* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, -//* GL_COLOR_ATTACHMENT0, -//* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -//* &attachment0Name); -//* -//* if (attachmentObjectType == GL_RENDERBUFFER && m_glHelper->supportsFeature(GraphicsHelperInterface::RenderBufferDimensionRetrieval)) -//* renderTargetSize = m_glHelper->getRenderBufferDimensions(attachment0Name); -//* else if (attachmentObjectType == GL_TEXTURE && m_glHelper->supportsFeature(GraphicsHelperInterface::TextureDimensionRetrieval)) -//* // Assumes texture level 0 and GL_TEXTURE_2D target -//* renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, GL_TEXTURE_2D); -//* else -//* return renderTargetSize; -//* } -//* } else { -//* renderTargetSize = m_surface->size(); -//* if (m_surface->surfaceClass() == QSurface::Window) { -//* const float dpr = static_cast(m_surface)->devicePixelRatio(); -//* renderTargetSize *= dpr; -//* } -//* } -//* return renderTargetSize; + //* QSize renderTargetSize{}; + //* if (m_activeFBO != m_defaultFBO) { + //* // For external FBOs we may not have a m_renderTargets entry. + //* if (m_renderTargetsSize.contains(m_activeFBO)) { + //* renderTargetSize = m_renderTargetsSize[m_activeFBO]; + //* } else if (surfaceSize.isValid()) { + //* renderTargetSize = surfaceSize; + //* } else { + //* // External FBO (when used with QtQuick2 Scene3D) + //* + //* // Query FBO color attachment 0 size + //* GLint attachmentObjectType = GL_NONE; + //* GLint attachment0Name = 0; + //* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + //* GL_COLOR_ATTACHMENT0, + //* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + //* &attachmentObjectType); + //* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + //* GL_COLOR_ATTACHMENT0, + //* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + //* &attachment0Name); + //* + //* if (attachmentObjectType == GL_RENDERBUFFER && + //m_glHelper->supportsFeature(GraphicsHelperInterface::RenderBufferDimensionRetrieval)) + //* renderTargetSize = m_glHelper->getRenderBufferDimensions(attachment0Name); + //* else if (attachmentObjectType == GL_TEXTURE && + //m_glHelper->supportsFeature(GraphicsHelperInterface::TextureDimensionRetrieval)) + //* // Assumes texture level 0 and GL_TEXTURE_2D target + //* renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, + //GL_TEXTURE_2D); + //* else + //* return renderTargetSize; + //* } + //* } else { + //* renderTargetSize = m_surface->size(); + //* if (m_surface->surfaceClass() == QSurface::Window) { + //* const float dpr = static_cast(m_surface)->devicePixelRatio(); + //* renderTargetSize *= dpr; + //* } + //* } + //* return renderTargetSize; } QImage SubmissionContext::readFramebuffer(const QRect &rect) { RHI_UNIMPLEMENTED; return {}; -//* QImage img; -//* const unsigned int area = rect.width() * rect.height(); -//* unsigned int bytes; -//* GLenum format, type; -//* QImage::Format imageFormat; -//* uint stride; -//* -//* /* format value should match GL internalFormat */ -//* GLenum internalFormat = m_renderTargetFormat; -//* -//* switch (m_renderTargetFormat) { -//* case QAbstractTexture::RGBAFormat: -//* case QAbstractTexture::RGBA8_SNorm: -//* case QAbstractTexture::RGBA8_UNorm: -//* case QAbstractTexture::RGBA8U: -//* case QAbstractTexture::SRGB8_Alpha8: -//*#ifdef QT_OPENGL_ES_2 -//* format = GL_RGBA; -//* imageFormat = QImage::Format_RGBA8888_Premultiplied; -//*#else -//* format = GL_BGRA; -//* imageFormat = QImage::Format_ARGB32_Premultiplied; -//* internalFormat = GL_RGBA8; -//*#endif -//* type = GL_UNSIGNED_BYTE; -//* bytes = area * 4; -//* stride = rect.width() * 4; -//* break; -//* case QAbstractTexture::SRGB8: -//* case QAbstractTexture::RGBFormat: -//* case QAbstractTexture::RGB8U: -//* case QAbstractTexture::RGB8_UNorm: -//*#ifdef QT_OPENGL_ES_2 -//* format = GL_RGBA; -//* imageFormat = QImage::Format_RGBX8888; -//*#else -//* format = GL_BGRA; -//* imageFormat = QImage::Format_RGB32; -//* internalFormat = GL_RGB8; -//*#endif -//* type = GL_UNSIGNED_BYTE; -//* bytes = area * 4; -//* stride = rect.width() * 4; -//* break; -//*#ifndef QT_OPENGL_ES_2 -//* case QAbstractTexture::RG11B10F: -//* bytes = area * 4; -//* format = GL_RGB; -//* type = GL_UNSIGNED_INT_10F_11F_11F_REV; -//* imageFormat = QImage::Format_RGB30; -//* stride = rect.width() * 4; -//* break; -//* case QAbstractTexture::RGB10A2: -//* bytes = area * 4; -//* format = GL_RGBA; -//* type = GL_UNSIGNED_INT_2_10_10_10_REV; -//* imageFormat = QImage::Format_A2BGR30_Premultiplied; -//* stride = rect.width() * 4; -//* break; -//* case QAbstractTexture::R5G6B5: -//* bytes = area * 2; -//* format = GL_RGB; -//* type = GL_UNSIGNED_SHORT; -//* internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV; -//* imageFormat = QImage::Format_RGB16; -//* stride = rect.width() * 2; -//* break; -//* case QAbstractTexture::RGBA16F: -//* case QAbstractTexture::RGBA16U: -//* case QAbstractTexture::RGBA32F: -//* case QAbstractTexture::RGBA32U: -//* bytes = area * 16; -//* format = GL_RGBA; -//* type = GL_FLOAT; -//* imageFormat = QImage::Format_ARGB32_Premultiplied; -//* stride = rect.width() * 16; -//* break; -//*#endif -//* default: -//* auto warning = qWarning(); -//* warning << "Unable to convert"; -//* QtDebugUtils::formatQEnum(warning, m_renderTargetFormat); -//* warning << "render target texture format to QImage."; -//* return img; -//* } -//* -//* GLint samples = 0; -//* m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); -//* if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) { -//* qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; " -//* "Required feature BlitFramebuffer is missing."; -//* return img; -//* } -//* -//* img = QImage(rect.width(), rect.height(), imageFormat); -//* -//* QScopedArrayPointer data(new uchar [bytes]); -//* -//* if (samples > 0) { -//* // resolve multisample-framebuffer to renderbuffer and read pixels from it -//* GLuint fbo, rb; -//* QOpenGLFunctions *gl = m_gl->functions(); -//* gl->glGenFramebuffers(1, &fbo); -//* gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); -//* gl->glGenRenderbuffers(1, &rb); -//* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); -//* gl->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.width(), rect.height()); -//* gl->glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); -//* -//* const GLenum status = gl->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); -//* if (status != GL_FRAMEBUFFER_COMPLETE) { -//* gl->glDeleteRenderbuffers(1, &rb); -//* gl->glDeleteFramebuffers(1, &fbo); -//* qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status; -//* return img; -//* } -//* -//* m_glHelper->blitFramebuffer(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), -//* 0, 0, rect.width(), rect.height(), -//* GL_COLOR_BUFFER_BIT, GL_NEAREST); -//* gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); -//* gl->glReadPixels(0,0,rect.width(), rect.height(), format, type, data.data()); -//* -//* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); -//* -//* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); -//* gl->glDeleteRenderbuffers(1, &rb); -//* gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); -//* gl->glDeleteFramebuffers(1, &fbo); -//* } else { -//* // read pixels directly from framebuffer -//* m_gl->functions()->glReadPixels(rect.x(), rect.y(), rect.width(), rect.height(), format, type, data.data()); -//* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); -//* } -//* -//* return img; + //* QImage img; + //* const unsigned int area = rect.width() * rect.height(); + //* unsigned int bytes; + //* GLenum format, type; + //* QImage::Format imageFormat; + //* uint stride; + //* + //* /* format value should match GL internalFormat */ + //* GLenum internalFormat = m_renderTargetFormat; + //* + //* switch (m_renderTargetFormat) { + //* case QAbstractTexture::RGBAFormat: + //* case QAbstractTexture::RGBA8_SNorm: + //* case QAbstractTexture::RGBA8_UNorm: + //* case QAbstractTexture::RGBA8U: + //* case QAbstractTexture::SRGB8_Alpha8: + //*#ifdef QT_OPENGL_ES_2 + //* format = GL_RGBA; + //* imageFormat = QImage::Format_RGBA8888_Premultiplied; + //*#else + //* format = GL_BGRA; + //* imageFormat = QImage::Format_ARGB32_Premultiplied; + //* internalFormat = GL_RGBA8; + //*#endif + //* type = GL_UNSIGNED_BYTE; + //* bytes = area * 4; + //* stride = rect.width() * 4; + //* break; + //* case QAbstractTexture::SRGB8: + //* case QAbstractTexture::RGBFormat: + //* case QAbstractTexture::RGB8U: + //* case QAbstractTexture::RGB8_UNorm: + //*#ifdef QT_OPENGL_ES_2 + //* format = GL_RGBA; + //* imageFormat = QImage::Format_RGBX8888; + //*#else + //* format = GL_BGRA; + //* imageFormat = QImage::Format_RGB32; + //* internalFormat = GL_RGB8; + //*#endif + //* type = GL_UNSIGNED_BYTE; + //* bytes = area * 4; + //* stride = rect.width() * 4; + //* break; + //*#ifndef QT_OPENGL_ES_2 + //* case QAbstractTexture::RG11B10F: + //* bytes = area * 4; + //* format = GL_RGB; + //* type = GL_UNSIGNED_INT_10F_11F_11F_REV; + //* imageFormat = QImage::Format_RGB30; + //* stride = rect.width() * 4; + //* break; + //* case QAbstractTexture::RGB10A2: + //* bytes = area * 4; + //* format = GL_RGBA; + //* type = GL_UNSIGNED_INT_2_10_10_10_REV; + //* imageFormat = QImage::Format_A2BGR30_Premultiplied; + //* stride = rect.width() * 4; + //* break; + //* case QAbstractTexture::R5G6B5: + //* bytes = area * 2; + //* format = GL_RGB; + //* type = GL_UNSIGNED_SHORT; + //* internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV; + //* imageFormat = QImage::Format_RGB16; + //* stride = rect.width() * 2; + //* break; + //* case QAbstractTexture::RGBA16F: + //* case QAbstractTexture::RGBA16U: + //* case QAbstractTexture::RGBA32F: + //* case QAbstractTexture::RGBA32U: + //* bytes = area * 16; + //* format = GL_RGBA; + //* type = GL_FLOAT; + //* imageFormat = QImage::Format_ARGB32_Premultiplied; + //* stride = rect.width() * 16; + //* break; + //*#endif + //* default: + //* auto warning = qWarning(); + //* warning << "Unable to convert"; + //* QtDebugUtils::formatQEnum(warning, m_renderTargetFormat); + //* warning << "render target texture format to QImage."; + //* return img; + //* } + //* + //* GLint samples = 0; + //* m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); + //* if (samples > 0 && + //!m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) { + //* qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; " + //* "Required feature BlitFramebuffer is missing."; + //* return img; + //* } + //* + //* img = QImage(rect.width(), rect.height(), imageFormat); + //* + //* QScopedArrayPointer data(new uchar [bytes]); + //* + //* if (samples > 0) { + //* // resolve multisample-framebuffer to renderbuffer and read pixels from it + //* GLuint fbo, rb; + //* QOpenGLFunctions *gl = m_gl->functions(); + //* gl->glGenFramebuffers(1, &fbo); + //* gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); + //* gl->glGenRenderbuffers(1, &rb); + //* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); + //* gl->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.width(), + //rect.height()); + //* gl->glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + //GL_RENDERBUFFER, rb); + //* + //* const GLenum status = gl->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + //* if (status != GL_FRAMEBUFFER_COMPLETE) { + //* gl->glDeleteRenderbuffers(1, &rb); + //* gl->glDeleteFramebuffers(1, &fbo); + //* qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status; + //* return img; + //* } + //* + //* m_glHelper->blitFramebuffer(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + + //rect.height(), + //* 0, 0, rect.width(), rect.height(), + //* GL_COLOR_BUFFER_BIT, GL_NEAREST); + //* gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + //* gl->glReadPixels(0,0,rect.width(), rect.height(), format, type, data.data()); + //* + //* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), + //m_renderTargetFormat); + //* + //* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); + //* gl->glDeleteRenderbuffers(1, &rb); + //* gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); + //* gl->glDeleteFramebuffers(1, &fbo); + //* } else { + //* // read pixels directly from framebuffer + //* m_gl->functions()->glReadPixels(rect.x(), rect.y(), rect.width(), rect.height(), + //format, type, data.data()); + //* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), + //m_renderTargetFormat); + //* } + //* + //* return img; } void SubmissionContext::releaseResources() @@ -985,12 +1010,11 @@ void SubmissionContext::releaseResources() #endif } - -//* // Stop and destroy the OpenGL logger -//* if (m_debugLogger) { -//* m_debugLogger->stopLogging(); -//* m_debugLogger.reset(nullptr); -//* } + //* // Stop and destroy the OpenGL logger + //* if (m_debugLogger) { + //* m_debugLogger->stopLogging(); + //* m_debugLogger.reset(nullptr); + //* } } // Called only from RenderThread @@ -1013,7 +1037,8 @@ bool SubmissionContext::activateShader(RHIShader *shader) return true; } -void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments) +void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, + const AttachmentPack &attachments) { RHI_UNIMPLEMENTED; // Set FBO attachments. These are normally textures, except that on Open GL @@ -1023,7 +1048,8 @@ void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const Atta // stencil before 3.1 with the appropriate extension). //* QSize fboSize; - //* RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); + //* RHITextureManager *rhiTextureManager = + //m_renderer->rhiResourceManagers()->rhiTextureManager(); //* const auto attachments_ = attachments.attachments(); //* for (const Attachment &attachment : attachments_) { //* RHITexture *rTex = rhiTextureManager->lookupResource(attachment.m_textureUuid); @@ -1035,7 +1061,8 @@ void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const Atta //* if (fboSize.isEmpty()) //* fboSize = QSize(glTex->width(), glTex->height()); //* else - //* fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.height(), glTex->height())); + //* fboSize = QSize(qMin(fboSize.width(), glTex->width()), + //qMin(fboSize.height(), glTex->height())); //* m_glHelper->bindFrameBufferAttachment(glTex, attachment); //* } //* } else { @@ -1044,7 +1071,8 @@ void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const Atta //* if (fboSize.isEmpty()) //* fboSize = QSize(renderBuffer->width(), renderBuffer->height()); //* else - //* fboSize = QSize(qMin(fboSize.width(), renderBuffer->width()), qMin(fboSize.height(), renderBuffer->height())); + //* fboSize = QSize(qMin(fboSize.width(), renderBuffer->width()), + //qMin(fboSize.height(), renderBuffer->height())); //* m_glHelper->bindFrameBufferAttachment(renderBuffer, attachment); //* } //* } @@ -1069,7 +1097,6 @@ void SubmissionContext::activateDrawBuffers(const AttachmentPack &attachments) //* } } - void SubmissionContext::setActiveMaterial(Material *rmat) { if (m_material == rmat) @@ -1085,108 +1112,130 @@ void SubmissionContext::applyState(const StateVariant &stateVariant, switch (stateVariant.type) { case AlphaCoverageStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case AlphaTestMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case BlendStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case BlendEquationArgumentsMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case MSAAEnabledStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline, m_renderer->format()); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline, m_renderer->format()); break; } case CullFaceStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case DepthWriteStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case DepthTestStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case DepthRangeMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case RasterModeMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case FrontFaceStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case ScissorStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case StencilTestStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case PointSizeMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case PolygonOffsetStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case ColorStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case ClipPlaneMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case SeamlessCubemapMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case StencilOpMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case StencilWriteStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case DitheringStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } case LineWidthMask: { - applyStateHelper(static_cast(stateVariant.constState()), graphicsPipeline); + applyStateHelper(static_cast(stateVariant.constState()), + graphicsPipeline); break; } default: @@ -1209,20 +1258,19 @@ void SubmissionContext::applyStateSet(const RenderStateSet *ss, StateVariant *SubmissionContext::getState(RenderStateSet *ss, StateMask type) const { - const QVector& statesToSet = ss->states(); + const QVector &statesToSet = ss->states(); for (int i = 0, m = statesToSet.size(); i < m; ++i) { - const StateVariant& ds = statesToSet.at(i); + const StateVariant &ds = statesToSet.at(i); if (ds.type == type) return ss->states().begin() + i; } return nullptr; } - SubmissionContext::SwapChainInfo *SubmissionContext::swapChainForSurface(QSurface *surface) noexcept { SwapChainInfo &swapChainInfo = m_swapChains[surface]; - auto& swapChain = swapChainInfo.swapChain; + auto &swapChain = swapChainInfo.swapChain; if (swapChain == nullptr) { swapChain = m_rhi->newSwapChain(); @@ -1231,29 +1279,25 @@ SubmissionContext::SwapChainInfo *SubmissionContext::swapChainForSurface(QSurfac Q_ASSERT(window != nullptr); const int samples = format().samples(); - swapChain->setWindow(window); swapChain->setFlags(QRhiSwapChain::Flags {}); swapChain->setSampleCount(samples); - QRhiRenderBuffer *renderBuffer = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, - QSize(), - samples, - QRhiRenderBuffer::UsedWithSwapChainOnly); + QRhiRenderBuffer *renderBuffer = + m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, QSize(), samples, + QRhiRenderBuffer::UsedWithSwapChainOnly); swapChain->setDepthStencil(renderBuffer); - QRhiRenderPassDescriptor *renderPassDescriptor = swapChain->newCompatibleRenderPassDescriptor(); + QRhiRenderPassDescriptor *renderPassDescriptor = + swapChain->newCompatibleRenderPassDescriptor(); swapChain->setRenderPassDescriptor(renderPassDescriptor); // Build swapChain the first time - if (swapChain->buildOrResize()) - { + if (swapChain->buildOrResize()) { swapChainInfo.swapChain = swapChain; swapChainInfo.renderBuffer = renderBuffer; swapChainInfo.renderPassDescriptor = renderPassDescriptor; - } - else - { + } else { swapChain->releaseAndDestroyLater(); m_swapChains.remove(surface); return nullptr; @@ -1284,9 +1328,8 @@ QRhiRenderPassDescriptor *SubmissionContext::currentRenderPassDescriptor() const QSurfaceFormat SubmissionContext::format() const noexcept { - if (this->m_rhi && this->m_rhi->backend() == QRhi::OpenGLES2) - { - auto rhi_gl = static_cast(this->m_rhi->nativeHandles()); + if (this->m_rhi && this->m_rhi->backend() == QRhi::OpenGLES2) { + auto rhi_gl = static_cast(this->m_rhi->nativeHandles()); return rhi_gl->context->format(); } return QSurfaceFormat::defaultFormat(); @@ -1314,11 +1357,13 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) //* const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i); //* // Given a Texture QNodeId, we retrieve the associated shared RHITexture //* if (uniformValues.contains(namedTex.glslNameId)) { - //* RHITexture *t = m_renderer->rhiResourceManagers()->rhiTextureManager()->lookupResource(namedTex.nodeId); + //* RHITexture *t = + //m_renderer->rhiResourceManagers()->rhiTextureManager()->lookupResource(namedTex.nodeId); //* if (t != nullptr) { //* UniformValue &texUniform = uniformValues.value(namedTex.glslNameId); //* if (texUniform.valueType() == UniformValue::TextureValue) { - //* const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t); + //* const int texUnit = + //m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t); //* texUniform.data()[namedTex.uniformArrayIndex] = texUnit; //* if (texUnit == -1) { //* if (namedTex.glslNameId != irradianceId && @@ -1339,16 +1384,17 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) // for SSBO and UBO // Bind Shader Storage block to SSBO and update SSBO - const QVector& blockToSSBOs = parameterPack.shaderStorageBuffers(); - for (const BlockToSSBO& b : blockToSSBOs) { + const QVector &blockToSSBOs = parameterPack.shaderStorageBuffers(); + for (const BlockToSSBO &b : blockToSSBOs) { RHI_UNIMPLEMENTED; - Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); + Buffer *cpuBuffer = + m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); RHIBuffer *ssbo = rhiBufferForRenderBuffer(cpuBuffer); // bindShaderStorageBlock // This is currently not required as we are introspecting the bindingIndex // value from the shaders and not replacing them, making such a call useless // bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex); -// bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex); + // bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex); // Needed to avoid conflict where the buffer would already // be bound as a VertexArray bindRHIBuffer(ssbo, RHIBuffer::ShaderStorageBuffer); @@ -1362,9 +1408,10 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) int uboIndex = 0; for (const BlockToUBO &b : blockToUBOs) { RHI_UNIMPLEMENTED; - Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); + Buffer *cpuBuffer = + m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); RHIBuffer *ubo = rhiBufferForRenderBuffer(cpuBuffer); -// bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex); + // bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex); // Needed to avoid conflict where the buffer would already // be bound as a VertexArray bindRHIBuffer(ubo, RHIBuffer::UniformBuffer); @@ -1383,12 +1430,12 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) const UniformValue &v = values.value(uniform.m_nameId); // skip invalid textures/images - if ((v.valueType() == UniformValue::TextureValue || - v.valueType() == UniformValue::ShaderImageValue) && - *v.constData() == -1) + if ((v.valueType() == UniformValue::TextureValue + || v.valueType() == UniformValue::ShaderImageValue) + && *v.constData() == -1) continue; -// applyUniform(uniform, v); + // applyUniform(uniform, v); } // if not all data is valid, the next frame will be rendered immediately return true; @@ -1396,16 +1443,20 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) void SubmissionContext::updateBuffer(Buffer *buffer) { - const QHash::iterator it = m_renderBufferHash.find(buffer->peerId()); + const QHash::iterator it = + m_renderBufferHash.find(buffer->peerId()); if (it != m_renderBufferHash.end()) - uploadDataToRHIBuffer(buffer, m_renderer->rhiResourceManagers()->rhiBufferManager()->data(it.value())); + uploadDataToRHIBuffer( + buffer, m_renderer->rhiResourceManagers()->rhiBufferManager()->data(it.value())); } QByteArray SubmissionContext::downloadBufferContent(Buffer *buffer) { - const QHash::iterator it = m_renderBufferHash.find(buffer->peerId()); + const QHash::iterator it = + m_renderBufferHash.find(buffer->peerId()); if (it != m_renderBufferHash.end()) - return downloadDataFromRHIBuffer(buffer, m_renderer->rhiResourceManagers()->rhiBufferManager()->data(it.value())); + return downloadDataFromRHIBuffer( + buffer, m_renderer->rhiResourceManagers()->rhiBufferManager()->data(it.value())); return QByteArray(); } @@ -1414,7 +1465,8 @@ void SubmissionContext::releaseBuffer(Qt3DCore::QNodeId bufferId) auto it = m_renderBufferHash.find(bufferId); if (it != m_renderBufferHash.end()) { HRHIBuffer glBuffHandle = it.value(); - RHIBuffer *glBuff = m_renderer->rhiResourceManagers()->rhiBufferManager()->data(glBuffHandle); + RHIBuffer *glBuff = + m_renderer->rhiResourceManagers()->rhiBufferManager()->data(glBuffHandle); Q_ASSERT(glBuff); // Destroy the GPU resource @@ -1428,7 +1480,8 @@ void SubmissionContext::releaseBuffer(Qt3DCore::QNodeId bufferId) bool SubmissionContext::hasRHIBufferForBuffer(Buffer *buffer) { - const QHash::iterator it = m_renderBufferHash.find(buffer->peerId()); + const QHash::iterator it = + m_renderBufferHash.find(buffer->peerId()); return (it != m_renderBufferHash.end()); } @@ -1436,7 +1489,8 @@ RHIBuffer *SubmissionContext::rhiBufferForRenderBuffer(Buffer *buf) { if (!m_renderBufferHash.contains(buf->peerId())) m_renderBufferHash.insert(buf->peerId(), createRHIBufferFor(buf)); - return m_renderer->rhiResourceManagers()->rhiBufferManager()->data(m_renderBufferHash.value(buf->peerId())); + return m_renderer->rhiResourceManagers()->rhiBufferManager()->data( + m_renderBufferHash.value(buf->peerId())); } HRHIBuffer SubmissionContext::createRHIBufferFor(Buffer *buffer) @@ -1465,11 +1519,10 @@ void SubmissionContext::uploadDataToRHIBuffer(Buffer *buffer, RHIBuffer *b, bool auto update = it; // We have a partial update if (update->offset >= 0) { - //accumulate sequential updates as single one + // accumulate sequential updates as single one int bufferSize = update->data.size(); auto it2 = it + 1; - while ((it2 != updates.end()) - && (it2->offset - update->offset == bufferSize)) { + while ((it2 != updates.end()) && (it2->offset - update->offset == bufferSize)) { bufferSize += it2->data.size(); ++it2; } @@ -1499,112 +1552,116 @@ void SubmissionContext::uploadDataToRHIBuffer(Buffer *buffer, RHIBuffer *b, bool QByteArray SubmissionContext::downloadDataFromRHIBuffer(Buffer *buffer, RHIBuffer *b) { - if (!bindRHIBuffer(b, RHIBuffer::ArrayBuffer)) // We're downloading, the type doesn't matter here + if (!bindRHIBuffer(b, + RHIBuffer::ArrayBuffer)) // We're downloading, the type doesn't matter here qCWarning(Io) << Q_FUNC_INFO << "buffer bind failed"; return b->download(this, buffer->data().size()); } void SubmissionContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, - Qt3DCore::QNodeId outputRenderTargetId, - QRect inputRect, QRect outputRect, - uint defaultFboId, + Qt3DCore::QNodeId outputRenderTargetId, QRect inputRect, + QRect outputRect, uint defaultFboId, QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, QBlitFramebuffer::InterpolationMethod interpolationMethod) { RHI_UNIMPLEMENTED; -//* 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 (!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; -//* } -//* -//* // Up until this point the input and output rects are normal Qt rectangles. -//* // Convert them to GL rectangles (Y at bottom). -//* const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[inputFboId].height(); -//* const GLint srcX0 = inputRect.left(); -//* const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); -//* const GLint srcX1 = srcX0 + inputRect.width(); -//* const GLint srcY1 = srcY0 + inputRect.height(); -//* -//* const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[outputFboId].height(); -//* const GLint dstX0 = outputRect.left(); -//* const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); -//* const GLint dstX1 = dstX0 + outputRect.width(); -//* const GLint dstY1 = dstY0 + outputRect.height(); -//* -//* //Get the last bounded framebuffers -//* const GLuint lastDrawFboId = boundFrameBufferObject(); -//* -//* // Activate input framebuffer for reading -//* bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); -//* -//* // Activate output framebuffer for writing -//* bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); -//* -//* //Bind texture -//* if (!inputBufferIsDefault) -//* readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); -//* -//* if (!outputBufferIsDefault) { -//* // Note that we use glDrawBuffers, not glDrawBuffer. The -//* // latter is not available with GLES. -//* const int buf = outputAttachmentPoint; -//* drawBuffers(1, &buf); -//* } -//* -//* // Blit framebuffer -//* const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; -//* m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, -//* dstX0, dstY0, dstX1, dstY1, -//* GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, -//* mode); -//* -//* // Reset draw buffer -//* bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); -//* if (outputAttachmentPoint != QRenderTargetOutput::Color0) { -//* const int buf = QRenderTargetOutput::Color0; -//* drawBuffers(1, &buf); -//* } + //* 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 (!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; + //* } + //* + //* // Up until this point the input and output rects are normal Qt rectangles. + //* // Convert them to GL rectangles (Y at bottom). + //* const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : + //m_renderTargetsSize[inputFboId].height(); + //* const GLint srcX0 = inputRect.left(); + //* const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); + //* const GLint srcX1 = srcX0 + inputRect.width(); + //* const GLint srcY1 = srcY0 + inputRect.height(); + //* + //* const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : + //m_renderTargetsSize[outputFboId].height(); + //* const GLint dstX0 = outputRect.left(); + //* const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); + //* const GLint dstX1 = dstX0 + outputRect.width(); + //* const GLint dstY1 = dstY0 + outputRect.height(); + //* + //* //Get the last bounded framebuffers + //* const GLuint lastDrawFboId = boundFrameBufferObject(); + //* + //* // Activate input framebuffer for reading + //* bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); + //* + //* // Activate output framebuffer for writing + //* bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); + //* + //* //Bind texture + //* if (!inputBufferIsDefault) + //* readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); + //* + //* if (!outputBufferIsDefault) { + //* // Note that we use glDrawBuffers, not glDrawBuffer. The + //* // latter is not available with GLES. + //* const int buf = outputAttachmentPoint; + //* drawBuffers(1, &buf); + //* } + //* + //* // Blit framebuffer + //* const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; + //* m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, + //* dstX0, dstY0, dstX1, dstY1, + //* GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, + //* mode); + //* + //* // Reset draw buffer + //* bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); + //* if (outputAttachmentPoint != QRenderTargetOutput::Color0) { + //* const int buf = QRenderTargetOutput::Color0; + //* drawBuffers(1, &buf); + //* } } -namespace -{ +namespace { template -constexpr int getFirstAvailableBit(const std::bitset& bits) +constexpr int getFirstAvailableBit(const std::bitset &bits) { - for (std::size_t i = 0; i < N; i++) - { + for (std::size_t i = 0; i < N; i++) { if (!bits.test(i)) return i; } return -1; } // This function ensures that the shader stages all have the same bindings -void preprocessRHIShader(QVector& shaderCodes) +void preprocessRHIShader(QVector &shaderCodes) { // Map the variable names to bindings std::map bindings; @@ -1615,21 +1672,22 @@ void preprocessRHIShader(QVector& shaderCodes) assignedBindings.set(1); thread_local const QRegularExpression samplerRegex( - QStringLiteral("binding\\s*=\\s*([0-9]+).*\\)\\s*uniform\\s*[ui]?sampler[a-zA-Z0-9]+\\s*([a-zA-Z0-9_]+)\\s*;")); + QStringLiteral("binding\\s*=\\s*([0-9]+).*\\)\\s*uniform\\s*[ui]?sampler[a-zA-Z0-9]+" + "\\s*([a-zA-Z0-9_]+)\\s*;")); thread_local const QRegularExpression uboRegex( - QStringLiteral("(?:std140\\s*,\\s*binding\\s*=\\s*([0-9]+).*|binding\\s*=\\s*([0-9]+)\\s*,\\s*std140.*)\\)\\s*uniform\\s*([a-zA-Z0-9_]+)")); + QStringLiteral("(?:std140\\s*,\\s*binding\\s*=\\s*([0-9]+).*|binding\\s*=\\s*([0-9]+)" + "\\s*,\\s*std140.*)\\)\\s*uniform\\s*([a-zA-Z0-9_]+)")); - auto replaceBinding = [&bindings, &assignedBindings] (int& offset, QRegularExpressionMatch& match, QByteArray& code, int indexCapture, int variableCapture) noexcept - { + auto replaceBinding = [&bindings, &assignedBindings]( + int &offset, QRegularExpressionMatch &match, QByteArray &code, + int indexCapture, int variableCapture) noexcept { int index = match.captured(indexCapture).toInt(); QByteArray variable = match.captured(variableCapture).toUtf8(); auto it = bindings.find(variable); - if (it == bindings.end()) - { + if (it == bindings.end()) { // 1. Check if the index is already used - if (assignedBindings.test(index)) - { + if (assignedBindings.test(index)) { index = getFirstAvailableBit(assignedBindings); if (index == -1) { return; @@ -1643,9 +1701,7 @@ void preprocessRHIShader(QVector& shaderCodes) assignedBindings.set(index); bindings.emplace(std::move(variable), index); - } - else - { + } else { int indexToUse = it->second; const int indexStartOffset = match.capturedStart(indexCapture); const int indexEndOffset = match.capturedEnd(indexCapture); @@ -1657,13 +1713,11 @@ void preprocessRHIShader(QVector& shaderCodes) offset = match.capturedEnd(0); }; - for (QByteArray& shaderCode : shaderCodes) - { + for (QByteArray &shaderCode : shaderCodes) { // Regex for the sampler variables int offset = 0; auto match = samplerRegex.match(shaderCode, offset); - while (match.hasMatch()) - { + while (match.hasMatch()) { const int indexCapture = 1; const int variableCapture = 2; replaceBinding(offset, match, shaderCode, indexCapture, variableCapture); @@ -1674,8 +1728,7 @@ void preprocessRHIShader(QVector& shaderCodes) // Regex for the UBOs offset = 0; match = uboRegex.match(shaderCode, offset); - while (match.hasMatch()) - { + while (match.hasMatch()) { const int indexCapture = !match.capturedView(1).isEmpty() ? 1 : 2; const int variableCapture = 3; replaceBinding(offset, match, shaderCode, indexCapture, variableCapture); @@ -1685,39 +1738,25 @@ void preprocessRHIShader(QVector& shaderCodes) } } -int glslVersionForFormat(const QSurfaceFormat& format) noexcept +int glslVersionForFormat(const QSurfaceFormat &format) noexcept { const int major = format.majorVersion(); const int minor = format.minorVersion(); static const QHash, int> glVersionToGLSLVersion = { - { {4, 6}, 460 }, - { {4, 5}, 450 }, - { {4, 4}, 440 }, - { {4, 3}, 430 }, - { {4, 2}, 420 }, - { {4, 1}, 410 }, - { {4, 0}, 400 }, - { {3, 3}, 330 }, - { {3, 2}, 150 }, - { {3, 2}, 120 }, - { {3, 1}, 120 }, + { { 4, 6 }, 460 }, { { 4, 5 }, 450 }, { { 4, 4 }, 440 }, { { 4, 3 }, 430 }, + { { 4, 2 }, 420 }, { { 4, 1 }, 410 }, { { 4, 0 }, 400 }, { { 3, 3 }, 330 }, + { { 3, 2 }, 150 }, { { 3, 2 }, 120 }, { { 3, 1 }, 120 }, }; - const auto it = glVersionToGLSLVersion.find({major, minor}); - if (it == glVersionToGLSLVersion.end()) - { - if (major < 3) - { + const auto it = glVersionToGLSLVersion.find({ major, minor }); + if (it == glVersionToGLSLVersion.end()) { + if (major < 3) { return 120; - } - else - { + } else { return major * 100 + minor * 10; } - } - else - { + } else { return *it; } } @@ -1727,25 +1766,22 @@ int glslVersionForFormat(const QSurfaceFormat& format) noexcept SubmissionContext::ShaderCreationInfo SubmissionContext::createShaderProgram(RHIShader *shader) { // Compile shaders - const auto& shaderCode = shader->shaderCode(); + const auto &shaderCode = shader->shaderCode(); QShaderBaker b; b.setGeneratedShaders({ - {QShader::SpirvShader, 100}, + { QShader::SpirvShader, 100 }, #ifndef QT_NO_OPENGL - {QShader::GlslShader, glslVersionForFormat(format())}, + { QShader::GlslShader, glslVersionForFormat(format()) }, #endif - {QShader::HlslShader, QShaderVersion(50)}, - {QShader::MslShader, QShaderVersion(12)}, - }); - - - b.setGeneratedShaderVariants({QShader::Variant{}, - #ifndef QT_NO_OPENGL - QShader::Variant{}, - #endif - QShader::Variant{}, - QShader::Variant{}}); + { QShader::HlslShader, QShaderVersion(50) }, + { QShader::MslShader, QShaderVersion(12) }, + }); + b.setGeneratedShaderVariants({ QShader::Variant {}, +#ifndef QT_NO_OPENGL + QShader::Variant {}, +#endif + QShader::Variant {}, QShader::Variant {} }); // TODO handle caching as QShader does not have a built-in mechanism for that QString logs; @@ -1760,7 +1796,8 @@ SubmissionContext::ShaderCreationInfo SubmissionContext::createShaderProgram(RHI b.setSourceString(shaderCode.at(i), rhiStage); QShader bakedShader = b.bake(); if (b.errorMessage() != QString() || !bakedShader.isValid()) { - qDebug() << "Shader Error: " << b.errorMessage() << shaderCode.at(i).data() << rhiStage; + qDebug() << "Shader Error: " << b.errorMessage() << shaderCode.at(i).data() + << rhiStage; logs += b.errorMessage(); success = false; } @@ -1772,12 +1809,11 @@ SubmissionContext::ShaderCreationInfo SubmissionContext::createShaderProgram(RHI if (success) shader->introspect(); - return {success, logs}; + return { success, logs }; } // Called by Renderer::updateResources -void SubmissionContext::loadShader(Shader *shaderNode, - ShaderManager *shaderManager, +void SubmissionContext::loadShader(Shader *shaderNode, ShaderManager *shaderManager, RHIShaderManager *rhiShaderManager) { const Qt3DCore::QNodeId shaderId = shaderNode->peerId(); @@ -1792,7 +1828,8 @@ void SubmissionContext::loadShader(Shader *shaderNode, // We create or adopt an already created rhiShader rhiShader = rhiShaderManager->createOrAdoptExisting(shaderNode); - const QVector sharedShaderIds = rhiShaderManager->shaderIdsForProgram(rhiShader); + const QVector sharedShaderIds = + rhiShaderManager->shaderIdsForProgram(rhiShader); if (sharedShaderIds.size() == 1) { // Shader in the cache hasn't been loaded yet QVector shaderCodes = shaderNode->shaderCode(); @@ -1800,13 +1837,14 @@ void SubmissionContext::loadShader(Shader *shaderNode, rhiShader->setShaderCode(shaderCodes); const ShaderCreationInfo loadResult = createShaderProgram(rhiShader); - shaderNode->setStatus(loadResult.linkSucceeded ? QShaderProgram::Ready : QShaderProgram::Error); + shaderNode->setStatus(loadResult.linkSucceeded ? QShaderProgram::Ready + : QShaderProgram::Error); shaderNode->setLog(loadResult.logs); // Loaded in the sense we tried to load it (and maybe it failed) rhiShader->setLoaded(true); } else { // Find an already loaded shader that shares the same QShaderProgram - for (const Qt3DCore::QNodeId& sharedShaderId : sharedShaderIds) { + for (const Qt3DCore::QNodeId &sharedShaderId : sharedShaderIds) { if (sharedShaderId != shaderNode->peerId()) { Shader *refShader = shaderManager->lookupResource(sharedShaderId); // We only introspect once per actual OpenGL shader program @@ -1821,7 +1859,6 @@ void SubmissionContext::loadShader(Shader *shaderNode, shaderNode->requestCacheRebuild(); } - const GraphicsApiFilterData *SubmissionContext::contextInfo() const { return &m_contextInfo; diff --git a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h index 82b08f05d..7578639e6 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h +++ b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h @@ -52,7 +52,6 @@ // We mean it. // - #include #include #include @@ -117,11 +116,7 @@ public: ShaderImage }; - enum FBOBindMode { - FBODraw, - FBORead, - FBOReadAndDraw - }; + enum FBOBindMode { FBODraw, FBORead, FBOReadAndDraw }; SubmissionContext(); ~SubmissionContext(); @@ -133,7 +128,7 @@ public: bool beginDrawing(QSurface *surface); void endDrawing(bool swapBuffers); void releaseResources(); - void setOpenGLContext(QOpenGLContext* ctx); + void setOpenGLContext(QOpenGLContext *ctx); bool isInitialized() const { return m_initialized; } const GraphicsApiFilterData *contextInfo() const; @@ -145,7 +140,8 @@ public: }; ShaderCreationInfo createShaderProgram(RHIShader *shaderNode); - void loadShader(Shader* shader, ShaderManager *shaderManager, RHIShaderManager *rhiShaderManager); + void loadShader(Shader *shader, ShaderManager *shaderManager, + RHIShaderManager *rhiShaderManager); GLuint defaultFBO() const { return m_defaultFBO; } @@ -155,19 +151,19 @@ public: // FBO GLuint activeFBO() const { return m_activeFBO; } - void activateRenderTarget(const Qt3DCore::QNodeId id, const AttachmentPack &attachments, GLuint defaultFboId); + void activateRenderTarget(const Qt3DCore::QNodeId id, const AttachmentPack &attachments, + GLuint defaultFboId); QSize renderTargetSize(const QSize &surfaceSize) const; QImage readFramebuffer(const QRect &rect); - void blitFramebuffer(Qt3DCore::QNodeId outputRenderTargetId, Qt3DCore::QNodeId inputRenderTargetId, - QRect inputRect, - QRect outputRect, uint defaultFboId, + void blitFramebuffer(Qt3DCore::QNodeId outputRenderTargetId, + Qt3DCore::QNodeId inputRenderTargetId, QRect inputRect, QRect outputRect, + uint defaultFboId, QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, QBlitFramebuffer::InterpolationMethod interpolationMethod); // Attributes - void specifyAttribute(const Attribute *attribute, - Buffer *buffer, + void specifyAttribute(const Attribute *attribute, Buffer *buffer, const ShaderAttribute *attributeDescription); void specifyIndices(Buffer *buffer); @@ -182,24 +178,20 @@ public: bool setParameters(ShaderParameterPack ¶meterPack); // RenderState - void applyStateSet(const RenderStateSet *ss, - QRhiGraphicsPipeline *graphicsPipeline); - StateVariant* getState(RenderStateSet *ss, - StateMask type) const; + void applyStateSet(const RenderStateSet *ss, QRhiGraphicsPipeline *graphicsPipeline); + StateVariant *getState(RenderStateSet *ss, StateMask type) const; // Swap chain - struct SwapChainInfo { QRhiSwapChain *swapChain = nullptr; QRhiRenderBuffer *renderBuffer = nullptr; QRhiRenderPassDescriptor *renderPassDescriptor = nullptr; }; - SwapChainInfo* swapChainForSurface(QSurface* surface) noexcept; - + SwapChainInfo *swapChainForSurface(QSurface *surface) noexcept; - QRhiResourceUpdateBatch *m_currentUpdates{}; + QRhiResourceUpdateBatch *m_currentUpdates {}; QRhi *rhi() const { return m_rhi; } QRhiCommandBuffer *currentFrameCommandBuffer() const; @@ -210,15 +202,17 @@ public: private: // Material - Material* activeMaterial() const { return m_material; } - void setActiveMaterial(Material* rmat); + Material *activeMaterial() const { return m_material; } + void setActiveMaterial(Material *rmat); // FBO void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments); void activateDrawBuffers(const AttachmentPack &attachments); void resolveRenderTargetFormat(); - GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments); - GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget); + GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, + const AttachmentPack &attachments); + GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, + const AttachmentPack &attachments, bool isActiveRenderTarget); // Buffers HRHIBuffer createRHIBufferFor(Buffer *buffer); @@ -227,9 +221,7 @@ private: bool bindRHIBuffer(RHIBuffer *buffer, RHIBuffer::Type type); // States - void applyState(const StateVariant &state, - QRhiGraphicsPipeline *graphicsPipeline); - + void applyState(const StateVariant &state, QRhiGraphicsPipeline *graphicsPipeline); bool m_ownCurrent; const unsigned int m_id; @@ -243,20 +235,19 @@ private: QHash m_renderTargetsSize; QAbstractTexture::TextureFormat m_renderTargetFormat; - Material* m_material; + Material *m_material; GLuint m_activeFBO; Renderer *m_renderer; QByteArray m_uboTempArray; - bool m_initialized; GLint m_maxTextureUnits; GLuint m_defaultFBO; GraphicsApiFilterData m_contextInfo; - QRhi* m_rhi; + QRhi *m_rhi; QHash m_swapChains; QRhiSwapChain *m_currentSwapChain; QRhiRenderPassDescriptor *m_currentRenderPassDescriptor; @@ -264,7 +255,6 @@ private: #ifndef QT_NO_OPENGL QOffscreenSurface *m_fallbackSurface; #endif - }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/io/rhibuffer.cpp b/src/plugins/renderers/rhi/io/rhibuffer.cpp index a10cbab03..7b63b01a2 100644 --- a/src/plugins/renderers/rhi/io/rhibuffer.cpp +++ b/src/plugins/renderers/rhi/io/rhibuffer.cpp @@ -48,14 +48,16 @@ namespace Render { namespace Rhi { -namespace -{ +namespace { QRhiBuffer::UsageFlag bufferTypeToRhi(RHIBuffer::Type t) { switch (t) { - case RHIBuffer::Type::ArrayBuffer: return QRhiBuffer::VertexBuffer; - case RHIBuffer::Type::IndexBuffer: return QRhiBuffer::IndexBuffer; - case RHIBuffer::Type::UniformBuffer: return QRhiBuffer::UniformBuffer; + case RHIBuffer::Type::ArrayBuffer: + return QRhiBuffer::VertexBuffer; + case RHIBuffer::Type::IndexBuffer: + return QRhiBuffer::IndexBuffer; + case RHIBuffer::Type::UniformBuffer: + return QRhiBuffer::UniformBuffer; default: RHI_UNIMPLEMENTED; return QRhiBuffer::StorageBuffer; @@ -66,12 +68,7 @@ QRhiBuffer::UsageFlag bufferTypeToRhi(RHIBuffer::Type t) // A UBO is created for each ShaderData Shader Pair // That means a UBO is unique to a shader/shaderdata -RHIBuffer::RHIBuffer() - : m_bufferId(0) - , m_dynamic(true) - , m_lastTarget(GL_ARRAY_BUFFER) -{ -} +RHIBuffer::RHIBuffer() : m_bufferId(0), m_dynamic(true), m_lastTarget(GL_ARRAY_BUFFER) { } bool RHIBuffer::bind(SubmissionContext *ctx, Type t) { @@ -79,9 +76,9 @@ bool RHIBuffer::bind(SubmissionContext *ctx, Type t) if (this->m_datasToUpload.empty()) return bool(m_rhiBuffer); - const auto uploadMethod = m_dynamic - ? &QRhiResourceUpdateBatch::updateDynamicBuffer - : qOverload(&QRhiResourceUpdateBatch::uploadStaticBuffer); + const auto uploadMethod = m_dynamic ? &QRhiResourceUpdateBatch::updateDynamicBuffer + : qOverload( + &QRhiResourceUpdateBatch::uploadStaticBuffer); if (!m_rhiBuffer) { if (m_allocSize <= 0) return false; @@ -101,16 +98,15 @@ bool RHIBuffer::bind(SubmissionContext *ctx, Type t) #if defined(QT_DEBUG) { // for debug: we set the buffer to zero - auto ptr = new char[m_allocSize]{}; + auto ptr = new char[m_allocSize] {}; (ctx->m_currentUpdates->*uploadMethod)(m_rhiBuffer, 0, m_allocSize, ptr); delete[] ptr; } #endif } - for (const std::pair& pair : this->m_datasToUpload) - { - const QByteArray& data = pair.first; + for (const std::pair &pair : this->m_datasToUpload) { + const QByteArray &data = pair.first; int offset = pair.second; (ctx->m_currentUpdates->*uploadMethod)(m_rhiBuffer, offset, data.size(), data.constData()); } @@ -133,8 +129,7 @@ bool RHIBuffer::create(SubmissionContext *ctx) void RHIBuffer::destroy(SubmissionContext *ctx) { - if (m_rhiBuffer) - { + if (m_rhiBuffer) { m_rhiBuffer->releaseAndDestroyLater(); m_rhiBuffer = nullptr; } @@ -144,45 +139,44 @@ void RHIBuffer::destroy(SubmissionContext *ctx) void RHIBuffer::orphan(SubmissionContext *) { m_datasToUpload.clear(); - if (m_rhiBuffer) - { + if (m_rhiBuffer) { m_rhiBuffer->releaseAndDestroyLater(); m_rhiBuffer = nullptr; } m_allocSize = 0; } -void RHIBuffer::allocate(SubmissionContext *ctx, const QByteArray& data, bool dynamic) +void RHIBuffer::allocate(SubmissionContext *ctx, const QByteArray &data, bool dynamic) { m_datasToUpload.clear(); - m_datasToUpload.push_back({data, 0}); + m_datasToUpload.push_back({ data, 0 }); m_allocSize = data.size(); m_dynamic = dynamic; } -void RHIBuffer::update(SubmissionContext *ctx, const QByteArray& data, int offset) +void RHIBuffer::update(SubmissionContext *ctx, const QByteArray &data, int offset) { - m_datasToUpload.push_back({data, offset}); + m_datasToUpload.push_back({ data, offset }); } QByteArray RHIBuffer::download(SubmissionContext *ctx, uint size) { RHI_UNIMPLEMENTED; -// char *gpu_ptr = ctx->mapBuffer(m_lastTarget, size); -// QByteArray data; -// if (gpu_ptr != nullptr) { -// data.resize(size); -// std::copy(gpu_ptr, gpu_ptr+size, data.data()); -// } -// ctx->unmapBuffer(m_lastTarget); -// return data; + // char *gpu_ptr = ctx->mapBuffer(m_lastTarget, size); + // QByteArray data; + // if (gpu_ptr != nullptr) { + // data.resize(size); + // std::copy(gpu_ptr, gpu_ptr+size, data.data()); + // } + // ctx->unmapBuffer(m_lastTarget); + // return data; return {}; } void RHIBuffer::bindBufferBase(SubmissionContext *ctx, int bindingPoint, RHIBuffer::Type t) { RHI_UNIMPLEMENTED; -// ctx->bindBufferBase(glBufferTypes[t], bindingPoint, m_bufferId); + // ctx->bindBufferBase(glBufferTypes[t], bindingPoint, m_bufferId); } void RHIBuffer::bindBufferBase(SubmissionContext *ctx, int bindingPoint) diff --git a/src/plugins/renderers/rhi/io/rhibuffer_p.h b/src/plugins/renderers/rhi/io/rhibuffer_p.h index 69f05b447..4616c4111 100644 --- a/src/plugins/renderers/rhi/io/rhibuffer_p.h +++ b/src/plugins/renderers/rhi/io/rhibuffer_p.h @@ -69,8 +69,7 @@ class RHIBuffer public: RHIBuffer(); - enum Type - { + enum Type { ArrayBuffer = 0, UniformBuffer, IndexBuffer, @@ -85,22 +84,23 @@ public: bool create(SubmissionContext *ctx); void destroy(SubmissionContext *ctx); void orphan(SubmissionContext *ctx); - void allocate(SubmissionContext *ctx, const QByteArray& data, bool dynamic = true); - void update(SubmissionContext *ctx, const QByteArray& data, int offset = 0); + void allocate(SubmissionContext *ctx, const QByteArray &data, bool dynamic = true); + void update(SubmissionContext *ctx, const QByteArray &data, int offset = 0); QByteArray download(SubmissionContext *ctx, uint size); void bindBufferBase(SubmissionContext *ctx, int bindingPoint, Type t); void bindBufferBase(SubmissionContext *ctx, int bindingPoint); void cleanup(); - QRhiBuffer* rhiBuffer() const noexcept { return m_rhiBuffer; } + QRhiBuffer *rhiBuffer() const noexcept { return m_rhiBuffer; } + private: uint m_bufferId; bool m_dynamic; - int m_allocSize{}; + int m_allocSize {}; int m_lastTarget; - QRhiBuffer* m_rhiBuffer{}; + QRhiBuffer *m_rhiBuffer {}; std::vector> m_datasToUpload; }; diff --git a/src/plugins/renderers/rhi/jobs/filtercompatibletechniquejob.cpp b/src/plugins/renderers/rhi/jobs/filtercompatibletechniquejob.cpp index 649b67eb3..657e5eea7 100644 --- a/src/plugins/renderers/rhi/jobs/filtercompatibletechniquejob.cpp +++ b/src/plugins/renderers/rhi/jobs/filtercompatibletechniquejob.cpp @@ -51,8 +51,7 @@ namespace Render { namespace Rhi { FilterCompatibleTechniqueJob::FilterCompatibleTechniqueJob() - : m_manager(nullptr) - , m_renderer(nullptr) + : m_manager(nullptr), m_renderer(nullptr) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::FilterCompatibleTechniques, 0) } @@ -86,7 +85,8 @@ void FilterCompatibleTechniqueJob::run() for (const Qt3DCore::QNodeId techniqueId : dirtyTechniqueIds) { Technique *technique = m_manager->lookupResource(techniqueId); if (Q_LIKELY(technique != nullptr)) - technique->setCompatibleWithRenderer((*m_renderer->contextInfo() == *technique->graphicsApiFilter())); + technique->setCompatibleWithRenderer( + (*m_renderer->contextInfo() == *technique->graphicsApiFilter())); } } diff --git a/src/plugins/renderers/rhi/jobs/materialparametergathererjob.cpp b/src/plugins/renderers/rhi/jobs/materialparametergathererjob.cpp index 909100075..c791d30f8 100644 --- a/src/plugins/renderers/rhi/jobs/materialparametergathererjob.cpp +++ b/src/plugins/renderers/rhi/jobs/materialparametergathererjob.cpp @@ -60,12 +60,13 @@ const int likelyNumberOfParameters = 24; } // anonymous MaterialParameterGathererJob::MaterialParameterGathererJob() - : Qt3DCore::QAspectJob() - , m_manager(nullptr) - , m_techniqueFilter(nullptr) - , m_renderPassFilter(nullptr) + : Qt3DCore::QAspectJob(), + m_manager(nullptr), + m_techniqueFilter(nullptr), + m_renderPassFilter(nullptr) { - SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, materialParameterGathererCounter++) + SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, + materialParameterGathererCounter++) } // TechniqueFilter / RenderPassFilter @@ -90,7 +91,8 @@ void MaterialParameterGathererJob::run() Technique *technique = findTechniqueForEffect(m_manager, m_techniqueFilter, effect); if (Q_LIKELY(technique != nullptr)) { - RenderPassList passes = findRenderPassesForTechnique(m_manager, m_renderPassFilter, technique); + RenderPassList passes = + findRenderPassesForTechnique(m_manager, m_renderPassFilter, technique); if (Q_LIKELY(passes.size() > 0)) { // Order set: // 1 Pass Filter @@ -113,13 +115,16 @@ void MaterialParameterGathererJob::run() if (m_techniqueFilter) parametersFromParametersProvider(¶meters, m_manager->parameterManager(), m_techniqueFilter); - // Get the parameters for our selected rendering setup (override what was defined in the technique/pass filter) - parametersFromMaterialEffectTechnique(¶meters, m_manager->parameterManager(), material, effect, technique); + // Get the parameters for our selected rendering setup (override what was defined in + // the technique/pass filter) + parametersFromMaterialEffectTechnique(¶meters, m_manager->parameterManager(), + material, effect, technique); for (RenderPass *renderPass : passes) { ParameterInfoList globalParameters = parameters; - parametersFromParametersProvider(&globalParameters, m_manager->parameterManager(), renderPass); - m_parameters[material->peerId()].push_back({renderPass, globalParameters}); + parametersFromParametersProvider(&globalParameters, + m_manager->parameterManager(), renderPass); + m_parameters[material->peerId()].push_back({ renderPass, globalParameters }); } } } diff --git a/src/plugins/renderers/rhi/jobs/materialparametergathererjob_p.h b/src/plugins/renderers/rhi/jobs/materialparametergathererjob_p.h index 177f5a0c5..f635755d7 100644 --- a/src/plugins/renderers/rhi/jobs/materialparametergathererjob_p.h +++ b/src/plugins/renderers/rhi/jobs/materialparametergathererjob_p.h @@ -78,10 +78,23 @@ public: MaterialParameterGathererJob(); inline void setNodeManagers(NodeManagers *manager) Q_DECL_NOTHROW { m_manager = manager; } - inline void setTechniqueFilter(TechniqueFilter *techniqueFilter) Q_DECL_NOTHROW { m_techniqueFilter = techniqueFilter; } - inline void setRenderPassFilter(RenderPassFilter *renderPassFilter) Q_DECL_NOTHROW { m_renderPassFilter = renderPassFilter; } - inline const QHash> &materialToPassAndParameter() Q_DECL_NOTHROW { return m_parameters; } - inline void setHandles(const QVector &handles) Q_DECL_NOTHROW { m_handles = handles; } + inline void setTechniqueFilter(TechniqueFilter *techniqueFilter) Q_DECL_NOTHROW + { + m_techniqueFilter = techniqueFilter; + } + inline void setRenderPassFilter(RenderPassFilter *renderPassFilter) Q_DECL_NOTHROW + { + m_renderPassFilter = renderPassFilter; + } + inline const QHash> & + materialToPassAndParameter() Q_DECL_NOTHROW + { + return m_parameters; + } + inline void setHandles(const QVector &handles) Q_DECL_NOTHROW + { + m_handles = handles; + } inline TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_techniqueFilter; } inline RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_renderPassFilter; } diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp index ee063bf77..7a7520b60 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp +++ b/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp @@ -54,10 +54,7 @@ int renderViewInstanceCounter = 0; } // anonymous RenderViewCommandBuilderJob::RenderViewCommandBuilderJob() - : Qt3DCore::QAspectJob() - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) + : Qt3DCore::QAspectJob(), m_offset(0), m_count(0), m_renderView(nullptr) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, renderViewInstanceCounter++) } diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp index d8fcc3aaf..442f9a7d3 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp +++ b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp @@ -55,14 +55,13 @@ namespace { int renderViewInstanceCounter = 0; } // anonymous - RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob() - : Qt3DCore::QAspectJob() - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) - , m_renderer(nullptr) - , m_renderables() + : Qt3DCore::QAspectJob(), + m_offset(0), + m_count(0), + m_renderView(nullptr), + m_renderer(nullptr), + m_renderables() { SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++) } diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h index 614e02f34..3b40124ad 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h +++ b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h @@ -74,7 +74,8 @@ public: inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; } - inline void setRenderables(const EntityRenderCommandDataPtr &renderables, int offset, int count) Q_DECL_NOTHROW + inline void setRenderables(const EntityRenderCommandDataPtr &renderables, int offset, + int count) Q_DECL_NOTHROW { m_offset = offset; m_count = count; diff --git a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp index 3af0d89cc..2a95cecaa 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp +++ b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp @@ -61,15 +61,13 @@ int renderViewInstanceCounter = 0; } // anonymous RenderViewInitializerJob::RenderViewInitializerJob() - : m_renderer(nullptr) - , m_fgLeaf(nullptr) - , m_index(0) - , m_renderView(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, renderViewInstanceCounter++) -} + : m_renderer(nullptr), + m_fgLeaf(nullptr), + m_index(0), + m_renderView(nullptr) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, + renderViewInstanceCounter++) } -RenderViewInitializerJob::~RenderViewInitializerJob() + RenderViewInitializerJob::~RenderViewInitializerJob() { renderViewInstanceCounter--; } diff --git a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h index d28b10a95..fb38c8716 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h +++ b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h @@ -78,10 +78,7 @@ public: inline void setRenderer(Renderer *renderer) { m_renderer = renderer; } inline RenderView *renderView() const Q_DECL_NOTHROW { return m_renderView; } - inline void setFrameGraphLeafNode(FrameGraphNode *fgLeaf) - { - m_fgLeaf = fgLeaf; - } + inline void setFrameGraphLeafNode(FrameGraphNode *fgLeaf) { m_fgLeaf = fgLeaf; } // Sets the position in the queue of RenderViews that the // RenderView generated by this job should be inserted. This is diff --git a/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp b/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp index 8918225cd..c9a37c5e1 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp +++ b/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp @@ -104,8 +104,10 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN case FrameGraphNode::CameraSelector: // Can be set only once and we take camera nearest to the leaf node if (!rv->renderCameraLens()) { - const CameraSelector *cameraSelector = static_cast(node); - Entity *camNode = manager->renderNodesManager()->lookupResource(cameraSelector->cameraUuid()); + const CameraSelector *cameraSelector = + static_cast(node); + Entity *camNode = manager->renderNodesManager()->lookupResource( + cameraSelector->cameraUuid()); if (camNode) { CameraLens *lens = camNode->renderComponent(); rv->setRenderCameraEntity(camNode); @@ -137,17 +139,22 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN case FrameGraphNode::RenderTarget: { // Can be set once and we take render target nearest to the leaf node - const RenderTargetSelector *targetSelector = static_cast(node); + const RenderTargetSelector *targetSelector = + static_cast(node); QNodeId renderTargetUid = targetSelector->renderTargetUuid(); - HTarget renderTargetHandle = manager->renderTargetManager()->lookupHandle(renderTargetUid); + HTarget renderTargetHandle = + manager->renderTargetManager()->lookupHandle(renderTargetUid); // Add renderTarget Handle and build renderCommand AttachmentPack if (!rv->renderTargetId()) { rv->setRenderTargetId(renderTargetUid); - RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle); + RenderTarget *renderTarget = + manager->renderTargetManager()->data(renderTargetHandle); if (renderTarget) - rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs())); + rv->setAttachmentPack(AttachmentPack(renderTarget, + manager->attachmentManager(), + targetSelector->outputs())); } break; } @@ -176,7 +183,8 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN } case FrameGraphNode::SortMethod: { - const Render::SortPolicy *sortPolicy = static_cast(node); + const Render::SortPolicy *sortPolicy = + static_cast(node); rv->addSortType(sortPolicy->sortTypes()); break; } @@ -187,7 +195,8 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN break; case FrameGraphNode::StateSet: { - const Render::StateSetNode *rStateSet = static_cast(node); + const Render::StateSetNode *rStateSet = + static_cast(node); // Create global RenderStateSet for renderView if no stateSet was set before RenderStateSet *stateSet = rv->stateSet(); if (stateSet == nullptr && rStateSet->hasRenderStates()) { @@ -198,7 +207,8 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN // Add states from new stateSet we might be missing // but don' t override existing states (lower StateSetNode always has priority) if (rStateSet->hasRenderStates()) - addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); + addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), + manager->renderStateManager()); break; } @@ -213,10 +223,10 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN } case FrameGraphNode::ComputeDispatch: { - const Render::DispatchCompute *dispatchCompute = static_cast(node); + const Render::DispatchCompute *dispatchCompute = + static_cast(node); rv->setCompute(true); - rv->setComputeWorkgroups(dispatchCompute->x(), - dispatchCompute->y(), + rv->setComputeWorkgroups(dispatchCompute->x(), dispatchCompute->y(), dispatchCompute->z()); break; } @@ -229,17 +239,18 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN case FrameGraphNode::Surface: { // Use the surface closest to leaf node if (rv->surface() == nullptr) { - const Render::RenderSurfaceSelector *surfaceSelector - = static_cast(node); + const Render::RenderSurfaceSelector *surfaceSelector = + static_cast(node); rv->setSurface(surfaceSelector->surface()); - rv->setSurfaceSize(surfaceSelector->renderTargetSize() * surfaceSelector->devicePixelRatio()); + rv->setSurfaceSize(surfaceSelector->renderTargetSize() + * surfaceSelector->devicePixelRatio()); rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); } break; } case FrameGraphNode::RenderCapture: { auto *renderCapture = const_cast( - static_cast(node)); + static_cast(node)); if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { rv->setRenderCaptureNodeId(renderCapture->peerId()); rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); @@ -254,9 +265,9 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN case FrameGraphNode::BufferCapture: { auto *bufferCapture = const_cast( - static_cast(node)); + static_cast(node)); if (bufferCapture != nullptr) - rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); + rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); break; } @@ -266,11 +277,13 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN rv->setHasBlitFramebufferInfo(true); BlitFramebufferInfo bfbInfo; bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); - bfbInfo.destinationRenderTargetId = blitFramebufferNode->destinationRenderTargetId(); + bfbInfo.destinationRenderTargetId = + blitFramebufferNode->destinationRenderTargetId(); bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); - bfbInfo.destinationAttachmentPoint = blitFramebufferNode->destinationAttachmentPoint(); + bfbInfo.destinationAttachmentPoint = + blitFramebufferNode->destinationAttachmentPoint(); bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); rv->setBlitFrameBufferInfo(bfbInfo); break; @@ -303,15 +316,15 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN \internal Searches the best matching Technique from \a effect specified. */ -Technique *findTechniqueForEffect(NodeManagers *manager, - const TechniqueFilter *techniqueFilter, +Technique *findTechniqueForEffect(NodeManagers *manager, const TechniqueFilter *techniqueFilter, Effect *effect) { if (!effect) return nullptr; - QVector matchingTechniques; - const bool hasInvalidTechniqueFilter = (techniqueFilter == nullptr || techniqueFilter->filters().isEmpty()); + QVector matchingTechniques; + const bool hasInvalidTechniqueFilter = + (techniqueFilter == nullptr || techniqueFilter->filters().isEmpty()); // Iterate through the techniques in the effect const auto techniqueIds = effect->techniques(); @@ -323,7 +336,9 @@ Technique *findTechniqueForEffect(NodeManagers *manager, // Check if the technique is compatible with the rendering API // If no techniqueFilter is present, we return the technique as it satisfies OpenGL version - if (technique->isCompatibleWithRenderer() && (hasInvalidTechniqueFilter || technique->isCompatibleWithFilters(techniqueFilter->filters()))) + if (technique->isCompatibleWithRenderer() + && (hasInvalidTechniqueFilter + || technique->isCompatibleWithFilters(techniqueFilter->filters()))) matchingTechniques.append(technique); } @@ -334,7 +349,7 @@ Technique *findTechniqueForEffect(NodeManagers *manager, return matchingTechniques.first(); // Several compatible techniques, return technique with highest major and minor version - Technique* highest = matchingTechniques.first(); + Technique *highest = matchingTechniques.first(); GraphicsApiFilterData filter = *highest->graphicsApiFilter(); for (auto it = matchingTechniques.cbegin() + 1; it < matchingTechniques.cend(); ++it) { if (filter < *(*it)->graphicsApiFilter()) { @@ -345,7 +360,6 @@ Technique *findTechniqueForEffect(NodeManagers *manager, return highest; } - RenderPassList findRenderPassesForTechnique(NodeManagers *manager, const RenderPassFilter *passFilter, Technique *technique) @@ -364,15 +378,18 @@ RenderPassList findRenderPassesForTechnique(NodeManagers *manager, // A pass filter is present so we need to check for matching criteria if (!foundMatch && renderPass->filterKeys().size() >= passFilter->filters().size()) { - // Iterate through the filter criteria and look for render passes with criteria that satisfy them + // Iterate through the filter criteria and look for render passes with criteria that + // satisfy them const auto filterKeyIds = passFilter->filters(); for (const QNodeId filterKeyId : filterKeyIds) { foundMatch = false; - FilterKey *filterFilterKey = manager->filterKeyManager()->lookupResource(filterKeyId); + FilterKey *filterFilterKey = + manager->filterKeyManager()->lookupResource(filterKeyId); const auto passFilterKeyIds = renderPass->filterKeys(); for (const QNodeId passFilterKeyId : passFilterKeyIds) { - FilterKey *passFilterKey = manager->filterKeyManager()->lookupResource(passFilterKeyId); + FilterKey *passFilterKey = + manager->filterKeyManager()->lookupResource(passFilterKeyId); if ((foundMatch = (*passFilterKey == *filterFilterKey))) break; } @@ -394,7 +411,6 @@ RenderPassList findRenderPassesForTechnique(NodeManagers *manager, return passes; } - ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *params, const int nameId) { const ParameterInfoList::const_iterator end = params->cend(); @@ -410,17 +426,15 @@ void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, for (const QNodeId paramId : parameterIds) { const HParameter parameterHandle = manager->lookupHandle(paramId); const Parameter *param = manager->data(parameterHandle); - ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId()); + ParameterInfoList::iterator it = + std::lower_bound(params->begin(), params->end(), param->nameId()); if (it == params->end() || it->nameId != param->nameId()) params->insert(it, ParameterInfo(param->nameId(), parameterHandle)); } } -void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, - ParameterManager *manager, - Material *material, - Effect *effect, - Technique *technique) +void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, ParameterManager *manager, + Material *material, Effect *effect, Technique *technique) { // The parameters are taken in the following priority order: // @@ -436,8 +450,7 @@ void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, } // Only add states with types we don't already have -void addStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector& stateIds, +void addStatesToRenderStateSet(RenderStateSet *stateSet, const QVector &stateIds, RenderStateManager *manager) { for (const Qt3DCore::QNodeId &stateId : stateIds) { @@ -456,36 +469,32 @@ const int qNodeIdTypeId = qMetaTypeId(); } UniformBlockValueBuilder::UniformBlockValueBuilder() - : updatedPropertiesOnly(false) - , shaderDataManager(nullptr) - , textureManager(nullptr) + : updatedPropertiesOnly(false), shaderDataManager(nullptr), textureManager(nullptr) { } -UniformBlockValueBuilder::~UniformBlockValueBuilder() -{ -} +UniformBlockValueBuilder::~UniformBlockValueBuilder() { } void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper( - const ShaderData *currentShaderData, - const QString &blockName, - const QString &qmlPropertyName, - const QVariant &value) + const ShaderData *currentShaderData, const QString &blockName, + const QString &qmlPropertyName, const QVariant &value) { // In the end, values are either scalar or a scalar array // Composed elements (structs, structs array) are simplified into simple scalars if (value.userType() == QMetaType::QVariantList) { // Array QVariantList list = value.value(); - if (list.at(0).userType() == qNodeIdTypeId) { // Array of struct qmlPropertyName[i].structMember + if (list.at(0).userType() + == qNodeIdTypeId) { // Array of struct qmlPropertyName[i].structMember for (int i = 0; i < list.size(); ++i) { - const QVariant& variantElement = list.at(i); + const QVariant &variantElement = list.at(i); if (list.at(i).userType() == qNodeIdTypeId) { const auto nodeId = variantElement.value(); ShaderData *subShaderData = shaderDataManager->lookupResource(nodeId); if (subShaderData) { - buildActiveUniformNameValueMapStructHelper(subShaderData, - blockName + QLatin1Char('.') + qmlPropertyName + blockArray.arg(i), - QLatin1String("")); + buildActiveUniformNameValueMapStructHelper( + subShaderData, + blockName + QLatin1Char('.') + qmlPropertyName + blockArray.arg(i), + QLatin1String("")); } // Note: we only handle ShaderData as nested container nodes here } @@ -506,11 +515,10 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper( const auto nodeId = value.value(); ShaderData *rSubShaderData = shaderDataManager->lookupResource(nodeId); if (rSubShaderData) { - buildActiveUniformNameValueMapStructHelper(rSubShaderData, - blockName, - qmlPropertyName); + buildActiveUniformNameValueMapStructHelper(rSubShaderData, blockName, qmlPropertyName); } else if (textureManager->contains(nodeId)) { - const auto varId = StringToInt::lookupId(blockName + QLatin1Char('.') + qmlPropertyName); + const auto varId = + StringToInt::lookupId(blockName + QLatin1Char('.') + qmlPropertyName); activeUniformNamesToValue.insert(varId, value); } } else { // Scalar / Vec @@ -525,16 +533,15 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper( // If the property needs to be transformed, we transform it here as // the shaderdata cannot hold transformed properties for multiple // thread contexts at once - activeUniformNamesToValue.insert(StringToInt::lookupId(varName), - currentShaderData->getTransformedProperty(qmlPropertyName, viewMatrix)); + activeUniformNamesToValue.insert( + StringToInt::lookupId(varName), + currentShaderData->getTransformedProperty(qmlPropertyName, viewMatrix)); } } } void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper( - const ShaderData *rShaderData, - const QString &blockName, - const QString &qmlPropertyName) + const ShaderData *rShaderData, const QString &blockName, const QString &qmlPropertyName) { const QHash &properties = rShaderData->properties(); auto it = properties.begin(); @@ -548,16 +555,16 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper( fullBlockName.append(QLatin1String(".")); fullBlockName.append(qmlPropertyName); } - buildActiveUniformNameValueMapHelper(rShaderData, fullBlockName, - it.key(), it.value().value); + buildActiveUniformNameValueMapHelper(rShaderData, fullBlockName, it.key(), + it.value().value); ++it; } } ParameterInfo::ParameterInfo(const int nameId, const HParameter &handle) - : nameId(nameId) - , handle(handle) -{} + : nameId(nameId), handle(handle) +{ +} bool ParameterInfo::operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT { diff --git a/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h b/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h index da4cf5ffa..31bc29b8d 100644 --- a/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h +++ b/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h @@ -99,7 +99,7 @@ Q_AUTOTEST_EXPORT Technique *findTechniqueForEffect(NodeManagers *manager, const TechniqueFilter *techniqueFilter, Effect *effect); -typedef QVarLengthArray RenderPassList; +typedef QVarLengthArray RenderPassList; Q_AUTOTEST_EXPORT RenderPassList findRenderPassesForTechnique(NodeManagers *manager, const RenderPassFilter *passFilter, Technique *technique); @@ -135,16 +135,14 @@ using MaterialParameterGathererData = QHash ¶meterIds); template -void parametersFromParametersProvider(ParameterInfoList *infoList, - ParameterManager *manager, +void parametersFromParametersProvider(ParameterInfoList *infoList, ParameterManager *manager, T *provider) { addParametersForIds(infoList, manager, provider->parameters()); @@ -154,7 +152,7 @@ Q_AUTOTEST_EXPORT ParameterInfoList::const_iterator findParamInfo(ParameterInfoL const int nameId); Q_AUTOTEST_EXPORT void addStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector& stateIds, + const QVector &stateIds, RenderStateManager *manager); typedef QHash UniformBlockValueBuilderHash; diff --git a/src/plugins/renderers/rhi/main.cpp b/src/plugins/renderers/rhi/main.cpp index b8d3e4890..47efc7530 100644 --- a/src/plugins/renderers/rhi/main.cpp +++ b/src/plugins/renderers/rhi/main.cpp @@ -47,7 +47,8 @@ class RhiRendererPlugin : public Qt3DRender::Render::QRendererPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QRendererPluginFactoryInterface_iid FILE "rhirenderer.json") - Qt3DRender::Render::AbstractRenderer *create(const QString &key, Qt3DRender::QRenderAspect::RenderType renderMode) override + Qt3DRender::Render::AbstractRenderer * + create(const QString &key, Qt3DRender::QRenderAspect::RenderType renderMode) override { Q_UNUSED(key) return new Qt3DRender::Render::Rhi::Renderer(renderMode); diff --git a/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp b/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp index 32d1318e4..3e813250b 100644 --- a/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp +++ b/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp @@ -48,10 +48,10 @@ namespace Render { namespace Rhi { RHIResourceManagers::RHIResourceManagers() - : m_rhiBufferManager(new RHIBufferManager()) - , m_rhiShaderManager(new RHIShaderManager()) - , m_rhiTextureManager(new RHITextureManager()) - , m_rhiGraphicsPipelineManager(new RHIGraphicsPipelineManager()) + : m_rhiBufferManager(new RHIBufferManager()), + m_rhiShaderManager(new RHIShaderManager()), + m_rhiTextureManager(new RHITextureManager()), + m_rhiGraphicsPipelineManager(new RHIGraphicsPipelineManager()) { } @@ -65,7 +65,7 @@ RHIResourceManagers::~RHIResourceManagers() void RHIResourceManagers::releaseAllResources() { - auto releaseAll = [] (auto* manager) noexcept { + auto releaseAll = [](auto *manager) noexcept { const auto handles = manager->activeHandles(); for (const auto &handle : handles) { manager->release(handle); @@ -74,7 +74,7 @@ void RHIResourceManagers::releaseAllResources() releaseAll(m_rhiTextureManager); releaseAll(m_rhiBufferManager); - //releaseAll(m_rhiShaderManager); + // releaseAll(m_rhiShaderManager); releaseAll(m_rhiGraphicsPipelineManager); } diff --git a/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h b/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h index 2a5040ef5..34758530d 100644 --- a/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h +++ b/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h @@ -68,17 +68,13 @@ namespace Render { namespace Rhi { -class Q_AUTOTEST_EXPORT RHIBufferManager : public Qt3DCore::QResourceManager< - RHIBuffer, - Qt3DCore::QNodeId, - Qt3DCore::NonLockingPolicy> +class Q_AUTOTEST_EXPORT RHIBufferManager + : public Qt3DCore::QResourceManager { }; -class Q_AUTOTEST_EXPORT RHITextureManager : public Qt3DCore::QResourceManager< - RHITexture, - Qt3DCore::QNodeId, - Qt3DCore::NonLockingPolicy> +class Q_AUTOTEST_EXPORT RHITextureManager + : public Qt3DCore::QResourceManager { public: QHash texNodeIdForRHITexture; @@ -87,9 +83,7 @@ public: class Q_AUTOTEST_EXPORT RHIShaderManager : public APIShaderManager { public: - explicit RHIShaderManager() - : APIShaderManager() - {} + explicit RHIShaderManager() : APIShaderManager() { } }; // Geometry | Shader | RenderStateMask @@ -100,13 +94,12 @@ struct GraphicsPipelineIdentifier int renderViewIndex; }; -class Q_AUTOTEST_EXPORT RHIGraphicsPipelineManager : public Qt3DCore::QResourceManager< - RHIGraphicsPipeline, - GraphicsPipelineIdentifier, - Qt3DCore::NonLockingPolicy> +class Q_AUTOTEST_EXPORT RHIGraphicsPipelineManager + : public Qt3DCore::QResourceManager { public: - RHIGraphicsPipelineManager() {} + RHIGraphicsPipelineManager() { } }; class Q_AUTOTEST_EXPORT RHIResourceManagers @@ -118,7 +111,10 @@ public: inline RHIShaderManager *rhiShaderManager() const noexcept { return m_rhiShaderManager; } inline RHITextureManager *rhiTextureManager() const noexcept { return m_rhiTextureManager; } inline RHIBufferManager *rhiBufferManager() const noexcept { return m_rhiBufferManager; } - inline RHIGraphicsPipelineManager *rhiGraphicsPipelineManager() const noexcept { return m_rhiGraphicsPipelineManager; } + inline RHIGraphicsPipelineManager *rhiGraphicsPipelineManager() const noexcept + { + return m_rhiGraphicsPipelineManager; + } void releaseAllResources(); @@ -131,14 +127,15 @@ private: inline uint qHash(const GraphicsPipelineIdentifier &key, uint seed) { - const QPair p = {key.geometry, key.shader}; + const QPair p = { key.geometry, key.shader }; using QT_PREPEND_NAMESPACE(qHash); return qHash(p, seed) + qHash(key.renderViewIndex, seed); } -inline bool operator ==(const GraphicsPipelineIdentifier &a, const GraphicsPipelineIdentifier &b) +inline bool operator==(const GraphicsPipelineIdentifier &a, const GraphicsPipelineIdentifier &b) { - return a.geometry == b.geometry && a.shader == b.shader && a.renderViewIndex == b.renderViewIndex; + return a.geometry == b.geometry && a.shader == b.shader + && a.renderViewIndex == b.renderViewIndex; } } // Rhi diff --git a/src/plugins/renderers/rhi/renderer/commandexecuter.cpp b/src/plugins/renderers/rhi/renderer/commandexecuter.cpp index d4f1a7482..cfa6531be 100644 --- a/src/plugins/renderers/rhi/renderer/commandexecuter.cpp +++ b/src/plugins/renderers/rhi/renderer/commandexecuter.cpp @@ -251,21 +251,22 @@ QJsonObject parameterPackToJson(const Render::Rhi::ShaderParameterPack &pack) no QJsonArray uniformsArray; for (int i = 0, m = uniforms.keys.size(); i < m; ++i) { QJsonObject uniformObj; - uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i))); + uniformObj.insert(QLatin1String("name"), + Render::StringToInt::lookupString(uniforms.keys.at(i))); const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType(); uniformObj.insert(QLatin1String("type"), - type == Render::UniformValue::ScalarValue - ? QLatin1String("value") - : QLatin1String("texture")); + type == Render::UniformValue::ScalarValue ? QLatin1String("value") + : QLatin1String("texture")); uniformsArray.push_back(uniformObj); } obj.insert(QLatin1String("uniforms"), uniformsArray); QJsonArray texturesArray; const QVector &textures = pack.textures(); - for (const auto & texture : textures) { + for (const auto &texture : textures) { QJsonObject textureObj; - textureObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(texture.glslNameId)); + textureObj.insert(QLatin1String("name"), + Render::StringToInt::lookupString(texture.glslNameId)); textureObj.insert(QLatin1String("id"), qint64(texture.nodeId.id())); texturesArray.push_back(textureObj); } @@ -278,7 +279,6 @@ QJsonObject parameterPackToJson(const Render::Rhi::ShaderParameterPack &pack) no uboObj.insert(QLatin1String("index"), ubo.m_blockIndex); uboObj.insert(QLatin1String("bufferId"), qint64(ubo.m_bufferID.id())); ubosArray.push_back(uboObj); - } obj.insert(QLatin1String("ubos"), ubosArray); @@ -297,93 +297,99 @@ QJsonObject parameterPackToJson(const Render::Rhi::ShaderParameterPack &pack) no } // anonymous -CommandExecuter::CommandExecuter(Render::Rhi::Renderer *renderer) - : m_renderer(renderer) -{ -} +CommandExecuter::CommandExecuter(Render::Rhi::Renderer *renderer) : m_renderer(renderer) { } // Render thread -void CommandExecuter::performAsynchronousCommandExecution(const QVector &views) +void CommandExecuter::performAsynchronousCommandExecution( + const QVector &views) { RHI_UNIMPLEMENTED; -//* QMutexLocker lock(&m_pendingCommandsMutex); -//* const QVector shellCommands = std::move(m_pendingCommands); -//* lock.unlock(); -//* -//* for (auto *reply : shellCommands) { -//* if (reply->commandName() == QLatin1String("glinfo")) { -//* QJsonObject replyObj; -//* const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo(); -//* if (contextInfo != nullptr) { -//* replyObj.insert(QLatin1String("api"), -//* contextInfo->m_api == QGraphicsApiFilter::OpenGL -//* ? QLatin1String("OpenGL") -//* : QLatin1String("OpenGLES")); -//* const QString versionString = -//* QString::number(contextInfo->m_major) -//* + QStringLiteral(".") -//* + QString::number(contextInfo->m_minor); -//* replyObj.insert(QLatin1String("version"), versionString); -//* replyObj.insert(QLatin1String("profile"), -//* contextInfo->m_profile == QGraphicsApiFilter::CoreProfile -//* ? QLatin1String("Core") -//* : contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile -//* ? QLatin1String("Compatibility") -//* : QLatin1String("None")); -//* } -//* reply->setData(QJsonDocument(replyObj).toJson()); -//* } else if (reply->commandName() == QLatin1String("rendercommands")) { -//* QJsonObject replyObj; -//* -//* QJsonArray viewArray; -//* for (Render::Rhi::RenderView *v : views) { -//* QJsonObject viewObj; -//* viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); -//* viewObj.insert(QLatin1String("surfaceSize"), typeToJsonValue(v->surfaceSize())); -//* viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); -//* viewObj.insert(QLatin1String("noDraw"), v->noDraw()); -//* viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); -//* viewObj.insert(QLatin1String("compute"), v->isCompute()); -//* viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); -//* viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); -//* -//* QJsonArray renderCommandsArray; -//* for (Render::Rhi::RenderCommand &c : v->commands()) { -//* QJsonObject commandObj; -//* Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); -//* commandObj.insert(QLatin1String("shader"), typeToJsonValue(QVariant::fromValue(c.m_shaderId))); -//* commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); -//* commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); -//* commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); -//* commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); -//* commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack)); -//* -//* renderCommandsArray.push_back(commandObj); -//* } -//* viewObj.insert(QLatin1String("commands"), renderCommandsArray); -//* viewArray.push_back(viewObj); -//* } -//* -//* replyObj.insert(QLatin1String("renderViews"), viewArray); -//* reply->setData(QJsonDocument(replyObj).toJson()); -//* } -//* reply->setFinished(true); -//* } + //* QMutexLocker lock(&m_pendingCommandsMutex); + //* const QVector shellCommands = + //std::move(m_pendingCommands); + //* lock.unlock(); + //* + //* for (auto *reply : shellCommands) { + //* if (reply->commandName() == QLatin1String("glinfo")) { + //* QJsonObject replyObj; + //* const GraphicsApiFilterData *contextInfo = + //m_renderer->submissionContext()->contextInfo(); + //* if (contextInfo != nullptr) { + //* replyObj.insert(QLatin1String("api"), + //* contextInfo->m_api == QGraphicsApiFilter::OpenGL + //* ? QLatin1String("OpenGL") + //* : QLatin1String("OpenGLES")); + //* const QString versionString = + //* QString::number(contextInfo->m_major) + //* + QStringLiteral(".") + //* + QString::number(contextInfo->m_minor); + //* replyObj.insert(QLatin1String("version"), versionString); + //* replyObj.insert(QLatin1String("profile"), + //* contextInfo->m_profile == QGraphicsApiFilter::CoreProfile + //* ? QLatin1String("Core") + //* : contextInfo->m_profile == + //QGraphicsApiFilter::CompatibilityProfile + //* ? QLatin1String("Compatibility") + //* : QLatin1String("None")); + //* } + //* reply->setData(QJsonDocument(replyObj).toJson()); + //* } else if (reply->commandName() == QLatin1String("rendercommands")) { + //* QJsonObject replyObj; + //* + //* QJsonArray viewArray; + //* for (Render::Rhi::RenderView *v : views) { + //* QJsonObject viewObj; + //* viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); + //* viewObj.insert(QLatin1String("surfaceSize"), + //typeToJsonValue(v->surfaceSize())); + //* viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); + //* viewObj.insert(QLatin1String("noDraw"), v->noDraw()); + //* viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); + //* viewObj.insert(QLatin1String("compute"), v->isCompute()); + //* viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); + //* viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); + //* + //* QJsonArray renderCommandsArray; + //* for (Render::Rhi::RenderCommand &c : v->commands()) { + //* QJsonObject commandObj; + //* Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); + //* commandObj.insert(QLatin1String("shader"), + //typeToJsonValue(QVariant::fromValue(c.m_shaderId))); + //* commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); + //* commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); + //* commandObj.insert(QLatin1String("geometry"), + //backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); + //* commandObj.insert(QLatin1String("geometryRenderer"), + //backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); + //* commandObj.insert(QLatin1String("shaderParameterPack"), + //parameterPackToJson(c.m_parameterPack)); + //* + //* renderCommandsArray.push_back(commandObj); + //* } + //* viewObj.insert(QLatin1String("commands"), renderCommandsArray); + //* viewArray.push_back(viewObj); + //* } + //* + //* replyObj.insert(QLatin1String("renderViews"), viewArray); + //* reply->setData(QJsonDocument(replyObj).toJson()); + //* } + //* reply->setFinished(true); + //* } } // Main thread QVariant CommandExecuter::executeCommand(const QStringList &args) { RHI_UNIMPLEMENTED; -//* // Note: The replies will be deleted by the AspectCommandDebugger -//* if (args.length() > 0 && -//* (args.first() == QLatin1String("glinfo") || -//* args.first() == QLatin1String("rendercommands"))) { -//* auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); -//* QMutexLocker lock(&m_pendingCommandsMutex); -//* m_pendingCommands.push_back(reply); -//* return QVariant::fromValue(reply); -//* } + //* // Note: The replies will be deleted by the AspectCommandDebugger + //* if (args.length() > 0 && + //* (args.first() == QLatin1String("glinfo") || + //* args.first() == QLatin1String("rendercommands"))) { + //* auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); + //* QMutexLocker lock(&m_pendingCommandsMutex); + //* m_pendingCommands.push_back(reply); + //* return QVariant::fromValue(reply); + //* } return QVariant(); } diff --git a/src/plugins/renderers/rhi/renderer/rendercommand.cpp b/src/plugins/renderers/rhi/renderer/rendercommand.cpp index ee1b76cef..8320abac1 100644 --- a/src/plugins/renderers/rhi/renderer/rendercommand.cpp +++ b/src/plugins/renderers/rhi/renderer/rendercommand.cpp @@ -47,36 +47,36 @@ namespace Render { namespace Rhi { RenderCommand::RenderCommand() - : m_rhiShader(nullptr) - , m_stateSet(nullptr) - , m_depth(0.0f) - , m_changeCost(0) - , m_type(RenderCommand::Draw) - , m_workGroups() - , m_primitiveCount(0) - , m_primitiveType(QGeometryRenderer::Triangles) - , m_restartIndexValue(-1) - , m_firstInstance(0) - , m_firstVertex(0) - , m_verticesPerPatch(0) - , m_instanceCount(0) - , m_indexOffset(0) - , m_indexAttributeByteOffset(0) - , m_indexAttributeDataType(Qt3DRender::QAttribute::UnsignedShort) - , m_indirectAttributeByteOffset(0) - , m_drawIndexed(false) - , m_drawIndirect(false) - , m_primitiveRestartEnabled(false) - , m_isValid(false) - , indexAttribute(nullptr) - , indexBuffer(nullptr) - , m_commandUBO() - , pipeline(nullptr) + : m_rhiShader(nullptr), + m_stateSet(nullptr), + m_depth(0.0f), + m_changeCost(0), + m_type(RenderCommand::Draw), + m_workGroups(), + m_primitiveCount(0), + m_primitiveType(QGeometryRenderer::Triangles), + m_restartIndexValue(-1), + m_firstInstance(0), + m_firstVertex(0), + m_verticesPerPatch(0), + m_instanceCount(0), + m_indexOffset(0), + m_indexAttributeByteOffset(0), + m_indexAttributeDataType(Qt3DRender::QAttribute::UnsignedShort), + m_indirectAttributeByteOffset(0), + m_drawIndexed(false), + m_drawIndirect(false), + m_primitiveRestartEnabled(false), + m_isValid(false), + indexAttribute(nullptr), + indexBuffer(nullptr), + m_commandUBO(), + pipeline(nullptr) { - m_workGroups[0] = 0; - m_workGroups[1] = 0; - m_workGroups[2] = 0; + m_workGroups[0] = 0; + m_workGroups[1] = 0; + m_workGroups[2] = 0; } bool RenderCommand::isValid() const noexcept @@ -86,16 +86,23 @@ bool RenderCommand::isValid() const noexcept bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept { - return (a.m_rhiShader == b.m_rhiShader && a.m_material == b.m_material && - a.m_stateSet == b.m_stateSet && a.m_geometry == b.m_geometry && a.m_geometryRenderer == b.m_geometryRenderer && - a.m_indirectDrawBuffer == b.m_indirectDrawBuffer && a.m_activeAttributes == b.m_activeAttributes && - a.m_depth == b.m_depth && a.m_changeCost == b.m_changeCost && a.m_shaderId == b.m_shaderId && - a.m_workGroups[0] == b.m_workGroups[0] && a.m_workGroups[1] == b.m_workGroups[1] && a.m_workGroups[2] == b.m_workGroups[2] && - a.m_primitiveCount == b.m_primitiveCount && a.m_primitiveType == b.m_primitiveType && a.m_restartIndexValue == b.m_restartIndexValue && - a.m_firstInstance == b.m_firstInstance && a.m_firstVertex == b.m_firstVertex && a.m_verticesPerPatch == b.m_verticesPerPatch && - a.m_instanceCount == b.m_instanceCount && a.m_indexOffset == b.m_indexOffset && a.m_indexAttributeByteOffset == b.m_indexAttributeByteOffset && - a.m_drawIndexed == b.m_drawIndexed && a.m_drawIndirect == b.m_drawIndirect && a.m_primitiveRestartEnabled == b.m_primitiveRestartEnabled && - a.m_isValid == b.m_isValid && a.m_computeCommand == b.m_computeCommand); + return (a.m_rhiShader == b.m_rhiShader && a.m_material == b.m_material + && a.m_stateSet == b.m_stateSet && a.m_geometry == b.m_geometry + && a.m_geometryRenderer == b.m_geometryRenderer + && a.m_indirectDrawBuffer == b.m_indirectDrawBuffer + && a.m_activeAttributes == b.m_activeAttributes && a.m_depth == b.m_depth + && a.m_changeCost == b.m_changeCost && a.m_shaderId == b.m_shaderId + && a.m_workGroups[0] == b.m_workGroups[0] && a.m_workGroups[1] == b.m_workGroups[1] + && a.m_workGroups[2] == b.m_workGroups[2] && a.m_primitiveCount == b.m_primitiveCount + && a.m_primitiveType == b.m_primitiveType + && a.m_restartIndexValue == b.m_restartIndexValue + && a.m_firstInstance == b.m_firstInstance && a.m_firstVertex == b.m_firstVertex + && a.m_verticesPerPatch == b.m_verticesPerPatch + && a.m_instanceCount == b.m_instanceCount && a.m_indexOffset == b.m_indexOffset + && a.m_indexAttributeByteOffset == b.m_indexAttributeByteOffset + && a.m_drawIndexed == b.m_drawIndexed && a.m_drawIndirect == b.m_drawIndirect + && a.m_primitiveRestartEnabled == b.m_primitiveRestartEnabled + && a.m_isValid == b.m_isValid && a.m_computeCommand == b.m_computeCommand); } } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/rendercommand_p.h b/src/plugins/renderers/rhi/renderer/rendercommand_p.h index 0a3d03e93..e6924a60c 100644 --- a/src/plugins/renderers/rhi/renderer/rendercommand_p.h +++ b/src/plugins/renderers/rhi/renderer/rendercommand_p.h @@ -90,7 +90,8 @@ struct CommandUBO float mvp[16]; float inverseModelViewProjectionMatrix[16]; }; -static_assert(sizeof(CommandUBO) == 6 * (16 * sizeof(float)) + 1 * (12 * sizeof(float)), "UBO doesn't match std140"); +static_assert(sizeof(CommandUBO) == 6 * (16 * sizeof(float)) + 1 * (12 * sizeof(float)), + "UBO doesn't match std140"); class Q_AUTOTEST_EXPORT RenderCommand { @@ -99,17 +100,19 @@ public: bool isValid() const noexcept; - HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes ....) + HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes + // ....) RHIShader *m_rhiShader; // GL Shader to be used at render time Qt3DCore::QNodeId m_shaderId; // Shader for given pass and mesh - ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the - // Texture while submission is happening. + ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy + // the Texture while submission is happening. RenderStateSetPtr m_stateSet; HGeometry m_geometry; HGeometryRenderer m_geometryRenderer; - HBuffer m_indirectDrawBuffer; // Reference to indirect draw buffer (valid only m_drawIndirect == true) + HBuffer m_indirectDrawBuffer; // Reference to indirect draw buffer (valid only m_drawIndirect == + // true) HComputeCommand m_computeCommand; // A QAttribute pack might be interesting @@ -119,10 +122,7 @@ public: float m_depth; int m_changeCost; - enum CommandType { - Draw, - Compute - }; + enum CommandType { Draw, Compute }; CommandType m_type; int m_workGroups[3]; @@ -146,17 +146,19 @@ public: QVarLengthArray vertex_input; - const Attribute* indexAttribute{}; - QRhiBuffer* indexBuffer{}; + const Attribute *indexAttribute {}; + QRhiBuffer *indexBuffer {}; CommandUBO m_commandUBO; - RHIGraphicsPipeline *pipeline{}; + RHIGraphicsPipeline *pipeline {}; }; Q_AUTOTEST_EXPORT bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept; inline bool operator!=(const RenderCommand &lhs, const RenderCommand &rhs) noexcept -{ return !operator==(lhs, rhs); } +{ + return !operator==(lhs, rhs); +} struct EntityRenderCommandData { @@ -194,7 +196,6 @@ struct EntityRenderCommandData passesData += std::move(t.passesData); return *this; } - }; using EntityRenderCommandDataPtr = QSharedPointer; diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp index eac14d0cb..ee9a26a98 100644 --- a/src/plugins/renderers/rhi/renderer/renderer.cpp +++ b/src/plugins/renderers/rhi/renderer/renderer.cpp @@ -136,13 +136,10 @@ namespace Rhi { namespace { -class CachingLightGatherer : public LightGatherer { +class CachingLightGatherer : public LightGatherer +{ public: - CachingLightGatherer(RendererCache *cache) - : LightGatherer() - , m_cache(cache) - { - } + CachingLightGatherer(RendererCache *cache) : LightGatherer(), m_cache(cache) { } void run() override { @@ -157,13 +154,11 @@ private: RendererCache *m_cache; }; -class CachingRenderableEntityFilter : public RenderableEntityFilter { +class CachingRenderableEntityFilter : public RenderableEntityFilter +{ public: - CachingRenderableEntityFilter(RendererCache *cache) - : RenderableEntityFilter() - , m_cache(cache) + CachingRenderableEntityFilter(RendererCache *cache) : RenderableEntityFilter(), m_cache(cache) { - } void run() override @@ -181,13 +176,11 @@ private: RendererCache *m_cache; }; -class CachingComputableEntityFilter : public ComputableEntityFilter { +class CachingComputableEntityFilter : public ComputableEntityFilter +{ public: - CachingComputableEntityFilter(RendererCache *cache) - : ComputableEntityFilter() - , m_cache(cache) + CachingComputableEntityFilter(RendererCache *cache) : ComputableEntityFilter(), m_cache(cache) { - } void run() override @@ -208,9 +201,9 @@ private: int locationForAttribute(Attribute *attr, RHIShader *shader) noexcept { const QVector attribInfo = shader->attributes(); - const auto it = std::find_if(attribInfo.begin(), attribInfo.end(), [attr] (const ShaderAttribute &sAttr) { - return attr->nameId() == sAttr.m_nameId; - }); + const auto it = std::find_if( + attribInfo.begin(), attribInfo.end(), + [attr](const ShaderAttribute &sAttr) { return attr->nameId() == sAttr.m_nameId; }); if (it != attribInfo.end()) return it->m_location; return -1; @@ -239,39 +232,42 @@ int locationForAttribute(Attribute *attr, RHIShader *shader) noexcept */ Renderer::Renderer(QRenderAspect::RenderType type) - : m_services(nullptr) - , m_aspect(nullptr) - , m_nodesManager(nullptr) - , m_renderSceneRoot(nullptr) - , m_defaultRenderStateSet(nullptr) - , m_submissionContext(nullptr) - , m_renderQueue(new RenderQueue()) - , m_renderThread(type == QRenderAspect::Threaded ? new RenderThread(this) : nullptr) - , m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr)) - , m_waitForInitializationToBeCompleted(0) - , m_hasBeenInitializedMutex() - , m_exposed(0) - , m_lastFrameCorrect(0) - , m_glContext(nullptr) - , m_time(0) - , m_settings(nullptr) - , m_updateShaderDataTransformJob(Render::UpdateShaderDataTransformJobPtr::create()) - , m_cleanupJob(Render::FrameCleanupJobPtr::create()) - , m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create()) - , m_filterCompatibleTechniqueJob(FilterCompatibleTechniqueJobPtr::create()) - , m_lightGathererJob(new CachingLightGatherer(&m_cache)) - , m_renderableEntityFilterJob(new CachingRenderableEntityFilter(&m_cache)) - , m_computableEntityFilterJob(new CachingComputableEntityFilter(&m_cache)) - , m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering)) - , m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) - , m_introspectShaderJob(SynchronizerPostFramePtr::create([this] { reloadDirtyShaders(); }, - [this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); }, - JobTypes::DirtyShaderGathering)) - , m_ownedContext(false) - , m_offscreenHelper(nullptr) - , m_RHIResourceManagers(nullptr) - , m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this)) - , m_shouldSwapBuffers(true) + : m_services(nullptr), + m_aspect(nullptr), + m_nodesManager(nullptr), + m_renderSceneRoot(nullptr), + m_defaultRenderStateSet(nullptr), + m_submissionContext(nullptr), + m_renderQueue(new RenderQueue()), + m_renderThread(type == QRenderAspect::Threaded ? new RenderThread(this) : nullptr), + m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr)), + m_waitForInitializationToBeCompleted(0), + m_hasBeenInitializedMutex(), + m_exposed(0), + m_lastFrameCorrect(0), + m_glContext(nullptr), + m_time(0), + m_settings(nullptr), + m_updateShaderDataTransformJob(Render::UpdateShaderDataTransformJobPtr::create()), + m_cleanupJob(Render::FrameCleanupJobPtr::create()), + m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create()), + m_filterCompatibleTechniqueJob(FilterCompatibleTechniqueJobPtr::create()), + m_lightGathererJob(new CachingLightGatherer(&m_cache)), + m_renderableEntityFilterJob(new CachingRenderableEntityFilter(&m_cache)), + m_computableEntityFilterJob(new CachingComputableEntityFilter(&m_cache)), + m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, + JobTypes::DirtyBufferGathering)), + m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, + JobTypes::DirtyTextureGathering)), + m_introspectShaderJob(SynchronizerPostFramePtr::create( + [this] { reloadDirtyShaders(); }, + [this](Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); }, + JobTypes::DirtyShaderGathering)), + m_ownedContext(false), + m_offscreenHelper(nullptr), + m_RHIResourceManagers(nullptr), + m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this)), + m_shouldSwapBuffers(true) { std::fill_n(m_textureTransform, 4, 0.f); @@ -289,7 +285,6 @@ Renderer::Renderer(QRenderAspect::RenderType type) m_defaultRenderStateSet->addState(StateVariant::createState(GL_LESS)); m_defaultRenderStateSet->addState(StateVariant::createState(GL_BACK)); m_defaultRenderStateSet->addState(StateVariant::createState(true, true, true, true)); - } Renderer::~Renderer() @@ -346,7 +341,8 @@ void Renderer::setJobsInLastFrame(int jobsInLastFrame) void Renderer::setAspect(QRenderAspect *aspect) { m_aspect = aspect; - m_updateShaderDataTransformJob->addDependency(QRenderAspectPrivate::get(aspect)->m_worldTransformJob); + m_updateShaderDataTransformJob->addDependency( + QRenderAspectPrivate::get(aspect)->m_worldTransformJob); } void Renderer::setNodeManagers(NodeManagers *managers) @@ -415,10 +411,8 @@ QScreen *Renderer::screen() const return m_screen; } -bool Renderer::accessOpenGLTexture(Qt3DCore::QNodeId nodeId, - QOpenGLTexture **texture, - QMutex **lock, - bool readonly) +bool Renderer::accessOpenGLTexture(Qt3DCore::QNodeId nodeId, QOpenGLTexture **texture, + QMutex **lock, bool readonly) { RHI_UNIMPLEMENTED; @@ -436,8 +430,8 @@ bool Renderer::accessOpenGLTexture(Qt3DCore::QNodeId nodeId, if (!readonly) glTex->setExternalRenderingEnabled(true); -// RHITexture::TextureUpdateInfo texInfo = glTex->createOrUpdateRhiTexture(m_submissionContext.data()); -// *texture = texInfo.texture; + // RHITexture::TextureUpdateInfo texInfo = + // glTex->createOrUpdateRhiTexture(m_submissionContext.data()); *texture = texInfo.texture; if (!readonly) *lock = glTex->externalRenderingLock(); @@ -466,22 +460,19 @@ void Renderer::initialize() // We need to adapt texture coordinates // m_textureTransform is (a;b) in texCoord = a * texCoord + b - if (m_submissionContext->rhi()->isYUpInFramebuffer()) - { + if (m_submissionContext->rhi()->isYUpInFramebuffer()) { // OpenGL case - that is what we assume to be the default so we do not change // anything m_textureTransform[0] = 1.f; m_textureTransform[1] = 1.f; m_textureTransform[2] = 0.f; m_textureTransform[3] = 0.f; - } - else - { + } else { // Other cases : y = 1 - y - m_textureTransform[0] = 1.f; + m_textureTransform[0] = 1.f; m_textureTransform[1] = -1.f; - m_textureTransform[2] = 0.f; - m_textureTransform[3] = 1.f; + m_textureTransform[2] = 0.f; + m_textureTransform[3] = 1.f; } // Awake setScenegraphRoot in case it was waiting @@ -569,24 +560,28 @@ void Renderer::releaseGraphicsResources() //* QOpenGLContext *context = m_submissionContext->openGLContext(); //* Q_ASSERT(context); //* - //* if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) { + //* if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) + //{ //* //* // Clean up the graphics context and any resources - //* const QVector activeTexturesHandles = m_RHIResourceManagers->rhiTextureManager()->activeHandles(); + //* const QVector activeTexturesHandles = + //m_RHIResourceManagers->rhiTextureManager()->activeHandles(); //* for (const HRHITexture &textureHandle : activeTexturesHandles) { //* RHITexture *tex = m_RHIResourceManagers->rhiTextureManager()->data(textureHandle); //* tex->destroy(); //* } //* //* // Do the same thing with buffers - //* const QVector activeBuffers = m_RHIResourceManagers->rhiBufferManager()->activeHandles(); + //* const QVector activeBuffers = + //m_RHIResourceManagers->rhiBufferManager()->activeHandles(); //* for (const HRHIBuffer &bufferHandle : activeBuffers) { //* RHIBuffer *buffer = m_RHIResourceManagers->rhiBufferManager()->data(bufferHandle); //* buffer->destroy(m_submissionContext.data()); //* } //* //* // Do the same thing with shaders - //* const QVector shaders = m_RHIResourceManagers->rhiShaderManager()->takeActiveResources(); + //* const QVector shaders = + //m_RHIResourceManagers->rhiShaderManager()->takeActiveResources(); //* qDeleteAll(shaders); //* //* @@ -600,8 +595,6 @@ void Renderer::releaseGraphicsResources() m_submissionContext.reset(nullptr); - - qCDebug(Backend) << Q_FUNC_INFO << "Renderer properly shutdown"; } @@ -709,17 +702,17 @@ void Renderer::doRender(bool swapBuffers) if (canSubmit && (queueIsComplete && !queueIsEmpty)) { const QVector renderViews = m_renderQueue->nextFrameQueue(); QTaskLogger submissionStatsPart1(m_services->systemInformation(), - {JobTypes::FrameSubmissionPart1, 0}, + { JobTypes::FrameSubmissionPart1, 0 }, QTaskLogger::Submission); QTaskLogger submissionStatsPart2(m_services->systemInformation(), - {JobTypes::FrameSubmissionPart2, 0}, + { JobTypes::FrameSubmissionPart2, 0 }, QTaskLogger::Submission); QVector rhiPassesInfo; if (canRender()) { QSurface *surface = nullptr; - for (const RenderView *rv: renderViews) { + for (const RenderView *rv : renderViews) { surface = rv->surface(); if (surface) break; @@ -727,9 +720,9 @@ void Renderer::doRender(bool swapBuffers) // In case we did not draw because e.g. there wase no swapchain, // we keep the resource updates from the previous frame. - if (!m_submissionContext->m_currentUpdates) - { - m_submissionContext->m_currentUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch(); + if (!m_submissionContext->m_currentUpdates) { + m_submissionContext->m_currentUpdates = + m_submissionContext->rhi()->nextResourceUpdateBatch(); } // 1) Execute commands for buffer uploads, texture updates, shader loading first @@ -740,14 +733,10 @@ void Renderer::doRender(bool swapBuffers) preprocessingComplete = true; bool hasCommands = false; - for (const RenderView *rv: renderViews) { - const auto& commands = rv->commands(); - hasCommands = std::any_of( - commands.begin(), - commands.end(), - [] (const RenderCommand& cmd) { - return cmd.isValid(); - }); + for (const RenderView *rv : renderViews) { + const auto &commands = rv->commands(); + hasCommands = std::any_of(commands.begin(), commands.end(), + [](const RenderCommand &cmd) { return cmd.isValid(); }); if (hasCommands) break; } @@ -775,15 +764,18 @@ void Renderer::doRender(bool swapBuffers) hasCleanedQueueAndProceeded = true; // Only try to submit the RenderViews if the preprocessing was successful - // This part of the submission is happening in parallel to the RV building for the next frame + // This part of the submission is happening in parallel to the RV building for the next + // frame if (beganDrawing) { submissionStatsPart1.end(submissionStatsPart2.restart()); - // 3) Submit the render commands for frame n (making sure we never reference something that could be changing) - // Render using current device state and renderer configuration + // 3) Submit the render commands for frame n (making sure we never reference + // something that could be changing) Render using current device state and renderer + // configuration submissionData = submitRenderViews(rhiPassesInfo); - // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader deleted...) + // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader + // deleted...) mustCleanResources = true; } } @@ -824,8 +816,7 @@ void Renderer::doRender(bool swapBuffers) SurfaceLocker surfaceLock(submissionData.surface); // Finish up with last surface used in the list of RenderViews const bool swapBuffers = submissionData.lastBoundFBOId == m_submissionContext->defaultFBO() - && surfaceLock.isSurfaceValid() - && m_shouldSwapBuffers; + && surfaceLock.isSurfaceValid() && m_shouldSwapBuffers; m_submissionContext->endDrawing(swapBuffers); if (mustCleanResources) @@ -909,10 +900,9 @@ QSurfaceFormat Renderer::format() return m_submissionContext->format(); } -void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int renderViewIndex) +void Renderer::updateGraphicsPipeline(RenderCommand &cmd, RenderView *rv, int renderViewIndex) { - if (!cmd.m_rhiShader) - { + if (!cmd.m_rhiShader) { qDebug() << "Warning: command has no shader"; return; } @@ -929,7 +919,8 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re RenderStateSet *renderState = nullptr; { - RenderStateSet *globalState = (rv->stateSet() != nullptr) ? rv->stateSet() : m_defaultRenderStateSet; + RenderStateSet *globalState = + (rv->stateSet() != nullptr) ? rv->stateSet() : m_defaultRenderStateSet; // Merge global state into local state RenderStateSet *localState = cmd.m_stateSet.data(); @@ -942,8 +933,9 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re } // Try to retrieve existing pipeline - auto& pipelineManager = *m_RHIResourceManagers->rhiGraphicsPipelineManager(); - const GraphicsPipelineIdentifier pipelineKey { cmd.m_geometry, cmd.m_shaderId, renderViewIndex }; + auto &pipelineManager = *m_RHIResourceManagers->rhiGraphicsPipelineManager(); + const GraphicsPipelineIdentifier pipelineKey { cmd.m_geometry, cmd.m_shaderId, + renderViewIndex }; RHIGraphicsPipeline *graphicsPipeline = pipelineManager.getOrCreateResource(pipelineKey); // TO DO: Ensure we find a way to know when the state is dirty to trigger a rebuild @@ -952,28 +944,31 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re return; } - // Increase score so that we know the pipeline was used for this frame and shouldn't be destroyed + // Increase score so that we know the pipeline was used for this frame and shouldn't be + // destroyed graphicsPipeline->increaseScore(); // TO DO: Set to true if geometry, shader or render state dirty bool requiredRebuild = false; - // Note: we can rebuild add/remove things from the QRhiShaderResourceBindings after having created the pipeline - // and rebuild it. Changes should be picked up automatically + // Note: we can rebuild add/remove things from the QRhiShaderResourceBindings after having + // created the pipeline and rebuild it. Changes should be picked up automatically // Create pipeline if it doesn't exist or needs to be updated if (graphicsPipeline->pipeline() == nullptr || requiredRebuild) { bool ok = true; - const SubmissionContext::SwapChainInfo* swapchain = + const SubmissionContext::SwapChainInfo *swapchain = m_submissionContext->swapChainForSurface(rv->surface()); if (!swapchain || !swapchain->swapChain || !swapchain->renderPassDescriptor) return; // TO DO: Find a way to recycle those // Create Per Command UBO - QRhiBuffer *commandUBO = m_submissionContext->rhi()->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(CommandUBO)); - QRhiBuffer *rvUBO = m_submissionContext->rhi()->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(RenderViewUBO)); + QRhiBuffer *commandUBO = m_submissionContext->rhi()->newBuffer( + QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(CommandUBO)); + QRhiBuffer *rvUBO = m_submissionContext->rhi()->newBuffer( + QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(RenderViewUBO)); commandUBO->build(); rvUBO->build(); graphicsPipeline->setCommandUBO(commandUBO); @@ -981,15 +976,17 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re QVector uboBindings; uboBindings << QRhiShaderResourceBinding::uniformBuffer( - 0, - QRhiShaderResourceBinding::VertexStage|QRhiShaderResourceBinding::FragmentStage, - rvUBO) + 0, + QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, + rvUBO) << QRhiShaderResourceBinding::uniformBuffer( - 1, - QRhiShaderResourceBinding::VertexStage|QRhiShaderResourceBinding::FragmentStage, - commandUBO); + 1, + QRhiShaderResourceBinding::VertexStage + | QRhiShaderResourceBinding::FragmentStage, + commandUBO); - // Create additional empty UBO Buffer for UBO with binding point > 1 (since we assume 0 and 1 and for Qt3D standard values) + // Create additional empty UBO Buffer for UBO with binding point > 1 (since we assume 0 and + // 1 and for Qt3D standard values) const QVector uniformBlocks = cmd.m_rhiShader->uniformBlocks(); QHash uboBuffers; for (const ShaderUniformBlock &block : uniformBlocks) { @@ -1000,36 +997,37 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re const QByteArray rawData(block.m_size, '\0'); ubo->allocate(m_submissionContext.data(), rawData, true); ok = ubo->bind(m_submissionContext.data(), RHIBuffer::UniformBuffer); - uboBuffers[block.m_binding] = {handle, ubo}; - uboBindings << QRhiShaderResourceBinding::uniformBuffer( - block.m_binding, - QRhiShaderResourceBinding::VertexStage|QRhiShaderResourceBinding::FragmentStage, - ubo->rhiBuffer()); + uboBuffers[block.m_binding] = { handle, ubo }; + uboBindings << QRhiShaderResourceBinding::uniformBuffer( + block.m_binding, + QRhiShaderResourceBinding::VertexStage + | QRhiShaderResourceBinding::FragmentStage, + ubo->rhiBuffer()); } } graphicsPipeline->setUBOs(uboBuffers); // Samplers - for (const auto& textureParameter: cmd.m_parameterPack.textures()) { - const auto handle = m_RHIResourceManagers->rhiTextureManager()->getOrAcquireHandle(textureParameter.nodeId); + for (const auto &textureParameter : cmd.m_parameterPack.textures()) { + const auto handle = m_RHIResourceManagers->rhiTextureManager()->getOrAcquireHandle( + textureParameter.nodeId); const auto textureData = m_RHIResourceManagers->rhiTextureManager()->data(handle); - for (const ShaderAttribute& samplerAttribute : cmd.m_rhiShader->samplers()) { + for (const ShaderAttribute &samplerAttribute : cmd.m_rhiShader->samplers()) { if (samplerAttribute.m_nameId == textureParameter.glslNameId) { const auto rhiTexture = textureData->getRhiTexture(); const auto rhiSampler = textureData->getRhiSampler(); if (rhiTexture && rhiSampler) { uboBindings.push_back(QRhiShaderResourceBinding::sampledTexture( - samplerAttribute.m_location, - QRhiShaderResourceBinding::FragmentStage, - rhiTexture, - rhiSampler)); + samplerAttribute.m_location, + QRhiShaderResourceBinding::FragmentStage, rhiTexture, rhiSampler)); } } } } - QRhiShaderResourceBindings *shaderResourceBindings = m_submissionContext->rhi()->newShaderResourceBindings(); + QRhiShaderResourceBindings *shaderResourceBindings = + m_submissionContext->rhi()->newShaderResourceBindings(); assert(shaderResourceBindings); shaderResourceBindings->setBindings(uboBindings.cbegin(), uboBindings.cend()); @@ -1048,16 +1046,14 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re assert(vertexShader.isValid()); assert(fragmentShader.isValid()); - pipeline->setShaderStages({ - { QRhiShaderStage::Vertex, vertexShader }, - { QRhiShaderStage::Fragment, fragmentShader } - }); + pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertexShader }, + { QRhiShaderStage::Fragment, fragmentShader } }); QVarLengthArray inputBindings; QVarLengthArray rhiAttributes; const auto geom = cmd.m_geometry; - const auto& attributes = geom->attributes(); + const auto &attributes = geom->attributes(); struct BufferBinding { @@ -1068,28 +1064,28 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re }; QVector uniqueBindings; - auto rhiAttributeType = [] (Attribute *attr) { + auto rhiAttributeType = [](Attribute *attr) { switch (attr->vertexBaseType()) { case QAttribute::Byte: case QAttribute::UnsignedByte: { if (attr->vertexSize() == 1) return QRhiVertexInputAttribute::UNormByte; - if (attr->vertexSize() == 2) - return QRhiVertexInputAttribute::UNormByte2; - if (attr->vertexSize() == 4) - return QRhiVertexInputAttribute::UNormByte4; - Q_FALLTHROUGH(); + if (attr->vertexSize() == 2) + return QRhiVertexInputAttribute::UNormByte2; + if (attr->vertexSize() == 4) + return QRhiVertexInputAttribute::UNormByte4; + Q_FALLTHROUGH(); } case QAttribute::Float: { if (attr->vertexSize() == 1) return QRhiVertexInputAttribute::Float; - if (attr->vertexSize() == 2) - return QRhiVertexInputAttribute::Float2; - if (attr->vertexSize() == 3) - return QRhiVertexInputAttribute::Float3; - if (attr->vertexSize() == 4) - return QRhiVertexInputAttribute::Float4; - Q_FALLTHROUGH(); + if (attr->vertexSize() == 2) + return QRhiVertexInputAttribute::Float2; + if (attr->vertexSize() == 3) + return QRhiVertexInputAttribute::Float3; + if (attr->vertexSize() == 4) + return QRhiVertexInputAttribute::Float4; + Q_FALLTHROUGH(); } default: qWarning() << "Attribute type not handles by RHI"; @@ -1097,33 +1093,32 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re } }; - // QRhiVertexInputBinding -> specifies the stride of an attribute, whether it's per vertex or per instance and the instance divisor - // QRhiVertexInputAttribute -> specifies the format of the attribute (offset, type), the shader location and the index of the binding + // QRhiVertexInputBinding -> specifies the stride of an attribute, whether it's per vertex + // or per instance and the instance divisor QRhiVertexInputAttribute -> specifies the format + // of the attribute (offset, type), the shader location and the index of the binding // QRhiCommandBuffer::VertexInput -> binds a buffer to a binding QHash attributeNameToBinding; for (Qt3DCore::QNodeId attribute_id : attributes) { - Attribute* attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); + Attribute *attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); if (attrib->attributeType() == QAttribute::VertexAttribute) { const bool isPerInstanceAttr = attrib->divisor() != 0; - const QRhiVertexInputBinding::Classification classification = isPerInstanceAttr ? - QRhiVertexInputBinding::PerInstance : - QRhiVertexInputBinding::PerVertex; - const BufferBinding binding { attrib->bufferId(), - attrib->byteStride(), + const QRhiVertexInputBinding::Classification classification = isPerInstanceAttr + ? QRhiVertexInputBinding::PerInstance + : QRhiVertexInputBinding::PerVertex; + const BufferBinding binding { attrib->bufferId(), attrib->byteStride(), classification, - isPerInstanceAttr ? attrib->divisor() : 1U - }; - - const auto it = std::find_if(uniqueBindings.begin(), - uniqueBindings.end(), - [binding] (const BufferBinding &a) { - return binding.bufferId == a.bufferId && - binding.stride == a.stride && - binding.classification == a.classification && - binding.attributeDivisor == a.attributeDivisor; - }); + isPerInstanceAttr ? attrib->divisor() : 1U }; + + const auto it = + std::find_if(uniqueBindings.begin(), uniqueBindings.end(), + [binding](const BufferBinding &a) { + return binding.bufferId == a.bufferId + && binding.stride == a.stride + && binding.classification == a.classification + && binding.attributeDivisor == a.attributeDivisor; + }); int bindingIndex = uniqueBindings.size(); if (it == uniqueBindings.end()) @@ -1133,8 +1128,7 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re rhiAttributes.push_back({ bindingIndex, locationForAttribute(attrib, cmd.m_rhiShader), - rhiAttributeType(attrib), - attrib->byteOffset() }); + rhiAttributeType(attrib), attrib->byteOffset() }); attributeNameToBinding.insert(attrib->nameId(), bindingIndex); } @@ -1149,7 +1143,8 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re << binding.classification << binding.attributeDivisor; */ - inputBindings[i] = QRhiVertexInputBinding{binding.stride, binding.classification, int(binding.attributeDivisor) }; + inputBindings[i] = QRhiVertexInputBinding { binding.stride, binding.classification, + int(binding.attributeDivisor) }; } QRhiVertexInputLayout inputLayout; @@ -1166,7 +1161,6 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re // Render States m_submissionContext->applyStateSet(renderState, pipeline); - ok = pipeline->build(); assert(ok); } @@ -1177,7 +1171,8 @@ void Renderer::updateGraphicsPipeline(RenderCommand& cmd, RenderView *rv, int re } // When this function is called, we must not be processing the commands for frame n+1 -QVector Renderer::prepareCommandsSubmission(const QVector &renderViews) +QVector +Renderer::prepareCommandsSubmission(const QVector &renderViews) { // TO DO: Find a central place to initialize RHI resources const int renderViewCount = renderViews.size(); @@ -1198,8 +1193,7 @@ QVector Renderer::prepareCommandsSubmission(const QVector RenderView *curRV = renderViews.at(i); if (refRV->renderTargetId() == curRV->renderTargetId()) { sameRenderTargetRVs.push_back(curRV); - } - else + } else break; } @@ -1217,12 +1211,15 @@ QVector Renderer::prepareCommandsSubmission(const QVector for (RenderCommand &command : commands) { // Update/Create GraphicsPipelines if (command.m_type == RenderCommand::Draw) { - Geometry *rGeometry = m_nodesManager->data(command.m_geometry); - GeometryRenderer *rGeometryRenderer = m_nodesManager->data(command.m_geometryRenderer); + Geometry *rGeometry = + m_nodesManager->data(command.m_geometry); + GeometryRenderer *rGeometryRenderer = + m_nodesManager->data( + command.m_geometryRenderer); // By this time shaders should have been loaded - RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command.m_shaderId); - if (!shader) - { + RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource( + command.m_shaderId); + if (!shader) { qDebug() << "Warning: could not find shader"; continue; } @@ -1245,7 +1242,8 @@ QVector Renderer::prepareCommandsSubmission(const QVector } else if (command.m_type == RenderCommand::Compute) { RHI_UNIMPLEMENTED; // By this time shaders have been loaded - RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command.m_shaderId); + RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource( + command.m_shaderId); command.m_rhiShader = shader; Q_ASSERT(shader); @@ -1274,7 +1272,7 @@ QVector Renderer::prepareCommandsSubmission(const QVector void Renderer::lookForDirtyBuffers() { const QVector activeBufferHandles = m_nodesManager->bufferManager()->activeHandles(); - for (const HBuffer &handle: activeBufferHandles) { + for (const HBuffer &handle : activeBufferHandles) { Buffer *buffer = m_nodesManager->bufferManager()->data(handle); if (buffer->isDirty()) m_dirtyBuffers.push_back(handle); @@ -1303,7 +1301,7 @@ void Renderer::lookForDirtyTextures() TextureImageManager *imageManager = m_nodesManager->textureImageManager(); const QVector activeTextureImageHandles = imageManager->activeHandles(); Qt3DCore::QNodeIdVector dirtyImageIds; - for (const HTextureImage &handle: activeTextureImageHandles) { + for (const HTextureImage &handle : activeTextureImageHandles) { TextureImage *image = imageManager->data(handle); if (image->isDirty()) { dirtyImageIds.push_back(image->peerId()); @@ -1313,12 +1311,12 @@ void Renderer::lookForDirtyTextures() TextureManager *textureManager = m_nodesManager->textureManager(); const QVector activeTextureHandles = textureManager->activeHandles(); - for (const HTexture &handle: activeTextureHandles) { + for (const HTexture &handle : activeTextureHandles) { Texture *texture = textureManager->data(handle); const QNodeIdVector imageIds = texture->textureImageIds(); // Does the texture reference any of the dirty texture images? - for (const QNodeId imageId: imageIds) { + for (const QNodeId imageId : imageIds) { if (dirtyImageIds.contains(imageId)) { texture->addDirtyFlag(Texture::DirtyImageGenerators); break; @@ -1339,21 +1337,26 @@ void Renderer::lookForDirtyTextures() void Renderer::reloadDirtyShaders() { Q_ASSERT(isRunning()); - const QVector activeTechniques = m_nodesManager->techniqueManager()->activeHandles(); - const QVector activeBuilders = m_nodesManager->shaderBuilderManager()->activeHandles(); + const QVector activeTechniques = + m_nodesManager->techniqueManager()->activeHandles(); + const QVector activeBuilders = + m_nodesManager->shaderBuilderManager()->activeHandles(); for (const HTechnique &techniqueHandle : activeTechniques) { Technique *technique = m_nodesManager->techniqueManager()->data(techniqueHandle); // If api of the renderer matches the one from the technique if (technique->isCompatibleWithRenderer()) { const auto passIds = technique->renderPasses(); for (const QNodeId &passId : passIds) { - RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId); - HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram()); + RenderPass *renderPass = + m_nodesManager->renderPassManager()->lookupResource(passId); + HShader shaderHandle = + m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram()); Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle); ShaderBuilder *shaderBuilder = nullptr; for (const HShaderBuilder &builderHandle : activeBuilders) { - ShaderBuilder *builder = m_nodesManager->shaderBuilderManager()->data(builderHandle); + ShaderBuilder *builder = + m_nodesManager->shaderBuilderManager()->data(builderHandle); if (builder->shaderProgramId() == shader->peerId()) { shaderBuilder = builder; break; @@ -1392,11 +1395,13 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) // Sync Shader const QVector activeShaders = m_nodesManager->shaderManager()->activeHandles(); - for (const HShader &handle :activeShaders) { + for (const HShader &handle : activeShaders) { Shader *s = m_nodesManager->shaderManager()->data(handle); if (s->requiresFrontendSync()) { - QShaderProgram *frontend = static_cast(manager->lookupNode(s->peerId())); - QShaderProgramPrivate *dFrontend = static_cast(QNodePrivate::get(frontend)); + QShaderProgram *frontend = + static_cast(manager->lookupNode(s->peerId())); + QShaderProgramPrivate *dFrontend = + static_cast(QNodePrivate::get(frontend)); s->unsetRequiresFrontendSync(); dFrontend->setStatus(s->status()); dFrontend->setLog(s->log()); @@ -1406,8 +1411,10 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) // Sync ShaderBuilder const QVector shaderBuilderUpdates = std::move(m_shaderBuilderUpdates); for (const ShaderBuilderUpdate &update : shaderBuilderUpdates) { - QShaderProgramBuilder *builder = static_cast(manager->lookupNode(update.builderId)); - QShaderProgramBuilderPrivate *dBuilder = static_cast(QNodePrivate::get(builder)); + QShaderProgramBuilder *builder = + static_cast(manager->lookupNode(update.builderId)); + QShaderProgramBuilderPrivate *dBuilder = + static_cast(QNodePrivate::get(builder)); dBuilder->setShaderCode(update.shaderCode, update.shaderType); } } @@ -1415,10 +1422,11 @@ void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) // Executed in a job (in main thread when jobs are done) void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager) { - const QVector> updateTextureProperties = std::move(m_updatedTextureProperties); + const QVector> + updateTextureProperties = std::move(m_updatedTextureProperties); for (const auto &pair : updateTextureProperties) { const Qt3DCore::QNodeIdVector targetIds = pair.second; - for (const Qt3DCore::QNodeId &targetId: targetIds) { + for (const Qt3DCore::QNodeId &targetId : targetIds) { // Lookup texture Texture *t = m_nodesManager->textureManager()->lookupResource(targetId); // If backend texture is Dirty, some property has changed and the properties we are @@ -1426,24 +1434,26 @@ void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager) if (t == nullptr || t->dirtyFlags() != Texture::NotDirty) continue; - QAbstractTexture *texture = static_cast(manager->lookupNode(targetId)); + QAbstractTexture *texture = + static_cast(manager->lookupNode(targetId)); if (!texture) continue; - const TextureProperties &properties = pair.first.properties; - - const bool blocked = texture->blockNotifications(true); - texture->setWidth(properties.width); - texture->setHeight(properties.height); - texture->setDepth(properties.depth); - texture->setLayers(properties.layers); - texture->setFormat(properties.format); - texture->blockNotifications(blocked); - - QAbstractTexturePrivate *dTexture = static_cast(QNodePrivate::get(texture)); - - dTexture->setStatus(properties.status); - dTexture->setHandleType(pair.first.handleType); - dTexture->setHandle(pair.first.handle); + const TextureProperties &properties = pair.first.properties; + + const bool blocked = texture->blockNotifications(true); + texture->setWidth(properties.width); + texture->setHeight(properties.height); + texture->setDepth(properties.depth); + texture->setLayers(properties.layers); + texture->setFormat(properties.format); + texture->blockNotifications(blocked); + + QAbstractTexturePrivate *dTexture = + static_cast(QNodePrivate::get(texture)); + + dTexture->setStatus(properties.status); + dTexture->setHandleType(pair.first.handleType); + dTexture->setHandle(pair.first.handle); } } } @@ -1459,11 +1469,13 @@ void Renderer::sendDisablesToFrontend(Qt3DCore::QAspectManager *manager) } // Compute Commands - const QVector activeCommands = m_nodesManager->computeJobManager()->activeHandles(); - for (const HComputeCommand &handle :activeCommands) { + const QVector activeCommands = + m_nodesManager->computeJobManager()->activeHandles(); + for (const HComputeCommand &handle : activeCommands) { ComputeCommand *c = m_nodesManager->computeJobManager()->data(handle); if (c->hasReachedFrameCount()) { - QComputeCommand *frontend = static_cast(manager->lookupNode(c->peerId())); + QComputeCommand *frontend = + static_cast(manager->lookupNode(c->peerId())); frontend->setEnabled(false); c->resetHasReachedFrameCount(); } @@ -1484,7 +1496,7 @@ void Renderer::updateResources() { { const QVector dirtyBufferHandles = std::move(m_dirtyBuffers); - for (const HBuffer &handle: dirtyBufferHandles) { + for (const HBuffer &handle : dirtyBufferHandles) { Buffer *buffer = m_nodesManager->bufferManager()->data(handle); // Can be null when using Scene3D rendering @@ -1505,7 +1517,7 @@ void Renderer::updateResources() { const QVector dirtyShaderHandles = std::move(m_dirtyShaders); ShaderManager *shaderManager = m_nodesManager->shaderManager(); - for (const HShader &handle: dirtyShaderHandles) { + for (const HShader &handle : dirtyShaderHandles) { Shader *shader = shaderManager->data(handle); // Can be null when using Scene3D rendering @@ -1513,18 +1525,19 @@ void Renderer::updateResources() continue; // Compile shader - m_submissionContext->loadShader(shader, shaderManager, m_RHIResourceManagers->rhiShaderManager()); + m_submissionContext->loadShader(shader, shaderManager, + m_RHIResourceManagers->rhiShaderManager()); } } #endif { const QVector activeTextureHandles = std::move(m_dirtyTextures); - for (const HTexture &handle: activeTextureHandles) { + for (const HTexture &handle : activeTextureHandles) { Texture *texture = m_nodesManager->textureManager()->data(handle); // Can be null when using Scene3D rendering - if (texture == nullptr) + if (texture == nullptr) continue; // Create or Update RHITexture (the RHITexture instance is created if required @@ -1543,19 +1556,24 @@ void Renderer::updateResources() RHITexture *glTexture = rhiTextureManager->data(glTextureHandle); // We create/update the actual GL texture using the GL context at this point - const RHITexture::TextureUpdateInfo info = glTexture->createOrUpdateRhiTexture(m_submissionContext.data()); + const RHITexture::TextureUpdateInfo info = + glTexture->createOrUpdateRhiTexture(m_submissionContext.data()); // RHITexture creation provides us width/height/format ... information - // 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(glTexture) }; + // 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(glTexture) + }; // Store properties and referenceTextureIds if (info.wasUpdated) { Texture::TextureUpdateInfo updateInfo; updateInfo.properties = info.properties; updateInfo.handleType = QAbstractTexture::OpenGLTextureId; -// updateInfo.handle = info.texture ? QVariant(info.texture->textureId()) : QVariant(); - m_updatedTextureProperties.push_back({updateInfo, referenceTextureIds}); + // updateInfo.handle = info.texture ? + // QVariant(info.texture->textureId()) : QVariant(); + m_updatedTextureProperties.push_back({ updateInfo, referenceTextureIds }); } } } @@ -1610,11 +1628,13 @@ void Renderer::updateTexture(Texture *texture) images.reserve(textureImageIds.size()); // TODO: Move this into RHITexture directly for (const QNodeId textureImageId : textureImageIds) { - const TextureImage *img = m_nodesManager->textureImageManager()->lookupResource(textureImageId); + const TextureImage *img = + m_nodesManager->textureImageManager()->lookupResource(textureImageId); if (img == nullptr) { qWarning() << Q_FUNC_INFO << "invalid TextureImage handle"; } else { - RHITexture::Image glImg {img->dataGenerator(), img->layer(), img->mipLevel(), img->face()}; + RHITexture::Image glImg { img->dataGenerator(), img->layer(), img->mipLevel(), + img->face() }; images.push_back(glImg); } } @@ -1676,24 +1696,24 @@ void Renderer::downloadGLBuffers() // Happens in RenderThread context when all RenderViewJobs are done // Returns the id of the last bound FBO -Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector &rhiPassesInfo) +Renderer::ViewSubmissionResultData +Renderer::submitRenderViews(const QVector &rhiPassesInfo) { QElapsedTimer timer; quint64 queueElapsed = 0; timer.start(); quint64 frameElapsed = queueElapsed; - m_lastFrameCorrect.storeRelaxed(1); // everything fine until now..... + m_lastFrameCorrect.storeRelaxed(1); // everything fine until now..... qCDebug(Memory) << Q_FUNC_INFO << "rendering frame "; // We might not want to render on the default FBO - uint lastBoundFBOId = 0;// m_submissionContext->boundFrameBufferObject(); + uint lastBoundFBOId = 0; // m_submissionContext->boundFrameBufferObject(); QSurface *surface = nullptr; QSurface *previousSurface = nullptr; QSurface *lastUsedSurface = nullptr; - const int rhiPassesCount = rhiPassesInfo.size(); for (int i = 0; i < rhiPassesCount; ++i) { @@ -1702,7 +1722,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectorsurface(); if (previousSurface) break; @@ -1731,8 +1751,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectordefaultFBO() - && surfaceLock.isSurfaceValid() - && m_shouldSwapBuffers; + && surfaceLock.isSurfaceValid() && m_shouldSwapBuffers; // We only call swap buffer if we are sure the previous surface is still valid m_submissionContext->endDrawing(swapBuffers); } @@ -1751,80 +1770,91 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectormemoryBarrier() != QMemoryBarrier::None) -// qWarning() << "RHI Doesn't support MemoryBarrier"; + // if (renderView->memoryBarrier() != QMemoryBarrier::None) + // qWarning() << "RHI Doesn't support MemoryBarrier"; // Set RenderTarget ... // Activate RenderTarget { m_submissionContext->activateRenderTarget(rhiPassInfo.renderTargetId, - rhiPassInfo.attachmentPack, - lastBoundFBOId); + rhiPassInfo.attachmentPack, lastBoundFBOId); } // Execute the render commands if (!executeCommandsSubmission(rhiPassInfo)) - m_lastFrameCorrect.storeRelaxed(0); // something went wrong; make sure to render the next frame! + m_lastFrameCorrect.storeRelaxed( + 0); // something went wrong; make sure to render the next frame! // executeCommandsSubmission takes care of restoring the stateset to the value // of gc->currentContext() at the moment it was called (either // renderViewStateSet or m_defaultRenderStateSet) -// if (!renderView->renderCaptureNodeId().isNull()) { -// RHI_UNIMPLEMENTED; -//* const QRenderCaptureRequest request = renderView->renderCaptureRequest(); -//* const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize()); -//* QRect rect(QPoint(0, 0), size); -//* if (!request.rect.isEmpty()) -//* rect = rect.intersected(request.rect); -//* QImage image; -//* if (!rect.isEmpty()) { -//* // Bind fbo as read framebuffer -//* m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), GraphicsHelperInterface::FBORead); -//* image = m_submissionContext->readFramebuffer(rect); -//* } else { -//* qWarning() << "Requested capture rectangle is outside framebuffer"; -//* } -//* Render::RenderCapture *renderCapture = -//* static_cast(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); -//* renderCapture->addRenderCapture(request.captureId, image); -//* if (!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId())) -//* m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId()); -// } - -// if (renderView->isDownloadBuffersEnable()) -// { -// RHI_UNIMPLEMENTED; -////* downloadGLBuffers(); -// } - -// // Perform BlitFramebuffer operations -// if (renderView->hasBlitFramebufferInfo()) { -// RHI_UNIMPLEMENTED; -////* const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); -////* const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; -////* const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId; -////* const QRect inputRect = blitFramebufferInfo.sourceRect; -////* const QRect outputRect = blitFramebufferInfo.destinationRect; -////* const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint; -////* const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint; -////* const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod; -////* m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId, -////* inputAttachmentPoint, outputAttachmentPoint, -////* interpolationMethod); -// } - + // if (!renderView->renderCaptureNodeId().isNull()) { + // RHI_UNIMPLEMENTED; + //* const QRenderCaptureRequest request = renderView->renderCaptureRequest(); + //* const QSize size = + //m_submissionContext->renderTargetSize(renderView->surfaceSize()); + //* QRect rect(QPoint(0, 0), size); + //* if (!request.rect.isEmpty()) + //* rect = rect.intersected(request.rect); + //* QImage image; + //* if (!rect.isEmpty()) { + //* // Bind fbo as read framebuffer + //* m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), + //GraphicsHelperInterface::FBORead); + //* image = m_submissionContext->readFramebuffer(rect); + //* } else { + //* qWarning() << "Requested capture rectangle is outside framebuffer"; + //* } + //* Render::RenderCapture *renderCapture = + //* + //static_cast(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); + //* renderCapture->addRenderCapture(request.captureId, image); + //* if + //(!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId())) + //* m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId()); + // } + + // if (renderView->isDownloadBuffersEnable()) + // { + // RHI_UNIMPLEMENTED; + ////* downloadGLBuffers(); + // } + + // // Perform BlitFramebuffer operations + // if (renderView->hasBlitFramebufferInfo()) { + // RHI_UNIMPLEMENTED; + ////* const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); + ////* const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; + ////* const QNodeId outputTargetId = + ///blitFramebufferInfo.destinationRenderTargetId; + ////* const QRect inputRect = blitFramebufferInfo.sourceRect; + ////* const QRect outputRect = blitFramebufferInfo.destinationRect; + ////* const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = + ///blitFramebufferInfo.sourceAttachmentPoint; + ////* const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = + ///blitFramebufferInfo.destinationAttachmentPoint; + ////* const QBlitFramebuffer::InterpolationMethod interpolationMethod = + ///blitFramebufferInfo.interpolationMethod; + ////* m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, + ///inputRect, outputRect, lastBoundFBOId, + ////* inputAttachmentPoint, + ///outputAttachmentPoint, + ////* interpolationMethod); + // } frameElapsed = timer.elapsed() - frameElapsed; - qCDebug(Rendering) << Q_FUNC_INFO << "Submitted RHI Passes " << i + 1 << "/" << rhiPassesCount << "in " << frameElapsed << "ms"; + qCDebug(Rendering) << Q_FUNC_INFO << "Submitted RHI Passes " << i + 1 << "/" + << rhiPassesCount << "in " << frameElapsed << "ms"; frameElapsed = timer.elapsed(); } // Bind lastBoundFBOId back. Needed also in threaded mode. - // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView - // contains RenderTargetSelector/RenderTarget + // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf + // node/renderView contains RenderTargetSelector/RenderTarget if (lastBoundFBOId != m_submissionContext->activeFBO()) { RHI_UNIMPLEMENTED; -// m_submissionContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw); + // m_submissionContext->bindFramebuffer(lastBoundFBOId, + // GraphicsHelperInterface::FBOReadAndDraw); } // Reset state and call doneCurrent if the surface @@ -1833,8 +1863,8 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectorcurrentStateSet() != m_defaultRenderStateSet) -// m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet); + // if (m_submissionContext->currentStateSet() != m_defaultRenderStateSet) + // m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet); } queueElapsed = timer.elapsed() - queueElapsed; @@ -1871,10 +1901,8 @@ bool Renderer::shouldRender() const { // Only render if something changed during the last frame, or the last frame // was not rendered successfully (or render-on-demand is disabled) - return (m_settings->renderPolicy() == QRenderSettings::Always - || m_dirtyBits.marked != 0 - || m_dirtyBits.remaining != 0 - || !m_lastFrameCorrect.loadRelaxed()); + return (m_settings->renderPolicy() == QRenderSettings::Always || m_dirtyBits.marked != 0 + || m_dirtyBits.remaining != 0 || !m_lastFrameCorrect.loadRelaxed()); } void Renderer::skipNextFrame() @@ -1891,10 +1919,11 @@ void Renderer::jobsDone(Qt3DCore::QAspectManager *manager) // called in main thread once all jobs are done running // sync captured renders to frontend - const QVector pendingCaptureIds = std::move(m_pendingRenderCaptureSendRequests); + const QVector pendingCaptureIds = + std::move(m_pendingRenderCaptureSendRequests); for (const Qt3DCore::QNodeId &id : qAsConst(pendingCaptureIds)) { - auto *backend = static_cast - (m_nodesManager->frameGraphManager()->lookupNode(id)); + auto *backend = static_cast( + m_nodesManager->frameGraphManager()->lookupNode(id)); backend->syncRenderCapturesToFrontend(manager); } @@ -1905,7 +1934,8 @@ void Renderer::jobsDone(Qt3DCore::QAspectManager *manager) sendDisablesToFrontend(manager); } -void Renderer::setPendingEvents(const QList > &mouseEvents, const QList &keyEvents) +void Renderer::setPendingEvents(const QList> &mouseEvents, + const QList &keyEvents) { QMutexLocker l(&m_frameEventsMutex); m_frameMouseEvents = mouseEvents; @@ -1916,7 +1946,7 @@ void Renderer::setPendingEvents(const QList > &mou QVector Renderer::preRenderingJobs() { if (m_sendBufferCaptureJob->hasRequests()) - return {m_sendBufferCaptureJob}; + return { m_sendBufferCaptureJob }; else return {}; } @@ -1952,7 +1982,6 @@ QVector Renderer::renderBinJobs() if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) renderBinJobs.push_back(m_textureGathererJob); - // Layer cache is dependent on layers, layer filters (hence FG structure // changes) and the enabled flag on entities const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty; @@ -1965,7 +1994,8 @@ QVector Renderer::renderBinJobs() const bool computeableDirty = dirtyBitsForFrame & AbstractRenderer::ComputeDirty; const bool renderableDirty = dirtyBitsForFrame & AbstractRenderer::GeometryDirty; const bool materialCacheNeedsToBeRebuilt = shadersDirty || materialDirty || frameGraphDirty; - const bool renderCommandsDirty = materialCacheNeedsToBeRebuilt || renderableDirty || computeableDirty; + const bool renderCommandsDirty = + materialCacheNeedsToBeRebuilt || renderableDirty || computeableDirty; // Rebuild Entity Layers list if layers are dirty @@ -2008,7 +2038,8 @@ QVector Renderer::renderBinJobs() // If we have a new RV (wasn't in the cache before, then it contains no cached data) const bool isNewRV = !m_cache.leafNodeCache.contains(leaf); builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt || isNewRV); - builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt || isNewRV); + builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt + || isNewRV); builder.setRenderCommandCacheNeedsToBeRebuilt(renderCommandsDirty || isNewRV); builder.prepareJobs(); @@ -2026,7 +2057,7 @@ QVector Renderer::renderBinJobs() } if (isRunning() && m_submissionContext->isInitialized()) { - if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty ) + if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty) renderBinJobs.push_back(m_filterCompatibleTechniqueJob); if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty) renderBinJobs.push_back(m_introspectShaderJob); @@ -2055,29 +2086,23 @@ void Renderer::performDraw(RenderCommand *command) } else { // Direct Draw Calls // TO DO: Add glMulti Draw variants - if (command->m_primitiveType == QGeometryRenderer::Patches) - { + if (command->m_primitiveType == QGeometryRenderer::Patches) { RHI_UNIMPLEMENTED; //* m_submissionContext->setVerticesPerPatch(command->m_verticesPerPatch); } - if (command->m_primitiveRestartEnabled) - { + if (command->m_primitiveRestartEnabled) { RHI_UNIMPLEMENTED; //* m_submissionContext->enablePrimitiveRestart(command->m_restartIndexValue); } // TO DO: Add glMulti Draw variants if (command->m_drawIndexed) { - cb->drawIndexed(command->m_primitiveCount, - command->m_instanceCount, - command->m_indexOffset, - command->m_indexAttributeByteOffset, + cb->drawIndexed(command->m_primitiveCount, command->m_instanceCount, + command->m_indexOffset, command->m_indexAttributeByteOffset, command->m_firstInstance); } else { - cb->draw(command->m_primitiveCount, - command->m_instanceCount, - command->m_firstVertex, + cb->draw(command->m_primitiveCount, command->m_instanceCount, command->m_firstVertex, command->m_firstInstance); } } @@ -2088,45 +2113,50 @@ void Renderer::performDraw(RenderCommand *command) qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); #endif -// if (command->m_primitiveRestartEnabled) -// m_submissionContext->disablePrimitiveRestart(); + // if (command->m_primitiveRestartEnabled) + // m_submissionContext->disablePrimitiveRestart(); } void Renderer::performCompute(const RenderView *, RenderCommand *command) { RHI_UNIMPLEMENTED; -//* { -//* RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command->m_shaderId); -//* m_submissionContext->activateShader(shader); -//* } -//* { -//* m_submissionContext->setParameters(command->m_parameterPack); -//* } -//* { -//* m_submissionContext->dispatchCompute(command->m_workGroups[0], -//* command->m_workGroups[1], -//* command->m_workGroups[2]); -//* } -//* // HACK: Reset the compute flag to dirty -//* m_dirtyBits.marked |= AbstractRenderer::ComputeDirty; - -//* #if defined(QT3D_RENDER_ASPECT_RHI_DEBUG) -//* int err = m_submissionContext->openGLContext()->functions()->glGetError(); -//* if (err) -//* qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); -//* #endif + //* { + //* RHIShader *shader = + //m_RHIResourceManagers->rhiShaderManager()->lookupResource(command->m_shaderId); + //* m_submissionContext->activateShader(shader); + //* } + //* { + //* m_submissionContext->setParameters(command->m_parameterPack); + //* } + //* { + //* m_submissionContext->dispatchCompute(command->m_workGroups[0], + //* command->m_workGroups[1], + //* command->m_workGroups[2]); + //* } + //* // HACK: Reset the compute flag to dirty + //* m_dirtyBits.marked |= AbstractRenderer::ComputeDirty; + + //* #if defined(QT3D_RENDER_ASPECT_RHI_DEBUG) + //* int err = m_submissionContext->openGLContext()->functions()->glGetError(); + //* if (err) + //* qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); + //* #endif } static auto rhiIndexFormat(QAttribute::VertexBaseType type) { switch (type) { - case QAttribute::VertexBaseType ::UnsignedShort: return QRhiCommandBuffer::IndexUInt16; - case QAttribute::VertexBaseType ::UnsignedInt: return QRhiCommandBuffer::IndexUInt32; - default: std::abort(); + case QAttribute::VertexBaseType ::UnsignedShort: + return QRhiCommandBuffer::IndexUInt16; + case QAttribute::VertexBaseType ::UnsignedInt: + return QRhiCommandBuffer::IndexUInt32; + default: + std::abort(); } } -bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand& command) +bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView *rv, + RenderCommand &command) { RHIGraphicsPipeline *graphicsPipeline = command.pipeline; if (!graphicsPipeline) @@ -2134,21 +2164,21 @@ bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView * // Create the vertex input description - // Note: we have to bind the buffers here -> which will trigger the actual // upload, as this is the only place where we know about the usage type of the buffers const auto geom = command.m_geometry; - const auto& attributes = geom->attributes(); + const auto &attributes = geom->attributes(); const QRhiVertexInputLayout layout = graphicsPipeline->pipeline()->vertexInputLayout(); const int bindingAttributeCount = std::distance(layout.cbeginBindings(), layout.cendBindings()); command.vertex_input.resize(bindingAttributeCount); for (Qt3DCore::QNodeId attribute_id : attributes) { // TODO isn't there a more efficient way than doing three hash lookups ? - Attribute* attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); + Attribute *attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attrib->bufferId()); - RHIBuffer* hbuf = m_RHIResourceManagers->rhiBufferManager()->lookupResource(buffer->peerId()); + RHIBuffer *hbuf = + m_RHIResourceManagers->rhiBufferManager()->lookupResource(buffer->peerId()); switch (attrib->attributeType()) { case QAttribute::VertexAttribute: { hbuf->bind(&*m_submissionContext, RHIBuffer::Type::ArrayBuffer); @@ -2158,7 +2188,7 @@ bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView * // We need to reference a binding, a buffer and an offset which is always = 0 // as Qt3D only assumes interleaved or continuous data but not // buffer where first half of it is attribute1 and second half attribute2 - command.vertex_input[bindingIndex] = {hbuf->rhiBuffer(), 0}; + command.vertex_input[bindingIndex] = { hbuf->rhiBuffer(), 0 }; break; } case QAttribute::IndexAttribute: { @@ -2176,7 +2206,7 @@ bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView * } } - for (const BlockToUBO& pack : command.m_parameterPack.uniformBuffers()) { + for (const BlockToUBO &pack : command.m_parameterPack.uniformBuffers()) { Buffer *cpuBuffer = nodeManagers()->bufferManager()->lookupResource(pack.m_bufferID); RHIBuffer *ubo = m_submissionContext->rhiBufferForRenderBuffer(cpuBuffer); ubo->bind(&*m_submissionContext, RHIBuffer::UniformBuffer); @@ -2185,54 +2215,48 @@ bool Renderer::uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView * return true; } -namespace -{ -void printUpload(const UniformValue& value, - const QShaderDescription::BlockVariable& member) -{ - switch (member.type) - { - case QShaderDescription::VariableType::Int: - qDebug() << "Updating" << member.name << "with int data: " << *value.constData() << " (offset: " << member.offset << ", size: " << member.size << ")"; - break; - case QShaderDescription::VariableType::Float: - qDebug() << "Updating" << member.name << "with float data: " << *value.constData() << " (offset: " << member.offset << ", size: " << member.size << ")"; - break; - case QShaderDescription::VariableType::Vec2: - qDebug() << "Updating" << member.name << "with vec2 data: " - << value.constData()[0] << ", " - << value.constData()[1] << " (offset: " << member.offset << ", size: " << member.size << ")"; - ; - break; - case QShaderDescription::VariableType::Vec3: - qDebug() << "Updating" << member.name << "with vec3 data: " - << value.constData()[0] << ", " - << value.constData()[1] << ", " - << value.constData()[2] << " (offset: " << member.offset << ", size: " << member.size << ")"; - ; - break; - case QShaderDescription::VariableType::Vec4: - qDebug() << "Updating" << member.name << "with vec4 data: " - << value.constData()[0] << ", " - << value.constData()[1] << ", " - << value.constData()[2] << ", " - << value.constData()[3] << " (offset: " << member.offset << ", size: " << member.size << ")"; - ; - break; - default: - qDebug() << "Updating" << member.name << "with data: " << value.constData(); - break; - } -} - -void uploadUniform( - SubmissionContext& submissionContext, - const PackUniformHash &uniforms, - const RHIShader::UBO_Member& uboMember, - const QHash& uboBuffers, - const QString& uniformName, - const QShaderDescription::BlockVariable& member, - int arrayOffset = 0) +namespace { +void printUpload(const UniformValue &value, const QShaderDescription::BlockVariable &member) +{ + switch (member.type) { + case QShaderDescription::VariableType::Int: + qDebug() << "Updating" << member.name << "with int data: " << *value.constData() + << " (offset: " << member.offset << ", size: " << member.size << ")"; + break; + case QShaderDescription::VariableType::Float: + qDebug() << "Updating" << member.name << "with float data: " << *value.constData() + << " (offset: " << member.offset << ", size: " << member.size << ")"; + break; + case QShaderDescription::VariableType::Vec2: + qDebug() << "Updating" << member.name << "with vec2 data: " << value.constData()[0] + << ", " << value.constData()[1] << " (offset: " << member.offset + << ", size: " << member.size << ")"; + ; + break; + case QShaderDescription::VariableType::Vec3: + qDebug() << "Updating" << member.name << "with vec3 data: " << value.constData()[0] + << ", " << value.constData()[1] << ", " << value.constData()[2] + << " (offset: " << member.offset << ", size: " << member.size << ")"; + ; + break; + case QShaderDescription::VariableType::Vec4: + qDebug() << "Updating" << member.name << "with vec4 data: " << value.constData()[0] + << ", " << value.constData()[1] << ", " << value.constData()[2] + << ", " << value.constData()[3] << " (offset: " << member.offset + << ", size: " << member.size << ")"; + ; + break; + default: + qDebug() << "Updating" << member.name << "with data: " << value.constData(); + break; + } +} + +void uploadUniform(SubmissionContext &submissionContext, const PackUniformHash &uniforms, + const RHIShader::UBO_Member &uboMember, + const QHash &uboBuffers, + const QString &uniformName, const QShaderDescription::BlockVariable &member, + int arrayOffset = 0) { const int uniformNameId = StringToInt::lookupId(uniformName); @@ -2244,7 +2268,7 @@ void uploadUniform( // Update UBO with uniform value Q_ASSERT(uboBuffers.contains(block.m_binding)); - const RHIGraphicsPipeline::UBOBuffer& ubo = uboBuffers[block.m_binding]; + const RHIGraphicsPipeline::UBOBuffer &ubo = uboBuffers[block.m_binding]; RHIBuffer *buffer = ubo.buffer; // TODO we should maybe have this thread_local to not reallocate memory every time @@ -2257,7 +2281,8 @@ void uploadUniform( } } -bool Renderer::uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, const RenderCommand &command) +bool Renderer::uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, + const RenderCommand &command) { RHIGraphicsPipeline *pipeline = command.pipeline; if (!pipeline) @@ -2265,20 +2290,23 @@ bool Renderer::uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, // Upload UBO data for the Command QRhiBuffer *commandUBO = pipeline->commandUBO(); - m_submissionContext->m_currentUpdates->updateDynamicBuffer(commandUBO, 0, sizeof(CommandUBO), &command.m_commandUBO); + m_submissionContext->m_currentUpdates->updateDynamicBuffer(commandUBO, 0, sizeof(CommandUBO), + &command.m_commandUBO); // We have to update the RV UBO once per graphics pipeline QRhiBuffer *rvUBO = pipeline->renderViewUBO(); - m_submissionContext->m_currentUpdates->updateDynamicBuffer(rvUBO, 0, sizeof(RenderViewUBO), rv->renderViewUBO()); + m_submissionContext->m_currentUpdates->updateDynamicBuffer(rvUBO, 0, sizeof(RenderViewUBO), + rv->renderViewUBO()); // Upload UBO for custom parameters { - RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command.m_shaderId); + RHIShader *shader = + m_RHIResourceManagers->rhiShaderManager()->lookupResource(command.m_shaderId); if (!shader) return true; - const QVector& uboMembers = shader->uboMembers(); - const QHash& uboBuffers = pipeline->ubos(); + const QVector &uboMembers = shader->uboMembers(); + const QHash &uboBuffers = pipeline->ubos(); const ShaderParameterPack ¶meterPack = command.m_parameterPack; const PackUniformHash &uniforms = parameterPack.uniforms(); @@ -2290,23 +2318,26 @@ bool Renderer::uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, if (!member.structMembers.empty()) { const int arr0 = member.arrayDims[0]; for (int i = 0; i < arr0; i++) { - for (const QShaderDescription::BlockVariable& structMember : member.structMembers) { - const QString processedName = member.name + "[" + QString::number(i) + "]." + structMember.name; - uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, processedName, structMember, i * member.size / arr0); + for (const QShaderDescription::BlockVariable &structMember : + member.structMembers) { + const QString processedName = member.name + "[" + QString::number(i) + + "]." + structMember.name; + uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, + processedName, structMember, i * member.size / arr0); } } } else { - uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, member.name, member); + uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, + member.name, member); } - } - else - { - uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, member.name, member); + } else { + uploadUniform(*m_submissionContext, uniforms, uboMember, uboBuffers, + member.name, member); } } } // Upload changes to GPU Buffer - for (const RHIGraphicsPipeline::UBOBuffer& ubo : uboBuffers) { + for (const RHIGraphicsPipeline::UBOBuffer &ubo : uboBuffers) { // Binding triggers the upload ubo.buffer->bind(m_submissionContext.data(), RHIBuffer::UniformBuffer); } @@ -2314,7 +2345,8 @@ bool Renderer::uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, return true; } -bool Renderer::performDraw(QRhiCommandBuffer *cb, const QRhiViewport& vp, const QRhiScissor* scissor, const RenderCommand& command) +bool Renderer::performDraw(QRhiCommandBuffer *cb, const QRhiViewport &vp, + const QRhiScissor *scissor, const RenderCommand &command) { RHIGraphicsPipeline *pipeline = command.pipeline; if (!pipeline) @@ -2324,25 +2356,21 @@ bool Renderer::performDraw(QRhiCommandBuffer *cb, const QRhiViewport& vp, const cb->setGraphicsPipeline(pipeline->pipeline()); cb->setViewport(vp); if (scissor) - cb->setScissor(*scissor); + cb->setScissor(*scissor); cb->setShaderResources(pipeline->pipeline()->shaderResourceBindings()); // Send the draw command if (Q_UNLIKELY(!command.indexBuffer)) { cb->setVertexInput(0, command.vertex_input.size(), command.vertex_input.data()); - cb->draw(command.m_primitiveCount, - command.m_instanceCount, - command.m_firstVertex, + cb->draw(command.m_primitiveCount, command.m_instanceCount, command.m_firstVertex, command.m_firstInstance); } else { auto indexFormat = rhiIndexFormat(command.indexAttribute->vertexBaseType()); auto indexOffset = command.indexAttribute->byteOffset(); - cb->setVertexInput(0, command.vertex_input.size(), command.vertex_input.data(), command.indexBuffer, indexOffset, indexFormat); - cb->drawIndexed(command.m_primitiveCount, - command.m_instanceCount, - command.m_indexOffset, - command.m_indexAttributeByteOffset, - command.m_firstInstance); + cb->setVertexInput(0, command.vertex_input.size(), command.vertex_input.data(), + command.indexBuffer, indexOffset, indexFormat); + cb->drawIndexed(command.m_primitiveCount, command.m_instanceCount, command.m_indexOffset, + command.m_indexAttributeByteOffset, command.m_firstInstance); } return true; } @@ -2353,7 +2381,7 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo) { bool allCommandsIssued = true; - const QVector& renderViews = passInfo.rvs; + const QVector &renderViews = passInfo.rvs; QColor clearColor; QRhiDepthStencilClearValue clearDepthStencil; @@ -2385,14 +2413,15 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo) } // TO DO: should be moved elsewhere // Perform compute actions -// cb->beginComputePass(m_submissionContext->m_currentUpdates); -// for (RenderCommand &command : commands) { -// if (command.m_type == RenderCommand::Compute) { -// performCompute(rv, &command); -// } -// } -// cb->endComputePass(); -// m_submissionContext->m_currentUpdates = m_submissionContext->rhi()->nextResourceUpdateBatch(); + // cb->beginComputePass(m_submissionContext->m_currentUpdates); + // for (RenderCommand &command : commands) { + // if (command.m_type == RenderCommand::Compute) { + // performCompute(rv, &command); + // } + // } + // cb->endComputePass(); + // m_submissionContext->m_currentUpdates = + // m_submissionContext->rhi()->nextResourceUpdateBatch(); // Draw the commands @@ -2400,7 +2429,8 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo) QRhiRenderTarget *renderTarget = m_submissionContext->currentFrameRenderTarget(); // Begin pass - cb->beginPass(renderTarget, clearColor, clearDepthStencil, m_submissionContext->m_currentUpdates); + cb->beginPass(renderTarget, clearColor, clearDepthStencil, + m_submissionContext->m_currentUpdates); // Per Pass Global States for (RenderView *rv : renderViews) { @@ -2410,30 +2440,30 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo) bool hasScissor = false; { const float x = rv->viewport().x() * rv->surfaceSize().width(); - const float y = (1. - rv->viewport().y() - rv->viewport().height()) * rv->surfaceSize().height(); + const float y = (1. - rv->viewport().y() - rv->viewport().height()) + * rv->surfaceSize().height(); const float w = rv->viewport().width() * rv->surfaceSize().width(); const float h = rv->viewport().height() * rv->surfaceSize().height(); -// qDebug() << x << y << w << h; - vp = {x, y, w, h}; + // qDebug() << x << y << w << h; + vp = { x, y, w, h }; } // Scissoring { RenderStateSet *ss = rv->stateSet(); if (ss == nullptr) ss = m_defaultRenderStateSet; - StateVariant *scissorTestSVariant = m_submissionContext->getState(ss, StateMask::ScissorStateMask); + StateVariant *scissorTestSVariant = + m_submissionContext->getState(ss, StateMask::ScissorStateMask); if (scissorTestSVariant) { - const ScissorTest *scissorTest = static_cast(scissorTestSVariant->constState()); - const auto& scissorValues = scissorTest->values(); - scissor = {std::get<0>(scissorValues), - std::get<1>(scissorValues), - std::get<2>(scissorValues), - std::get<3>(scissorValues)}; + const ScissorTest *scissorTest = + static_cast(scissorTestSVariant->constState()); + const auto &scissorValues = scissorTest->values(); + scissor = { std::get<0>(scissorValues), std::get<1>(scissorValues), + std::get<2>(scissorValues), std::get<3>(scissorValues) }; hasScissor = true; } } - // Render drawing commands const QVector &commands = rv->commands(); @@ -2454,34 +2484,36 @@ bool Renderer::executeCommandsSubmission(const RHIPassInfo &passInfo) void Renderer::cleanGraphicsResources() { // Remove unused GraphicsPipeline - RHIGraphicsPipelineManager *pipelineManager = m_RHIResourceManagers->rhiGraphicsPipelineManager(); + RHIGraphicsPipelineManager *pipelineManager = + m_RHIResourceManagers->rhiGraphicsPipelineManager(); const QVector graphicsPipelinesHandles = pipelineManager->activeHandles(); for (HRHIGraphicsPipeline pipelineHandle : graphicsPipelinesHandles) { RHIGraphicsPipeline *pipeline = pipelineManager->data(pipelineHandle); pipeline->decreaseScore(); // Pipeline wasn't used recently, let's destroy it - if (pipeline->score() < 0) - { + if (pipeline->score() < 0) { pipeline->cleanup(); } } // Clean buffers - const QVector buffersToRelease = m_nodesManager->bufferManager()->takeBuffersToRelease(); + const QVector buffersToRelease = + m_nodesManager->bufferManager()->takeBuffersToRelease(); for (Qt3DCore::QNodeId bufferId : buffersToRelease) m_submissionContext->releaseBuffer(bufferId); // When Textures are cleaned up, their id is saved so that they can be // cleaned up in the render thread const QVector cleanedUpTextureIds = std::move(m_textureIdsToCleanup); - for (const Qt3DCore::QNodeId textureCleanedUpId: cleanedUpTextureIds) + for (const Qt3DCore::QNodeId textureCleanedUpId : cleanedUpTextureIds) cleanupTexture(textureCleanedUpId); // Abandon GL shaders when a Shader node is destroyed Note: We are sure // that when this gets executed, all scene changes have been received and // shader nodes updated - const QVector cleanedUpShaderIds = m_nodesManager->shaderManager()->takeShaderIdsToCleanup(); - for (const Qt3DCore::QNodeId shaderCleanedUpId: cleanedUpShaderIds) { + const QVector cleanedUpShaderIds = + m_nodesManager->shaderManager()->takeShaderIdsToCleanup(); + for (const Qt3DCore::QNodeId shaderCleanedUpId : cleanedUpShaderIds) { cleanupShader(m_nodesManager->shaderManager()->lookupResource(shaderCleanedUpId)); // We can really release the texture at this point m_nodesManager->shaderManager()->releaseResource(shaderCleanedUpId); diff --git a/src/plugins/renderers/rhi/renderer/renderer_p.h b/src/plugins/renderers/rhi/renderer/renderer_p.h index 780b23ac2..8cceca801 100644 --- a/src/plugins/renderers/rhi/renderer/renderer_p.h +++ b/src/plugins/renderers/rhi/renderer/renderer_p.h @@ -144,11 +144,14 @@ class ResourceAccessor; using ComputableEntityFilter = FilterEntityByComponentJob; using ComputableEntityFilterPtr = QSharedPointer; -using RenderableEntityFilter = FilterEntityByComponentJob; +using RenderableEntityFilter = + FilterEntityByComponentJob; using RenderableEntityFilterPtr = QSharedPointer; using SynchronizerJobPtr = GenericLambdaJobPtr>; -using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr, std::function>; +using SynchronizerPostFramePtr = + GenericLambdaJobAndPostFramePtr, + std::function>; namespace Rhi { @@ -208,20 +211,33 @@ public: void skipNextFrame() override; void jobsDone(Qt3DCore::QAspectManager *manager) override; - void setPendingEvents(const QList> &mouseEvents, const QList &keyEvents) override; + void setPendingEvents(const QList> &mouseEvents, + const QList &keyEvents) override; QVector preRenderingJobs() override; QVector renderBinJobs() override; inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; } - inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; } - inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } + inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const + { + return m_updateShaderDataTransformJob; + } + inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const + { + return m_filterCompatibleTechniqueJob; + } inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; } inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; } inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; } - inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; } - inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; } + inline RenderableEntityFilterPtr renderableEntityFilterJob() const + { + return m_renderableEntityFilterJob; + } + inline ComputableEntityFilterPtr computableEntityFilterJob() const + { + return m_computableEntityFilterJob; + } Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override; @@ -234,19 +250,15 @@ public: // Executed in secondary GL thread void loadShader(Shader *shader, Qt3DRender::Render::HShader shaderHandle) override; - void updateResources(); void updateTexture(Texture *texture); void cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId); void cleanupShader(const Shader *shader); void downloadGLBuffers(); void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, - Qt3DCore::QNodeId outputRenderTargetId, - QRect inputRect, - QRect outputRect, + Qt3DCore::QNodeId outputRenderTargetId, QRect inputRect, QRect outputRect, GLuint defaultFramebuffer); - struct RHIPassInfo { QVector rvs; @@ -260,19 +272,16 @@ public: // For Scene2D rendering void setOpenGLContext(QOpenGLContext *context) override; - bool accessOpenGLTexture(Qt3DCore::QNodeId nodeId, - QOpenGLTexture **texture, - QMutex **lock, + bool accessOpenGLTexture(Qt3DCore::QNodeId nodeId, QOpenGLTexture **texture, QMutex **lock, bool readonly) override; QSharedPointer resourceAccessor() const override; - const GraphicsApiFilterData *contextInfo() const; SubmissionContext *submissionContext() const; inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; } - QList> pendingPickingEvents() const; + QList> pendingPickingEvents() const; QList pendingKeyEvents() const; void enqueueRenderView(RenderView *renderView, int submitOrder); @@ -284,10 +293,7 @@ public: struct ViewSubmissionResultData { - ViewSubmissionResultData() - : lastBoundFBOId(0) - , surface(nullptr) - {} + ViewSubmissionResultData() : lastBoundFBOId(0), surface(nullptr) { } uint lastBoundFBOId; QSurface *surface; @@ -299,8 +305,8 @@ public: void setScreen(QScreen *scr) override; QScreen *screen() const override; - float* textureTransform() noexcept { return m_textureTransform; } - const float* textureTransform() const noexcept { return m_textureTransform; } + float *textureTransform() noexcept { return m_textureTransform; } + const float *textureTransform() const noexcept { return m_textureTransform; } #ifdef QT3D_RENDER_UNIT_TESTS public: #else @@ -310,7 +316,7 @@ private: bool canRender() const; Qt3DCore::QServiceLocator *m_services; - QRenderAspect* m_aspect; + QRenderAspect *m_aspect; NodeManagers *m_nodesManager; // Frame graph root @@ -339,7 +345,8 @@ private: QVector m_dirtyGeometry; QAtomicInt m_exposed; - struct DirtyBits { + struct DirtyBits + { BackendNodeDirtySet marked; // marked dirty since last job build BackendNodeDirtySet remaining; // remaining dirty after jobs have finished }; @@ -407,7 +414,7 @@ private: QScreen *m_screen = nullptr; QSharedPointer m_scene2DResourceAccessor; - QOffscreenSurface *m_fallbackSurface{}; + QOffscreenSurface *m_fallbackSurface {}; bool m_hasSwapChain = false; @@ -418,11 +425,13 @@ private: float m_textureTransform[4]; - void updateGraphicsPipeline(RenderCommand& command, RenderView *rv, int renderViewIndex); - bool uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); - bool uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, const RenderCommand &command); - bool performDraw(QRhiCommandBuffer *cb, const QRhiViewport& vp, const QRhiScissor* scissor, const RenderCommand &command); - + void updateGraphicsPipeline(RenderCommand &command, RenderView *rv, int renderViewIndex); + bool uploadBuffersForCommand(QRhiCommandBuffer *cb, const RenderView *rv, + RenderCommand &command); + bool uploadUBOsForCommand(QRhiCommandBuffer *cb, const RenderView *rv, + const RenderCommand &command); + bool performDraw(QRhiCommandBuffer *cb, const QRhiViewport &vp, const QRhiScissor *scissor, + const RenderCommand &command); }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/renderercache_p.h b/src/plugins/renderers/rhi/renderer/renderercache_p.h index f2ca76148..ec3223dd2 100644 --- a/src/plugins/renderers/rhi/renderer/renderercache_p.h +++ b/src/plugins/renderers/rhi/renderer/renderercache_p.h @@ -79,7 +79,7 @@ struct RendererCache QVector renderableEntities; QVector computeEntities; QVector gatheredLights; - EnvironmentLight* environmentLight; + EnvironmentLight *environmentLight; // Per RV cache QHash leafNodeCache; diff --git a/src/plugins/renderers/rhi/renderer/renderqueue.cpp b/src/plugins/renderers/rhi/renderer/renderqueue.cpp index ae4145c76..39eaddc9a 100644 --- a/src/plugins/renderers/rhi/renderer/renderqueue.cpp +++ b/src/plugins/renderers/rhi/renderer/renderqueue.cpp @@ -50,11 +50,11 @@ namespace Render { namespace Rhi { RenderQueue::RenderQueue() - : m_noRender(false) - , m_wasReset(true) - , m_targetRenderViewCount(0) - , m_currentRenderViewCount(0) - , m_currentWorkQueue(1) + : m_noRender(false), + m_wasReset(true), + m_targetRenderViewCount(0), + m_currentRenderViewCount(0), + m_currentWorkQueue(1) { } @@ -125,7 +125,8 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) bool RenderQueue::isFrameQueueComplete() const { return (m_noRender - || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount)); + || (m_targetRenderViewCount > 0 + && m_targetRenderViewCount == m_currentRenderViewCount)); } } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp index c08be80eb..54295ef5f 100644 --- a/src/plugins/renderers/rhi/renderer/renderview.cpp +++ b/src/plugins/renderers/rhi/renderer/renderview.cpp @@ -87,17 +87,16 @@ namespace Qt3DRender { namespace Render { namespace Rhi { - -namespace { +namespace { // register our QNodeId's as a metatype during program loading const int Q_DECL_UNUSED qNodeIdTypeId = qMetaTypeId(); const int MAX_LIGHTS = 8; -#define LIGHT_POSITION_NAME QLatin1String(".position") -#define LIGHT_TYPE_NAME QLatin1String(".type") -#define LIGHT_COLOR_NAME QLatin1String(".color") +#define LIGHT_POSITION_NAME QLatin1String(".position") +#define LIGHT_TYPE_NAME QLatin1String(".type") +#define LIGHT_COLOR_NAME QLatin1String(".color") #define LIGHT_INTENSITY_NAME QLatin1String(".intensity") int LIGHT_COUNT_NAME_ID = 0; @@ -107,7 +106,7 @@ int LIGHT_COLOR_NAMES[MAX_LIGHTS]; int LIGHT_INTENSITY_NAMES[MAX_LIGHTS]; QString LIGHT_STRUCT_NAMES[MAX_LIGHTS]; -std::atomic_bool wasInitialized{}; +std::atomic_bool wasInitialized {}; } // anonymous namespace @@ -115,53 +114,49 @@ std::atomic_bool wasInitialized{}; static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &surfaceSize) { return QRectF(fractionalViewport.x() * surfaceSize.width(), - (1.0 - fractionalViewport.y() - fractionalViewport.height()) * surfaceSize.height(), + (1.0 - fractionalViewport.y() - fractionalViewport.height()) + * surfaceSize.height(), fractionalViewport.width() * surfaceSize.width(), fractionalViewport.height() * surfaceSize.height()); } static Matrix4x4 getProjectionMatrix(const CameraLens *lens, bool yIsUp) { - if (lens) - { - if (yIsUp) - { + if (lens) { + if (yIsUp) { // OpenGL return lens->projection(); - } - else - { + } else { // Others. Note : this could likely be optimized... auto p = lens->projection(); - Matrix4x4 rev{0, 0, 0, 0, 0, - 2* p.m22(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + Matrix4x4 rev { 0, 0, 0, 0, 0, -2 * p.m22(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; p += rev; return p; } - } - else - { - qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered."; + } else { + qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame " + "Graph or make sure that no entities will be rendered."; return Matrix4x4(); } } RenderView::RenderView() - : m_isDownloadBuffersEnable(false) - , m_hasBlitFramebufferInfo(false) - , m_renderer(nullptr) - , m_manager(nullptr) - , m_devicePixelRatio(1.) - , m_viewport(QRectF(0., 0., 1., 1.)) - , m_gamma(2.2f) - , m_surface(nullptr) - , m_clearBuffer(QClearBuffers::None) - , m_clearDepthValue(1.f) - , m_clearStencilValue(0) - , m_stateSet(nullptr) - , m_noDraw(false) - , m_compute(false) - , m_frustumCulling(false) - , m_environmentLight(nullptr) + : m_isDownloadBuffersEnable(false), + m_hasBlitFramebufferInfo(false), + m_renderer(nullptr), + m_manager(nullptr), + m_devicePixelRatio(1.), + m_viewport(QRectF(0., 0., 1., 1.)), + m_gamma(2.2f), + m_surface(nullptr), + m_clearBuffer(QClearBuffers::None), + m_clearDepthValue(1.f), + m_clearStencilValue(0), + m_stateSet(nullptr), + m_noDraw(false), + m_compute(false), + m_frustumCulling(false), + m_environmentLight(nullptr) { m_workGroups[0] = 1; m_workGroups[1] = 1; @@ -174,11 +169,14 @@ RenderView::RenderView() LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QLatin1String("lightCount")); for (int i = 0; i < MAX_LIGHTS; ++i) { Q_STATIC_ASSERT_X(MAX_LIGHTS < 10, "can't use the QChar trick anymore"); - LIGHT_STRUCT_NAMES[i] = QLatin1String("lights[") + QLatin1Char(char('0' + i)) + QLatin1Char(']'); - LIGHT_POSITION_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME); + LIGHT_STRUCT_NAMES[i] = + QLatin1String("lights[") + QLatin1Char(char('0' + i)) + QLatin1Char(']'); + LIGHT_POSITION_NAMES[i] = + StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME); LIGHT_TYPE_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_TYPE_NAME); LIGHT_COLOR_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_COLOR_NAME); - LIGHT_INTENSITY_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME); + LIGHT_INTENSITY_NAMES[i] = + StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME); } } } @@ -258,8 +256,8 @@ struct AdjacentSubRangeFinder }; template -int advanceUntilNonAdjacent(const QVector &commands, - const int beg, const int end, Predicate pred) +int advanceUntilNonAdjacent(const QVector &commands, const int beg, const int end, + Predicate pred) { int i = beg + 1; while (i < end) { @@ -270,7 +268,6 @@ int advanceUntilNonAdjacent(const QVector &commands, return i; } - using CommandIt = QVector::iterator; template @@ -289,7 +286,7 @@ struct SubRangeSorter { static void sortSubRange(CommandIt begin, const CommandIt end) { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { + std::stable_sort(begin, end, [](const RenderCommand &a, const RenderCommand &b) { return a.m_changeCost > b.m_changeCost; }); } @@ -300,7 +297,7 @@ struct SubRangeSorter { static void sortSubRange(CommandIt begin, const CommandIt end) { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { + std::stable_sort(begin, end, [](const RenderCommand &a, const RenderCommand &b) { return a.m_depth > b.m_depth; }); } @@ -312,7 +309,7 @@ struct SubRangeSorter static void sortSubRange(CommandIt begin, const CommandIt end) { // First we sort by shader - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { + std::stable_sort(begin, end, [](const RenderCommand &a, const RenderCommand &b) { return a.m_rhiShader > b.m_rhiShader; }); } @@ -323,7 +320,7 @@ struct SubRangeSorter { static void sortSubRange(CommandIt begin, const CommandIt end) { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { + std::stable_sort(begin, end, [](const RenderCommand &a, const RenderCommand &b) { return a.m_depth < b.m_depth; }); } @@ -357,21 +354,30 @@ struct SubRangeSorter } }; -int findSubRange(const QVector &commands, - const int begin, const int end, +int findSubRange(const QVector &commands, const int begin, const int end, const QSortPolicy::SortType sortType) { switch (sortType) { case QSortPolicy::StateChangeCost: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + return advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); case QSortPolicy::BackToFront: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + return advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); case QSortPolicy::Material: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + return advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); case QSortPolicy::FrontToBack: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + return advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); case QSortPolicy::Texture: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + return advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); default: Q_UNREACHABLE(); return end; @@ -381,15 +387,19 @@ int findSubRange(const QVector &commands, void sortByMaterial(QVector &commands, int begin, const int end) { // We try to arrange elements so that their rendering cost is minimized for a given shader - int rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + int rangeEnd = advanceUntilNonAdjacent( + commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); while (begin != end) { if (begin + 1 < rangeEnd) { - std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (const RenderCommand &a, const RenderCommand &b){ - return a.m_material.handle() < b.m_material.handle(); - }); + std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, + [](const RenderCommand &a, const RenderCommand &b) { + return a.m_material.handle() < b.m_material.handle(); + }); } begin = rangeEnd; - rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder::adjacentSubRange); + rangeEnd = advanceUntilNonAdjacent( + commands, begin, end, + AdjacentSubRangeFinder::adjacentSubRange); } } @@ -401,22 +411,27 @@ void sortCommandRange(QVector &commands, int begin, const int end switch (sortingTypes.at(level)) { case QSortPolicy::StateChangeCost: - SubRangeSorter::sortSubRange(commands.begin() + begin, commands.begin() + end); + SubRangeSorter::sortSubRange(commands.begin() + begin, + commands.begin() + end); break; case QSortPolicy::BackToFront: - SubRangeSorter::sortSubRange(commands.begin() + begin, commands.begin() + end); + SubRangeSorter::sortSubRange(commands.begin() + begin, + commands.begin() + end); break; case QSortPolicy::Material: // Groups all same shader DNA together - SubRangeSorter::sortSubRange(commands.begin() + begin, commands.begin() + end); + SubRangeSorter::sortSubRange(commands.begin() + begin, + commands.begin() + end); // Group all same material together (same parameters most likely) sortByMaterial(commands, begin, end); break; case QSortPolicy::FrontToBack: - SubRangeSorter::sortSubRange(commands.begin() + begin, commands.begin() + end); + SubRangeSorter::sortSubRange(commands.begin() + begin, + commands.begin() + end); break; case QSortPolicy::Texture: - SubRangeSorter::sortSubRange(commands.begin() + begin, commands.begin() + end); + SubRangeSorter::sortSubRange(commands.begin() + begin, + commands.begin() + end); break; default: Q_UNREACHABLE(); @@ -497,7 +512,8 @@ void RenderView::setRenderer(Renderer *renderer) m_manager = renderer->nodeManagers(); } -void RenderView::addClearBuffers(const ClearBuffers *cb) { +void RenderView::addClearBuffers(const ClearBuffers *cb) +{ QClearBuffers::BufferTypeFlags type = cb->type(); if (type & QClearBuffers::StencilBuffer) { @@ -519,11 +535,12 @@ void RenderView::addClearBuffers(const ClearBuffers *cb) { m_clearBuffer |= QClearBuffers::ColorBuffer; } else { if (cb->bufferId()) { - const RenderTargetOutput *targetOutput = m_manager->attachmentManager()->lookupResource(cb->bufferId()); + const RenderTargetOutput *targetOutput = + m_manager->attachmentManager()->lookupResource(cb->bufferId()); if (targetOutput) { clearBufferInfo.attchmentPoint = targetOutput->point(); - // Note: a job is later performed to find the drawIndex from the buffer attachment point - // using the AttachmentPack + // Note: a job is later performed to find the drawIndex from the buffer + // attachment point using the AttachmentPack m_specificClearColorBuffers.push_back(clearBufferInfo); } } @@ -547,15 +564,17 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorcomponentHandle(); // There is a geometry renderer with geometry - if ((geometryRenderer = m_manager->geometryRendererManager()->data(geometryRendererHandle)) != nullptr - && geometryRenderer->isEnabled() - && !geometryRenderer->geometryId().isNull()) { + if ((geometryRenderer = m_manager->geometryRendererManager()->data(geometryRendererHandle)) + != nullptr + && geometryRenderer->isEnabled() && !geometryRenderer->geometryId().isNull()) { const Qt3DCore::QNodeId materialComponentId = entity->componentUuid(); const HMaterial materialHandle = entity->componentHandle(); - const QVector renderPassData = m_parameters.value(materialComponentId); + const QVector renderPassData = + m_parameters.value(materialComponentId); - HGeometry geometryHandle = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId()); + HGeometry geometryHandle = + m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId()); Geometry *geometry = m_manager->geometryManager()->data(geometryHandle); if (geometry == nullptr) @@ -576,10 +595,12 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorhasRenderStates()) { command.m_stateSet = RenderStateSetPtr::create(); - addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager()); + addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), + m_manager->renderStateManager()); if (m_stateSet != nullptr) command.m_stateSet->merge(m_stateSet); - command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); + command.m_changeCost = + m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); } command.m_shaderId = pass->shaderProgram(); command.m_rhiShader = rhiShaderManager->lookupResource(command.m_shaderId); @@ -600,7 +621,8 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector attributeIds = geometry->attributes(); for (Qt3DCore::QNodeId attributeId : attributeIds) { - Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId); + Attribute *attribute = + m_manager->attributeManager()->lookupResource(attributeId); switch (attribute->attributeType()) { case QAttribute::IndexAttribute: indexAttribute = attribute; @@ -623,18 +645,21 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorvertexBaseType(); - command.m_indexAttributeByteOffset = indexAttribute->byteOffset() + geometryRenderer->indexBufferByteOffset(); + command.m_indexAttributeByteOffset = indexAttribute->byteOffset() + + geometryRenderer->indexBufferByteOffset(); } // Note: we only care about the primitiveCount when using direct draw calls // For indirect draw calls it is assumed the buffer was properly set already if (command.m_drawIndirect) { command.m_indirectAttributeByteOffset = indirectAttribute->byteOffset(); - command.m_indirectDrawBuffer = m_manager->bufferManager()->lookupHandle(indirectAttribute->bufferId()); + command.m_indirectDrawBuffer = m_manager->bufferManager()->lookupHandle( + indirectAttribute->bufferId()); } else { // Use the count specified by the GeometryRender // If not specify use the indexAttribute count if present - // Otherwise tries to use the count from the attribute with the highest count + // Otherwise tries to use the count from the attribute with the highest + // count if (primitiveCount == 0) { if (indexAttribute) primitiveCount = indexAttribute->count(); @@ -654,10 +679,7 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorverticesPerPatch(); } // scope - - commands.push_back(entity, - std::move(command), - passData); + commands.push_back(entity, std::move(command), passData); } } } @@ -683,11 +705,13 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVectorcomponentHandle(); - if ((computeJob = nodeManagers()->computeJobManager()->data(computeCommandHandle)) != nullptr - && computeJob->isEnabled()) { + if ((computeJob = nodeManagers()->computeJobManager()->data(computeCommandHandle)) + != nullptr + && computeJob->isEnabled()) { const Qt3DCore::QNodeId materialComponentId = entity->componentUuid(); - const QVector& renderPassData = m_parameters.value(materialComponentId); + const QVector &renderPassData = + m_parameters.value(materialComponentId); // 1 RenderCommand per RenderPass pass on an Entity with a Mesh for (const RenderPassParameterData &passData : renderPassData) { @@ -697,13 +721,15 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVectorhasRenderStates()) { command.m_stateSet = RenderStateSetPtr::create(); - addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager()); + addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), + m_manager->renderStateManager()); // Merge per pass stateset with global stateset // so that the local stateset only overrides if (m_stateSet != nullptr) command.m_stateSet->merge(m_stateSet); - command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); + command.m_changeCost = + m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); } command.m_shaderId = pass->shaderProgram(); command.m_rhiShader = rhiShaderManager->lookupResource(command.m_shaderId); @@ -720,9 +746,7 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVectory()); command.m_workGroups[2] = std::max(m_workGroups[2], computeJob->z()); - commands.push_back(entity, - std::move(command), - passData); + commands.push_back(entity, std::move(command), passData); } } } @@ -730,8 +754,7 @@ EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVectortextureTransform(), sizeof(float) * 4); + memcpy(&m_renderViewUBO.textureTransformMatrix, m_renderer->textureTransform(), + sizeof(float) * 4); memcpy(&m_renderViewUBO.eyePosition, &m_data.m_eyePos, sizeof(float) * 3); - const float ratio = float(m_surfaceSize.width()) / std::max(1.f, float(m_surfaceSize.height())); + const float ratio = + float(m_surfaceSize.width()) / std::max(1.f, float(m_surfaceSize.height())); memcpy(&m_renderViewUBO.aspectRatio, &ratio, sizeof(float)); memcpy(&m_renderViewUBO.gamma, &m_gamma, sizeof(float)); - const float exposure = m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f; + const float exposure = + m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f; memcpy(&m_renderViewUBO.exposure, &exposure, sizeof(float)); const float timeValue = float(m_renderer->time() / 1000000000.0f); memcpy(&m_renderViewUBO.time, &timeValue, sizeof(float)); @@ -786,7 +814,8 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, // Pick which lights to take in to account. // For now decide based on the distance by taking the MAX_LIGHTS closest lights. // Replace with more sophisticated mechanisms later. - // Copy vector so that we can sort it concurrently and we only want to sort the one for the current command + // Copy vector so that we can sort it concurrently and we only want to sort the one for the + // current command QVector lightSources; EnvironmentLight *environmentLight = nullptr; @@ -794,7 +823,8 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, // Project the camera-to-object-center vector onto the camera // view vector. This gives a depth value suitable as the key // for BackToFront sorting. - command.m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir); + command.m_depth = Vector3D::dotProduct( + entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir); environmentLight = m_environmentLight; lightSources = m_lightSources; @@ -802,17 +832,20 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, if (lightSources.size() > 1) { const Vector3D entityCenter = entity->worldBoundingVolume()->center(); std::sort(lightSources.begin(), lightSources.end(), - [&] (const LightSource &a, const LightSource &b) { - const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center()); - const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center()); - return distA < distB; - }); + [&](const LightSource &a, const LightSource &b) { + const float distA = entityCenter.distanceToPoint( + a.entity->worldBoundingVolume()->center()); + const float distB = entityCenter.distanceToPoint( + b.entity->worldBoundingVolume()->center()); + return distA < distB; + }); } lightSources = lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)); } else { // Compute // Note: if frameCount has reached 0 in the previous frame, isEnabled // would be false - ComputeCommand *computeJob = m_manager->computeJobManager()->data(command.m_computeCommand); + ComputeCommand *computeJob = + m_manager->computeJobManager()->data(command.m_computeCommand); if (computeJob->runType() == QComputeCommand::Manual) computeJob->updateFrameCount(); } @@ -821,11 +854,7 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, // setShaderAndUniforms can initialize a localData // make sure this is cleared before we leave this function - setShaderAndUniforms(&command, - globalParameters, - entity, - lightSources, - environmentLight); + setShaderAndUniforms(&command, globalParameters, entity, lightSources, environmentLight); // Update CommandUBO (Qt3D standard uniforms) const Matrix4x4 worldTransform = *(entity->worldTransform()); @@ -837,25 +866,28 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, const Matrix4x4 inverseModelViewProjection = mvp.inverted(); { memcpy(&command.m_commandUBO.modelMatrix, &worldTransform, sizeof(Matrix4x4)); - memcpy(&command.m_commandUBO.inverseModelMatrix, &inverseWorldTransform, sizeof(Matrix4x4)); + memcpy(&command.m_commandUBO.inverseModelMatrix, &inverseWorldTransform, + sizeof(Matrix4x4)); memcpy(&command.m_commandUBO.modelViewMatrix, &modelViewMatrix, sizeof(Matrix4x4)); { - float (& normal)[12] = command.m_commandUBO.modelNormalMatrix; - normal[0] = modelNormalMatrix.constData()[0 * 3 + 0]; - normal[1] = modelNormalMatrix.constData()[0 * 3 + 1]; - normal[2] = modelNormalMatrix.constData()[0 * 3 + 2]; + float(&normal)[12] = command.m_commandUBO.modelNormalMatrix; + normal[0] = modelNormalMatrix.constData()[0 * 3 + 0]; + normal[1] = modelNormalMatrix.constData()[0 * 3 + 1]; + normal[2] = modelNormalMatrix.constData()[0 * 3 + 2]; - normal[4] = modelNormalMatrix.constData()[1 * 3 + 0]; - normal[5] = modelNormalMatrix.constData()[1 * 3 + 1]; - normal[6] = modelNormalMatrix.constData()[1 * 3 + 2]; + normal[4] = modelNormalMatrix.constData()[1 * 3 + 0]; + normal[5] = modelNormalMatrix.constData()[1 * 3 + 1]; + normal[6] = modelNormalMatrix.constData()[1 * 3 + 2]; - normal[8] = modelNormalMatrix.constData()[2 * 3 + 0]; - normal[9] = modelNormalMatrix.constData()[2 * 3 + 1]; + normal[8] = modelNormalMatrix.constData()[2 * 3 + 0]; + normal[9] = modelNormalMatrix.constData()[2 * 3 + 1]; normal[10] = modelNormalMatrix.constData()[2 * 3 + 2]; } - memcpy(&command.m_commandUBO.inverseModelViewMatrix, &inverseModelViewMatrix, sizeof(Matrix4x4)); + memcpy(&command.m_commandUBO.inverseModelViewMatrix, &inverseModelViewMatrix, + sizeof(Matrix4x4)); memcpy(&command.m_commandUBO.mvp, &mvp, sizeof(Matrix4x4)); - memcpy(&command.m_commandUBO.inverseModelViewProjectionMatrix, &inverseModelViewProjection, sizeof(Matrix4x4)); + memcpy(&command.m_commandUBO.inverseModelViewProjectionMatrix, + &inverseModelViewProjection, sizeof(Matrix4x4)); } } @@ -865,13 +897,14 @@ void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, void RenderView::updateMatrices() { - if (m_data.m_renderCameraNode && m_data.m_renderCameraLens && m_data.m_renderCameraLens->isEnabled()) { + if (m_data.m_renderCameraNode && m_data.m_renderCameraLens + && m_data.m_renderCameraLens->isEnabled()) { const Matrix4x4 cameraWorld = *(m_data.m_renderCameraNode->worldTransform()); setViewMatrix(m_data.m_renderCameraLens->viewMatrix(cameraWorld)); setViewProjectionMatrix(m_data.m_renderCameraLens->projection() * viewMatrix()); - //To get the eyePosition of the camera, we need to use the inverse of the - //camera's worldTransform matrix. + // To get the eyePosition of the camera, we need to use the inverse of the + // camera's worldTransform matrix. const Matrix4x4 inverseWorldTransform = viewMatrix().inverted(); const Vector3D eyePosition(inverseWorldTransform.column(3)); setEyePosition(eyePosition); @@ -880,11 +913,13 @@ void RenderView::updateMatrices() // ensure non-uniform scale works too. const QMatrix3x3 normalMat = convertToQMatrix4x4(m_data.m_viewMatrix).normalMatrix(); // dir = normalize(QVector3D(0, 0, -1) * normalMat) - setEyeViewDirection(Vector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized()); + setEyeViewDirection( + Vector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized()); } } -void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const +void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, + const UniformValue &value) const { // At this point a uniform value can only be a scalar type // or a Qt3DCore::QNodeId corresponding to a Texture or Image @@ -899,11 +934,12 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, c for (int i = 0; i < uniformArraySize; ++i) { const Qt3DCore::QNodeId resourceId = nodeIds[i]; - const Texture *tex = m_manager->textureManager()->lookupResource(resourceId); + const Texture *tex = m_manager->textureManager()->lookupResource(resourceId); if (tex != nullptr) { uniformPack.setTexture(nameId, i, resourceId); } else { - const ShaderImage *img = m_manager->shaderImageManager()->lookupResource(resourceId); + const ShaderImage *img = + m_manager->shaderImageManager()->lookupResource(resourceId); if (img != nullptr) { resourceType = UniformValue::ShaderImageValue; uniformPack.setImage(nameId, i, resourceId); @@ -921,8 +957,7 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, c } } -void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, - const RHIShader *shader, +void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, const RHIShader *shader, const ShaderUniformBlock &block, const UniformValue &value) const { @@ -931,7 +966,9 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, if (value.valueType() == UniformValue::NodeId) { Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData())) != nullptr) { + if ((buffer = m_manager->bufferManager()->lookupResource( + *value.constData())) + != nullptr) { BlockToUBO uniformBlockUBO; uniformBlockUBO.m_blockIndex = block.m_index; uniformBlockUBO.m_bufferID = buffer->peerId(); @@ -942,15 +979,16 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, } } -void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack, - const RHIShader *shader, +void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack, const RHIShader *shader, const ShaderStorageBlock &block, const UniformValue &value) const { Q_UNUSED(shader) if (value.valueType() == UniformValue::NodeId) { Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData())) != nullptr) { + if ((buffer = m_manager->bufferManager()->lookupResource( + *value.constData())) + != nullptr) { BlockToSSBO shaderStorageBlock; shaderStorageBlock.m_blockIndex = block.m_index; shaderStorageBlock.m_bufferID = buffer->peerId(); @@ -961,11 +999,10 @@ void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack, } } -void RenderView::setDefaultUniformBlockShaderDataValue( - ShaderParameterPack &uniformPack, - const RHIShader *shader, - const ShaderData *shaderData, - const QString &structName) const +void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, + const RHIShader *shader, + const ShaderData *shaderData, + const QString &structName) const { UniformBlockValueBuilder *builder = m_localData.localData(); builder->activeUniformNamesToValue.clear(); @@ -979,59 +1016,64 @@ void RenderView::setDefaultUniformBlockShaderDataValue( // Build name-value map for the block builder->buildActiveUniformNameValueMapStructHelper(shaderData, structName); // Set uniform values for each entrie of the block name-value map - QHash::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin(); - const QHash::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd(); + QHash::const_iterator activeValuesIt = + builder->activeUniformNamesToValue.constBegin(); + const QHash::const_iterator activeValuesEnd = + builder->activeUniformNamesToValue.constEnd(); // TO DO: Make the ShaderData store UniformValue while (activeValuesIt != activeValuesEnd) { - setUniformValue(uniformPack, activeValuesIt.key(), UniformValue::fromVariant(activeValuesIt.value())); + setUniformValue(uniformPack, activeValuesIt.key(), + UniformValue::fromVariant(activeValuesIt.value())); ++activeValuesIt; } } -void RenderView::applyParameter( - const Parameter *param, - RenderCommand *command, - const RHIShader *shader) const noexcept +void RenderView::applyParameter(const Parameter *param, RenderCommand *command, + const RHIShader *shader) const noexcept { const int nameId = param->nameId(); const UniformValue &uniformValue = param->uniformValue(); - switch (shader->categorizeVariable(nameId)) - { + switch (shader->categorizeVariable(nameId)) { case RHIShader::Uniform: { setUniformValue(command->m_parameterPack, nameId, uniformValue); break; } case RHIShader::UBO: { - setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(nameId), uniformValue); + setUniformBlockValue(command->m_parameterPack, shader, + shader->uniformBlockForBlockNameId(nameId), uniformValue); break; } case RHIShader::SSBO: { - setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(nameId), uniformValue); + setShaderStorageValue(command->m_parameterPack, shader, + shader->storageBlockForBlockNameId(nameId), uniformValue); break; } case RHIShader::Struct: { ShaderData *shaderData = nullptr; - if (uniformValue.valueType() == UniformValue::NodeId && - (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData())) != nullptr) { + if (uniformValue.valueType() == UniformValue::NodeId + && (shaderData = m_manager->shaderDataManager()->lookupResource( + *uniformValue.constData())) + != nullptr) { // Try to check if we have a struct or array matching a QShaderData parameter - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(nameId)); + setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, + StringToInt::lookupString(nameId)); } break; } } } -void RenderView::setShaderAndUniforms(RenderCommand *command, - ParameterInfoList ¶meters, +void RenderView::setShaderAndUniforms(RenderCommand *command, ParameterInfoList ¶meters, Entity *entity, const QVector &activeLightSources, EnvironmentLight *environmentLight) const { - // The VAO Handle is set directly in the renderer thread so as to avoid having to use a mutex here - // Set shader, technique, and effect by basically doing : + // The VAO Handle is set directly in the renderer thread so as to avoid having to use a mutex + // here Set shader, technique, and effect by basically doing : // ShaderProgramManager[MaterialManager[frontentEntity->id()]->Effect->Techniques[TechniqueFilter->name]->RenderPasses[RenderPassFilter->name]]; - // The Renderer knows that if one of those is null, a default material / technique / effect as to be used + // The Renderer knows that if one of those is null, a default material / technique / effect as + // to be used // Find all RenderPasses (in order) matching values set in the RenderPassFilter // Get list of parameters for the Material, Effect, and Technique @@ -1041,9 +1083,9 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RHIShader *shader = command->m_rhiShader; if (shader != nullptr && shader->isLoaded()) { - // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings - // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name - // equals to the parameter name + // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname + // bindings If a parameter is defined and not found in the bindings it is assumed to be a + // binding of Uniform type with the glsl name equals to the parameter name // Set fragData Name and index // Later on we might want to relink the shader if attachments have changed @@ -1099,7 +1141,8 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, if (!light->isEnabled()) continue; - ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData()); + ShaderData *shaderData = + m_manager->shaderDataManager()->lookupResource(light->shaderData()); if (!shaderData) continue; @@ -1107,11 +1150,14 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, break; // Note: implicit conversion of values to UniformValue - setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f); - + setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], + worldPos); + setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], + int(QAbstractLight::PointLight)); + setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], + Vector3D(1.0f, 1.0f, 1.0f)); + setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], + 0.5f); // There is no risk in doing that even if multithreaded // since we are sure that a shaderData is unique for a given light @@ -1120,41 +1166,52 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, if (worldTransform) shaderData->updateWorldTransform(*worldTransform); - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]); + setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, + shaderData, LIGHT_STRUCT_NAMES[lightIdx]); ++lightIdx; } } if (shader->hasUniform(LIGHT_COUNT_NAME_ID)) - setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx))); + setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, + UniformValue(qMax((environmentLight ? 0 : 1), lightIdx))); // If no active light sources and no environment light, add a default light if (activeLightSources.isEmpty() && !environmentLight) { // Note: implicit conversion of values to UniformValue - setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f)); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f)); + setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], + Vector3D(10.0f, 10.0f, 0.0f)); + setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], + int(QAbstractLight::PointLight)); + setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], + Vector3D(1.0f, 1.0f, 1.0f)); setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f); } // Environment Light int envLightCount = 0; if (environmentLight && environmentLight->isEnabled()) { - static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight_irradiance")); - static const int specularId = StringToInt::lookupId(QLatin1String("envLight_specular")); - ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData()); + static const int irradianceId = + StringToInt::lookupId(QLatin1String("envLight_irradiance")); + static const int specularId = + StringToInt::lookupId(QLatin1String("envLight_specular")); + ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource( + environmentLight->shaderData()); if (shaderData) { envLightCount = 1; // ("specularSize", "irradiance", "irradianceSize", "specular") - auto irr = shaderData->properties()["irradiance"].value.value(); - auto spec = shaderData->properties()["specular"].value.value(); + auto irr = + shaderData->properties()["irradiance"].value.value(); + auto spec = + shaderData->properties()["specular"].value.value(); setUniformValue(command->m_parameterPack, irradianceId, irr); setUniformValue(command->m_parameterPack, specularId, spec); } } - setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount); + setUniformValue(command->m_parameterPack, + StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount); } } } diff --git a/src/plugins/renderers/rhi/renderer/renderview_p.h b/src/plugins/renderers/rhi/renderer/renderview_p.h index b42596498..3206b6e66 100644 --- a/src/plugins/renderers/rhi/renderer/renderview_p.h +++ b/src/plugins/renderers/rhi/renderer/renderview_p.h @@ -99,7 +99,7 @@ class Renderer; class RenderCommand; typedef QPair ActivePropertyContent; -typedef QPair ActiveProperty; +typedef QPair ActiveProperty; struct Q_AUTOTEST_EXPORT ClearBufferInfo { @@ -139,7 +139,8 @@ struct RenderViewUBO float exposure; float time; }; -static_assert(sizeof(RenderViewUBO) == sizeof(float) * (8 * 16 + 1 * 4 + 1 * 3 + 4 * 1), "UBO doesn't match std140"); +static_assert(sizeof(RenderViewUBO) == sizeof(float) * (8 * 16 + 1 * 4 + 1 * 3 + 4 * 1), + "UBO doesn't match std140"); class Q_AUTOTEST_EXPORT RenderView { @@ -160,35 +161,77 @@ public: inline void setDevicePixelRatio(qreal r) Q_DECL_NOTHROW { m_devicePixelRatio = r; } inline qreal devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; } - inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW { m_data.m_renderCameraLens = renderCameraLens; } + inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW + { + m_data.m_renderCameraLens = renderCameraLens; + } inline CameraLens *renderCameraLens() const Q_DECL_NOTHROW { return m_data.m_renderCameraLens; } - inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_data.m_renderCameraNode = renderCameraNode; } + inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW + { + m_data.m_renderCameraNode = renderCameraNode; + } inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_data.m_renderCameraNode; } - inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; } + inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW + { + m_data.m_viewMatrix = viewMatrix; + } inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; } - inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; } - inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; } + inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW + { + m_data.m_viewProjectionMatrix = viewProjectionMatrix; + } + inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW + { + return m_data.m_viewProjectionMatrix; + } inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; } inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; } - inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; } + inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW + { + m_data.m_eyeViewDir = dir; + } inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; } - inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); } - inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; } - - inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); } - inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; } - - inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; } - inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; } - - inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW { m_data.m_techniqueFilter = filter; } - inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_data.m_techniqueFilter; } + inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW + { + m_data.m_layerFilterIds.push_back(layerFilterId); + } + inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW + { + return m_data.m_layerFilterIds; + } + + inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) + { + m_data.m_proximityFilterIds.push_back(proximityFilterId); + } + inline Qt3DCore::QNodeIdVector proximityFilterIds() const + { + return m_data.m_proximityFilterIds; + } + + inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW + { + m_data.m_passFilter = rpFilter; + } + inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW + { + return m_data.m_passFilter; + } + + inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW + { + m_data.m_techniqueFilter = filter; + } + inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW + { + return m_data.m_techniqueFilter; + } inline RenderStateSet *stateSet() const Q_DECL_NOTHROW { return m_stateSet; } void setStateSet(RenderStateSet *stateSet) Q_DECL_NOTHROW { m_stateSet = stateSet; } @@ -199,16 +242,29 @@ public: inline bool isCompute() const Q_DECL_NOTHROW { return m_compute; } void setCompute(bool compute) Q_DECL_NOTHROW { m_compute = compute; } - void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; } + void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW + { + m_workGroups[0] = x; + m_workGroups[1] = y; + m_workGroups[2] = z; + } const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; } inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; } - void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; } + void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW + { + m_frustumCulling = frustumCulling; + } - inline void setMaterialParameterTable(const MaterialParameterGathererData ¶meters) Q_DECL_NOTHROW { m_parameters = parameters; } + inline void + setMaterialParameterTable(const MaterialParameterGathererData ¶meters) Q_DECL_NOTHROW + { + m_parameters = parameters; + } // TODO: Get rid of this overly complex memory management by splitting out the - // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode - // and passed along with the RenderView to the functions that populate the renderview + // InnerData as a RenderViewConfig struct. This can be created by + // setRenderViewConfigFromFrameGraphLeafNode and passed along with the RenderView to the + // functions that populate the renderview inline void setViewport(const QRectF &vp) Q_DECL_NOTHROW { m_viewport = vp; } inline QRectF viewport() const Q_DECL_NOTHROW { return m_viewport; } @@ -219,8 +275,14 @@ public: // color ClearBuffers are collected, as there may be multiple // color buffers to be cleared. we need to apply all these at rendering void addClearBuffers(const ClearBuffers *cb); - inline QVector specificClearColorBufferInfo() const { return m_specificClearColorBuffers; } - inline QVector &specificClearColorBufferInfo() { return m_specificClearColorBuffers; } + inline QVector specificClearColorBufferInfo() const + { + return m_specificClearColorBuffers; + } + inline QVector &specificClearColorBufferInfo() + { + return m_specificClearColorBuffers; + } inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; } inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; } @@ -229,53 +291,78 @@ public: inline const RenderViewUBO *renderViewUBO() const { return &m_renderViewUBO; } - RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true); + RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, + bool useDefaultMaterials = true); - EntityRenderCommandData buildDrawRenderCommands(const QVector &entities, - int offset, int count) const; + EntityRenderCommandData buildDrawRenderCommands(const QVector &entities, int offset, + int count) const; EntityRenderCommandData buildComputeRenderCommands(const QVector &entities, int offset, int count) const; + void updateRenderCommand(EntityRenderCommandData *renderCommandData, int offset, int count); - void updateRenderCommand(EntityRenderCommandData *renderCommandData, - int offset, int count); - - - void setCommands(const QVector &commands) Q_DECL_NOTHROW { m_commands = commands; } + void setCommands(const QVector &commands) Q_DECL_NOTHROW + { + m_commands = commands; + } QVector &commands() { return m_commands; } QVector commands() const { return m_commands; } void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; } const AttachmentPack &attachmentPack() const { return m_attachmentPack; } - void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW { m_renderTarget = renderTargetId; } + void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW + { + m_renderTarget = renderTargetId; + } Qt3DCore::QNodeId renderTargetId() const Q_DECL_NOTHROW { return m_renderTarget; } - void addSortType(const QVector &sortTypes) { m_data.m_sortingTypes.append(sortTypes); } + void addSortType(const QVector &sortTypes) + { + m_data.m_sortingTypes.append(sortTypes); + } void setSurface(QSurface *surface) { m_surface = surface; } QSurface *surface() const { return m_surface; } - void setLightSources(const QVector &lightSources) Q_DECL_NOTHROW { m_lightSources = lightSources; } - void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW { m_environmentLight = environmentLight; } + void setLightSources(const QVector &lightSources) Q_DECL_NOTHROW + { + m_lightSources = lightSources; + } + void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW + { + m_environmentLight = environmentLight; + } void updateMatrices(); - inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; } - inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; } - inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) Q_DECL_NOTHROW { m_renderCaptureRequest = request; } - inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW { return m_renderCaptureRequest; } - + inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW + { + m_renderCaptureNodeId = nodeId; + } + inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW + { + return m_renderCaptureNodeId; + } + inline void setRenderCaptureRequest(const QRenderCaptureRequest &request) Q_DECL_NOTHROW + { + m_renderCaptureRequest = request; + } + inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW + { + return m_renderCaptureRequest; + } // Helps making the size of RenderView smaller // Contains all the data needed for the actual building of the RenderView // But that aren't used later by the Renderer - struct InnerData { + struct InnerData + { InnerData() - : m_renderCameraLens(nullptr) - , m_renderCameraNode(nullptr) - , m_techniqueFilter(nullptr) - , m_passFilter(nullptr) + : m_renderCameraLens(nullptr), + m_renderCameraNode(nullptr), + m_techniqueFilter(nullptr), + m_passFilter(nullptr) { } CameraLens *m_renderCameraLens; @@ -301,12 +388,10 @@ public: void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo); private: - void setShaderAndUniforms(RenderCommand *command, - ParameterInfoList ¶meters, - Entity *entity, + void setShaderAndUniforms(RenderCommand *command, ParameterInfoList ¶meters, Entity *entity, const QVector &activeLightSources, EnvironmentLight *environmentLight) const; - mutable QThreadStorage m_localData; + mutable QThreadStorage m_localData; Qt3DCore::QNodeId m_renderCaptureNodeId; QRenderCaptureRequest m_renderCaptureRequest; @@ -330,12 +415,13 @@ private: QClearBuffers::BufferTypeFlags m_clearBuffer; float m_clearDepthValue; int m_clearStencilValue; - ClearBufferInfo m_globalClearColorBuffer; // global ClearColor - QVector m_specificClearColorBuffers; // different draw buffers with distinct colors + ClearBufferInfo m_globalClearColorBuffer; // global ClearColor + QVector + m_specificClearColorBuffers; // different draw buffers with distinct colors RenderStateSet *m_stateSet; - bool m_noDraw:1; - bool m_compute:1; - bool m_frustumCulling:1; + bool m_noDraw : 1; + bool m_compute : 1; + bool m_frustumCulling : 1; int m_workGroups[3]; RenderViewUBO m_renderViewUBO; @@ -346,20 +432,18 @@ private: MaterialParameterGathererData m_parameters; - void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const; - void setUniformBlockValue(ShaderParameterPack &uniformPack, - const RHIShader *shader, - const ShaderUniformBlock &block, - const UniformValue &value) const; - void setShaderStorageValue(ShaderParameterPack &uniformPack, - const RHIShader *shader, - const ShaderStorageBlock &block, - const UniformValue &value) const; + void setUniformValue(ShaderParameterPack &uniformPack, int nameId, + const UniformValue &value) const; + void setUniformBlockValue(ShaderParameterPack &uniformPack, const RHIShader *shader, + const ShaderUniformBlock &block, const UniformValue &value) const; + void setShaderStorageValue(ShaderParameterPack &uniformPack, const RHIShader *shader, + const ShaderStorageBlock &block, const UniformValue &value) const; void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, const RHIShader *shader, const ShaderData *shaderData, const QString &structName) const; - void applyParameter(const Parameter* param, RenderCommand* command, const RHIShader* shader) const noexcept; + void applyParameter(const Parameter *param, RenderCommand *command, + const RHIShader *shader) const noexcept; }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp index f3d470765..6455d2e10 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp @@ -61,18 +61,17 @@ int findIdealNumberOfWorkers(int elementCount, int packetSize = 100) return std::min(std::max(elementCount / packetSize, 1), RenderViewBuilder::optimalJobCount()); } - class SyncPreCommandBuilding { public: - explicit SyncPreCommandBuilding(RenderViewInitializerJobPtr renderViewInitializerJob, - const QVector &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_renderViewInitializer(std::move(renderViewInitializerJob)) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) + explicit SyncPreCommandBuilding( + RenderViewInitializerJobPtr renderViewInitializerJob, + const QVector &renderViewCommandBuilderJobs, + Renderer *renderer, FrameGraphNode *leafNode) + : m_renderViewInitializer(std::move(renderViewInitializerJob)), + m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs), + m_renderer(renderer), + m_leafNode(leafNode) { } @@ -91,13 +90,17 @@ public: lock.unlock(); // Split among the ideal number of command builders - const int idealPacketSize = std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), entities.size()); + const int idealPacketSize = + std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), + entities.size()); // Try to split work into an ideal number of workers const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize); for (int i = 0; i < m; ++i) { - const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = m_renderViewCommandBuilderJobs.at(i); - const int count = (i == m - 1) ? entities.size() - (i * idealPacketSize) : idealPacketSize; + const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = + m_renderViewCommandBuilderJobs.at(i); + const int count = + (i == m - 1) ? entities.size() - (i * idealPacketSize) : idealPacketSize; renderViewCommandBuilder->setEntities(entities, i * idealPacketSize, count); } } @@ -112,20 +115,23 @@ private: class SyncRenderViewPostCommandUpdate { public: - explicit SyncRenderViewPostCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const QVector &renderViewCommandUpdateJobs, - Renderer *renderer) - : m_renderViewJob(renderViewJob) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdateJobs) - , m_renderer(renderer) - {} + explicit SyncRenderViewPostCommandUpdate( + const RenderViewInitializerJobPtr &renderViewJob, + const QVector &renderViewCommandUpdateJobs, + Renderer *renderer) + : m_renderViewJob(renderViewJob), + m_renderViewCommandUpdaterJobs(renderViewCommandUpdateJobs), + m_renderer(renderer) + { + } void operator()() { // Append all the commands and sort them RenderView *rv = m_renderViewJob->renderView(); - const EntityRenderCommandDataPtr commandData = m_renderViewCommandUpdaterJobs.first()->renderables(); + const EntityRenderCommandDataPtr commandData = + m_renderViewCommandUpdaterJobs.first()->renderables(); if (commandData) { const QVector commands = std::move(commandData->commands); @@ -151,9 +157,9 @@ class SyncPreFrustumCulling public: explicit SyncPreFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob, const FrustumCullingJobPtr &frustumCulling) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCulling) - {} + : m_renderViewJob(renderViewJob), m_frustumCullingJob(frustumCulling) + { + } void operator()() { @@ -174,21 +180,23 @@ private: class SyncRenderViewPostInitialization { public: - explicit SyncRenderViewPostInitialization(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterLayerEntityJobPtr &filterEntityByLayerJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector &materialGathererJobs, - const QVector &renderViewCommandUpdaterJobs, - const QVector &renderViewCommandBuilderJobs) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - {} + explicit SyncRenderViewPostInitialization( + const RenderViewInitializerJobPtr &renderViewJob, + const FrustumCullingJobPtr &frustumCullingJob, + const FilterLayerEntityJobPtr &filterEntityByLayerJob, + const FilterProximityDistanceJobPtr &filterProximityJob, + const QVector &materialGathererJobs, + const QVector &renderViewCommandUpdaterJobs, + const QVector &renderViewCommandBuilderJobs) + : m_renderViewJob(renderViewJob), + m_frustumCullingJob(frustumCullingJob), + m_filterEntityByLayerJob(filterEntityByLayerJob), + m_filterProximityJob(filterProximityJob), + m_materialGathererJobs(materialGathererJobs), + m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs), + m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) + { + } void operator()() { @@ -203,8 +211,10 @@ public: // Material Parameter building for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { - materialGatherer->setRenderPassFilter(const_cast(rv->renderPassFilter())); - materialGatherer->setTechniqueFilter(const_cast(rv->techniqueFilter())); + materialGatherer->setRenderPassFilter( + const_cast(rv->renderPassFilter())); + materialGatherer->setTechniqueFilter( + const_cast(rv->techniqueFilter())); } // Command builders and updates @@ -230,25 +240,25 @@ private: class SyncRenderViewPreCommandUpdate { public: - explicit SyncRenderViewPreCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector &materialGathererJobs, - const QVector &renderViewCommandUpdaterJobs, - const QVector &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode, - bool fullCommandRebuild) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - , m_fullRebuild(fullCommandRebuild) - {} + explicit SyncRenderViewPreCommandUpdate( + const RenderViewInitializerJobPtr &renderViewJob, + const FrustumCullingJobPtr &frustumCullingJob, + const FilterProximityDistanceJobPtr &filterProximityJob, + const QVector &materialGathererJobs, + const QVector &renderViewCommandUpdaterJobs, + const QVector &renderViewCommandBuilderJobs, + Renderer *renderer, FrameGraphNode *leafNode, bool fullCommandRebuild) + : m_renderViewJob(renderViewJob), + m_frustumCullingJob(frustumCullingJob), + m_filterProximityJob(filterProximityJob), + m_materialGathererJobs(materialGathererJobs), + m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs), + m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs), + m_renderer(renderer), + m_leafNode(leafNode), + m_fullRebuild(fullCommandRebuild) + { + } void operator()() { @@ -274,22 +284,25 @@ public: // Reduction { int totalCommandCount = 0; - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) + for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : + qAsConst(m_renderViewCommandBuilderJobs)) totalCommandCount += renderViewCommandBuilder->commandData().size(); commandData.reserve(totalCommandCount); - //assert(totalCommandCount != 0); - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) + // assert(totalCommandCount != 0); + for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : + qAsConst(m_renderViewCommandBuilderJobs)) commandData += std::move(renderViewCommandBuilder->commandData()); } - // Store new cache - RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode]; + RendererCache::LeafNodeData &writableCacheForLeaf = + cache->leafNodeCache[m_leafNode]; writableCacheForLeaf.renderCommandData = std::move(commandData); } const EntityRenderCommandData commandData = dataCacheForLeaf.renderCommandData; const QVector filteredEntities = dataCacheForLeaf.filterEntitiesByLayer; - QVector renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities; + QVector renderableEntities = + isDraw ? cache->renderableEntities : cache->computeEntities; QVector lightSources = cache->gatheredLights; rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer); @@ -298,8 +311,10 @@ public: ///////// END OF CACHE LOCKED //////////// // Filter out entities that weren't selected by the layer filters - // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities); + // Remove all entities from the compute and renderable vectors that aren't in the + // filtered layer vector + renderableEntities = + RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities); // Set the light sources, with layer filters applied. for (int i = 0; i < lightSources.count(); ++i) { @@ -311,10 +326,12 @@ public: if (isDraw) { // Filter out frustum culled entity for drawable entities if (rv->frustumCulling()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); + renderableEntities = RenderViewBuilder::entitiesInSubset( + renderableEntities, m_frustumCullingJob->visibleEntities()); // Filter out entities which didn't satisfy proximity filtering if (!rv->proximityFilterIds().empty()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities()); + renderableEntities = RenderViewBuilder::entitiesInSubset( + renderableEntities, m_filterProximityJob->filteredEntities()); } // Early return in case we have nothing to filter @@ -352,13 +369,19 @@ public: // Split among the number of command builders // The idealPacketSize is at least 100 entities per worker - const int idealPacketSize = std::min(std::max(100, filteredCommandData->size() / RenderViewBuilder::optimalJobCount()), filteredCommandData->size()); + const int idealPacketSize = std::min( + std::max(100, + filteredCommandData->size() / RenderViewBuilder::optimalJobCount()), + filteredCommandData->size()); const int m = findIdealNumberOfWorkers(filteredCommandData->size(), idealPacketSize); for (int i = 0; i < m; ++i) { - const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i); - const int count = (i == m - 1) ? filteredCommandData->size() - (i * idealPacketSize) : idealPacketSize; - renderViewCommandBuilder->setRenderables(filteredCommandData, i * idealPacketSize, count); + const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = + m_renderViewCommandUpdaterJobs.at(i); + const int count = (i == m - 1) ? filteredCommandData->size() - (i * idealPacketSize) + : idealPacketSize; + renderViewCommandBuilder->setRenderables(filteredCommandData, i * idealPacketSize, + count); } } } @@ -380,7 +403,8 @@ class SetClearDrawBufferIndex public: explicit SetClearDrawBufferIndex(const RenderViewInitializerJobPtr &renderViewJob) : m_renderViewJob(renderViewJob) - {} + { + } void operator()() { @@ -388,8 +412,8 @@ public: QVector &clearBuffersInfo = rv->specificClearColorBufferInfo(); const AttachmentPack &attachmentPack = rv->attachmentPack(); for (ClearBufferInfo &clearBufferInfo : clearBuffersInfo) - clearBufferInfo.drawBufferIndex = attachmentPack.getDrawBufferIndex(clearBufferInfo.attchmentPoint); - + clearBufferInfo.drawBufferIndex = + attachmentPack.getDrawBufferIndex(clearBufferInfo.attchmentPoint); } private: @@ -400,11 +424,10 @@ class SyncFilterEntityByLayer { public: explicit SyncFilterEntityByLayer(const FilterLayerEntityJobPtr &filterEntityByLayerJob, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_renderer(renderer) - , m_leafNode(leafNode) + Renderer *renderer, FrameGraphNode *leafNode) + : m_filterEntityByLayerJob(filterEntityByLayerJob), + m_renderer(renderer), + m_leafNode(leafNode) { } @@ -413,7 +436,8 @@ public: QMutexLocker lock(m_renderer->cache()->mutex()); // Save the filtered by layer subset into the cache const QVector filteredEntities = m_filterEntityByLayerJob->filteredEntities(); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; + RendererCache::LeafNodeData &dataCacheForLeaf = + m_renderer->cache()->leafNodeCache[m_leafNode]; dataCacheForLeaf.filterEntitiesByLayer = filteredEntities; } @@ -426,23 +450,25 @@ private: class SyncMaterialParameterGatherer { public: - explicit SyncMaterialParameterGatherer(const QVector &materialParameterGathererJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_materialParameterGathererJobs(materialParameterGathererJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) + explicit SyncMaterialParameterGatherer( + const QVector &materialParameterGathererJobs, + Renderer *renderer, FrameGraphNode *leafNode) + : m_materialParameterGathererJobs(materialParameterGathererJobs), + m_renderer(renderer), + m_leafNode(leafNode) { } void operator()() { QMutexLocker lock(m_renderer->cache()->mutex()); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; + RendererCache::LeafNodeData &dataCacheForLeaf = + m_renderer->cache()->leafNodeCache[m_leafNode]; dataCacheForLeaf.materialParameterGatherer.clear(); for (const auto &materialGatherer : qAsConst(m_materialParameterGathererJobs)) - dataCacheForLeaf.materialParameterGatherer.unite(materialGatherer->materialToPassAndParameter()); + dataCacheForLeaf.materialParameterGatherer.unite( + materialGatherer->materialToPassAndParameter()); } private: @@ -453,20 +479,24 @@ private: } // anonymous -RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer) - : m_leafNode(leafNode) - , m_renderViewIndex(renderViewIndex) - , m_renderer(renderer) - , m_layerCacheNeedsToBeRebuilt(false) - , m_materialGathererCacheNeedsToBeRebuilt(false) - , m_renderCommandCacheNeedsToBeRebuilt(false) - , m_renderViewJob(RenderViewInitializerJobPtr::create()) - , m_filterEntityByLayerJob() - , m_frustumCullingJob(new Render::FrustumCullingJob()) - , m_syncPreFrustumCullingJob(SynchronizerJobPtr::create(SyncPreFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling)) - , m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex)) - , m_syncFilterEntityByLayerJob() - , m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create()) +RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, + Renderer *renderer) + : m_leafNode(leafNode), + m_renderViewIndex(renderViewIndex), + m_renderer(renderer), + m_layerCacheNeedsToBeRebuilt(false), + m_materialGathererCacheNeedsToBeRebuilt(false), + m_renderCommandCacheNeedsToBeRebuilt(false), + m_renderViewJob(RenderViewInitializerJobPtr::create()), + m_filterEntityByLayerJob(), + m_frustumCullingJob(new Render::FrustumCullingJob()), + m_syncPreFrustumCullingJob(SynchronizerJobPtr::create( + SyncPreFrustumCulling(m_renderViewJob, m_frustumCullingJob), + JobTypes::SyncFrustumCulling)), + m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create( + SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex)), + m_syncFilterEntityByLayerJob(), + m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create()) { } @@ -558,11 +588,10 @@ void RenderViewBuilder::prepareJobs() auto renderViewCommandBuilder = Render::Rhi::RenderViewCommandBuilderJobPtr::create(); m_renderViewCommandBuilderJobs.push_back(renderViewCommandBuilder); } - m_syncRenderViewPreCommandBuildingJob = SynchronizerJobPtr::create(SyncPreCommandBuilding(m_renderViewJob, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode), - JobTypes::SyncRenderViewPreCommandBuilding); + m_syncRenderViewPreCommandBuildingJob = SynchronizerJobPtr::create( + SyncPreCommandBuilding(m_renderViewJob, m_renderViewCommandBuilderJobs, m_renderer, + m_leafNode), + JobTypes::SyncRenderViewPreCommandBuilding); } m_renderViewJob->setRenderer(m_renderer); @@ -580,58 +609,56 @@ void RenderViewBuilder::prepareJobs() if (m_materialGathererCacheNeedsToBeRebuilt) { // Since Material gathering is an heavy task, we split it - const QVector materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles(); - const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount; - const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount; + const QVector materialHandles = + m_renderer->nodeManagers()->materialManager()->activeHandles(); + const int elementsPerJob = + materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount; + const int lastRemaingElements = + materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount; m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { auto materialGatherer = MaterialParameterGathererJobPtr::create(); materialGatherer->setNodeManagers(m_renderer->nodeManagers()); if (i == RenderViewBuilder::m_optimalParallelJobCount - 1) - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements)); + materialGatherer->setHandles(materialHandles.mid( + i * elementsPerJob, elementsPerJob + lastRemaingElements)); else - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob)); + materialGatherer->setHandles( + materialHandles.mid(i * elementsPerJob, elementsPerJob)); m_materialGathererJobs.push_back(materialGatherer); } - m_syncMaterialGathererJob = SynchronizerJobPtr::create(SyncMaterialParameterGatherer(m_materialGathererJobs, - m_renderer, - m_leafNode), - JobTypes::SyncMaterialGatherer); + m_syncMaterialGathererJob = SynchronizerJobPtr::create( + SyncMaterialParameterGatherer(m_materialGathererJobs, m_renderer, m_leafNode), + JobTypes::SyncMaterialGatherer); } if (m_layerCacheNeedsToBeRebuilt) { m_filterEntityByLayerJob = Render::FilterLayerEntityJobPtr::create(); m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers()); - m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create(SyncFilterEntityByLayer(m_filterEntityByLayerJob, - m_renderer, - m_leafNode), - JobTypes::SyncFilterEntityByLayer); + m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create( + SyncFilterEntityByLayer(m_filterEntityByLayerJob, m_renderer, m_leafNode), + JobTypes::SyncFilterEntityByLayer); } - m_syncRenderViewPreCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPreCommandUpdate(m_renderViewJob, - m_frustumCullingJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode, - m_renderCommandCacheNeedsToBeRebuilt), - JobTypes::SyncRenderViewPreCommandUpdate); - - m_syncRenderViewPostCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPostCommandUpdate(m_renderViewJob, - m_renderViewCommandUpdaterJobs, - m_renderer), - JobTypes::SyncRenderViewPostCommandUpdate); - - m_syncRenderViewPostInitializationJob = SynchronizerJobPtr::create(SyncRenderViewPostInitialization(m_renderViewJob, - m_frustumCullingJob, - m_filterEntityByLayerJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs), - JobTypes::SyncRenderViewInitialization); + m_syncRenderViewPreCommandUpdateJob = SynchronizerJobPtr::create( + SyncRenderViewPreCommandUpdate(m_renderViewJob, m_frustumCullingJob, + m_filterProximityJob, m_materialGathererJobs, + m_renderViewCommandUpdaterJobs, + m_renderViewCommandBuilderJobs, m_renderer, m_leafNode, + m_renderCommandCacheNeedsToBeRebuilt), + JobTypes::SyncRenderViewPreCommandUpdate); + + m_syncRenderViewPostCommandUpdateJob = SynchronizerJobPtr::create( + SyncRenderViewPostCommandUpdate(m_renderViewJob, m_renderViewCommandUpdaterJobs, + m_renderer), + JobTypes::SyncRenderViewPostCommandUpdate); + + m_syncRenderViewPostInitializationJob = SynchronizerJobPtr::create( + SyncRenderViewPostInitialization(m_renderViewJob, m_frustumCullingJob, + m_filterEntityByLayerJob, m_filterProximityJob, + m_materialGathererJobs, m_renderViewCommandUpdaterJobs, + m_renderViewCommandBuilderJobs), + JobTypes::SyncRenderViewInitialization); } QVector RenderViewBuilder::buildJobHierachy() const @@ -691,8 +718,10 @@ QVector RenderViewBuilder::buildJobHierachy() const jobs.push_back(m_syncRenderViewPostInitializationJob); // Step 2 if (m_renderCommandCacheNeedsToBeRebuilt) { // Step 3 - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->computableEntityFilterJob()); - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->renderableEntityFilterJob()); + m_syncRenderViewPreCommandBuildingJob->addDependency( + m_renderer->computableEntityFilterJob()); + m_syncRenderViewPreCommandBuildingJob->addDependency( + m_renderer->renderableEntityFilterJob()); m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncRenderViewPostInitializationJob); if (m_materialGathererCacheNeedsToBeRebuilt) @@ -723,7 +752,7 @@ QVector RenderViewBuilder::buildJobHierachy() const jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3 if (m_materialGathererCacheNeedsToBeRebuilt) { - for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { + for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { materialGatherer->addDependency(m_syncRenderViewPostInitializationJob); materialGatherer->addDependency(m_renderer->introspectShadersJob()); materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob()); @@ -792,12 +821,12 @@ int RenderViewBuilder::optimalJobCount() return RenderViewBuilder::m_optimalParallelJobCount; } -QVector RenderViewBuilder::entitiesInSubset(const QVector &entities, const QVector &subset) +QVector RenderViewBuilder::entitiesInSubset(const QVector &entities, + const QVector &subset) { QVector intersection; intersection.reserve(qMin(entities.size(), subset.size())); - std::set_intersection(entities.begin(), entities.end(), - subset.begin(), subset.end(), + std::set_intersection(entities.begin(), entities.end(), subset.begin(), subset.end(), std::back_inserter(intersection)); return intersection; diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h index 6ca904a24..4df57b139 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h @@ -78,7 +78,8 @@ using SynchronizerJobPtr = GenericLambdaJobPtr>; class Q_AUTOTEST_EXPORT RenderViewBuilder { public: - explicit RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer); + explicit RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, + Renderer *renderer); RenderViewInitializerJobPtr renderViewJob() const; FilterLayerEntityJobPtr filterEntityByLayerJob() const; @@ -110,7 +111,8 @@ public: bool renderCommandCacheNeedsToBeRebuilt() const; static int optimalJobCount(); - static QVector entitiesInSubset(const QVector &entities, const QVector &subset); + static QVector entitiesInSubset(const QVector &entities, + const QVector &subset); private: Render::FrameGraphNode *m_leafNode; diff --git a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline.cpp b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline.cpp index 25e1c8c63..2a76f9c10 100644 --- a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline.cpp +++ b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline.cpp @@ -48,17 +48,15 @@ namespace Render { namespace Rhi { RHIGraphicsPipeline::RHIGraphicsPipeline() - : m_rvUbo(nullptr) - , m_cmdUbo(nullptr) - , m_pipeline(nullptr) - , m_shaderResourceBindings(nullptr) - , m_score(0) + : m_rvUbo(nullptr), + m_cmdUbo(nullptr), + m_pipeline(nullptr), + m_shaderResourceBindings(nullptr), + m_score(0) { } -RHIGraphicsPipeline::~RHIGraphicsPipeline() -{ -} +RHIGraphicsPipeline::~RHIGraphicsPipeline() { } void RHIGraphicsPipeline::cleanup() { diff --git a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h index 61f0fd2a8..a13bf50d3 100644 --- a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h +++ b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h @@ -69,8 +69,8 @@ class RHIGraphicsPipeline public: struct UBOBuffer { - HRHIBuffer handle{}; - RHIBuffer *buffer{}; + HRHIBuffer handle {}; + RHIBuffer *buffer {}; }; RHIGraphicsPipeline(); @@ -80,17 +80,26 @@ public: QRhiBuffer *renderViewUBO() const { return m_rvUbo; } QRhiGraphicsPipeline *pipeline() const { return m_pipeline; } QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; } - QHash ubos() const { return m_ubos; } + QHash ubos() const { return m_ubos; } int score() const { return m_score; } void setPipeline(QRhiGraphicsPipeline *pipeline) { m_pipeline = pipeline; } void setCommandUBO(QRhiBuffer *commandUBO) { m_cmdUbo = commandUBO; } void setRenderViewUBO(QRhiBuffer *rvUBO) { m_rvUbo = rvUBO; } - void setShaderResourceBindings(QRhiShaderResourceBindings *shaderResourceBindings) { m_shaderResourceBindings = shaderResourceBindings; } + void setShaderResourceBindings(QRhiShaderResourceBindings *shaderResourceBindings) + { + m_shaderResourceBindings = shaderResourceBindings; + } void setUBOs(const QHash ubos) { m_ubos = ubos; } - void setAttributesToBindingHash(const QHash &attributeNameToBinding) { m_attributeNameIdToBindingIndex = attributeNameToBinding; } - int bindingIndexForAttribute(int attributeNameId) const { return m_attributeNameIdToBindingIndex.value(attributeNameId, -1); } + void setAttributesToBindingHash(const QHash &attributeNameToBinding) + { + m_attributeNameIdToBindingIndex = attributeNameToBinding; + } + int bindingIndexForAttribute(int attributeNameId) const + { + return m_attributeNameIdToBindingIndex.value(attributeNameId, -1); + } void increaseScore() { ++m_score; } void decreaseScore() { --m_score; } @@ -115,5 +124,4 @@ private: QT_END_NAMESPACE - #endif // QT3DRENDER_RENDER_RHI_RHIGRAPHICSPIPELINE_H diff --git a/src/plugins/renderers/rhi/renderer/rhishader.cpp b/src/plugins/renderers/rhi/renderer/rhishader.cpp index ffb74145a..20da46347 100644 --- a/src/plugins/renderers/rhi/renderer/rhishader.cpp +++ b/src/plugins/renderers/rhi/renderer/rhishader.cpp @@ -52,8 +52,7 @@ namespace Render { namespace Rhi { -RHIShader::RHIShader() - : m_isLoaded(false) +RHIShader::RHIShader() : m_isLoaded(false) { m_shaderCode.resize(static_cast(QShaderProgram::Compute) + 1); } @@ -93,16 +92,19 @@ QVector RHIShader::shaderCode() const return m_shaderCode; } -namespace +namespace { +static constexpr QRhiVertexInputAttribute::Format +rhiInputType(QShaderDescription::VariableType type) { -static constexpr QRhiVertexInputAttribute::Format rhiInputType(QShaderDescription::VariableType type) -{ - switch (type) - { - case QShaderDescription::Vec4: return QRhiVertexInputAttribute::Float4; - case QShaderDescription::Vec3: return QRhiVertexInputAttribute::Float3; - case QShaderDescription::Vec2: return QRhiVertexInputAttribute::Float2; - case QShaderDescription::Float: return QRhiVertexInputAttribute::Float; + switch (type) { + case QShaderDescription::Vec4: + return QRhiVertexInputAttribute::Float4; + case QShaderDescription::Vec3: + return QRhiVertexInputAttribute::Float3; + case QShaderDescription::Vec2: + return QRhiVertexInputAttribute::Float2; + case QShaderDescription::Float: + return QRhiVertexInputAttribute::Float; default: // TODO UNormByte4, UNormByte2, UNormByte RHI_UNIMPLEMENTED; @@ -113,81 +115,145 @@ static constexpr QRhiVertexInputAttribute::Format rhiInputType(QShaderDescriptio static constexpr int rhiTypeSize(QShaderDescription::VariableType type) { - switch (type) - { - case QShaderDescription::Unknown: return 0; - - case QShaderDescription::Float: return 1; - case QShaderDescription::Vec2: return 2; - case QShaderDescription::Vec3: return 3; - case QShaderDescription::Vec4: return 4; - case QShaderDescription::Mat2: return 2*2; - case QShaderDescription::Mat2x3: return 2*3; - case QShaderDescription::Mat2x4: return 2*4; - case QShaderDescription::Mat3: return 3*3; - case QShaderDescription::Mat3x2: return 3*2; - case QShaderDescription::Mat3x4: return 3*4; - case QShaderDescription::Mat4: return 4*4; - case QShaderDescription::Mat4x2: return 4*2; - case QShaderDescription::Mat4x3: return 4*3; - - case QShaderDescription::Int: return 1; - case QShaderDescription::Int2: return 2; - case QShaderDescription::Int3: return 3; - case QShaderDescription::Int4: return 4; - - case QShaderDescription::Uint: return 1; - case QShaderDescription::Uint2: return 2; - case QShaderDescription::Uint3: return 3; - case QShaderDescription::Uint4: return 4; - - case QShaderDescription::Bool: return 1; - case QShaderDescription::Bool2: return 2; - case QShaderDescription::Bool3: return 3; - case QShaderDescription::Bool4: return 4; - - case QShaderDescription::Double: return 1; - case QShaderDescription::Double2: return 2; - case QShaderDescription::Double3: return 3; - case QShaderDescription::Double4: return 4; - case QShaderDescription::DMat2: return 2*2; - case QShaderDescription::DMat2x3: return 2*3; - case QShaderDescription::DMat2x4: return 2*4; - case QShaderDescription::DMat3: return 3*3; - case QShaderDescription::DMat3x2: return 3*2; - case QShaderDescription::DMat3x4: return 3*4; - case QShaderDescription::DMat4: return 4*4; - case QShaderDescription::DMat4x2: return 4*2; - case QShaderDescription::DMat4x3: return 4*3; - - case QShaderDescription::Sampler1D: return 0; - case QShaderDescription::Sampler2D: return 0; - case QShaderDescription::Sampler2DMS: return 0; - case QShaderDescription::Sampler3D: return 0; - case QShaderDescription::SamplerCube: return 0; - case QShaderDescription::Sampler1DArray: return 0; - case QShaderDescription::Sampler2DArray: return 0; - case QShaderDescription::Sampler2DMSArray: return 0; - case QShaderDescription::Sampler3DArray: return 0; - case QShaderDescription::SamplerCubeArray: return 0; - case QShaderDescription::SamplerRect: return 0; - case QShaderDescription::SamplerBuffer: return 0; - - case QShaderDescription::Image1D: return 0; - case QShaderDescription::Image2D: return 0; - case QShaderDescription::Image2DMS: return 0; - case QShaderDescription::Image3D: return 0; - case QShaderDescription::ImageCube: return 0; - case QShaderDescription::Image1DArray: return 0; - case QShaderDescription::Image2DArray: return 0; - case QShaderDescription::Image2DMSArray: return 0; - case QShaderDescription::Image3DArray: return 0; - case QShaderDescription::ImageCubeArray: return 0; - case QShaderDescription::ImageRect: return 0; - case QShaderDescription::ImageBuffer: return 0; - - case QShaderDescription::Struct: return 0; - default: return 0; + switch (type) { + case QShaderDescription::Unknown: + return 0; + + case QShaderDescription::Float: + return 1; + case QShaderDescription::Vec2: + return 2; + case QShaderDescription::Vec3: + return 3; + case QShaderDescription::Vec4: + return 4; + case QShaderDescription::Mat2: + return 2 * 2; + case QShaderDescription::Mat2x3: + return 2 * 3; + case QShaderDescription::Mat2x4: + return 2 * 4; + case QShaderDescription::Mat3: + return 3 * 3; + case QShaderDescription::Mat3x2: + return 3 * 2; + case QShaderDescription::Mat3x4: + return 3 * 4; + case QShaderDescription::Mat4: + return 4 * 4; + case QShaderDescription::Mat4x2: + return 4 * 2; + case QShaderDescription::Mat4x3: + return 4 * 3; + + case QShaderDescription::Int: + return 1; + case QShaderDescription::Int2: + return 2; + case QShaderDescription::Int3: + return 3; + case QShaderDescription::Int4: + return 4; + + case QShaderDescription::Uint: + return 1; + case QShaderDescription::Uint2: + return 2; + case QShaderDescription::Uint3: + return 3; + case QShaderDescription::Uint4: + return 4; + + case QShaderDescription::Bool: + return 1; + case QShaderDescription::Bool2: + return 2; + case QShaderDescription::Bool3: + return 3; + case QShaderDescription::Bool4: + return 4; + + case QShaderDescription::Double: + return 1; + case QShaderDescription::Double2: + return 2; + case QShaderDescription::Double3: + return 3; + case QShaderDescription::Double4: + return 4; + case QShaderDescription::DMat2: + return 2 * 2; + case QShaderDescription::DMat2x3: + return 2 * 3; + case QShaderDescription::DMat2x4: + return 2 * 4; + case QShaderDescription::DMat3: + return 3 * 3; + case QShaderDescription::DMat3x2: + return 3 * 2; + case QShaderDescription::DMat3x4: + return 3 * 4; + case QShaderDescription::DMat4: + return 4 * 4; + case QShaderDescription::DMat4x2: + return 4 * 2; + case QShaderDescription::DMat4x3: + return 4 * 3; + + case QShaderDescription::Sampler1D: + return 0; + case QShaderDescription::Sampler2D: + return 0; + case QShaderDescription::Sampler2DMS: + return 0; + case QShaderDescription::Sampler3D: + return 0; + case QShaderDescription::SamplerCube: + return 0; + case QShaderDescription::Sampler1DArray: + return 0; + case QShaderDescription::Sampler2DArray: + return 0; + case QShaderDescription::Sampler2DMSArray: + return 0; + case QShaderDescription::Sampler3DArray: + return 0; + case QShaderDescription::SamplerCubeArray: + return 0; + case QShaderDescription::SamplerRect: + return 0; + case QShaderDescription::SamplerBuffer: + return 0; + + case QShaderDescription::Image1D: + return 0; + case QShaderDescription::Image2D: + return 0; + case QShaderDescription::Image2DMS: + return 0; + case QShaderDescription::Image3D: + return 0; + case QShaderDescription::ImageCube: + return 0; + case QShaderDescription::Image1DArray: + return 0; + case QShaderDescription::Image2DArray: + return 0; + case QShaderDescription::Image2DMSArray: + return 0; + case QShaderDescription::Image3DArray: + return 0; + case QShaderDescription::ImageCubeArray: + return 0; + case QShaderDescription::ImageRect: + return 0; + case QShaderDescription::ImageBuffer: + return 0; + + case QShaderDescription::Struct: + return 0; + default: + return 0; } } @@ -195,9 +261,9 @@ template QVector stableRemoveDuplicates(QVector in, Pred predicate) { QVector out; - for (const auto& element : in) - { - if (std::none_of(out.begin(), out.end(), [&] (T& other) { return predicate(element, other); })) + for (const auto &element : in) { + if (std::none_of(out.begin(), out.end(), + [&](T &other) { return predicate(element, other); })) out.push_back(element); } return out; @@ -208,25 +274,19 @@ QVector stableRemoveDuplicates(QVector in, Pred predicate) // changes dims into [0, 3, 3] // Given dims == [0, 3, 3] and maxs == [4, 4, 4] // changes dims into [1, 0, 0] -bool incrementArray(QVarLengthArray& dims, const QVector& maxs) +bool incrementArray(QVarLengthArray &dims, const QVector &maxs) { const int n = dims.size(); int i = n; - for (; i --> 0 ;) - { - if (dims[i] == maxs[i] - 1) - { - if ( i == 0 ) - { + for (; i-- > 0;) { + if (dims[i] == maxs[i] - 1) { + if (i == 0) { // we're done return false; } continue; - - } - else - { + } else { dims[i]++; for (int j = i + 1; j < n; j++) { dims[j] = 0; @@ -241,15 +301,15 @@ bool incrementArray(QVarLengthArray& dims, const QVector& maxs) // for all valable array values, given an array of dimension sizes. // Dimensions must all be >= 1 template -void forEachArrayAccessor(const QVector& maxs, F f) +void forEachArrayAccessor(const QVector &maxs, F f) { - if (std::any_of(maxs.begin(), maxs.end(), [] (int v) { return v <= 0; })) + if (std::any_of(maxs.begin(), maxs.end(), [](int v) { return v <= 0; })) return; QVarLengthArray dims; dims.resize(maxs.size()); - // QVarLengthArray does not initialize ints + // QVarLengthArray does not initialize ints std::fill(dims.begin(), dims.end(), 0); QString str; @@ -264,7 +324,8 @@ void forEachArrayAccessor(const QVector& maxs, F f) } } -void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable& member, QString parentName) +void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable &member, + QString parentName) { const bool isStruct = !member.structMembers.empty(); const bool isArray = !member.arrayDims.empty(); @@ -273,29 +334,24 @@ void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable& membe const QString fullMemberName = parentName + member.name; m_unqualifiedUniformNames << fullMemberName; - if (isStruct && !isArray) - { + if (isStruct && !isArray) { m_structNames << fullMemberName; m_structNamesIds << StringToInt::lookupId(fullMemberName); - for (const QShaderDescription::BlockVariable& bv : member.structMembers) - { + for (const QShaderDescription::BlockVariable& bv : member.structMembers) { // recordAllUniforms("baz", "foo.bar.") recordAllUniforms(bv, fullMemberName + QLatin1Char('.')); } - } - else if (!isStruct && isArray) - { + } else if (!isStruct && isArray) { // We iterate through all the [l][n][m] by building [0][0][0] and incrementing - forEachArrayAccessor(member.arrayDims, [&] (const QString& str) { + forEachArrayAccessor(member.arrayDims, [&](const QString &str) { // "foo.bar[1][2]" m_unqualifiedUniformNames << (fullMemberName + str); // Question : does it make sense to also record foo[0], foo[0][0], etc... // if there are e.g. 3 dimensions ? }); } - else if (isStruct && isArray) - { + else if (isStruct && isArray) { // Record the struct names forEachArrayAccessor(member.arrayDims, [&] (const QString& str) { m_structNames << (fullMemberName + str); @@ -303,8 +359,7 @@ void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable& membe }); // Record the struct members - for (const QShaderDescription::BlockVariable& bv : member.structMembers) - { + for (const QShaderDescription::BlockVariable& bv : member.structMembers) { forEachArrayAccessor(member.arrayDims, [&] (const QString& str) { //recordAllUniforms("baz", "foo.bar[1][2].") recordAllUniforms(bv, fullMemberName + str + QLatin1Char('.')); @@ -315,7 +370,7 @@ void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable& membe void RHIShader::introspect() { - const thread_local QRegularExpression generatedUBOName{"_[0-9]+"}; + const thread_local QRegularExpression generatedUBOName { "_[0-9]+" }; QVector rhiUBO; QVector rhiSSBO; @@ -327,10 +382,12 @@ void RHIShader::introspect() // Introspect shader vertex input if (m_stages[QShader::VertexStage].isValid()) { - const QShaderDescription& vtx = m_stages[QShader::VertexStage].description(); + const QShaderDescription &vtx = m_stages[QShader::VertexStage].description(); - for (const QShaderDescription::InOutVariable& input : vtx.inputVariables()) { - attributes.push_back(ShaderAttribute{input.name, StringToInt::lookupId(input.name), input.type, rhiTypeSize(input.type), input.location}); + for (const QShaderDescription::InOutVariable &input : vtx.inputVariables()) { + attributes.push_back(ShaderAttribute { input.name, StringToInt::lookupId(input.name), + input.type, rhiTypeSize(input.type), + input.location }); } rhiUBO += vtx.uniformBlocks(); @@ -340,48 +397,58 @@ void RHIShader::introspect() // Introspect shader uniforms if (m_stages[QShader::FragmentStage].isValid()) { - const QShaderDescription& frag = m_stages[QShader::FragmentStage].description(); - for (const QShaderDescription::InOutVariable& sampler : frag.combinedImageSamplers()) { - samplers.push_back(ShaderAttribute{sampler.name, StringToInt::lookupId(sampler.name), sampler.type, rhiTypeSize(sampler.type), sampler.binding}); + const QShaderDescription &frag = m_stages[QShader::FragmentStage].description(); + for (const QShaderDescription::InOutVariable &sampler : frag.combinedImageSamplers()) { + samplers.push_back(ShaderAttribute { sampler.name, StringToInt::lookupId(sampler.name), + sampler.type, rhiTypeSize(sampler.type), + sampler.binding }); } - for (const QShaderDescription::InOutVariable& image : frag.storageImages()) { - images.push_back(ShaderAttribute{image.name, StringToInt::lookupId(image.name), image.type, rhiTypeSize(image.type), image.binding}); + for (const QShaderDescription::InOutVariable &image : frag.storageImages()) { + images.push_back(ShaderAttribute { image.name, StringToInt::lookupId(image.name), + image.type, rhiTypeSize(image.type), + image.binding }); } rhiUBO += frag.uniformBlocks(); rhiSSBO += frag.storageBlocks(); } - rhiUBO = stableRemoveDuplicates(rhiUBO, [] (const QShaderDescription::UniformBlock& lhs, const QShaderDescription::UniformBlock& rhs) { - return lhs.blockName == rhs.blockName; - }); - rhiSSBO = stableRemoveDuplicates(rhiSSBO, [] (const QShaderDescription::StorageBlock& lhs, const QShaderDescription::StorageBlock& rhs) { - return lhs.blockName == rhs.blockName; - }); - - for (const QShaderDescription::UniformBlock& ubo : rhiUBO) { - uniformBlocks.push_back(ShaderUniformBlock{ubo.blockName, StringToInt::lookupId(ubo.blockName), -1, ubo.binding, ubo.members.size(), ubo.size}); + rhiUBO = stableRemoveDuplicates(rhiUBO, + [](const QShaderDescription::UniformBlock &lhs, + const QShaderDescription::UniformBlock &rhs) { + return lhs.blockName == rhs.blockName; + }); + rhiSSBO = stableRemoveDuplicates(rhiSSBO, + [](const QShaderDescription::StorageBlock &lhs, + const QShaderDescription::StorageBlock &rhs) { + return lhs.blockName == rhs.blockName; + }); + + for (const QShaderDescription::UniformBlock &ubo : rhiUBO) { + uniformBlocks.push_back(ShaderUniformBlock { ubo.blockName, + StringToInt::lookupId(ubo.blockName), -1, + ubo.binding, ubo.members.size(), ubo.size }); const bool addUnqualifiedUniforms = ubo.structName.contains(generatedUBOName); - // Parse Uniform Block members so that we can later on map a Parameter name to an actual member + // Parse Uniform Block members so that we can later on map a Parameter name to an actual + // member const QVector members = ubo.members; QVector namesIds; namesIds.reserve(members.size()); - for (const QShaderDescription::BlockVariable& member : members) { + for (const QShaderDescription::BlockVariable &member : members) { namesIds << StringToInt::lookupId(member.name); - if (addUnqualifiedUniforms) - { + if (addUnqualifiedUniforms) { recordAllUniforms(member, QStringLiteral("")); } } m_uniformsNamesIds += namesIds; - m_uboMembers.push_back({uniformBlocks.last(), members}); + m_uboMembers.push_back({ uniformBlocks.last(), members }); } - for (const QShaderDescription::StorageBlock& ssbo : rhiSSBO) { - storageBlocks.push_back(ShaderStorageBlock{ssbo.blockName, -1, -1, ssbo.binding, 0, 0}); + for (const QShaderDescription::StorageBlock &ssbo : rhiSSBO) { + storageBlocks.push_back(ShaderStorageBlock { ssbo.blockName, -1, -1, ssbo.binding, 0, 0 }); } initializeAttributes(attributes); @@ -416,7 +483,7 @@ ShaderUniformBlock RHIShader::uniformBlockForBlockNameId(int blockNameId) const return ShaderUniformBlock(); } -ShaderUniformBlock RHIShader::uniformBlockForBlockName(const QString &blockName) const noexcept +ShaderUniformBlock RHIShader::uniformBlockForBlockName(const QString &blockName) const noexcept { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_name == blockName) { @@ -473,10 +540,8 @@ bool RHIShader::hasUniform(int nameId) const noexcept bool RHIShader::hasActiveVariables() const noexcept { - return !m_attributeNamesIds.empty() - || !m_uniformsNamesIds.empty() - || !m_uniformBlockNamesIds.empty() - || !m_shaderStorageBlockNamesIds.empty(); + return !m_attributeNamesIds.empty() || !m_uniformsNamesIds.empty() + || !m_uniformBlockNamesIds.empty() || !m_shaderStorageBlockNamesIds.empty(); } void RHIShader::prepareUniforms(ShaderParameterPack &pack) @@ -504,7 +569,7 @@ void RHIShader::setFragOutputs(const QHash &fragOutputs) QMutexLocker lock(&m_mutex); m_fragOutputs = fragOutputs; } -// updateDNA(); + // updateDNA(); } const QHash RHIShader::fragOutputs() const @@ -575,19 +640,24 @@ void RHIShader::initializeUniformBlocks(const QVector &unifo while (uniformsIt != uniformsEnd && uniformNamesIt != uniformNamesEnd) { if (uniformsIt->m_blockIndex == uniformBlockDescription[i].m_index) { QString uniformName = *uniformNamesIt; - if (!m_uniformBlockNames[i].isEmpty() && !uniformName.startsWith(m_uniformBlockNames[i])) + if (!m_uniformBlockNames[i].isEmpty() + && !uniformName.startsWith(m_uniformBlockNames[i])) uniformName = m_uniformBlockNames[i] + QLatin1Char('.') + *uniformNamesIt; activeUniformsInBlock.insert(uniformName, *uniformsIt); - qCDebug(Shaders) << "Active Uniform Block " << uniformName << " in block " << m_uniformBlockNames[i] << " at index " << uniformsIt->m_blockIndex; + qCDebug(Shaders) << "Active Uniform Block " << uniformName << " in block " + << m_uniformBlockNames[i] << " at index " + << uniformsIt->m_blockIndex; } ++uniformsIt; ++uniformNamesIt; } - m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock); + m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, + activeUniformsInBlock); } } -void RHIShader::initializeShaderStorageBlocks(const QVector &shaderStorageBlockDescription) +void RHIShader::initializeShaderStorageBlocks( + const QVector &shaderStorageBlockDescription) { m_shaderStorageBlocks = shaderStorageBlockDescription; m_shaderStorageBlockNames.resize(shaderStorageBlockDescription.size()); @@ -596,8 +666,9 @@ void RHIShader::initializeShaderStorageBlocks(const QVector for (int i = 0, m = shaderStorageBlockDescription.size(); i < m; ++i) { m_shaderStorageBlockNames[i] = m_shaderStorageBlocks[i].m_name; m_shaderStorageBlockNamesIds[i] = StringToInt::lookupId(m_shaderStorageBlockNames[i]); - m_shaderStorageBlocks[i].m_nameId =m_shaderStorageBlockNamesIds[i]; - qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}"; + m_shaderStorageBlocks[i].m_nameId = m_shaderStorageBlockNamesIds[i]; + qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] + << "}"; } } diff --git a/src/plugins/renderers/rhi/renderer/rhishader_p.h b/src/plugins/renderers/rhi/renderer/rhishader_p.h index baed31fc2..774dcbdb0 100644 --- a/src/plugins/renderers/rhi/renderer/rhishader_p.h +++ b/src/plugins/renderers/rhi/renderer/rhishader_p.h @@ -51,7 +51,6 @@ // We mean it. // - #include #include #include @@ -59,7 +58,6 @@ #include #include - QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -117,12 +115,7 @@ public: ShaderStorageBlock storageBlockForBlockNameId(int blockNameId) const noexcept; ShaderStorageBlock storageBlockForBlockName(const QString &blockName) const noexcept; - enum ParameterKind { - Uniform, - UBO, - SSBO, - Struct - }; + enum ParameterKind { Uniform, UBO, SSBO, Struct }; ParameterKind categorizeVariable(int nameId) const noexcept; bool hasUniform(int nameId) const noexcept; @@ -131,12 +124,16 @@ public: void setShaderCode(const QVector shaderCode) { m_shaderCode = shaderCode; } QVector shaderCode() const; - const QShader& shaderStage(QShader::Stage stage) const noexcept { return m_stages[stage]; } + const QShader &shaderStage(QShader::Stage stage) const noexcept { return m_stages[stage]; } QVector uboMembers() const { return m_uboMembers; } - const QSet& unqualifiedUniformNames() const noexcept { return m_unqualifiedUniformNames; } + const QSet &unqualifiedUniformNames() const noexcept + { + return m_unqualifiedUniformNames; + } void introspect(); + private: bool m_isLoaded; QShader m_stages[6]; @@ -153,7 +150,7 @@ private: QVector m_uniformBlockNames; QVector m_uniformBlockNamesIds; QVector m_uniformBlocks; - QHash > m_uniformBlockIndexToShaderUniforms; + QHash> m_uniformBlockIndexToShaderUniforms; QSet m_unqualifiedUniformNames; QVector m_shaderStorageBlockNames; @@ -178,14 +175,14 @@ private: friend class SubmissionContext; void initializeAttributes(const QVector &attributesDescription); void initializeUniformBlocks(const QVector &uniformBlockDescription); - void initializeShaderStorageBlocks(const QVector &shaderStorageBlockDescription); + void + initializeShaderStorageBlocks(const QVector &shaderStorageBlockDescription); void initializeSamplers(const QVector &samplerDescription); void initializeImages(const QVector &imageDescription); void recordAllUniforms(const QShaderDescription::BlockVariable &ubo, QString parentName); QVector m_uboMembers; - mutable QMutex m_mutex; QMetaObject::Connection m_contextConnection; }; diff --git a/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp b/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp index ffe96c326..5a28d28d4 100644 --- a/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp +++ b/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp @@ -56,18 +56,17 @@ namespace Qt3DRender { namespace Render { namespace Rhi { -ShaderParameterPack::~ShaderParameterPack() -{ -} +ShaderParameterPack::~ShaderParameterPack() { } void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val) { m_uniforms.insert(glslNameId, val); } -void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId texId) +void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex, + Qt3DCore::QNodeId texId) { - for (NamedResource& texture : m_textures) { + for (NamedResource &texture : m_textures) { if (texture.glslNameId != glslNameId || texture.uniformArrayIndex != uniformArrayIndex) continue; @@ -78,9 +77,10 @@ void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex m_textures.append(NamedResource(glslNameId, texId, uniformArrayIndex, NamedResource::Texture)); } -void ShaderParameterPack::setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id) +void ShaderParameterPack::setImage(const int glslNameId, int uniformArrayIndex, + Qt3DCore::QNodeId id) { - for (NamedResource& image : m_images) { + for (NamedResource &image : m_images) { if (image.glslNameId != glslNameId || image.uniformArrayIndex != uniformArrayIndex) continue; diff --git a/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h b/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h index 5aa6ed695..94c485a94 100644 --- a/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h +++ b/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h @@ -74,7 +74,8 @@ namespace Rhi { class GraphicsContext; -struct BlockToUBO { +struct BlockToUBO +{ int m_blockIndex; Qt3DCore::QNodeId m_bufferID; bool m_needsUpdate; @@ -82,14 +83,14 @@ struct BlockToUBO { }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, BlockToUBO, Q_MOVABLE_TYPE) -struct BlockToSSBO { +struct BlockToSSBO +{ int m_blockIndex; int m_bindingIndex; Qt3DCore::QNodeId m_bufferID; }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, BlockToSSBO, Q_PRIMITIVE_TYPE) - struct PackUniformHash { QVector keys; @@ -120,7 +121,7 @@ struct PackUniformHash return UniformValue(); } - UniformValue& value(int key) + UniformValue &value(int key) { const int idx = keys.indexOf(key); if (idx != -1) @@ -135,10 +136,7 @@ struct PackUniformHash values.removeAt(idx); } - bool contains(int key) const - { - return keys.contains(key); - } + bool contains(int key) const { return keys.contains(key); } }; class Q_AUTOTEST_EXPORT ShaderParameterPack @@ -158,22 +156,19 @@ public: inline const PackUniformHash &uniforms() const { return m_uniforms; } UniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); } - struct NamedResource { - enum Type { - Texture = 0, - Image - }; - - NamedResource() {} - NamedResource(const int glslNameId, Qt3DCore::QNodeId texId, - int uniformArrayIndex, Type type) - : glslNameId(glslNameId) - , nodeId(texId) - , uniformArrayIndex(uniformArrayIndex) - , type(type) - { } + enum Type { Texture = 0, Image }; + + NamedResource() { } + NamedResource(const int glslNameId, Qt3DCore::QNodeId texId, int uniformArrayIndex, + Type type) + : glslNameId(glslNameId), + nodeId(texId), + uniformArrayIndex(uniformArrayIndex), + type(type) + { + } int glslNameId; Qt3DCore::QNodeId nodeId; @@ -182,16 +177,11 @@ public: bool operator==(const NamedResource &other) const { - return glslNameId == other.glslNameId && - nodeId == other.nodeId && - uniformArrayIndex == other.uniformArrayIndex && - type == other.type; + return glslNameId == other.glslNameId && nodeId == other.nodeId + && uniformArrayIndex == other.uniformArrayIndex && type == other.type; } - bool operator!=(const NamedResource &other) const - { - return !(*this == other); - } + bool operator!=(const NamedResource &other) const { return !(*this == other); } }; inline QVector textures() const { return m_textures; } @@ -199,6 +189,7 @@ public: inline QVector uniformBuffers() const { return m_uniformBuffers; } inline QVector shaderStorageBuffers() const { return m_shaderStorageBuffers; } inline QVector submissionUniforms() const { return m_submissionUniforms; } + private: PackUniformHash m_uniforms; @@ -210,7 +201,8 @@ private: friend class RenderView; }; -QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderParameterPack::NamedResource, Q_PRIMITIVE_TYPE) +QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderParameterPack::NamedResource, + Q_PRIMITIVE_TYPE) } // namespace Rhi } // namespace Render diff --git a/src/plugins/renderers/rhi/renderer/shadervariables_p.h b/src/plugins/renderers/rhi/renderer/shadervariables_p.h index 40f906b18..4e710a92c 100644 --- a/src/plugins/renderers/rhi/renderer/shadervariables_p.h +++ b/src/plugins/renderers/rhi/renderer/shadervariables_p.h @@ -66,25 +66,29 @@ namespace Rhi { struct ShaderAttribute { QString m_name; - int m_nameId{-1}; - QShaderDescription::VariableType m_type{}; - int m_size{}; - int m_location{-1}; + int m_nameId { -1 }; + QShaderDescription::VariableType m_type {}; + int m_size {}; + int m_location { -1 }; }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderAttribute, Q_MOVABLE_TYPE) struct ShaderUniform { QString m_name; - int m_nameId{-1}; - QShaderDescription::VariableType m_type{QShaderDescription::Unknown}; - int m_size{0}; - int m_offset{-1}; // -1 default, >= 0 if uniform defined in uniform block - int m_location{-1}; // -1 if uniform defined in a uniform block - int m_blockIndex{-1}; // -1 is the default, >= 0 if uniform defined in uniform block - int m_arrayStride{-1}; // -1 is the default, >= 0 if uniform defined in uniform block and if it's an array - int m_matrixStride{-1}; // -1 is the default, >= 0 uniform defined in uniform block and is a matrix - uint m_rawByteSize{0}; // contains byte size (size / type / strides) + int m_nameId { -1 }; + QShaderDescription::VariableType m_type { QShaderDescription::Unknown }; + int m_size { 0 }; + int m_offset { -1 }; // -1 default, >= 0 if uniform defined in uniform block + int m_location { -1 }; // -1 if uniform defined in a uniform block + int m_blockIndex { -1 }; // -1 is the default, >= 0 if uniform defined in uniform block + int m_arrayStride { + -1 + }; // -1 is the default, >= 0 if uniform defined in uniform block and if it's an array + int m_matrixStride { + -1 + }; // -1 is the default, >= 0 uniform defined in uniform block and is a matrix + uint m_rawByteSize { 0 }; // contains byte size (size / type / strides) // size, offset and strides are in bytes }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderUniform, Q_MOVABLE_TYPE) @@ -92,22 +96,22 @@ QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderUniform, Q_MOVABLE_TYPE) struct ShaderUniformBlock { QString m_name; - int m_nameId{-1}; - int m_index{-1}; - int m_binding{-1}; - int m_activeUniformsCount{0}; - int m_size{0}; + int m_nameId { -1 }; + int m_index { -1 }; + int m_binding { -1 }; + int m_activeUniformsCount { 0 }; + int m_size { 0 }; }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderUniformBlock, Q_MOVABLE_TYPE) struct ShaderStorageBlock { QString m_name; - int m_nameId{-1}; - int m_index{-1}; - int m_binding{-1}; - int m_size{0}; - int m_activeVariablesCount{0}; + int m_nameId { -1 }; + int m_index { -1 }; + int m_binding { -1 }; + int m_size { 0 }; + int m_activeVariablesCount { 0 }; }; QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, Rhi, ShaderStorageBlock, Q_MOVABLE_TYPE) diff --git a/src/plugins/renderers/rhi/textures/renderbuffer.cpp b/src/plugins/renderers/rhi/textures/renderbuffer.cpp index d4786e632..8df256ad1 100644 --- a/src/plugins/renderers/rhi/textures/renderbuffer.cpp +++ b/src/plugins/renderers/rhi/textures/renderbuffer.cpp @@ -48,10 +48,7 @@ namespace Render { namespace Rhi { RenderBuffer::RenderBuffer(int width, int height, QAbstractTexture::TextureFormat format) - : m_size(width, height), - m_format(format), - m_renderBuffer(0), - m_context(nullptr) + : m_size(width, height), m_format(format), m_renderBuffer(0), m_context(nullptr) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx) { diff --git a/src/plugins/renderers/rhi/textures/texture.cpp b/src/plugins/renderers/rhi/textures/texture.cpp index 3b2df6ff8..53f9e62ca 100644 --- a/src/plugins/renderers/rhi/textures/texture.cpp +++ b/src/plugins/renderers/rhi/textures/texture.cpp @@ -52,7 +52,6 @@ #include #include - QT_BEGIN_NAMESPACE using namespace Qt3DCore; @@ -151,14 +150,11 @@ QRhiSampler::Filter rhiMipMapFilterFromTextureFilter(QAbstractTexture::Filter fi } } -std::tuple -rhiWrapModeFromTextureWrapMode(QTextureWrapMode::WrapMode x, - QTextureWrapMode::WrapMode y, +std::tuple +rhiWrapModeFromTextureWrapMode(QTextureWrapMode::WrapMode x, QTextureWrapMode::WrapMode y, QTextureWrapMode::WrapMode z) noexcept { - auto toRhiAddress = [] (QTextureWrapMode::WrapMode mode) noexcept { + auto toRhiAddress = [](QTextureWrapMode::WrapMode mode) noexcept { switch (mode) { case Qt3DRender::QTextureWrapMode::Repeat: return QRhiSampler::Repeat; @@ -175,7 +171,8 @@ rhiWrapModeFromTextureWrapMode(QTextureWrapMode::WrapMode x, return { toRhiAddress(x), toRhiAddress(y), toRhiAddress(z) }; } -QRhiSampler::CompareOp rhiCompareOpFromTextureCompareOp(QAbstractTexture::ComparisonFunction mode) noexcept +QRhiSampler::CompareOp +rhiCompareOpFromTextureCompareOp(QAbstractTexture::ComparisonFunction mode) noexcept { switch (mode) { case QAbstractTexture::CompareLessEqual: @@ -208,7 +205,6 @@ QRhiTextureUploadEntry createUploadEntry(int level, int layer, const QByteArray return QRhiTextureUploadEntry(layer, level, description); } - template void filterLayersAndFaces(const QTextureImageData &data, F f) { @@ -216,14 +212,11 @@ void filterLayersAndFaces(const QTextureImageData &data, F f) const int faces = data.faces(); const int miplevels = data.mipLevels(); - if (layers == 1 && faces == 1) - { + if (layers == 1 && faces == 1) { for (int level = 0; level < miplevels; level++) { f(createUploadEntry(level, 0, data.data(0, 0, level))); } - } - else if (layers > 1 && faces == 1) - { + } else if (layers > 1 && faces == 1) { qWarning() << Q_FUNC_INFO << "Unsupported case, see QTBUG-83343"; /* for (int layer = 0; layer < data.layers(); layer++) { @@ -232,47 +225,35 @@ void filterLayersAndFaces(const QTextureImageData &data, F f) } } */ - } - else if (faces > 1 && layers == 1) - { + } else if (faces > 1 && layers == 1) { // Mip levels do not seem to be supported by cubemaps... for (int face = 0; face < data.faces(); face++) { f(createUploadEntry(0, face, data.data(0, face, 0))); } - } - else - { - qWarning() << Q_FUNC_INFO << "Unsupported case"; + } else { + qWarning() << Q_FUNC_INFO << "Unsupported case"; } } template void filterLayerAndFace(int layer, int face, F f) { - if (layer == 0 && face == 0) - { + if (layer == 0 && face == 0) { f(0); - } - else if (layer > 0 && face == 0) - { + } else if (layer > 0 && face == 0) { qWarning() << Q_FUNC_INFO << "Unsupported case, see QTBUG-83343"; // f(layer); - } - else if (layer == 0 && face > 0) - { + } else if (layer == 0 && face > 0) { f(face); - } - else - { + } else { qWarning() << Q_FUNC_INFO << "Unsupported case"; } } - // For partial sub image uploads -QRhiTextureUploadEntry createUploadEntry(int mipLevel, int layer, - int xOffset, int yOffset, int zOffset, - const QByteArray &bytes, const QTextureImageDataPtr &data) noexcept +QRhiTextureUploadEntry createUploadEntry(int mipLevel, int layer, int xOffset, int yOffset, + int zOffset, const QByteArray &bytes, + const QTextureImageDataPtr &data) noexcept { QRhiTextureSubresourceUploadDescription description; description.setData(bytes); @@ -282,23 +263,20 @@ QRhiTextureUploadEntry createUploadEntry(int mipLevel, int layer, } // anonymous - RHITexture::RHITexture() - : m_dirtyFlags(None) - , m_rhi(nullptr) - , m_rhiSampler(nullptr) - , m_renderBuffer(nullptr) - , m_dataFunctor() - , m_pendingDataFunctor(nullptr) - , m_sharedTextureId(-1) - , m_externalRendering(false) - , m_wasTextureRecreated(false) + : m_dirtyFlags(None), + m_rhi(nullptr), + m_rhiSampler(nullptr), + m_renderBuffer(nullptr), + m_dataFunctor(), + m_pendingDataFunctor(nullptr), + m_sharedTextureId(-1), + m_externalRendering(false), + m_wasTextureRecreated(false) { } -RHITexture::~RHITexture() -{ -} +RHITexture::~RHITexture() { } // Must be called from RenderThread with active GL context void RHITexture::destroy() @@ -334,16 +312,16 @@ bool RHITexture::loadTextureDataFromGenerator() // If both target and functor return Automatic we are still // probably loading the texture, return false - if (m_properties.target == QAbstractTexture::TargetAutomatic && - target == QAbstractTexture::TargetAutomatic) { + if (m_properties.target == QAbstractTexture::TargetAutomatic + && target == QAbstractTexture::TargetAutomatic) { m_textureData.reset(); return false; } - if (m_properties.target != QAbstractTexture::TargetAutomatic && - target != QAbstractTexture::TargetAutomatic && - m_properties.target != target) { - qWarning() << Q_FUNC_INFO << "Generator and Properties not requesting the same texture target"; + if (m_properties.target != QAbstractTexture::TargetAutomatic + && target != QAbstractTexture::TargetAutomatic && m_properties.target != target) { + qWarning() << Q_FUNC_INFO + << "Generator and Properties not requesting the same texture target"; m_textureData.reset(); return false; } @@ -387,7 +365,8 @@ void RHITexture::loadTextureDataFromImages() // If the texture doesn't have a texture generator, we will // derive some properties from the first TextureImage (layer=0, miplvl=0, face=0) - if (!m_textureData && img.layer == 0 && img.mipLevel == 0 && img.face == QAbstractTexture::CubeMapPositiveX) { + if (!m_textureData && img.layer == 0 && img.mipLevel == 0 + && img.face == QAbstractTexture::CubeMapPositiveX) { if (imgData->width() != -1 && imgData->height() != -1 && imgData->depth() != -1) { m_properties.width = imgData->width(); m_properties.height = imgData->height(); @@ -395,7 +374,8 @@ void RHITexture::loadTextureDataFromImages() } // Set the format of the texture if the texture format is set to Automatic if (m_properties.format == QAbstractTexture::Automatic) { - m_properties.format = static_cast(imgData->format()); + m_properties.format = + static_cast(imgData->format()); } setDirtyFlag(Properties, true); } @@ -427,7 +407,8 @@ RHITexture::TextureUpdateInfo RHITexture::createOrUpdateRhiTexture(SubmissionCon setDirtyFlag(TextureData, true); } else { if (m_pendingDataFunctor != m_dataFunctor.get()) { - qWarning() << "[Qt3DRender::RHITexture] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; + qWarning() << "[Qt3DRender::RHITexture] No QTextureData generated from Texture " + "Generator yet. Texture will be invalid for this frame"; m_pendingDataFunctor = m_dataFunctor.get(); } textureInfo.properties.status = QAbstractTexture::Loading; @@ -452,9 +433,9 @@ RHITexture::TextureUpdateInfo RHITexture::createOrUpdateRhiTexture(SubmissionCon // Format should either be set by user or if Automatic // by either the dataGenerator of the texture or the first Image // Target should explicitly be set by the user or the dataGenerator - if (m_properties.target == QAbstractTexture::TargetAutomatic || - m_properties.format == QAbstractTexture::Automatic || - m_properties.format == QAbstractTexture::NoFormat) { + if (m_properties.target == QAbstractTexture::TargetAutomatic + || m_properties.format == QAbstractTexture::Automatic + || m_properties.format == QAbstractTexture::NoFormat) { textureInfo.properties.status = QAbstractTexture::Error; return textureInfo; } @@ -470,8 +451,8 @@ RHITexture::TextureUpdateInfo RHITexture::createOrUpdateRhiTexture(SubmissionCon // our content data make sure we are marked for upload // TO DO: We should actually check if the textureData is still correct // in regard to the size, target and format of the texture though. - if (!testDirtyFlag(SharedTextureId) && - (m_textureData || !m_imageData.empty() || !m_pendingTextureDataUpdates.empty())) + if (!testDirtyFlag(SharedTextureId) + && (m_textureData || !m_imageData.empty() || !m_pendingTextureDataUpdates.empty())) setDirtyFlag(TextureData, true); } @@ -522,7 +503,8 @@ RenderBuffer *RHITexture::getOrCreateRenderBuffer() m_textureData = m_dataFunctor->operator()(); if (m_textureData) { if (m_properties.target != QAbstractTexture::TargetAutomatic) - qWarning() << "[Qt3DRender::RHITexture] [renderbuffer] When a texture provides a generator, it's target is expected to be TargetAutomatic"; + qWarning() << "[Qt3DRender::RHITexture] [renderbuffer] When a texture provides a " + "generator, it's target is expected to be TargetAutomatic"; m_properties.width = m_textureData->width(); m_properties.height = m_textureData->height(); @@ -531,7 +513,8 @@ RenderBuffer *RHITexture::getOrCreateRenderBuffer() setDirtyFlag(Properties); } else { if (m_pendingDataFunctor != m_dataFunctor.get()) { - qWarning() << "[Qt3DRender::RHITexture] [renderbuffer] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; + qWarning() << "[Qt3DRender::RHITexture] [renderbuffer] No QTextureData generated " + "from Texture Generator yet. Texture will be invalid for this frame"; m_pendingDataFunctor = m_dataFunctor.get(); } return nullptr; @@ -544,7 +527,8 @@ RenderBuffer *RHITexture::getOrCreateRenderBuffer() } if (!m_renderBuffer) - m_renderBuffer = new RenderBuffer(m_properties.width, m_properties.height, m_properties.format); + m_renderBuffer = + new RenderBuffer(m_properties.width, m_properties.height, m_properties.format); setDirtyFlag(Properties, false); setDirtyFlag(Parameters, false); @@ -588,7 +572,6 @@ void RHITexture::setImages(const QVector &images) } } - if (!same) { m_images = images; requestImageUpload(); @@ -632,47 +615,39 @@ QRhiTexture *RHITexture::buildRhiTexture(SubmissionContext *ctx) const QRhiTexture::Format rhiFormat = rhiFormatFromTextureFormat(m_properties.format); const QSize pixelSize(m_properties.width, m_properties.height); - QRhiTexture::Flags rhiFlags{}; + QRhiTexture::Flags rhiFlags {}; int sampleCount = 1; const bool issRGB8Format = issRGBFormat(m_properties.format); if (issRGB8Format) rhiFlags |= QRhiTexture::sRGB; - if (actualTarget == QAbstractTexture::Target2DMultisample || - actualTarget == QAbstractTexture::Target2DMultisampleArray) { + if (actualTarget == QAbstractTexture::Target2DMultisample + || actualTarget == QAbstractTexture::Target2DMultisampleArray) { // Set samples count if multisampled texture // (multisampled textures don't have mipmaps) sampleCount = m_properties.samples; } - switch (actualTarget) - { + switch (actualTarget) { case QAbstractTexture::TargetCubeMap: - case QAbstractTexture::TargetCubeMapArray: - { + case QAbstractTexture::TargetCubeMapArray: { rhiFlags |= QRhiTexture::CubeMap; break; } - default: - { + default: { // Mipmaps don't see to work with cubemaps at the moment if (m_properties.generateMipMaps) { rhiFlags |= QRhiTexture::UsedWithGenerateMips; rhiFlags |= QRhiTexture::MipMapped; - } - else if (m_properties.mipLevels > 1) { + } else if (m_properties.mipLevels > 1) { rhiFlags |= QRhiTexture::MipMapped; } break; } } - - QRhiTexture* rhiTexture = ctx->rhi()->newTexture(rhiFormat, - pixelSize, - sampleCount, - rhiFlags); + QRhiTexture *rhiTexture = ctx->rhi()->newTexture(rhiFormat, pixelSize, sampleCount, rhiFlags); if (!rhiTexture->build()) { qWarning() << Q_FUNC_INFO << "creating QRhiTexture failed"; @@ -688,14 +663,13 @@ void RHITexture::uploadRhiTextureData(SubmissionContext *ctx) // Upload all QTexImageData set by the QTextureGenerator if (m_textureData) { - const QVector& imgData = m_textureData->imageData(); + const QVector &imgData = m_textureData->imageData(); - for (const QTextureImageDataPtr &data : imgData) - { + for (const QTextureImageDataPtr &data : imgData) { const int mipLevels = data->mipLevels(); - Q_ASSERT(mipLevels <= ctx->rhi()->mipLevelsForSize({data->width(), data->height()})); + Q_ASSERT(mipLevels <= ctx->rhi()->mipLevelsForSize({ data->width(), data->height() })); - filterLayersAndFaces(*data, [&] (QRhiTextureUploadEntry&& entry) { + filterLayersAndFaces(*data, [&](QRhiTextureUploadEntry &&entry) { uploadEntries.push_back(std::move(entry)); }); } @@ -710,7 +684,7 @@ void RHITexture::uploadRhiTextureData(SubmissionContext *ctx) const QByteArray bytes(QTextureImageDataPrivate::get(imgData.get())->m_data); const int layer = m_images[i].layer; const int face = m_images[i].face; - filterLayerAndFace(layer, face, [&] (int rhiLayer) { + filterLayerAndFace(layer, face, [&](int rhiLayer) { uploadEntries.push_back(createUploadEntry(m_images[i].mipLevel, rhiLayer, bytes)); }); } @@ -736,10 +710,8 @@ void RHITexture::uploadRhiTextureData(SubmissionContext *ctx) const int yExtent = yOffset + imgData->height(); // Check update is compatible with our texture - if (xOffset >= m_rhi->pixelSize().width() || - yOffset >= m_rhi->pixelSize().height() || - xExtent > m_rhi->pixelSize().width() || - yExtent > m_rhi->pixelSize().height()) { + if (xOffset >= m_rhi->pixelSize().width() || yOffset >= m_rhi->pixelSize().height() + || xExtent > m_rhi->pixelSize().width() || yExtent > m_rhi->pixelSize().height()) { qWarning() << Q_FUNC_INFO << "QTextureDataUpdate incompatible with texture"; continue; } @@ -751,9 +723,9 @@ void RHITexture::uploadRhiTextureData(SubmissionContext *ctx) const int layer = update.layer(); const int face = update.face(); - filterLayerAndFace(layer, face, [&] (int rhiLayer) { + filterLayerAndFace(layer, face, [&](int rhiLayer) { const QRhiTextureUploadEntry entry = createUploadEntry( - update.mipLevel(), rhiLayer, xOffset, yOffset, 0, bytes, imgData); + update.mipLevel(), rhiLayer, xOffset, yOffset, 0, bytes, imgData); uploadEntries.push_back(entry); }); } @@ -769,8 +741,9 @@ void RHITexture::uploadRhiTextureData(SubmissionContext *ctx) void RHITexture::updateRhiTextureParameters(SubmissionContext *ctx) { const QAbstractTexture::Target actualTarget = m_properties.target; - const bool isMultisampledTexture = (actualTarget == QAbstractTexture::Target2DMultisample || - actualTarget == QAbstractTexture::Target2DMultisampleArray); + const bool isMultisampledTexture = + (actualTarget == QAbstractTexture::Target2DMultisample + || actualTarget == QAbstractTexture::Target2DMultisampleArray); // Multisampled textures can only be accessed by texelFetch in shaders // and don't support wrap modes and mig/mag filtes if (isMultisampledTexture) @@ -782,19 +755,18 @@ void RHITexture::updateRhiTextureParameters(SubmissionContext *ctx) m_rhiSampler = nullptr; } - const QRhiSampler::Filter magFilter = rhiFilterFromTextureFilter(m_parameters.magnificationFilter); - const QRhiSampler::Filter minFilter = rhiFilterFromTextureFilter(m_parameters.minificationFilter); - const QRhiSampler::Filter mipMapFilter = rhiMipMapFilterFromTextureFilter(m_parameters.magnificationFilter); - const auto wrapMode = rhiWrapModeFromTextureWrapMode(m_parameters.wrapModeX, - m_parameters.wrapModeY, - m_parameters.wrapModeZ); - const QRhiSampler::CompareOp compareOp = rhiCompareOpFromTextureCompareOp(m_parameters.comparisonFunction); - m_rhiSampler = ctx->rhi()->newSampler(magFilter, - minFilter, - mipMapFilter, - std::get<0>(wrapMode), - std::get<1>(wrapMode), - std::get<2>(wrapMode)); + const QRhiSampler::Filter magFilter = + rhiFilterFromTextureFilter(m_parameters.magnificationFilter); + const QRhiSampler::Filter minFilter = + rhiFilterFromTextureFilter(m_parameters.minificationFilter); + const QRhiSampler::Filter mipMapFilter = + rhiMipMapFilterFromTextureFilter(m_parameters.magnificationFilter); + const auto wrapMode = rhiWrapModeFromTextureWrapMode( + m_parameters.wrapModeX, m_parameters.wrapModeY, m_parameters.wrapModeZ); + const QRhiSampler::CompareOp compareOp = + rhiCompareOpFromTextureCompareOp(m_parameters.comparisonFunction); + m_rhiSampler = ctx->rhi()->newSampler(magFilter, minFilter, mipMapFilter, std::get<0>(wrapMode), + std::get<1>(wrapMode), std::get<2>(wrapMode)); m_rhiSampler->setTextureCompareOp(compareOp); @@ -805,126 +777,138 @@ void RHITexture::updateRhiTextureParameters(SubmissionContext *ctx) void RHITexture::introspectPropertiesFromSharedTextureId() { -// // We know that the context is active when this function is called -// QOpenGLContext *ctx = QOpenGLContext::currentContext(); -// if (!ctx) { -// qWarning() << Q_FUNC_INFO << "requires an OpenGL context"; -// return; -// } -// QOpenGLFunctions *gl = ctx->functions(); - -// // If the user has set the target format himself, we won't try to deduce it -// if (m_properties.target != QAbstractTexture::TargetAutomatic) -// return; - -// const QAbstractTexture::Target targets[] = { -// QAbstractTexture::Target2D, -// QAbstractTexture::TargetCubeMap, -//#ifndef QT_OPENGL_ES_2 -// QAbstractTexture::Target1D, -// QAbstractTexture::Target1DArray, -// QAbstractTexture::Target3D, -// QAbstractTexture::Target2DArray, -// QAbstractTexture::TargetCubeMapArray, -// QAbstractTexture::Target2DMultisample, -// QAbstractTexture::Target2DMultisampleArray, -// QAbstractTexture::TargetRectangle, -// QAbstractTexture::TargetBuffer, -//#endif -// }; - -//#ifndef QT_OPENGL_ES_2 -// // Try to find texture target with GL 4.5 functions -// const QPair ctxGLVersion = ctx->format().version(); -// if (ctxGLVersion.first > 4 || (ctxGLVersion.first == 4 && ctxGLVersion.second >= 5)) { -// // Only for GL 4.5+ -//#ifdef GL_TEXTURE_TARGET -// QOpenGLFunctions_4_5_Core *gl5 = ctx->versionFunctions(); -// if (gl5 != nullptr) -// gl5->glGetTextureParameteriv(m_sharedTextureId, GL_TEXTURE_TARGET, reinterpret_cast(&m_properties.target)); -//#endif -// } -//#endif - -// // If GL 4.5 function unavailable or not working, try a slower way -// if (m_properties.target == QAbstractTexture::TargetAutomatic) { -// // // OpenGL offers no proper way of querying for the target of a texture given its id -// gl->glActiveTexture(GL_TEXTURE0); - -// const GLenum targetBindings[] = { -// GL_TEXTURE_BINDING_2D, -// GL_TEXTURE_BINDING_CUBE_MAP, -//#ifndef QT_OPENGL_ES_2 -// GL_TEXTURE_BINDING_1D, -// GL_TEXTURE_BINDING_1D_ARRAY, -// GL_TEXTURE_BINDING_3D, -// GL_TEXTURE_BINDING_2D_ARRAY, -// GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, -// GL_TEXTURE_BINDING_2D_MULTISAMPLE, -// GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, -// GL_TEXTURE_BINDING_RECTANGLE, -// GL_TEXTURE_BINDING_BUFFER -//#endif -// }; - -// Q_ASSERT(sizeof(targetBindings) / sizeof(targetBindings[0] == sizeof(targets) / sizeof(targets[0]))); - -// for (uint i = 0; i < sizeof(targetBindings) / sizeof(targetBindings[0]); ++i) { -// const int target = targets[i]; -// gl->glBindTexture(target, m_sharedTextureId); -// int boundId = 0; -// gl->glGetIntegerv(targetBindings[i], &boundId); -// gl->glBindTexture(target, 0); -// if (boundId == m_sharedTextureId) { -// m_properties.target = static_cast(target); -// break; -// } -// } -// } - -// // Return early if we weren't able to find texture target -// if (std::find(std::begin(targets), std::end(targets), m_properties.target) == std::end(targets)) { -// qWarning() << "Unable to determine texture target for shared GL texture"; -// return; -// } - -// // Bind texture once we know its target -// gl->glBindTexture(m_properties.target, m_sharedTextureId); - -// // TO DO: Improve by using glGetTextureParameters when available which -// // support direct state access -//#ifndef GL_TEXTURE_MAX_LEVEL -//#define GL_TEXTURE_MAX_LEVEL 0x813D -//#endif - -//#ifndef GL_TEXTURE_WRAP_R -//#define GL_TEXTURE_WRAP_R 0x8072 -//#endif - -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAX_LEVEL, reinterpret_cast(&m_properties.mipLevels)); -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MIN_FILTER, reinterpret_cast(&m_parameters.minificationFilter)); -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAG_FILTER, reinterpret_cast(&m_parameters.magnificationFilter)); -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_R, reinterpret_cast(&m_parameters.wrapModeX)); -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_S, reinterpret_cast(&m_parameters.wrapModeY)); -// gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_T, reinterpret_cast(&m_parameters.wrapModeZ)); - -//#ifndef QT_OPENGL_ES_2 -// // Try to retrieve dimensions (not available on ES 2.0) -// if (!ctx->isOpenGLES()) { -// QOpenGLFunctions_3_1 *gl3 = ctx->versionFunctions(); -// if (!gl3) { -// qWarning() << "Failed to retrieve shared texture dimensions"; -// return; -// } - -// gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_WIDTH, reinterpret_cast(&m_properties.width)); -// gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_HEIGHT, reinterpret_cast(&m_properties.height)); -// gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_DEPTH, reinterpret_cast(&m_properties.depth)); -// gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_INTERNAL_FORMAT, reinterpret_cast(&m_properties.format)); -// } -//#endif - -// gl->glBindTexture(m_properties.target, 0); + // // We know that the context is active when this function is called + // QOpenGLContext *ctx = QOpenGLContext::currentContext(); + // if (!ctx) { + // qWarning() << Q_FUNC_INFO << "requires an OpenGL context"; + // return; + // } + // QOpenGLFunctions *gl = ctx->functions(); + + // // If the user has set the target format himself, we won't try to deduce it + // if (m_properties.target != QAbstractTexture::TargetAutomatic) + // return; + + // const QAbstractTexture::Target targets[] = { + // QAbstractTexture::Target2D, + // QAbstractTexture::TargetCubeMap, + //#ifndef QT_OPENGL_ES_2 + // QAbstractTexture::Target1D, + // QAbstractTexture::Target1DArray, + // QAbstractTexture::Target3D, + // QAbstractTexture::Target2DArray, + // QAbstractTexture::TargetCubeMapArray, + // QAbstractTexture::Target2DMultisample, + // QAbstractTexture::Target2DMultisampleArray, + // QAbstractTexture::TargetRectangle, + // QAbstractTexture::TargetBuffer, + //#endif + // }; + + //#ifndef QT_OPENGL_ES_2 + // // Try to find texture target with GL 4.5 functions + // const QPair ctxGLVersion = ctx->format().version(); + // if (ctxGLVersion.first > 4 || (ctxGLVersion.first == 4 && ctxGLVersion.second >= 5)) { + // // Only for GL 4.5+ + //#ifdef GL_TEXTURE_TARGET + // QOpenGLFunctions_4_5_Core *gl5 = ctx->versionFunctions(); + // if (gl5 != nullptr) + // gl5->glGetTextureParameteriv(m_sharedTextureId, GL_TEXTURE_TARGET, + // reinterpret_cast(&m_properties.target)); + //#endif + // } + //#endif + + // // If GL 4.5 function unavailable or not working, try a slower way + // if (m_properties.target == QAbstractTexture::TargetAutomatic) { + // // // OpenGL offers no proper way of querying for the target of a texture given its + // id gl->glActiveTexture(GL_TEXTURE0); + + // const GLenum targetBindings[] = { + // GL_TEXTURE_BINDING_2D, + // GL_TEXTURE_BINDING_CUBE_MAP, + //#ifndef QT_OPENGL_ES_2 + // GL_TEXTURE_BINDING_1D, + // GL_TEXTURE_BINDING_1D_ARRAY, + // GL_TEXTURE_BINDING_3D, + // GL_TEXTURE_BINDING_2D_ARRAY, + // GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, + // GL_TEXTURE_BINDING_2D_MULTISAMPLE, + // GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, + // GL_TEXTURE_BINDING_RECTANGLE, + // GL_TEXTURE_BINDING_BUFFER + //#endif + // }; + + // Q_ASSERT(sizeof(targetBindings) / sizeof(targetBindings[0] == sizeof(targets) / + // sizeof(targets[0]))); + + // for (uint i = 0; i < sizeof(targetBindings) / sizeof(targetBindings[0]); ++i) { + // const int target = targets[i]; + // gl->glBindTexture(target, m_sharedTextureId); + // int boundId = 0; + // gl->glGetIntegerv(targetBindings[i], &boundId); + // gl->glBindTexture(target, 0); + // if (boundId == m_sharedTextureId) { + // m_properties.target = static_cast(target); + // break; + // } + // } + // } + + // // Return early if we weren't able to find texture target + // if (std::find(std::begin(targets), std::end(targets), m_properties.target) == + // std::end(targets)) { + // qWarning() << "Unable to determine texture target for shared GL texture"; + // return; + // } + + // // Bind texture once we know its target + // gl->glBindTexture(m_properties.target, m_sharedTextureId); + + // // TO DO: Improve by using glGetTextureParameters when available which + // // support direct state access + //#ifndef GL_TEXTURE_MAX_LEVEL + //#define GL_TEXTURE_MAX_LEVEL 0x813D + //#endif + + //#ifndef GL_TEXTURE_WRAP_R + //#define GL_TEXTURE_WRAP_R 0x8072 + //#endif + + // gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAX_LEVEL, + // reinterpret_cast(&m_properties.mipLevels)); + // gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MIN_FILTER, + // reinterpret_cast(&m_parameters.minificationFilter)); + // gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAG_FILTER, + // reinterpret_cast(&m_parameters.magnificationFilter)); + // gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_R, reinterpret_cast(&m_parameters.wrapModeX)); gl->glGetTexParameteriv(int(m_properties.target), + // GL_TEXTURE_WRAP_S, reinterpret_cast(&m_parameters.wrapModeY)); + // gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_T, reinterpret_cast(&m_parameters.wrapModeZ)); + + //#ifndef QT_OPENGL_ES_2 + // // Try to retrieve dimensions (not available on ES 2.0) + // if (!ctx->isOpenGLES()) { + // QOpenGLFunctions_3_1 *gl3 = ctx->versionFunctions(); + // if (!gl3) { + // qWarning() << "Failed to retrieve shared texture dimensions"; + // return; + // } + + // gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_WIDTH, + // reinterpret_cast(&m_properties.width)); + // gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_HEIGHT, + // reinterpret_cast(&m_properties.height)); + // gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_DEPTH, + // reinterpret_cast(&m_properties.depth)); + // gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_INTERNAL_FORMAT, + // reinterpret_cast(&m_properties.format)); + // } + //#endif + + // gl->glBindTexture(m_properties.target, 0); } } // namespace Rhi diff --git a/src/plugins/renderers/rhi/textures/texture_p.h b/src/plugins/renderers/rhi/textures/texture_p.h index 589abcb4d..536cb962e 100644 --- a/src/plugins/renderers/rhi/textures/texture_p.h +++ b/src/plugins/renderers/rhi/textures/texture_p.h @@ -107,23 +107,25 @@ public: enum DirtyFlag { None = 0, - TextureData = (1 << 0), // texture data needs uploading to GPU - Properties = (1 << 1), // texture needs to be (re-)created - Parameters = (1 << 2), // texture parameters need to be (re-)set - SharedTextureId = (1 << 3), // texture id from shared context - TextureImageData = (1 << 4) // texture image data needs uploading + TextureData = (1 << 0), // texture data needs uploading to GPU + Properties = (1 << 1), // texture needs to be (re-)created + Parameters = (1 << 2), // texture parameters need to be (re-)set + SharedTextureId = (1 << 3), // texture id from shared context + TextureImageData = (1 << 4) // texture image data needs uploading }; /** * Helper class to hold the defining properties of TextureImages */ - struct Image { + struct Image + { QTextureImageDataGeneratorPtr generator; int layer; int mipLevel; QAbstractTexture::CubeMapFace face; - inline bool operator==(const Image &o) const { + inline bool operator==(const Image &o) const + { bool sameGenerators = (generator == o.generator) || (!generator.isNull() && !o.generator.isNull() && *generator == *o.generator); return sameGenerators && layer == o.layer && mipLevel == o.mipLevel && face == o.face; @@ -167,41 +169,25 @@ public: */ RenderBuffer *getOrCreateRenderBuffer(); - void destroy(); void cleanup(); - bool isDirty() const - { - return m_dirtyFlags != None; - } + bool isDirty() const { return m_dirtyFlags != None; } bool hasTextureData() const { return !m_textureData.isNull(); } bool hasImagesData() const { return !m_imageData.isEmpty(); } QFlags dirtyFlags() const { return m_dirtyFlags; } - QMutex *externalRenderingLock() - { - return &m_externalRenderingMutex; - } + QMutex *externalRenderingLock() { return &m_externalRenderingMutex; } - void setExternalRenderingEnabled(bool enable) - { - m_externalRendering = enable; - } + void setExternalRenderingEnabled(bool enable) { m_externalRendering = enable; } - bool isExternalRenderingEnabled() const - { - return m_externalRendering; - } + bool isExternalRenderingEnabled() const { return m_externalRendering; } // Purely for unit testing purposes - bool wasTextureRecreated() const - { - return m_wasTextureRecreated; - } + bool wasTextureRecreated() const { return m_wasTextureRecreated; } void setParameters(const TextureParameters ¶ms); void setProperties(const TextureProperties &props); @@ -214,25 +200,13 @@ public: QTextureGeneratorPtr dataGenerator() const { return m_dataFunctor; } private: - void requestImageUpload() - { - m_dirtyFlags |= TextureImageData; - } + void requestImageUpload() { m_dirtyFlags |= TextureImageData; } - void requestUpload() - { - m_dirtyFlags |= TextureData; - } + void requestUpload() { m_dirtyFlags |= TextureData; } - bool testDirtyFlag(DirtyFlag flag) - { - return m_dirtyFlags.testFlag(flag); - } + bool testDirtyFlag(DirtyFlag flag) { return m_dirtyFlags.testFlag(flag); } - void setDirtyFlag(DirtyFlag flag, bool value = true) - { - m_dirtyFlags.setFlag(flag, value); - } + void setDirtyFlag(DirtyFlag flag, bool value = true) { m_dirtyFlags.setFlag(flag, value); } QRhiTexture *buildRhiTexture(SubmissionContext *ctx); bool loadTextureDataFromGenerator(); -- cgit v1.2.3