Follow QQuickGraphicsDevice changes in QQuickRenderTarget

They are not strictly related of course, but the API pattern should be
kept. We can also move away from the QSGTexture dependency which is good
since that was never directly related.

Change-Id: I9aedff5918443bda3d6e3ee1ea389071222d1ad7
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2020-06-26 17:18:37 +02:00
parent e79281533d
commit ccb9eb0cc1
7 changed files with 174 additions and 27 deletions

View File

@ -368,9 +368,9 @@ void Window::updateQuick()
qWarning("Failed to initialize redirected Qt Quick rendering");
// Redirect Qt Quick's output.
m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_res.texture), 0 },
QSize(QML_WIDTH, QML_HEIGHT),
SAMPLE_COUNT));
m_quickWindow->setRenderTarget(QQuickRenderTarget::fromD3D11Texture(m_res.texture,
QSize(QML_WIDTH, QML_HEIGHT),
SAMPLE_COUNT));
m_quickInitialized = true;
}

View File

@ -182,7 +182,7 @@ void WindowSingleThreaded::createTexture()
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_textureSize.width(), m_textureSize.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_textureId), 0 }, m_textureSize));
m_quickWindow->setRenderTarget(QQuickRenderTarget::fromOpenGLTexture(m_textureId, m_textureSize));
}
void WindowSingleThreaded::destroyTexture()

View File

