diff options
Diffstat (limited to 'src/plugins/renderers/rhi/renderer')
20 files changed, 304 insertions, 232 deletions
diff --git a/src/plugins/renderers/rhi/renderer/fence_p.h b/src/plugins/renderers/rhi/renderer/fence_p.h index 2581026d9..169e01914 100644 --- a/src/plugins/renderers/rhi/renderer/fence_p.h +++ b/src/plugins/renderers/rhi/renderer/fence_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/logging.cpp b/src/plugins/renderers/rhi/renderer/logging.cpp index 6a90c4a61..29bdb2145 100644 --- a/src/plugins/renderers/rhi/renderer/logging.cpp +++ b/src/plugins/renderers/rhi/renderer/logging.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/logging_p.h b/src/plugins/renderers/rhi/renderer/logging_p.h index f3f8d7068..45d63978d 100644 --- a/src/plugins/renderers/rhi/renderer/logging_p.h +++ b/src/plugins/renderers/rhi/renderer/logging_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/openglvertexarrayobject.cpp b/src/plugins/renderers/rhi/renderer/openglvertexarrayobject.cpp index 7aea905fc..afc205cf9 100644 --- a/src/plugins/renderers/rhi/renderer/openglvertexarrayobject.cpp +++ b/src/plugins/renderers/rhi/renderer/openglvertexarrayobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -52,17 +52,12 @@ namespace Rhi { RHIVertexArrayObject::RHIVertexArrayObject() : m_ctx(nullptr) , m_specified(false) - , m_supportsVao(false) {} void RHIVertexArrayObject::bind() { Q_ASSERT(m_ctx); - if (m_supportsVao) { - Q_ASSERT(!m_vao.isNull()); - Q_ASSERT(m_vao->isCreated()); - m_vao->bind(); - } else { + { // Unbind any other VAO that may have been bound and not released correctly if (m_ctx->m_currentVAO != nullptr && m_ctx->m_currentVAO != this) m_ctx->m_currentVAO->release(); @@ -80,11 +75,7 @@ void RHIVertexArrayObject::bind() void RHIVertexArrayObject::release() { Q_ASSERT(m_ctx); - if (m_supportsVao) { - Q_ASSERT(!m_vao.isNull()); - Q_ASSERT(m_vao->isCreated()); - m_vao->release(); - } else { + { if (m_ctx->m_currentVAO == this) { for (const SubmissionContext::VAOVertexAttribute &attr : qAsConst(m_vertexAttributes)) m_ctx->disableAttribute(attr); @@ -98,14 +89,10 @@ void RHIVertexArrayObject::create(SubmissionContext *ctx, const VAOIdentifier &k { QMutexLocker lock(&m_mutex); - Q_ASSERT(!m_ctx && !m_vao); + Q_ASSERT(!m_ctx); m_ctx = ctx; - m_supportsVao = m_ctx->supportsVAO(); - if (m_supportsVao) { - m_vao.reset(new QOpenGLVertexArrayObject()); - m_vao->create(); - } + m_owners = key; } @@ -125,10 +112,8 @@ void RHIVertexArrayObject::destroy() void RHIVertexArrayObject::cleanup() { - m_vao.reset(); m_ctx = nullptr; m_specified = false; - m_supportsVao = false; m_indexAttribute = SubmissionContext::VAOIndexAttribute(); m_vertexAttributes.clear(); } diff --git a/src/plugins/renderers/rhi/renderer/openglvertexarrayobject_p.h b/src/plugins/renderers/rhi/renderer/openglvertexarrayobject_p.h index 72e816f9b..a873d8d25 100644 --- a/src/plugins/renderers/rhi/renderer/openglvertexarrayobject_p.h +++ b/src/plugins/renderers/rhi/renderer/openglvertexarrayobject_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -82,9 +82,6 @@ public: bool isAbandoned(GeometryManager *geomMgr, RHIShaderManager *shaderMgr); - QOpenGLVertexArrayObject *vao() { return m_vao.data(); } - const QOpenGLVertexArrayObject *vao() const { return m_vao.data(); } - void setSpecified(bool b) { m_specified = b; } bool isSpecified() const { return m_specified; } @@ -92,9 +89,7 @@ public: private: QMutex m_mutex; SubmissionContext *m_ctx; - QScopedPointer<QOpenGLVertexArrayObject> m_vao; bool m_specified; - bool m_supportsVao; VAOIdentifier m_owners; friend class SubmissionContext; diff --git a/src/plugins/renderers/rhi/renderer/rendercommand.cpp b/src/plugins/renderers/rhi/renderer/rendercommand.cpp index 9a360c750..395eeab78 100644 --- a/src/plugins/renderers/rhi/renderer/rendercommand.cpp +++ b/src/plugins/renderers/rhi/renderer/rendercommand.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/rendercommand_p.h b/src/plugins/renderers/rhi/renderer/rendercommand_p.h index 25ffab3e6..baaf79f7c 100644 --- a/src/plugins/renderers/rhi/renderer/rendercommand_p.h +++ b/src/plugins/renderers/rhi/renderer/rendercommand_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). ** Contact: https://www.qt.io/licensing/ ** @@ -106,8 +106,8 @@ public: float m_depth; int m_changeCost; - QRhiShaderResourceBindings *srb = nullptr; - QRhiGraphicsPipeline *ps = nullptr; + QRhiShaderResourceBindings *shaderResourceBindings = nullptr; + QRhiGraphicsPipeline *graphicsPipeline = nullptr; enum CommandType { Draw, Compute diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp index 0d588ef41..055b420bc 100644 --- a/src/plugins/renderers/rhi/renderer/renderer.cpp +++ b/src/plugins/renderers/rhi/renderer/renderer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). ** Contact: https://www.qt.io/licensing/ ** @@ -535,7 +535,7 @@ void Renderer::initialize() m_rp = m_sc->newCompatibleRenderPassDescriptor(); m_sc->setRenderPassDescriptor(m_rp); } -/* + // Awake setScenegraphRoot in case it was waiting m_waitForInitializationToBeCompleted.release(1); @@ -543,76 +543,10 @@ void Renderer::initialize() m_vsyncFrameAdvanceService->proceedToNextFrame(); // Force initial refresh - markDirty(AllDirty, nullptr);*/ - } - - - - - - - - - - /* - QOpenGLContext* ctx = m_glContext; - - { - // If we are using our own context (not provided by QtQuick), - // we need to create it - if (!m_glContext) { - ctx = new QOpenGLContext; - if (m_screen) - ctx->setScreen(m_screen); - ctx->setShareContext(qt_gl_global_share_context()); - - // TO DO: Shouldn't we use the highest context available and trust - // QOpenGLContext to fall back on the best lowest supported ? - const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING"); - - if (!debugLoggingMode.isEmpty()) { - QSurfaceFormat sf = ctx->format(); - sf.setOption(QSurfaceFormat::DebugContext); - ctx->setFormat(sf); - } - - // Create OpenGL context<<<<<<< HEAD - - if (ctx->create()) - qCDebug(Backend) << "OpenGL context created with actual format" << ctx->format(); - else - qCWarning(Backend) << Q_FUNC_INFO << "OpenGL context creation failed"; - m_ownedContext = true; - } else { - // Context is not owned by us, so we need to know if it gets destroyed - m_contextConnection = QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed, - [this] { releaseGraphicsResources(); }); - } - - qCDebug(Backend) << "Qt3D shared context:" << ctx->shareContext(); - qCDebug(Backend) << "Qt global shared context:" << qt_gl_global_share_context(); - - // Note: we don't have a surface at this point - // The context will be made current later on (at render time) - m_submissionContext->setOpenGLContext(ctx); - - // Store the format used by the context and queue up creating an - // offscreen surface in the main thread so that it is available - // for use when we want to shutdown the renderer. We need to create - // the offscreen surface on the main thread because on some platforms - // (MS Windows), an offscreen surface is just a hidden QWindow. - m_format = ctx->format(); - QMetaObject::invokeMethod(m_offscreenHelper, "createOffscreenSurface"); + markDirty(AllDirty, nullptr); + return; } - */ - // Awake setScenegraphRoot in case it was waiting - m_waitForInitializationToBeCompleted.release(1); - // Allow the aspect manager to proceed - m_vsyncFrameAdvanceService->proceedToNextFrame(); - - // Force initial refresh - markDirty(AllDirty, nullptr); } /*! @@ -905,7 +839,7 @@ void Renderer::doRender(bool swapBuffers) beganDrawing = m_submissionContext->beginDrawing(surface); if (beganDrawing) { // 1) Execute commands for buffer uploads, texture updates, shader loading first - updateGLResources(); + updateResources(); // 2) Update VAO and copy data into commands to allow concurrent submission prepareCommandsSubmission(renderViews); preprocessingComplete = true; @@ -1056,12 +990,8 @@ QSurfaceFormat Renderer::format() { return m_format; } -void Renderer::setupRHICommand(RenderCommand& cmd) +void Renderer::setupDrawCommand(RenderCommand& cmd) { - auto shaders = cmd.m_glShader->shaderCode(); - if(shaders.empty()) - return; - // Create UBOs auto standard_ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(float) * 16); standard_ubuf->build(); @@ -1074,8 +1004,12 @@ void Renderer::setupRHICommand(RenderCommand& cmd) this->m_submissionContext->m_currentUpdates->updateDynamicBuffer(custom_ubuf, 0, sizeof(float), &f); - cmd.srb = m_r->newShaderResourceBindings(); - cmd.srb->setBindings({ + bool ok = true; + + cmd.shaderResourceBindings = m_r->newShaderResourceBindings(); + assert(cmd.shaderResourceBindings); + + cmd.shaderResourceBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer( 0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, @@ -1085,54 +1019,47 @@ void Renderer::setupRHICommand(RenderCommand& cmd) QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, custom_ubuf), }); - cmd.srb->build(); - + ok = cmd.shaderResourceBindings->build(); + assert(ok); // Create pipeline - cmd.ps = m_r->newGraphicsPipeline(); - auto vert = shaders[0]; - auto frag = shaders[1]; - QShaderBaker b; - b.setGeneratedShaders({ - {QShader::SpirvShader, 100}, - {QShader::GlslShader, 120}, // Only GLSL version supported by RHI right now. - {QShader::HlslShader, 100}, - {QShader::MslShader, 100}, - }); - b.setGeneratedShaderVariants({QShader::Variant{}, - QShader::Variant{}, - QShader::Variant{}, - QShader::Variant{}}); - - b.setSourceString(vert, QShader::VertexStage); - auto vs = b.bake(); - if(b.errorMessage() != QString{}) - qDebug() << "Vertex Shader Error: " << b.errorMessage(); - - b.setSourceString(frag, QShader::FragmentStage); - auto fs = b.bake(); - if(b.errorMessage() != QString{}) - qDebug() << "Fragment Shader Error: " << b.errorMessage(); - - cmd.ps->setShaderStages({ - { QRhiShaderStage::Vertex, vs }, - { QRhiShaderStage::Fragment, fs } - }); + cmd.graphicsPipeline = m_r->newGraphicsPipeline(); + assert(cmd.graphicsPipeline); - QRhiVertexInputLayout inputLayout; - inputLayout.setBindings({ - { 3 * sizeof(float) } - }); - inputLayout.setAttributes({ - { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, - //{ 0, 1, QRhiVertexInputAttribute::Float4, 3 * sizeof(float) } + cmd.graphicsPipeline->setShaderStages({ + { QRhiShaderStage::Vertex, cmd.m_glShader->shaderStage(QShader::VertexStage) }, + { QRhiShaderStage::Fragment, cmd.m_glShader->shaderStage(QShader::FragmentStage) } }); - cmd.ps->setVertexInputLayout(inputLayout); - cmd.ps->setShaderResourceBindings(cmd.srb); - cmd.ps->setRenderPassDescriptor(m_rp); + QRhiVertexInputLayout inputLayout = cmd.m_glShader->inputLayout(); + QVarLengthArray<QRhiVertexInputBinding, 8> inputBindings; + + const auto geom = cmd.m_geometry; + const auto& attributes = geom->attributes(); + for(Qt3DCore::QNodeId attribute_id : attributes) + { + Attribute* attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); + if(attrib->attributeType() == QAttribute::VertexAttribute) + { + inputBindings.resize(std::max((std::size_t)inputBindings.size(), (std::size_t)attrib->location() + 1)); + // TODO handle the other arguments to QRhiVertexInputBinding + inputBindings[attrib->location()] = QRhiVertexInputBinding{attrib->byteStride()}; + } + } + + inputLayout.setBindings(inputBindings.begin(), inputBindings.end()); + + cmd.graphicsPipeline->setVertexInputLayout(inputLayout); + cmd.graphicsPipeline->setShaderResourceBindings(cmd.shaderResourceBindings); + cmd.graphicsPipeline->setRenderPassDescriptor(m_rp); + + ok = cmd.graphicsPipeline->build(); + assert(ok); +} + +void Renderer::setupComputeCommand(RenderCommand &command) +{ - cmd.ps->build(); } // When this function is called, we must not be processing the commands for frame n+1 @@ -1203,7 +1130,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView // Prepare the ShaderParameterPack based on the active uniforms of the shader shader->prepareUniforms(command.m_parameterPack); - setupRHICommand(command); + setupDrawCommand(command); } else if (command.m_type == RenderCommand::Compute) { RHI_UNIMPLEMENTED; @@ -1475,7 +1402,7 @@ void Renderer::sendDisablesToFrontend(Qt3DCore::QAspectManager *manager) // may contain destruction changes targeting resources. When the above // happens, this can result in the dirtyResource vectors containing handles of // objects that may already have been destroyed -void Renderer::updateGLResources() +void Renderer::updateResources() { { // Update active fence objects: @@ -1918,11 +1845,14 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView // contains RenderTargetSelector/RenderTarget if (lastBoundFBOId != m_submissionContext->activeFBO()) - m_submissionContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw); + { + RHI_UNIMPLEMENTED; +//* m_submissionContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw); + } // Reset state and call doneCurrent if the surface // is valid and was actually activated - if (lastUsedSurface && m_submissionContext->hasValidGLHelper()) { + if (lastUsedSurface) { // Reset state to the default state if the last stateset is not the // defaultRenderStateSet if (m_submissionContext->currentStateSet() != m_defaultRenderStateSet) @@ -2391,14 +2321,22 @@ bool Renderer::prepareDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCo break; } } + + for(const BlockToUBO& pack : command.m_parameterPack.uniformBuffers()) + { + qDebug() << pack.m_bufferID; + Buffer *cpuBuffer = nodeManagers()->bufferManager()->lookupResource(pack.m_bufferID); + RHIBuffer *ubo = m_submissionContext->glBufferForRenderBuffer(cpuBuffer); + ubo->bind(&*m_submissionContext, RHIBuffer::UniformBuffer); + } return true; } bool Renderer::performDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand& command) { // Setup the rendering pass - cb->setGraphicsPipeline(command.ps); - cb->setShaderResources(command.ps->shaderResourceBindings()); + cb->setGraphicsPipeline(command.graphicsPipeline); + cb->setShaderResources(command.graphicsPipeline->shaderResourceBindings()); // Send the draw command if (Q_UNLIKELY(!command.indexBuffer)) diff --git a/src/plugins/renderers/rhi/renderer/renderer_p.h b/src/plugins/renderers/rhi/renderer/renderer_p.h index e59ddad9d..2f7b18a61 100644 --- a/src/plugins/renderers/rhi/renderer/renderer_p.h +++ b/src/plugins/renderers/rhi/renderer/renderer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). ** Contact: https://www.qt.io/licensing/ ** @@ -265,7 +265,7 @@ public: void loadShader(Shader *shader, Qt3DRender::Render::HShader shaderHandle) override; - void updateGLResources(); + void updateResources(); void updateTexture(Texture *texture); void cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId); void cleanupShader(const Shader *shader); @@ -470,9 +470,12 @@ private: QOffscreenSurface *m_fallbackSurface{}; bool m_hasSwapChain = false; - void setupRHICommand(RenderCommand& command); - bool performDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); + + void setupDrawCommand(RenderCommand& command); bool prepareDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); + bool performDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); + + void setupComputeCommand(RenderCommand& command); }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/renderqueue.cpp b/src/plugins/renderers/rhi/renderer/renderqueue.cpp index f592187e0..ae4145c76 100644 --- a/src/plugins/renderers/rhi/renderer/renderqueue.cpp +++ b/src/plugins/renderers/rhi/renderer/renderqueue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/renderqueue_p.h b/src/plugins/renderers/rhi/renderer/renderqueue_p.h index 7abfe5272..3b6eec13d 100644 --- a/src/plugins/renderers/rhi/renderer/renderqueue_p.h +++ b/src/plugins/renderers/rhi/renderer/renderqueue_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp index 68c282433..fca3fc8eb 100644 --- a/src/plugins/renderers/rhi/renderer/renderview.cpp +++ b/src/plugins/renderers/rhi/renderer/renderview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). ** Contact: https://www.qt.io/licensing/ ** diff --git a/src/plugins/renderers/rhi/renderer/renderview_p.h b/src/plugins/renderers/rhi/renderer/renderview_p.h index 1c0c265ff..b1667a76a 100644 --- a/src/plugins/renderers/rhi/renderer/renderview_p.h +++ b/src/plugins/renderers/rhi/renderer/renderview_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). ** Contact: https://www.qt.io/licensing/ ** diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp index f2715dc5e..9e25307ef 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h index 82ef97f34..379a6f26f 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/shader.cpp b/src/plugins/renderers/rhi/renderer/shader.cpp index 114fe92cc..b6be8f029 100644 --- a/src/plugins/renderers/rhi/renderer/shader.cpp +++ b/src/plugins/renderers/rhi/renderer/shader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -101,6 +101,181 @@ QVector<QByteArray> RHIShader::shaderCode() const return m_shaderCode; } +static auto 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; + default: + // TODO UNormByte4, UNormByte2, UNormByte + RHI_UNIMPLEMENTED; + return QRhiVertexInputAttribute::UNormByte; + break; + } +} + +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; + } +} + +template<typename T, typename Pred> +auto stableRemoveDuplicates(QVector<T> in, Pred predicate) +{ + QVector<T> out; + for(const auto& element : in) + { + if(std::none_of(out.begin(), out.end(), [&] (auto& other) { return predicate(element, other); })) + out.push_back(element); + } + return out; +} +void RHIShader::introspect() +{ + QVector<QShaderDescription::UniformBlock> rhiUBO; + QVector<QShaderDescription::StorageBlock> rhiSSBO; + + QVector<ShaderUniformBlock> uniformBlocks; + QVector<ShaderStorageBlock> storageBlocks; + QVector<ShaderAttribute> attributes; + + QRhiVertexInputLayout lay; + + // Introspect shader vertex input + if(m_stages[QShader::VertexStage].isValid()) + { + const QShaderDescription& vtx = m_stages[QShader::VertexStage].description(); + + QVarLengthArray<QRhiVertexInputAttribute, 8> rhiAttributes; + + for(const QShaderDescription::InOutVariable& input : vtx.inputVariables()) + { + // TODO offset ? + rhiAttributes.push_back({ 0, input.location, rhiInputType(input.type), 0 }); + qDebug() << "Pushing attribute: " << rhiAttributes.back(); + + attributes.push_back(ShaderAttribute{input.name, -1, input.type, rhiTypeSize(input.type), input.location}); + } + lay.setAttributes(rhiAttributes.begin(), rhiAttributes.end()); + + for(const auto& var: vtx.uniformBlocks()) + rhiUBO.push_back(var); + for(const auto& var: vtx.storageBlocks()) + rhiSSBO.push_back(var); + } + m_input = std::move(lay); + + // Introspect shader uniforms + + if(m_stages[QShader::FragmentStage].isValid()) + { + const QShaderDescription& frag = m_stages[QShader::FragmentStage].description(); + for(const auto& var: frag.uniformBlocks()) + rhiUBO.push_back(var); + for(const auto& var: frag.storageBlocks()) + rhiSSBO.push_back(var); + } + + 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, -1, -1, ubo.binding, 0, 0}); + } + + for(const QShaderDescription::StorageBlock& ssbo : rhiSSBO) + { + storageBlocks.push_back(ShaderStorageBlock{ssbo.blockName, -1, -1, ssbo.binding, 0, 0}); + } + + initializeAttributes(attributes); + initializeUniformBlocks(uniformBlocks); + initializeShaderStorageBlocks(storageBlocks); +} + QHash<QString, ShaderUniform> RHIShader::activeUniformsForUniformBlock(int blockIndex) const { return m_uniformBlockIndexToShaderUniforms.value(blockIndex); diff --git a/src/plugins/renderers/rhi/renderer/shader_p.h b/src/plugins/renderers/rhi/renderer/shader_p.h index 3520aaa2c..abf06d9a7 100644 --- a/src/plugins/renderers/rhi/renderer/shader_p.h +++ b/src/plugins/renderers/rhi/renderer/shader_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -56,6 +56,8 @@ #include <shaderparameterpack_p.h> #include <Qt3DRender/qshaderprogram.h> #include <QMutex> +#include <QtGui/private/qshader_p.h> +#include <QtGui/private/qrhi_p.h> QT_BEGIN_NAMESPACE @@ -115,8 +117,16 @@ public: void setShaderCode(const QVector<QByteArray> shaderCode) { m_shaderCode = shaderCode; } QVector<QByteArray> shaderCode() const; + const QShader& shaderStage(QShader::Stage stage) const noexcept { return m_stages[stage]; } + const QRhiVertexInputLayout& inputLayout() const noexcept { return m_input; } + + void introspect(); private: bool m_isLoaded; + QShader m_stages[6]; + + QRhiVertexInputLayout m_input; + QOpenGLShaderProgram m_shader; GraphicsContext *m_graphicsContext; diff --git a/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp b/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp index 8fa0943fd..d129c742d 100644 --- a/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp +++ b/src/plugins/renderers/rhi/renderer/shaderparameterpack.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h b/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h index 67f52feea..5aa6ed695 100644 --- a/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h +++ b/src/plugins/renderers/rhi/renderer/shaderparameterpack_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. diff --git a/src/plugins/renderers/rhi/renderer/shadervariables_p.h b/src/plugins/renderers/rhi/renderer/shadervariables_p.h index e2cf3667e..40f906b18 100644 --- a/src/plugins/renderers/rhi/renderer/shadervariables_p.h +++ b/src/plugins/renderers/rhi/renderer/shadervariables_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -52,6 +52,7 @@ // #include <Qt3DRender/qt3drender_global.h> +#include <QtGui/private/qshaderdescription_p.h> #include <QOpenGLContext> QT_BEGIN_NAMESPACE @@ -64,84 +65,49 @@ namespace Rhi { struct ShaderAttribute { - ShaderAttribute() - : m_nameId(-1) - , m_type(0) - , m_size(0) - , m_location(-1) - {} - QString m_name; - int m_nameId; - GLenum m_type; - int m_size; - int m_location; + 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 { - ShaderUniform() - : m_nameId(-1) - , m_type(GL_NONE) - , m_size(0) - , m_offset(-1) - , m_location(-1) - , m_blockIndex(-1) - , m_arrayStride(-1) - , m_matrixStride(-1) - , m_rawByteSize(0) - {} - QString m_name; - int m_nameId; - GLenum m_type; - int m_size; - int m_offset; // -1 default, >= 0 if uniform defined in uniform block - int m_location; // -1 if uniform defined in a uniform block - int m_blockIndex; // -1 is the default, >= 0 if uniform defined in uniform block - int m_arrayStride; // -1 is the default, >= 0 if uniform defined in uniform block and if it's an array - int m_matrixStride; // -1 is the default, >= 0 uniform defined in uniform block and is a matrix - uint m_rawByteSize; // 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) struct ShaderUniformBlock { - ShaderUniformBlock() - : m_nameId(-1) - , m_index(-1) - , m_binding(-1) - , m_activeUniformsCount(0) - , m_size(0) - {} - QString m_name; - int m_nameId; - int m_index; - int m_binding; - int m_activeUniformsCount; - int m_size; + 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 { - ShaderStorageBlock() - : m_nameId(-1) - , m_index(-1) - , m_binding(-1) - , m_size(0) - , m_activeVariablesCount(0) - {} - QString m_name; - int m_nameId; - int m_index; - int m_binding; - int m_size; - int m_activeVariablesCount; + 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) |