From c2fc8b0fa8ffd02a708b9ed8af97992b014ff751 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@qt.io>
Date: Tue, 20 Oct 2020 13:18:12 +0300
Subject: [PATCH] Clear deleted pipeline pointers from draw call data cache

Same pipeline may be cached with different renderpass descriptors
in draw call data cache. Presumably this happens when a pipeline is
compatible with multiple different render passes.

When clearing the cache, check for actual deleted pipelines instead
of just matching descriptor.

Task-number: QDS-2899
Change-Id: Ib1326892dad9a4cf550536b4e06a24073437f7a1
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
---
 src/runtimerender/qssgrhicontext.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/runtimerender/qssgrhicontext.cpp b/src/runtimerender/qssgrhicontext.cpp
index cab91202e..625a2e0aa 100644
--- a/src/runtimerender/qssgrhicontext.cpp
+++ b/src/runtimerender/qssgrhicontext.cpp
@@ -921,12 +921,15 @@ void QSSGRhiContext::invalidateCachedReferences(QRhiRenderPassDescriptor *rpDesc
     if (!rpDesc)
         return;
 
+    QVarLengthArray<QRhiGraphicsPipeline *, 16> deletedPipelines;
+
     for (auto it = m_pipelines.begin(); it != m_pipelines.end(); ) {
         if (it.key().compatibleRpDesc == rpDesc) {
             // The QRhiGraphicsPipeline object is kept alive until the current
             // frame is submitted (by QRhi::endFrame()) The underlying native
             // graphics object(s) may live even longer in fact, but QRhi takes
             // care of that so that's no concern for us here.
+            deletedPipelines.append(it.value());
             it.value()->deleteLater();
             it = m_pipelines.erase(it);
         } else {
@@ -935,7 +938,7 @@ void QSSGRhiContext::invalidateCachedReferences(QRhiRenderPassDescriptor *rpDesc
     }
 
     for (auto it = m_drawCallData.begin(), end = m_drawCallData.end(); it != end; ++it) {
-        if (it->pipelineRpDesc == rpDesc) {
+        if (deletedPipelines.contains(it->pipeline)) {
             it->pipeline = nullptr;
             it->pipelineRpDesc = nullptr;
         }
-- 
GitLab