From cdaa4c317cf1969330e3ad148e7cb0a7cb01d859 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 4 Jul 2024 11:36:26 +0200 Subject: [PATCH] rhi: gl: Add a helper virtual to punch through to glBufferSubData The default implementation of the virtual is of course just memcopying into beginFullDynamicBufferUpdateForCurrentFrame()'s result, so not very useful for any backend except OpenGL where (for non-uniform buffers) it is implemented rather with glBufferSubData (leaving it up to the OpenGL implementation what's going to happen internally). The value is somewhat limited in practice, however one user is going to be Qt Quick: to get as identical as possible results to Qt 5 in artificial "benchmark" scenes, it becomes important to go directly to glBufferSubData (just as Qt 5 did) when updating geometry for a large number of items in every frame, and skip any intermediate resource update logic. Pick-to: 6.8 Task-number: QTBUG-125087 Change-Id: I780a1431e021b90590b493e1fb82334cd71bd75b Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 12 ++++++++++++ src/gui/rhi/qrhi.h | 1 + src/gui/rhi/qrhigles2.cpp | 11 +++++++++++ src/gui/rhi/qrhigles2_p.h | 1 + 4 files changed, 25 insertions(+) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index ee0562d12db..b046f2cd692 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -3981,6 +3981,18 @@ void QRhiBuffer::endFullDynamicBufferUpdateForCurrentFrame() { } +/*! + \internal + */ +void QRhiBuffer::fullDynamicBufferUpdateForCurrentFrame(const void *data) +{ + char *p = beginFullDynamicBufferUpdateForCurrentFrame(); + if (p) { + memcpy(p, data, m_size); + endFullDynamicBufferUpdateForCurrentFrame(); + } +} + /*! \class QRhiRenderBuffer \inmodule QtGui diff --git a/src/gui/rhi/qrhi.h b/src/gui/rhi/qrhi.h index 5ee8c736799..f491cd3507d 100644 --- a/src/gui/rhi/qrhi.h +++ b/src/gui/rhi/qrhi.h @@ -881,6 +881,7 @@ public: virtual char *beginFullDynamicBufferUpdateForCurrentFrame(); virtual void endFullDynamicBufferUpdateForCurrentFrame(); + virtual void fullDynamicBufferUpdateForCurrentFrame(const void *data); protected: QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, quint32 size_); diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 49a1b8465d6..b40383e9fc9 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -5370,6 +5370,17 @@ void QGles2Buffer::endFullDynamicBufferUpdateForCurrentFrame() } } +void QGles2Buffer::fullDynamicBufferUpdateForCurrentFrame(const void *bufferData) +{ + if (!m_usage.testFlag(UniformBuffer)) { + QRHI_RES_RHI(QRhiGles2); + rhiD->f->glBindBuffer(targetForDataOps, buffer); + rhiD->f->glBufferSubData(targetForDataOps, 0, m_size, bufferData); + } else { + memcpy(data.data(), bufferData, m_size); + } +} + QGles2RenderBuffer::QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint) diff --git a/src/gui/rhi/qrhigles2_p.h b/src/gui/rhi/qrhigles2_p.h index d17662007ef..61ab99c260d 100644 --- a/src/gui/rhi/qrhigles2_p.h +++ b/src/gui/rhi/qrhigles2_p.h @@ -38,6 +38,7 @@ struct QGles2Buffer : public QRhiBuffer QRhiBuffer::NativeBuffer nativeBuffer() override; char *beginFullDynamicBufferUpdateForCurrentFrame() override; void endFullDynamicBufferUpdateForCurrentFrame() override; + void fullDynamicBufferUpdateForCurrentFrame(const void *data) override; quint32 nonZeroSize = 0; GLuint buffer = 0;