From 918018b717ee597de67dc0a7645db753e5e2b2b6 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 18 Aug 2020 16:29:24 +0200 Subject: rhi: Use render states as part of the GraphicsPipeline key Instead of the RenderView index as the states for the commands for a given RV could change over time, we really have to compare the value of the states. Change-Id: I7b5870ec8fefce09ce31892ebc863bfaaea555d4 Reviewed-by: Mike Krus --- .../renderers/rhi/managers/rhiresourcemanagers.cpp | 15 +++++++++++++++ .../renderers/rhi/managers/rhiresourcemanagers_p.h | 6 ++++-- src/plugins/renderers/rhi/renderer/renderer.cpp | 8 ++++---- src/plugins/renderers/rhi/renderer/renderer_p.h | 3 +-- .../renderers/rhi/renderer/rhigraphicspipeline_p.h | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp b/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp index d0aed29bc..e653a364e 100644 --- a/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp +++ b/src/plugins/renderers/rhi/managers/rhiresourcemanagers.cpp @@ -99,6 +99,21 @@ int RHIGraphicsPipelineManager::getIdForAttributeVec(const std::vector &states = stateSet->states(); + auto it = std::find(m_renderStates.begin(), + m_renderStates.end(), + states); + if (it == m_renderStates.end()) { + m_renderStates.emplace_back(states); + return m_renderStates.size() - 1; + } + return std::distance(m_renderStates.begin(), it); +} + namespace { template diff --git a/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h b/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h index b5dc67aee..677632675 100644 --- a/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h +++ b/src/plugins/renderers/rhi/managers/rhiresourcemanagers_p.h @@ -101,6 +101,7 @@ public: RHIGraphicsPipelineManager() { } int getIdForAttributeVec(const std::vector &attributesInfo); + int getIdForRenderStates(const RenderStateSetPtr &stateSet); void releasePipelinesReferencingShader(const Qt3DCore::QNodeId &shaderId); void releasePipelinesReferencingRenderTarget(const Qt3DCore::QNodeId &renderTargetId); @@ -108,6 +109,7 @@ public: private: using AttributeInfoVec= std::vector; std::vector m_attributesInfo; + std::vector> m_renderStates; }; class Q_AUTOTEST_EXPORT RHIComputePipelineManager @@ -156,7 +158,7 @@ inline uint qHash(const GraphicsPipelineIdentifier &key, uint seed = 0) using QT_PREPEND_NAMESPACE(qHash); seed = qHash(p, seed); seed = qHash(key.renderTarget, seed); - seed = qHash(key.renderViewIndex, seed); + seed = qHash(key.renderStatesKey, seed); seed = qHash(key.primitiveType, seed); return seed; } @@ -166,7 +168,7 @@ inline bool operator==(const GraphicsPipelineIdentifier &a, const GraphicsPipeli return a.geometryLayoutKey == b.geometryLayoutKey && a.shader == b.shader && a.renderTarget == b.renderTarget && - a.renderViewIndex == b.renderViewIndex && + a.renderStatesKey == b.renderStatesKey && a.primitiveType == b.primitiveType; } diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp index d77b40d76..d4680d98f 100644 --- a/src/plugins/renderers/rhi/renderer/renderer.cpp +++ b/src/plugins/renderers/rhi/renderer/renderer.cpp @@ -845,8 +845,7 @@ std::optional rhiAttributeType(Attribute *attr } } -void Renderer::updateGraphicsPipeline(RenderCommand &cmd, RenderView *rv, - int renderViewIndex) +void Renderer::updateGraphicsPipeline(RenderCommand &cmd, RenderView *rv) { if (!cmd.m_rhiShader) { qCWarning(Backend) << "Command has no shader"; @@ -868,7 +867,8 @@ void Renderer::updateGraphicsPipeline(RenderCommand &cmd, RenderView *rv, // as it is likely many geometrys will have the same layout RHIGraphicsPipelineManager *pipelineManager = m_RHIResourceManagers->rhiGraphicsPipelineManager(); const int geometryLayoutId = pipelineManager->getIdForAttributeVec(cmd.m_attributeInfo); - const GraphicsPipelineIdentifier pipelineKey { geometryLayoutId, cmd.m_shaderId, rv->renderTargetId(), cmd.m_primitiveType, renderViewIndex }; + const int renderStatesKey = pipelineManager->getIdForRenderStates(cmd.m_stateSet); + const GraphicsPipelineIdentifier pipelineKey { geometryLayoutId, cmd.m_shaderId, rv->renderTargetId(), cmd.m_primitiveType, renderStatesKey }; RHIGraphicsPipeline *graphicsPipeline = pipelineManager->lookupResource(pipelineKey); if (graphicsPipeline == nullptr) { // Init UBOSet the first time we allocate a new pipeline @@ -1388,7 +1388,7 @@ Renderer::prepareCommandsSubmission(const std::vector &renderViews if (rGeometryRenderer->isDirty()) rGeometryRenderer->unsetDirty(); - updateGraphicsPipeline(command, rv, i); + updateGraphicsPipeline(command, rv); } else if (command.m_type == RenderCommand::Compute) { // By this time shaders have been loaded diff --git a/src/plugins/renderers/rhi/renderer/renderer_p.h b/src/plugins/renderers/rhi/renderer/renderer_p.h index 29a9541d6..f157e04a2 100644 --- a/src/plugins/renderers/rhi/renderer/renderer_p.h +++ b/src/plugins/renderers/rhi/renderer/renderer_p.h @@ -418,8 +418,7 @@ private: QVarLengthArray &rhiAttributes, QHash &attributeNameToBinding); - void updateGraphicsPipeline(RenderCommand &command, RenderView *rv, - int renderViewIndex); + void updateGraphicsPipeline(RenderCommand &command, RenderView *rv); void updateComputePipeline(RenderCommand &cmd, RenderView *rv, int renderViewIndex); diff --git a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h index 52803deb0..ff619c56d 100644 --- a/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h +++ b/src/plugins/renderers/rhi/renderer/rhigraphicspipeline_p.h @@ -75,7 +75,7 @@ struct GraphicsPipelineIdentifier Qt3DCore::QNodeId shader; Qt3DCore::QNodeId renderTarget; Qt3DRender::QGeometryRenderer::PrimitiveType primitiveType; - int renderViewIndex = 0; + int renderStatesKey = 0; }; struct ComputePipelineIdentifier -- cgit v1.2.3