summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2022-08-10 10:25:12 +0200
committerPaul Lemire <paul.lemire@kdab.com>2022-08-11 06:57:04 +0200
commitbed3d7b000a0ce84523fa79ab29731716bb8ed3b (patch)
treef591397792af349840ab30e5878906128bd13f49
parentde14c77db216577d497519e6937c386927495a83 (diff)
RHI backend: set texture handle on the frontend node
Allows to then use the handle with a 3rd party external renderer (e.g QtQuick with QQuickWindowPrivate::createTextureFromNativeTexture). Note: we need to be careful and only set the handles once we know the internal QRhiTextures aren't modified anymore. This means we can only do it after having created/updated the textures and the render targets as the render target creation might result in some QRhiTextures being recreated. Pick-to: 6.4 Change-Id: I7e85fd2661cf935368ee55dc2ebd240bbda38a6f Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r--src/plugins/renderers/rhi/renderer/renderer.cpp61
-rw-r--r--src/render/texture/qabstracttexture.h3
2 files changed, 44 insertions, 20 deletions
diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp
index b2b3674ae..9c438cc36 100644
--- a/src/plugins/renderers/rhi/renderer/renderer.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderer.cpp
@@ -1148,11 +1148,11 @@ void Renderer::createRenderTarget(RenderTarget *target)
for (const Attachment &attachment : pack.attachments()) {
RHITexture *tex = texman->lookupResource(attachment.m_textureUuid);
if (tex && tex->getRhiTexture()) {
-
auto rhiTex = tex->getRhiTexture();
if (!rhiTex->flags().testFlag(QRhiTexture::RenderTarget) ||
!rhiTex->flags().testFlag(QRhiTexture::UsedAsTransferSource)) {
// UsedAsTransferSource is required if we ever want to read back from the texture
+ rhiTex->destroy();
rhiTex->setFlags(rhiTex->flags() | QRhiTexture::RenderTarget|QRhiTexture::UsedAsTransferSource);
rhiTex->create();
}
@@ -1583,7 +1583,6 @@ void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager)
QAbstractTexturePrivate *dTexture =
static_cast<QAbstractTexturePrivate *>(QNodePrivate::get(texture));
-
dTexture->setStatus(properties.status);
dTexture->setHandleType(pair.first.handleType);
dTexture->setHandle(pair.first.handle);
@@ -1798,6 +1797,12 @@ void Renderer::updateResources()
}
}
+ std::vector<RHITexture *> updatedRHITextures;
+
+ // Create/Update textures. We record the update info to later fill
+ // m_updatedTextureProperties once we are use the RHITextures have been
+ // fully created (as creating the RenderTargets below could change existing
+ // RHITextures)
{
const std::vector<HTexture> activeTextureHandles = Qt3DCore::moveAndClear(m_dirtyTextures);
for (const HTexture &handle : activeTextureHandles) {
@@ -1816,31 +1821,29 @@ void Renderer::updateResources()
// RHITexture
if (m_submissionContext != nullptr) {
RHITextureManager *rhiTextureManager = m_RHIResourceManagers->rhiTextureManager();
- const std::vector<HRHITexture> &glTextureHandles = rhiTextureManager->activeHandles();
+ const std::vector<HRHITexture> &rhiTextureHandles = rhiTextureManager->activeHandles();
// Upload texture data
- for (const HRHITexture &glTextureHandle : glTextureHandles) {
+ for (const HRHITexture &rhiTextureHandle : rhiTextureHandles) {
RHI_UNIMPLEMENTED;
- RHITexture *glTexture = rhiTextureManager->data(glTextureHandle);
+ RHITexture *rhiTexture = rhiTextureManager->data(rhiTextureHandle);
- // We create/update the actual GL texture using the GL context at this point
+ // We create/update the actual RHI texture using the RHI context at this point
const RHITexture::TextureUpdateInfo info =
- glTexture->createOrUpdateRhiTexture(m_submissionContext.data());
-
- // RHITexture creation provides us width/height/format ... information
- // for textures which had not initially specified these information
- // (TargetAutomatic...) Gather these information and store them to be distributed by
- // a change next frame
- const QNodeIdVector referenceTextureIds = {
- rhiTextureManager->texNodeIdForRHITexture.value(glTexture)
- };
- // Store properties and referenceTextureIds
+ rhiTexture->createOrUpdateRhiTexture(m_submissionContext.data());
+
if (info.wasUpdated) {
+ // RHITexture creation provides us width/height/format ... information
+ // for textures which had not initially specified these information
+ // (TargetAutomatic...) Gather these information and store them to be distributed by
+ // a change next frame
+ const QNodeIdVector referenceTextureIds = { rhiTextureManager->texNodeIdForRHITexture.value(rhiTexture) };
+ // Store properties and referenceTextureIds
Texture::TextureUpdateInfo updateInfo;
updateInfo.properties = info.properties;
- updateInfo.handleType = QAbstractTexture::OpenGLTextureId;
- // updateInfo.handle = info.texture ?
- // QVariant(info.texture->textureId()) : QVariant();
+ // Record texture updates to notify frontend (we are sure at this stage
+ // that the internal QRHITexture won't be updated further for this frame
m_updatedTextureProperties.push_back({ updateInfo, referenceTextureIds });
+ updatedRHITextures.push_back(rhiTexture);
}
}
}
@@ -1854,6 +1857,10 @@ void Renderer::updateResources()
// -> attachments added/removed
// -> attachments textures updated (new dimensions, format ...)
// -> destroy pipelines associated with dirty renderTargets
+
+ // Note: we might end up recreating some of the internal textures when
+ // creating the RenderTarget as those might have been created above without
+ // the proper RenderTarget/TransformSource flags
{
RHIRenderTargetManager *rhiRenderTargetManager = m_RHIResourceManagers->rhiRenderTargetManager();
RenderTargetManager *renderTargetManager = m_nodesManager->renderTargetManager();
@@ -1894,6 +1901,22 @@ void Renderer::updateResources()
}
}
+
+ // Note: we can only retrieve the internal QRhiResource handle to set on
+ // the frontend nodes after we are sure we are no going to modify the
+ // QRhiTextures (which happens when we create the Textures or the
+ // RenderTargets)
+ {
+ for (size_t i = 0, m = m_updatedTextureProperties.size(); i < m; ++i) {
+ auto &updateInfoPair = m_updatedTextureProperties[i];
+ RHITexture *rhiTexture = updatedRHITextures[i];
+ QRhiTexture *qRhiTexture = rhiTexture->getRhiTexture();
+ Texture::TextureUpdateInfo &updateInfo = updateInfoPair.first;
+ updateInfo.handleType = QAbstractTexture::RHITextureId;
+ updateInfo.handle = qRhiTexture ? QVariant(qRhiTexture->nativeTexture().object) : QVariant();
+ }
+ }
+
// Record list of buffer that might need uploading
lookForDownloadableBuffers();
}
diff --git a/src/render/texture/qabstracttexture.h b/src/render/texture/qabstracttexture.h
index afe8abaf6..9fc55fa7f 100644
--- a/src/render/texture/qabstracttexture.h
+++ b/src/render/texture/qabstracttexture.h
@@ -237,7 +237,8 @@ public:
enum HandleType {
NoHandle,
- OpenGLTextureId
+ OpenGLTextureId,
+ RHITextureId
};
Q_ENUM(HandleType) // LCOV_EXCL_LINE