diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 53 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 8 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 2 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 4 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 2 |
7 files changed, 61 insertions, 17 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index f857142bd7..584fbb263d 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -627,18 +627,27 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") is what some OpenGL ES implementations provide. \value FramesInFlight The number of frames the backend may keep "in - flight". The value has no relevance, and is unspecified, with backends like - OpenGL and Direct3D 11. With backends like Vulkan or Metal, it is the - responsibility of QRhi to block whenever starting a new frame and finding - the CPU is already \c{N - 1} frames ahead of the GPU (because the command - buffer submitted in frame no. \c{current} - \c{N} has not yet completed). - The value N is what is returned from here, and is typically 2. This can be - relevant to applications that integrate rendering done directly with the - graphics API, as such rendering code may want to perform double (if the - value is 2) buffering for resources, such as, buffers, similarly to the - QRhi backends themselves. The current frame slot index (a value running 0, - 1, .., N-1, then wrapping around) is retrievable from - QRhi::currentFrameSlot(). + flight": with backends like Vulkan or Metal, it is the responsibility of + QRhi to block whenever starting a new frame and finding the CPU is already + \c{N - 1} frames ahead of the GPU (because the command buffer submitted in + frame no. \c{current} - \c{N} has not yet completed). The value N is what + is returned from here, and is typically 2. This can be relevant to + applications that integrate rendering done directly with the graphics API, + as such rendering code may want to perform double (if the value is 2) + buffering for resources, such as, buffers, similarly to the QRhi backends + themselves. The current frame slot index (a value running 0, 1, .., N-1, + then wrapping around) is retrievable from QRhi::currentFrameSlot(). The + value is 1 for backends where the graphics API offers no such low level + control over the command submission process. Note that pipelining may still + happen even when this value is 1 (some backends, such as D3D11, are + designed to attempt to enable this, for instance, by using an update + strategy for uniform buffers that does not stall the pipeline), but that is + then not controlled by QRhi and so not reflected here in the API. + + \value MaxAsyncReadbackFrames The number of \l{QRhi::endFrame()}{submitted} + frames (including the one that contains the readback) after which an + asynchronous texture or buffer readback is guaranteed to complete upon + \l{QRhi::beginFrame()}{starting a new frame}. */ /*! @@ -4339,7 +4348,15 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da is supported only when the QRhi::ReadBackNonUniformBuffer feature is reported as supported. - \a readBackTexture(), QRhi::isFeatureSupported() + \note The asynchronous readback is guaranteed to have completed when one of + the following conditions is met: \l{QRhi::finish()}{finish()} has been + called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted}, + including the frame that issued the readback operation, and the + \l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c + N is the \l{QRhi::resourceLimit()}{resource limit value} returned for + QRhi::MaxAsyncReadbackFrames. + + \sa readBackTexture(), QRhi::isFeatureSupported(), QRhi::resourceLimit() */ void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result) { @@ -4430,6 +4447,16 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co happens with a byte ordered format. A \l{QRhiTexture::RGBA8}{RGBA8} texture maps therefore to byte ordered QImage formats, such as, QImage::Format_RGBA8888. + + \note The asynchronous readback is guaranteed to have completed when one of + the following conditions is met: \l{QRhi::finish()}{finish()} has been + called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted}, + including the frame that issued the readback operation, and the + \l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c + N is the \l{QRhi::resourceLimit()}{resource limit value} returned for + QRhi::MaxAsyncReadbackFrames. + + \sa readBackBuffer(), QRhi::resourceLimit() */ void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result) { diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 7d03ac8aaa..be96ebbf05 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1448,7 +1448,8 @@ public: TextureSizeMin = 1, TextureSizeMax, MaxColorAttachments, - FramesInFlight + FramesInFlight, + MaxAsyncReadbackFrames }; ~QRhi(); diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 883aa68df7..221ec6e6e5 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -482,7 +482,13 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const case QRhi::MaxColorAttachments: return 8; case QRhi::FramesInFlight: - return 2; // dummy + // From our perspective. What D3D does internally is another question + // (there could be pipelining, helped f.ex. by our MAP_DISCARD based + // uniform buffer update strategy), but that's out of our hands and + // does not concern us here. + return 1; + case QRhi::MaxAsyncReadbackFrames: + return 1; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index f2b9f7081b..df0b255bed 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -787,7 +787,11 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const case QRhi::MaxColorAttachments: return caps.maxDrawBuffers; case QRhi::FramesInFlight: - return 2; // dummy + // From our perspective. What the GL impl does internally is another + // question, but that's out of our hands and does not concern us here. + return 1; + case QRhi::MaxAsyncReadbackFrames: + return 1; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 5b77086983..b0813bfc77 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -581,6 +581,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const return 8; case QRhi::FramesInFlight: return QMTL_FRAMES_IN_FLIGHT; + case QRhi::MaxAsyncReadbackFrames: + return QMTL_FRAMES_IN_FLIGHT; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 4c59900aa6..8c07e09b32 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -146,7 +146,9 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const case QRhi::MaxColorAttachments: return 8; case QRhi::FramesInFlight: - return 2; // dummy + return 1; + case QRhi::MaxAsyncReadbackFrames: + return 1; default: Q_UNREACHABLE(); return 0; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 840eed5a79..5d6e9b21bc 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4009,6 +4009,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const return int(physDevProperties.limits.maxColorAttachments); case QRhi::FramesInFlight: return QVK_FRAMES_IN_FLIGHT; + case QRhi::MaxAsyncReadbackFrames: + return QVK_FRAMES_IN_FLIGHT; default: Q_UNREACHABLE(); return 0; |