@ -123,15 +123,8 @@ bool QQuickRenderTarget::isNull() const
}
/*!
\return a new QQuickRenderTarget referencing a native texture or image
object.
\a nativeTexture references a native resource, for example, a \c VkImage,
\c ID3D11Texture2D*, c MTLTexture*, or \c GLuint. Where applicable, this
must be complemented by the current layout of the image.
\note the \c object field in \a nativeTexture must always be a pointer to
the native object, even if the type is already a pointer.
\return a new QQuickRenderTarget referencing an OpenGL texture object
specified by \a textureId.
\a pixelSize specifies the size of the image, in pixels. Currently only 2D
textures are supported.
@ -147,15 +140,14 @@ bool QQuickRenderTarget::isNull() const
\sa QQuickWindow::setRenderTarget(), QQuickRenderControl
*/
QQuickRenderTarget QQuickRenderTarget::fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture,
const QSize &pixelSize,
int sampleCount)
#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC)
QQuickRenderTarget QQuickRenderTarget::fromOpenGLTexture(uint textureId, const QSize &pixelSize, int sampleCount)
{
QQuickRenderTarget rt;
QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
if (!nativeTexture.object) {
qWarning("QQuickRenderTarget: nativeTexture.object is null");
if (!textureId) {
qWarning("QQuickRenderTarget: textureId is invalid");
return rt;
}
@ -167,10 +159,141 @@ QQuickRenderTarget QQuickRenderTarget::fromNativeTexture(const QSGTexture::Nativ
d->type = QQuickRenderTargetPrivate::Type::NativeTexture;
d->pixelSize = pixelSize;
d->sampleCount = qMax(1, sampleCount);
d->u.nativeTexture = nativeTexture;
d->u.nativeTexture = { textureId, 0 };
return rt;
}
#endif
/*!
\return a new QQuickRenderTarget referencing an D3D11 texture object
specified by \a texture.
\a pixelSize specifies the size of the image, in pixels. Currently only 2D
textures are supported.
\a sampleCount specific the number of samples. 0 or 1 means no
multisampling, while a value like 4 or 8 states that the native object is a
multisample texture.
\note the resulting QQuickRenderTarget does not own any native resources,
it merely contains references and the associated metadata of the size and
sample count. It is the caller's responsibility to ensure that the native
resource exists as long as necessary.
\sa QQuickWindow::setRenderTarget(), QQuickRenderControl
*/
#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
QQuickRenderTarget QQuickRenderTarget::fromD3D11Texture(void *texture, const QSize &pixelSize, int sampleCount)
{
QQuickRenderTarget rt;
QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
if (!texture) {
qWarning("QQuickRenderTarget: texture is null");
return rt;
}
if (pixelSize.isEmpty()) {
qWarning("QQuickRenderTarget: Cannot create with empty size");
return rt;
}
d->type = QQuickRenderTargetPrivate::Type::NativeTexture;
d->pixelSize = pixelSize;
d->sampleCount = qMax(1, sampleCount);
d->u.nativeTexture = { quint64(texture), 0 };
return rt;
}
#endif
/*!
\return a new QQuickRenderTarget referencing an Metal texture object
specified by \a texture.
\a pixelSize specifies the size of the image, in pixels. Currently only 2D
textures are supported.
\a sampleCount specific the number of samples. 0 or 1 means no
multisampling, while a value like 4 or 8 states that the native object is a
multisample texture.
\note the resulting QQuickRenderTarget does not own any native resources,
it merely contains references and the associated metadata of the size and
sample count. It is the caller's responsibility to ensure that the native
resource exists as long as necessary.
\sa QQuickWindow::setRenderTarget(), QQuickRenderControl
*/
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC)
QQuickRenderTarget QQuickRenderTarget::fromMetalTexture(MTLTexture *texture, const QSize &pixelSize, int sampleCount)
{
QQuickRenderTarget rt;
QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
if (!texture) {
qWarning("QQuickRenderTarget: texture is null");
return rt;
}
if (pixelSize.isEmpty()) {
qWarning("QQuickRenderTarget: Cannot create with empty size");
return rt;
}
d->type = QQuickRenderTargetPrivate::Type::NativeTexture;
d->pixelSize = pixelSize;
d->sampleCount = qMax(1, sampleCount);
d->u.nativeTexture = { quint64(texture), 0 };
return rt;
}
#endif
/*!
\return a new QQuickRenderTarget referencing an Vulkan image object
specified by \a image. The current \a layout of the image must be provided
as well.
\a pixelSize specifies the size of the image, in pixels. Currently only 2D
textures are supported.
\a sampleCount specific the number of samples. 0 or 1 means no
multisampling, while a value like 4 or 8 states that the native object is a
multisample texture.
\note the resulting QQuickRenderTarget does not own any native resources,
it merely contains references and the associated metadata of the size and
sample count. It is the caller's responsibility to ensure that the native
resource exists as long as necessary.
\sa QQuickWindow::setRenderTarget(), QQuickRenderControl
*/
#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
QQuickRenderTarget QQuickRenderTarget::fromVulkanImage(VkImage image, VkImageLayout layout, const QSize &pixelSize, int sampleCount)
{
QQuickRenderTarget rt;
QQuickRenderTargetPrivate *d = QQuickRenderTargetPrivate::get(&rt);
if (image == VK_NULL_HANDLE) {
qWarning("QQuickRenderTarget: image is invalid");
return rt;
}
if (pixelSize.isEmpty()) {
qWarning("QQuickRenderTarget: Cannot create with empty size");
return rt;
}
d->type = QQuickRenderTargetPrivate::Type::NativeTexture;
d->pixelSize = pixelSize;
d->sampleCount = qMax(1, sampleCount);
d->u.nativeTexture = { quint64(image), layout };
return rt;
}
#endif
/*!
\internal

View File

@ -41,7 +41,14 @@
#define QQUICKRENDERTARGET_H
#include <QtQuick/qtquickglobal.h>
#include <QtQuick/qsgtexture.h>
#if QT_CONFIG(vulkan)
#include <QtGui/QVulkanInstance>
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
Q_FORWARD_DECLARE_OBJC_CLASS(MTLTexture);
#endif
QT_BEGIN_NAMESPACE
@ -58,9 +65,21 @@ public:
bool isNull() const;
static QQuickRenderTarget fromNativeTexture(const QSGTexture::NativeTexture &nativeTexture,
const QSize &pixelSize,
int sampleCount = 1);
#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC)
static QQuickRenderTarget fromOpenGLTexture(uint textureId, const QSize &pixelSize, int sampleCount = 1);
#endif
#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
static QQuickRenderTarget fromD3D11Texture(void *texture, const QSize &pixelSize, int sampleCount = 1);
#endif
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC)
static QQuickRenderTarget fromMetalTexture(MTLTexture *texture, const QSize &pixelSize, int sampleCount = 1);
#endif
#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
static QQuickRenderTarget fromVulkanImage(VkImage image, VkImageLayout layout, const QSize &pixelSize, int sampleCount = 1);
#endif
static QQuickRenderTarget fromRhiRenderTarget(QRhiRenderTarget *renderTarget);

View File

@ -79,8 +79,12 @@ public:
Type type = Type::Null;
QSize pixelSize;
int sampleCount = 1;
struct NativeTexture {
quint64 object;
int layout;
};
union {
QSGTexture::NativeTexture nativeTexture;
NativeTexture nativeTexture;
QRhiRenderTarget *rhiRt;
} u;
};

View File

@ -1077,7 +1077,7 @@ void QQuickWidget::createFramebufferObject()
#endif
GLuint textureId = d->fbo->texture();
d->offscreenWindow->setRenderTarget( QQuickRenderTarget::fromNativeTexture({ textureId, 0 }, fboSize, samples));
d->offscreenWindow->setRenderTarget( QQuickRenderTarget::fromOpenGLTexture(textureId, fboSize, samples));
d->renderControl->setSamples(samples);

View File

@ -487,8 +487,9 @@ void tst_RenderControl::renderAndReadBackWithVulkanNative()
QCOMPARE(err, VK_SUCCESS);
// Tell Qt Quick to target our VkImage.
quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(img), VK_IMAGE_LAYOUT_PREINITIALIZED },
rootItem->size().toSize()));
quickWindow->setRenderTarget(QQuickRenderTarget::fromVulkanImage(img,
VK_IMAGE_LAYOUT_PREINITIALIZED,
rootItem->size().toSize()));
// Create a readback buffer.
VkBuffer buf = VK_NULL_HANDLE;