summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2019-11-29 12:41:38 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2019-12-05 10:04:46 +0100
commit913146ccd401216f71f037ea304b5e61b7a138cf (patch)
tree333ea1a5d39d8bab456de2df78a40fbc90c80e5f /src
parentf43cb31ba00a431c6d0a0b17750483a72ae03bb0 (diff)
RHI: new native texture API
The new version takes/returns a value that can be unpacked and passed to other functions without knowing which backend is in use. The old API will be removed in a later change when dependent modules have been updated Task-number: QTBUG-78570 Change-Id: I18d928ceef3cb617c0c509ecccb345551a7990af Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhi.cpp67
-rw-r--r--src/gui/rhi/qrhi_p.h7
-rw-r--r--src/gui/rhi/qrhid3d11.cpp28
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h2
-rw-r--r--src/gui/rhi/qrhigles2.cpp29
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h2
-rw-r--r--src/gui/rhi/qrhimetal.mm29
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h2
-rw-r--r--src/gui/rhi/qrhinull.cpp6
-rw-r--r--src/gui/rhi/qrhinull_p_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp30
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h2
12 files changed, 205 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index ece5190ff7..58f30deb41 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -2160,6 +2160,32 @@ QRhiResource::Type QRhiRenderBuffer::resourceType() const
*/
/*!
+ \class QRhiTexture::NativeTexture
+ \brief Contains information about the underlying native resources of a texture.
+ */
+
+/*!
+ \variable QRhiTexture::NativeTexture::object
+ \brief a pointer to the native object handle.
+
+ With OpenGL, the native handle is a GLuint value, so \c object is then a
+ pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \c
+ object is a pointer to a VkImage. With Direct3D 11 and Metal \c
+ object is a pointer to a ID3D11Texture2D or MTLTexture pointer, respectively.
+
+ \note Pay attention to the fact that \a object is always a pointer
+ to the native texture handle type, even if the native type itself is a
+ pointer.
+ */
+
+/*!
+ \variable QRhiTexture::NativeTexture::layout
+ \brief Specifies the current image layout for APIs like Vulkan.
+
+ For Vulkan, \c layout contains a \c VkImageLayout value.
+ */
+
+/*!
\internal
*/
QRhiTexture::QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_,
@@ -2196,12 +2222,25 @@ QRhiResource::Type QRhiTexture::resourceType() const
\sa QRhiVulkanTextureNativeHandles, QRhiD3D11TextureNativeHandles,
QRhiMetalTextureNativeHandles, QRhiGles2TextureNativeHandles
*/
+// TODO: remove this version once QtQuick has stopped using it
const QRhiNativeHandles *QRhiTexture::nativeHandles()
{
return nullptr;
}
/*!
+ \return the underlying native resources for this texture. The returned value
+ will be empty if exposing the underlying native resources is not supported by
+ the backend.
+
+ \sa buildFrom()
+ */
+QRhiTexture::NativeTexture QRhiTexture::nativeTexture()
+{
+ return {};
+}
+
+/*!
Similar to build() except that no new native textures are created. Instead,
the texture from \a src is used.
@@ -2224,6 +2263,7 @@ const QRhiNativeHandles *QRhiTexture::nativeHandles()
\sa QRhiVulkanTextureNativeHandles, QRhiD3D11TextureNativeHandles,
QRhiMetalTextureNativeHandles, QRhiGles2TextureNativeHandles
*/
+// TODO: remove this version once QtQuick has stopped using it
bool QRhiTexture::buildFrom(const QRhiNativeHandles *src)
{
Q_UNUSED(src);
@@ -2231,6 +2271,33 @@ bool QRhiTexture::buildFrom(const QRhiNativeHandles *src)
}
/*!
+ Similar to build() except that no new native textures are created. Instead,
+ the native texture resources specified by \a src is used.
+
+ This allows importing an existing native texture object (which must belong
+ to the same device or sharing context, depending on the graphics API) from
+ an external graphics engine.
+
+ \note format(), pixelSize(), sampleCount(), and flags() must still be set
+ correctly. Passing incorrect sizes and other values to QRhi::newTexture()
+ and then following it with a buildFrom() expecting that the native texture
+ object alone is sufficient to deduce such values is \b wrong and will lead
+ to problems.
+
+ \note QRhiTexture does not take ownership of the texture object. release()
+ does not free the object or any associated memory.
+
+ The opposite of this operation, exposing a QRhiTexture-created native
+ texture object to a foreign engine, is possible via nativeTexture().
+
+*/
+bool QRhiTexture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ Q_UNUSED(src);
+ return false;
+}
+
+/*!
\class QRhiSampler
\internal
\inmodule QtGui
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 6fb9c44ae6..44118b2f10 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -760,6 +760,11 @@ public:
ASTC_12x12
};
+ struct NativeTexture {
+ const void *object;
+ int layout;
+ };
+
QRhiResource::Type resourceType() const override;
Format format() const { return m_format; }
@@ -776,7 +781,9 @@ public:
virtual bool build() = 0;
virtual const QRhiNativeHandles *nativeHandles();
+ virtual NativeTexture nativeTexture();
virtual bool buildFrom(const QRhiNativeHandles *src);
+ virtual bool buildFrom(NativeTexture src);
protected:
QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_,
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 52109edce0..ba2488bffb 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -2764,11 +2764,39 @@ bool QD3D11Texture::buildFrom(const QRhiNativeHandles *src)
return true;
}
+bool QD3D11Texture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ auto *srcTex = static_cast<ID3D11Texture2D * const *>(src.object);
+ if (!srcTex || !*srcTex)
+ return false;
+
+ if (!prepareBuild())
+ return false;
+
+ tex = *srcTex;
+
+ if (!finishBuild())
+ return false;
+
+ QRHI_PROF;
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, int(sampleDesc.Count)));
+
+ owns = false;
+ QRHI_RES_RHI(QRhiD3D11);
+ rhiD->registerResource(this);
+ return true;
+}
+
const QRhiNativeHandles *QD3D11Texture::nativeHandles()
{
return &nativeHandlesStruct;
}
+QRhiTexture::NativeTexture QD3D11Texture::nativeTexture()
+{
+ return {&nativeHandlesStruct.texture, 0};
+}
+
ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
{
if (perLevelViews[level])
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 13c56b1d6d..8f02c4300b 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -100,7 +100,9 @@ struct QD3D11Texture : public QRhiTexture
void release() override;
bool build() override;
bool buildFrom(const QRhiNativeHandles *src) override;
+ bool buildFrom(NativeTexture src) override;
const QRhiNativeHandles *nativeHandles() override;
+ NativeTexture nativeTexture() override;
bool prepareBuild(QSize *adjustedSize = nullptr);
bool finishBuild();
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index b551980bb3..563d59b318 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -3404,11 +3404,40 @@ bool QGles2Texture::buildFrom(const QRhiNativeHandles *src)
return true;
}
+bool QGles2Texture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ const uint *textureId = static_cast<const uint *>(src.object);
+ if (!textureId || !*textureId)
+ return false;
+
+ if (!prepareBuild())
+ return false;
+
+ texture = *textureId;
+ specified = true;
+
+ QRHI_RES_RHI(QRhiGles2);
+ QRHI_PROF;
+ QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, 1));
+
+ owns = false;
+ nativeHandlesStruct.texture = texture;
+
+ generation += 1;
+ rhiD->registerResource(this);
+ return true;
+}
+
const QRhiNativeHandles *QGles2Texture::nativeHandles()
{
return &nativeHandlesStruct;
}
+QRhiTexture::NativeTexture QGles2Texture::nativeTexture()
+{
+ return {&nativeHandlesStruct.texture, 0};
+}
+
QGles2Sampler::QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
AddressMode u, AddressMode v)
: QRhiSampler(rhi, magFilter, minFilter, mipmapMode, u, v)
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index b0f5e340fb..0283fadb4e 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -133,7 +133,9 @@ struct QGles2Texture : public QRhiTexture
void release() override;
bool build() override;
bool buildFrom(const QRhiNativeHandles *src) override;
+ bool buildFrom(NativeTexture src) override;
const QRhiNativeHandles *nativeHandles() override;
+ NativeTexture nativeTexture() override;
bool prepareBuild(QSize *adjustedSize = nullptr);
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index e5af1cfab1..555ed5e79f 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -2499,11 +2499,40 @@ bool QMetalTexture::buildFrom(const QRhiNativeHandles *src)
return true;
}
+bool QMetalTexture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ void * const * tex = (void * const *) src.object;
+ if (!tex || !*tex)
+ return false;
+
+ if (!prepareBuild())
+ return false;
+
+ d->tex = (id<MTLTexture>) *tex;
+
+ d->owns = false;
+ nativeHandlesStruct.texture = d->tex;
+
+ QRHI_PROF;
+ QRHI_PROF_F(newTexture(this, false, mipLevelCount, m_flags.testFlag(CubeMap) ? 6 : 1, samples));
+
+ lastActiveFrameSlot = -1;
+ generation += 1;
+ QRHI_RES_RHI(QRhiMetal);
+ rhiD->registerResource(this);
+ return true;
+}
+
const QRhiNativeHandles *QMetalTexture::nativeHandles()
{
return &nativeHandlesStruct;
}
+QRhiTexture::NativeTexture QMetalTexture::nativeTexture()
+{
+ return {&nativeHandlesStruct.texture, 0};
+}
+
id<MTLTexture> QMetalTextureData::viewForLevel(int level)
{
Q_ASSERT(level >= 0 && level < int(q->mipLevelCount));
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index 7876539fcd..8e655fd98b 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -101,7 +101,9 @@ struct QMetalTexture : public QRhiTexture
void release() override;
bool build() override;
bool buildFrom(const QRhiNativeHandles *src) override;
+ bool buildFrom(NativeTexture src) override;
const QRhiNativeHandles *nativeHandles() override;
+ NativeTexture nativeTexture() override;
bool prepareBuild(QSize *adjustedSize = nullptr);
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index 0baea1b9d6..80f004e049 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -651,6 +651,12 @@ bool QNullTexture::buildFrom(const QRhiNativeHandles *src)
return true;
}
+bool QNullTexture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ Q_UNUSED(src)
+ return buildFrom(nullptr);
+}
+
const QRhiNativeHandles *QNullTexture::nativeHandles()
{
return &nativeHandlesStruct;
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index c96f279f7d..57c3de0418 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -81,6 +81,7 @@ struct QNullTexture : public QRhiTexture
void release() override;
bool build() override;
bool buildFrom(const QRhiNativeHandles *src) override;
+ bool buildFrom(NativeTexture src) override;
const QRhiNativeHandles *nativeHandles() override;
QRhiNullTextureNativeHandles nativeHandlesStruct;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 49ca2326bc..21ae142b1d 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -5370,12 +5370,42 @@ bool QVkTexture::buildFrom(const QRhiNativeHandles *src)
return true;
}
+bool QVkTexture::buildFrom(QRhiTexture::NativeTexture src)
+{
+ auto *img = static_cast<const VkImage*>(src.object);
+ if (!img || !*img)
+ return false;
+
+ if (!prepareBuild())
+ return false;
+
+ image = *img;
+
+ if (!finishBuild())
+ return false;
+
+ QRHI_PROF;
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, samples));
+
+ usageState.layout = VkImageLayout(src.layout);
+
+ owns = false;
+ QRHI_RES_RHI(QRhiVulkan);
+ rhiD->registerResource(this);
+ return true;
+}
+
const QRhiNativeHandles *QVkTexture::nativeHandles()
{
nativeHandlesStruct.layout = usageState.layout;
return &nativeHandlesStruct;
}
+QRhiTexture::NativeTexture QVkTexture::nativeTexture()
+{
+ return {&nativeHandlesStruct.image, usageState.layout};
+}
+
VkImageView QVkTexture::imageViewForLevel(int level)
{
Q_ASSERT(level >= 0 && level < int(mipLevelCount));
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index ffa8c59ed5..d1b77870a1 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -121,7 +121,9 @@ struct QVkTexture : public QRhiTexture
void release() override;
bool build() override;
bool buildFrom(const QRhiNativeHandles *src) override;
+ bool buildFrom(NativeTexture src) override;
const QRhiNativeHandles *nativeHandles() override;
+ NativeTexture nativeTexture() override;
bool prepareBuild(QSize *adjustedSize = nullptr);
bool finishBuild();