summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-07-15 09:13:41 +0200
committerPaul Lemire <paul.lemire@kdab.com>2020-07-16 13:23:05 +0200
commit81d4c607660dd1eb116ada95b5878fd51531442c (patch)
tree81e3049ad0fdee01ab1b1b9fb1a7ee25381fc103 /src
parent67e6048291e4d71de56abd5d44664096e113da40 (diff)
RHIBuffer: don't destroy buffer immediately when orphaning
We need to keep past QRhiBuffer alive long enough to have submitted any updates we might have already recorded for them. Change-Id: I3807cbca64773b0c61afefd6378ae397b175c2e5 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/renderers/rhi/io/rhibuffer.cpp19
-rw-r--r--src/plugins/renderers/rhi/io/rhibuffer_p.h3
-rw-r--r--src/plugins/renderers/rhi/renderer/renderer.cpp6
3 files changed, 26 insertions, 2 deletions
diff --git a/src/plugins/renderers/rhi/io/rhibuffer.cpp b/src/plugins/renderers/rhi/io/rhibuffer.cpp
index edff21e0c..0f19bf250 100644
--- a/src/plugins/renderers/rhi/io/rhibuffer.cpp
+++ b/src/plugins/renderers/rhi/io/rhibuffer.cpp
@@ -116,17 +116,32 @@ bool RHIBuffer::bind(SubmissionContext *ctx, Type t)
void RHIBuffer::destroy()
{
if (m_rhiBuffer) {
- m_rhiBuffer->destroy();
delete m_rhiBuffer;
m_rhiBuffer = nullptr;
}
+ destroyOrphaned();
m_allocSize = 0;
}
+void RHIBuffer::destroyOrphaned()
+{
+ for (QRhiBuffer *oldBuffer : m_buffersToCleanup)
+ delete oldBuffer;
+ m_buffersToCleanup.clear();
+}
+
+// Note: when we orphan, we have to keep the previous QRhiBuffer alive until
+// after frame has been submitted. This is because we might have already stored
+// updates in the RHI Command Buffers for the buffer that is about to be
+// destroyed. We therefore have to wait until command buffer has been submitted
+// until we can destroy the buffer.
void RHIBuffer::orphan()
{
m_datasToUpload.clear();
- destroy();
+ if (m_rhiBuffer) {
+ m_buffersToCleanup.push_back(m_rhiBuffer);
+ m_rhiBuffer = nullptr;
+ }
}
void RHIBuffer::allocate(const QByteArray &data, bool dynamic)
diff --git a/src/plugins/renderers/rhi/io/rhibuffer_p.h b/src/plugins/renderers/rhi/io/rhibuffer_p.h
index 27d26c9a4..4d13836b7 100644
--- a/src/plugins/renderers/rhi/io/rhibuffer_p.h
+++ b/src/plugins/renderers/rhi/io/rhibuffer_p.h
@@ -81,6 +81,7 @@ public:
bool bind(SubmissionContext *ctx, Type t);
void destroy();
+ void destroyOrphaned();
void allocate(const QByteArray &data, bool dynamic = true);
void update(const QByteArray &data, int offset = 0);
QByteArray download(SubmissionContext *ctx, uint size);
@@ -98,6 +99,8 @@ private:
QRhiBuffer *m_rhiBuffer {};
+ std::vector<QRhiBuffer *> m_buffersToCleanup;
+
std::vector<std::pair<QByteArray /*data*/, int /*offset*/>> m_datasToUpload;
};
diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp
index 2b9c858d0..096994da1 100644
--- a/src/plugins/renderers/rhi/renderer/renderer.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderer.cpp
@@ -2561,6 +2561,12 @@ void Renderer::cleanGraphicsResources()
for (Qt3DCore::QNodeId bufferId : buffersToRelease)
m_submissionContext->releaseBuffer(bufferId);
+ const RHIBufferManager *bufferManager = m_RHIResourceManagers->rhiBufferManager();
+ const std::vector<HRHIBuffer> &activeBufferHandles = bufferManager->activeHandles();
+ // Release internal QRhiBuffer that might have been orphaned
+ for (const HRHIBuffer &bufferH : activeBufferHandles)
+ bufferH->destroyOrphaned();
+
// When Textures are cleaned up, their id is saved so that they can be
// cleaned up in the render thread
const QList<Qt3DCore::QNodeId> cleanedUpTextureIds = std::move(m_textureIdsToCleanup);