path: root/src
diff options
authorLaszlo Agocs <>2019-08-06 16:47:10 +0200
committerLaszlo Agocs <>2019-08-17 15:00:51 +0200
commit60599486e81853138b2eb6210e875c214085c377 (patch)
treea76ef88e47ecbc49a811f94e8c341cf0b5e95d06 /src
parent82a2c7df3023e68f152e522dacdcbb076cdde701 (diff)
rhi: metal: Avoid flicker due to writing an in-use Managed buffer
Qt Quick apps feature an occasional flicker which seems to be caused by updating the contents of a Static (or Immutable) QRhiBuffer in a frame where the QRhiBuffer in question is read in the previous frame as well. On macOS these types map to a Managed MTLBuffer and only one native buffer object (MTLBuffer). It seems modifying such a buffer is not safe if the previous frame has not completed. (this may be as expected, but hard to tell due to Metal's underdocumented automatic hazard tracking which we rely on atm) So for now switch to having 2 native buffers, like we do for Dynamic (on iOS/tvOS this would be the case anyway since there all buffers are host visible and slotted regardless of the QRhiBuffer type). This seems to solve the issue. To be seen if we want to move to a more Vulkan-like setup where Immutable and Static map to device local (Private). Change-Id: I76013f58a2e183ad8eab0705b28a03b395c4530c Reviewed-by: Christian Strømme <>
Diffstat (limited to 'src')
1 files changed, 5 insertions, 3 deletions
diff --git a/src/gui/rhi/ b/src/gui/rhi/
index ffb2283ae7..b7cc1da3fe 100644
--- a/src/gui/rhi/
+++ b/src/gui/rhi/
@@ -1986,9 +1986,11 @@ bool QMetalBuffer::build()
- // Immutable and Static only has buf[0] and pendingUpdates[0] in use.
- // Dynamic uses all.
- d->slotted = m_type == Dynamic;
+ // Have QMTL_FRAMES_IN_FLIGHT versions regardless of the type, for now.
+ // This is because writing to a Managed buffer (which is what Immutable and
+ // Static maps to on macOS) is not safe when another frame reading from the
+ // same buffer is still in flight.
+ d->slotted = !m_usage.testFlag(QRhiBuffer::StorageBuffer); // except for SSBOs written in the shader
for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) {