diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-04-28 18:15:03 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-04-29 22:36:00 +0200 |
commit | 1c0a7a87e9e8dd630d35b2c3e57d45c42f6d12bd (patch) | |
tree | 6bba3482a817ecf5dcd732de633131e0b0a9416e /src | |
parent | f2347077f503d103974636cae9319d127714e2e4 (diff) |
rhi: Add backing format hint to QRhiRenderBuffer
Task-number: QTBUG-83707
Change-Id: I63548f4ace70af614a2aa082663bb3ae9fbedc25
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 25 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 18 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11_p_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 189 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 284 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal_p_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 10 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull_p_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 17 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan_p_p.h | 6 |
13 files changed, 332 insertions, 250 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 1eb26985bf..6a118d20c8 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -2123,9 +2123,11 @@ QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer() \internal */ QRhiRenderBuffer::QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QSize &pixelSize_, - int sampleCount_, Flags flags_) + int sampleCount_, Flags flags_, + QRhiTexture::Format backingFormatHint_) : QRhiResource(rhi), - m_type(type_), m_pixelSize(pixelSize_), m_sampleCount(sampleCount_), m_flags(flags_) + m_type(type_), m_pixelSize(pixelSize_), m_sampleCount(sampleCount_), m_flags(flags_), + m_backingFormatHint(backingFormatHint_) { } @@ -5488,14 +5490,29 @@ QRhiBuffer *QRhi::newBuffer(QRhiBuffer::Type type, \return a new renderbuffer with the specified \a type, \a pixelSize, \a sampleCount, and \a flags. + When \a backingFormatHint is set to a texture format other than + QRhiTexture::UnknownFormat, it may be used by the backend to decide what + format to use for the storage backing the renderbuffer. + + \note \a backingFormatHint becomes relevant typically when multisampling + and floating point texture formats are involved: rendering into a + multisample QRhiRenderBuffer and then resolving into a non-RGBA8 + QRhiTexture implies (with some graphics APIs) that the storage backing the + QRhiRenderBuffer uses the matching non-RGBA8 format. That means that + passing a format like QRhiTexture::RGBA32F is important, because backends + will typically opt for QRhiTexture::RGBA8 by default, which would then + break later on due to attempting to set up RGBA8->RGBA32F multisample + resolve in the color attachment(s) of the QRhiTextureRenderTarget. + \sa QRhiResource::release() */ QRhiRenderBuffer *QRhi::newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return d->createRenderBuffer(type, pixelSize, sampleCount, flags); + return d->createRenderBuffer(type, pixelSize, sampleCount, flags, backingFormatHint); } /*! diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 5ef415e96c..e63a828bfc 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -908,11 +908,12 @@ public: protected: QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QSize &pixelSize_, - int sampleCount_, Flags flags_); + int sampleCount_, Flags flags_, QRhiTexture::Format backingFormatHint_); Type m_type; QSize m_pixelSize; int m_sampleCount; Flags m_flags; + QRhiTexture::Format m_backingFormatHint; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiRenderBuffer::Flags) @@ -1493,7 +1494,8 @@ public: QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount = 1, - QRhiRenderBuffer::Flags flags = QRhiRenderBuffer::Flags()); + QRhiRenderBuffer::Flags flags = QRhiRenderBuffer::Flags(), + QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat); QRhiTexture *newTexture(QRhiTexture::Format format, const QSize &pixelSize, diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 4a4c044a29..95f04fbd1b 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -80,7 +80,8 @@ public: virtual QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) = 0; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) = 0; virtual QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index c3c40b4cc4..8336d43ff6 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -528,9 +528,10 @@ bool QRhiD3D11::isDeviceLost() const } QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return new QD3D11RenderBuffer(this, type, pixelSize, sampleCount, flags); + return new QD3D11RenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint); } QRhiTexture *QRhiD3D11::createTexture(QRhiTexture::Format format, const QSize &pixelSize, @@ -2613,8 +2614,9 @@ ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView() } QD3D11RenderBuffer::QD3D11RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) - : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) + : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags, backingFormatHint) { } @@ -2668,7 +2670,8 @@ bool QD3D11RenderBuffer::build() desc.Usage = D3D11_USAGE_DEFAULT; if (m_type == Color) { - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + dxgiFormat = m_backingFormatHint == QRhiTexture::UnknownFormat ? DXGI_FORMAT_R8G8B8A8_UNORM + : toD3DTextureFormat(m_backingFormatHint, {}); desc.Format = dxgiFormat; desc.BindFlags = D3D11_BIND_RENDER_TARGET; HRESULT hr = rhiD->dev->CreateTexture2D(&desc, nullptr, &tex); @@ -2721,7 +2724,10 @@ bool QD3D11RenderBuffer::build() QRhiTexture::Format QD3D11RenderBuffer::backingFormat() const { - return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) + return m_backingFormatHint; + else + return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; } QD3D11Texture::QD3D11Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h index 33412b8011..2cb59b32b5 100644 --- a/src/gui/rhi/qrhid3d11_p_p.h +++ b/src/gui/rhi/qrhid3d11_p_p.h @@ -79,7 +79,8 @@ struct QD3D11Buffer : public QRhiBuffer struct QD3D11RenderBuffer : public QRhiRenderBuffer { QD3D11RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags); + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint); ~QD3D11RenderBuffer(); void release() override; bool build() override; @@ -567,7 +568,8 @@ public: QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) override; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) override; QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 1e97d2ed0c..d8c64c7408 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -690,6 +690,87 @@ static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRh } } +static inline void toGlTextureFormat(QRhiTexture::Format format, const QRhiGles2::Caps &caps, + GLenum *glintformat, GLenum *glsizedintformat, + GLenum *glformat, GLenum *gltype) +{ + switch (format) { + case QRhiTexture::RGBA8: + *glintformat = GL_RGBA; + *glsizedintformat = caps.rgba8Format ? GL_RGBA8 : GL_RGBA; + *glformat = GL_RGBA; + *gltype = GL_UNSIGNED_BYTE; + break; + case QRhiTexture::BGRA8: + *glintformat = caps.bgraInternalFormat ? GL_BGRA : GL_RGBA; + *glsizedintformat = caps.rgba8Format ? GL_RGBA8 : GL_RGBA; + *glformat = GL_BGRA; + *gltype = GL_UNSIGNED_BYTE; + break; + case QRhiTexture::R16: + *glintformat = GL_R16; + *glsizedintformat = *glintformat; + *glformat = GL_RED; + *gltype = GL_UNSIGNED_SHORT; + break; + case QRhiTexture::R8: + *glintformat = GL_R8; + *glsizedintformat = *glintformat; + *glformat = GL_RED; + *gltype = GL_UNSIGNED_BYTE; + break; + case QRhiTexture::RED_OR_ALPHA8: + *glintformat = caps.coreProfile ? GL_R8 : GL_ALPHA; + *glsizedintformat = *glintformat; + *glformat = caps.coreProfile ? GL_RED : GL_ALPHA; + *gltype = GL_UNSIGNED_BYTE; + break; + case QRhiTexture::RGBA16F: + *glintformat = GL_RGBA16F; + *glsizedintformat = *glintformat; + *glformat = GL_RGBA; + *gltype = GL_HALF_FLOAT; + break; + case QRhiTexture::RGBA32F: + *glintformat = GL_RGBA32F; + *glsizedintformat = *glintformat; + *glformat = GL_RGBA; + *gltype = GL_FLOAT; + break; + case QRhiTexture::R16F: + *glintformat = GL_R16F; + *glsizedintformat = *glintformat; + *glformat = GL_RED; + *gltype = GL_HALF_FLOAT; + break; + case QRhiTexture::R32F: + *glintformat = GL_R32F; + *glsizedintformat = *glintformat; + *glformat = GL_RED; + *gltype = GL_FLOAT; + break; + case QRhiTexture::D16: + *glintformat = GL_DEPTH_COMPONENT16; + *glsizedintformat = *glintformat; + *glformat = GL_DEPTH_COMPONENT; + *gltype = GL_UNSIGNED_SHORT; + break; + case QRhiTexture::D32F: + *glintformat = GL_DEPTH_COMPONENT32F; + *glsizedintformat = *glintformat; + *glformat = GL_DEPTH_COMPONENT; + *gltype = GL_FLOAT; + break; + default: + Q_UNREACHABLE(); + *glintformat = GL_RGBA; + *glsizedintformat = caps.rgba8Format ? GL_RGBA8 : GL_RGBA; + *glformat = GL_RGBA; + *gltype = GL_UNSIGNED_BYTE; + break; + } +} + bool QRhiGles2::isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const { if (isCompressedFormat(format)) @@ -833,9 +914,10 @@ bool QRhiGles2::isDeviceLost() const } QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return new QGles2RenderBuffer(this, type, pixelSize, sampleCount, flags); + return new QGles2RenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint); } QRhiTexture *QRhiGles2::createTexture(QRhiTexture::Format format, const QSize &pixelSize, @@ -3435,8 +3517,9 @@ QRhiBuffer::NativeBuffer QGles2Buffer::nativeBuffer() } QGles2RenderBuffer::QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) - : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) + : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags, backingFormatHint) { } @@ -3522,13 +3605,26 @@ bool QGles2RenderBuffer::build() QRHI_PROF_F(newRenderBuffer(this, false, false, samples)); break; case QRhiRenderBuffer::Color: - if (rhiD->caps.msaaRenderBuffer && samples > 1) - rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, + { + GLenum internalFormat = GL_RGBA4; // ES 2.0 + if (rhiD->caps.rgba8Format) { + internalFormat = GL_RGBA8; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) { + GLenum glintformat, glformat, gltype; + // only care about the sized internal format, the rest is not used here + toGlTextureFormat(m_backingFormatHint, rhiD->caps, + &glintformat, &internalFormat, &glformat, &gltype); + } + } + if (rhiD->caps.msaaRenderBuffer && samples > 1) { + rhiD->f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalFormat, size.width(), size.height()); - else - rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA4, + } else { + rhiD->f->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, size.width(), size.height()); + } QRHI_PROF_F(newRenderBuffer(this, false, false, samples)); + } break; default: Q_UNREACHABLE(); @@ -3541,7 +3637,10 @@ bool QGles2RenderBuffer::build() QRhiTexture::Format QGles2RenderBuffer::backingFormat() const { - return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) + return m_backingFormatHint; + else + return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; } QGles2Texture::QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, @@ -3608,76 +3707,8 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize) glsizedintformat = glintformat; glformat = GL_RGBA; } else { - switch (m_format) { - case QRhiTexture::RGBA8: - glintformat = GL_RGBA; - glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; - glformat = GL_RGBA; - break; - case QRhiTexture::BGRA8: - glintformat = rhiD->caps.bgraInternalFormat ? GL_BGRA : GL_RGBA; - glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; - glformat = GL_BGRA; - break; - case QRhiTexture::R16: - glintformat = GL_R16; - glsizedintformat = glintformat; - glformat = GL_RED; - gltype = GL_UNSIGNED_SHORT; - break; - case QRhiTexture::R8: - glintformat = GL_R8; - glsizedintformat = glintformat; - glformat = GL_RED; - break; - case QRhiTexture::RED_OR_ALPHA8: - glintformat = rhiD->caps.coreProfile ? GL_R8 : GL_ALPHA; - glsizedintformat = glintformat; - glformat = rhiD->caps.coreProfile ? GL_RED : GL_ALPHA; - break; - case QRhiTexture::RGBA16F: - glintformat = GL_RGBA16F; - glsizedintformat = glintformat; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - break; - case QRhiTexture::RGBA32F: - glintformat = GL_RGBA32F; - glsizedintformat = glintformat; - glformat = GL_RGBA; - gltype = GL_FLOAT; - break; - case QRhiTexture::R16F: - glintformat = GL_R16F; - glsizedintformat = glintformat; - glformat = GL_RED; - gltype = GL_HALF_FLOAT; - break; - case QRhiTexture::R32F: - glintformat = GL_R32F; - glsizedintformat = glintformat; - glformat = GL_RED; - gltype = GL_FLOAT; - break; - case QRhiTexture::D16: - glintformat = GL_DEPTH_COMPONENT16; - glsizedintformat = glintformat; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_SHORT; - break; - case QRhiTexture::D32F: - glintformat = GL_DEPTH_COMPONENT32F; - glsizedintformat = glintformat; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_FLOAT; - break; - default: - Q_UNREACHABLE(); - glintformat = GL_RGBA; - glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; - glformat = GL_RGBA; - break; - } + toGlTextureFormat(m_format, rhiD->caps, + &glintformat, &glsizedintformat, &glformat, &gltype); } samplerState = QGles2SamplerData(); diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index ac7b384cb6..e326b661d9 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -89,7 +89,8 @@ struct QGles2Buffer : public QRhiBuffer struct QGles2RenderBuffer : public QRhiRenderBuffer { QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags); + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint); ~QGles2RenderBuffer(); void release() override; bool build() override; @@ -694,7 +695,8 @@ public: QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) override; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) override; QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index f021e78097..c5afdf63eb 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -621,9 +621,10 @@ bool QRhiMetal::isDeviceLost() const } QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return new QMetalRenderBuffer(this, type, pixelSize, sampleCount, flags); + return new QMetalRenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint); } QRhiTexture *QRhiMetal::createTexture(QRhiTexture::Format format, const QSize &pixelSize, @@ -2232,9 +2233,142 @@ QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer() return { { &d->buf[0] }, 1 }; } +static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags) +{ + const bool srgb = flags.testFlag(QRhiTexture::sRGB); + switch (format) { + case QRhiTexture::RGBA8: + return srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; + case QRhiTexture::BGRA8: + return srgb ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; + case QRhiTexture::R8: +#ifdef Q_OS_MACOS + return MTLPixelFormatR8Unorm; +#else + return srgb ? MTLPixelFormatR8Unorm_sRGB : MTLPixelFormatR8Unorm; +#endif + case QRhiTexture::R16: + return MTLPixelFormatR16Unorm; + case QRhiTexture::RED_OR_ALPHA8: + return MTLPixelFormatR8Unorm; + + case QRhiTexture::RGBA16F: + return MTLPixelFormatRGBA16Float; + case QRhiTexture::RGBA32F: + return MTLPixelFormatRGBA32Float; + case QRhiTexture::R16F: + return MTLPixelFormatR16Float; + case QRhiTexture::R32F: + return MTLPixelFormatR32Float; + + case QRhiTexture::D16: +#ifdef Q_OS_MACOS + return MTLPixelFormatDepth16Unorm; +#else + return MTLPixelFormatDepth32Float; +#endif + case QRhiTexture::D32F: + return MTLPixelFormatDepth32Float; + +#ifdef Q_OS_MACOS + case QRhiTexture::BC1: + return srgb ? MTLPixelFormatBC1_RGBA_sRGB : MTLPixelFormatBC1_RGBA; + case QRhiTexture::BC2: + return srgb ? MTLPixelFormatBC2_RGBA_sRGB : MTLPixelFormatBC2_RGBA; + case QRhiTexture::BC3: + return srgb ? MTLPixelFormatBC3_RGBA_sRGB : MTLPixelFormatBC3_RGBA; + case QRhiTexture::BC4: + return MTLPixelFormatBC4_RUnorm; + case QRhiTexture::BC5: + qWarning("QRhiMetal does not support BC5"); + return MTLPixelFormatRGBA8Unorm; + case QRhiTexture::BC6H: + return MTLPixelFormatBC6H_RGBUfloat; + case QRhiTexture::BC7: + return srgb ? MTLPixelFormatBC7_RGBAUnorm_sRGB : MTLPixelFormatBC7_RGBAUnorm; +#else + case QRhiTexture::BC1: + case QRhiTexture::BC2: + case QRhiTexture::BC3: + case QRhiTexture::BC4: + case QRhiTexture::BC5: + case QRhiTexture::BC6H: + case QRhiTexture::BC7: + qWarning("QRhiMetal: BCx compression not supported on this platform"); + return MTLPixelFormatRGBA8Unorm; +#endif + +#ifndef Q_OS_MACOS + case QRhiTexture::ETC2_RGB8: + return srgb ? MTLPixelFormatETC2_RGB8_sRGB : MTLPixelFormatETC2_RGB8; + case QRhiTexture::ETC2_RGB8A1: + return srgb ? MTLPixelFormatETC2_RGB8A1_sRGB : MTLPixelFormatETC2_RGB8A1; + case QRhiTexture::ETC2_RGBA8: + return srgb ? MTLPixelFormatEAC_RGBA8_sRGB : MTLPixelFormatEAC_RGBA8; + + case QRhiTexture::ASTC_4x4: + return srgb ? MTLPixelFormatASTC_4x4_sRGB : MTLPixelFormatASTC_4x4_LDR; + case QRhiTexture::ASTC_5x4: + return srgb ? MTLPixelFormatASTC_5x4_sRGB : MTLPixelFormatASTC_5x4_LDR; + case QRhiTexture::ASTC_5x5: + return srgb ? MTLPixelFormatASTC_5x5_sRGB : MTLPixelFormatASTC_5x5_LDR; + case QRhiTexture::ASTC_6x5: + return srgb ? MTLPixelFormatASTC_6x5_sRGB : MTLPixelFormatASTC_6x5_LDR; + case QRhiTexture::ASTC_6x6: + return srgb ? MTLPixelFormatASTC_6x6_sRGB : MTLPixelFormatASTC_6x6_LDR; + case QRhiTexture::ASTC_8x5: + return srgb ? MTLPixelFormatASTC_8x5_sRGB : MTLPixelFormatASTC_8x5_LDR; + case QRhiTexture::ASTC_8x6: + return srgb ? MTLPixelFormatASTC_8x6_sRGB : MTLPixelFormatASTC_8x6_LDR; + case QRhiTexture::ASTC_8x8: + return srgb ? MTLPixelFormatASTC_8x8_sRGB : MTLPixelFormatASTC_8x8_LDR; + case QRhiTexture::ASTC_10x5: + return srgb ? MTLPixelFormatASTC_10x5_sRGB : MTLPixelFormatASTC_10x5_LDR; + case QRhiTexture::ASTC_10x6: + return srgb ? MTLPixelFormatASTC_10x6_sRGB : MTLPixelFormatASTC_10x6_LDR; + case QRhiTexture::ASTC_10x8: + return srgb ? MTLPixelFormatASTC_10x8_sRGB : MTLPixelFormatASTC_10x8_LDR; + case QRhiTexture::ASTC_10x10: + return srgb ? MTLPixelFormatASTC_10x10_sRGB : MTLPixelFormatASTC_10x10_LDR; + case QRhiTexture::ASTC_12x10: + return srgb ? MTLPixelFormatASTC_12x10_sRGB : MTLPixelFormatASTC_12x10_LDR; + case QRhiTexture::ASTC_12x12: + return srgb ? MTLPixelFormatASTC_12x12_sRGB : MTLPixelFormatASTC_12x12_LDR; +#else + case QRhiTexture::ETC2_RGB8: + case QRhiTexture::ETC2_RGB8A1: + case QRhiTexture::ETC2_RGBA8: + qWarning("QRhiMetal: ETC2 compression not supported on this platform"); + return MTLPixelFormatRGBA8Unorm; + + case QRhiTexture::ASTC_4x4: + case QRhiTexture::ASTC_5x4: + case QRhiTexture::ASTC_5x5: + case QRhiTexture::ASTC_6x5: + case QRhiTexture::ASTC_6x6: + case QRhiTexture::ASTC_8x5: + case QRhiTexture::ASTC_8x6: + case QRhiTexture::ASTC_8x8: + case QRhiTexture::ASTC_10x5: + case QRhiTexture::ASTC_10x6: + case QRhiTexture::ASTC_10x8: + case QRhiTexture::ASTC_10x10: + case QRhiTexture::ASTC_12x10: + case QRhiTexture::ASTC_12x12: + qWarning("QRhiMetal: ASTC compression not supported on this platform"); + return MTLPixelFormatRGBA8Unorm; +#endif + + default: + Q_UNREACHABLE(); + return MTLPixelFormatRGBA8Unorm; + } +} + QMetalRenderBuffer::QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) - : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags), + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) + : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags, backingFormatHint), d(new QMetalRenderBufferData) { } @@ -2300,7 +2434,10 @@ bool QMetalRenderBuffer::build() break; case Color: desc.storageMode = MTLStorageModePrivate; - d->format = MTLPixelFormatRGBA8Unorm; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) + d->format = toMetalTextureFormat(m_backingFormatHint, {}); + else + d->format = MTLPixelFormatRGBA8Unorm; desc.pixelFormat = d->format; break; default: @@ -2325,7 +2462,10 @@ bool QMetalRenderBuffer::build() QRhiTexture::Format QMetalRenderBuffer::backingFormat() const { - return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) + return m_backingFormatHint; + else + return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; } QMetalTexture::QMetalTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, @@ -2375,138 +2515,6 @@ void QMetalTexture::release() rhiD->unregisterResource(this); } -static inline MTLPixelFormat toMetalTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags) -{ - const bool srgb = flags.testFlag(QRhiTexture::sRGB); - switch (format) { - case QRhiTexture::RGBA8: - return srgb ? MTLPixelFormatRGBA8Unorm_sRGB : MTLPixelFormatRGBA8Unorm; - case QRhiTexture::BGRA8: - return srgb ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; - case QRhiTexture::R8: -#ifdef Q_OS_MACOS - return MTLPixelFormatR8Unorm; -#else - return srgb ? MTLPixelFormatR8Unorm_sRGB : MTLPixelFormatR8Unorm; -#endif - case QRhiTexture::R16: - return MTLPixelFormatR16Unorm; - case QRhiTexture::RED_OR_ALPHA8: - return MTLPixelFormatR8Unorm; - - case QRhiTexture::RGBA16F: - return MTLPixelFormatRGBA16Float; - case QRhiTexture::RGBA32F: - return MTLPixelFormatRGBA32Float; - case QRhiTexture::R16F: - return MTLPixelFormatR16Float; - case QRhiTexture::R32F: - return MTLPixelFormatR32Float; - - case QRhiTexture::D16: -#ifdef Q_OS_MACOS - return MTLPixelFormatDepth16Unorm; -#else - return MTLPixelFormatDepth32Float; -#endif - case QRhiTexture::D32F: - return MTLPixelFormatDepth32Float; - -#ifdef Q_OS_MACOS - case QRhiTexture::BC1: - return srgb ? MTLPixelFormatBC1_RGBA_sRGB : MTLPixelFormatBC1_RGBA; - case QRhiTexture::BC2: - return srgb ? MTLPixelFormatBC2_RGBA_sRGB : MTLPixelFormatBC2_RGBA; - case QRhiTexture::BC3: - return srgb ? MTLPixelFormatBC3_RGBA_sRGB : MTLPixelFormatBC3_RGBA; - case QRhiTexture::BC4: - return MTLPixelFormatBC4_RUnorm; - case QRhiTexture::BC5: - qWarning("QRhiMetal does not support BC5"); - return MTLPixelFormatRGBA8Unorm; - case QRhiTexture::BC6H: - return MTLPixelFormatBC6H_RGBUfloat; - case QRhiTexture::BC7: - return srgb ? MTLPixelFormatBC7_RGBAUnorm_sRGB : MTLPixelFormatBC7_RGBAUnorm; -#else - case QRhiTexture::BC1: - case QRhiTexture::BC2: - case QRhiTexture::BC3: - case QRhiTexture::BC4: - case QRhiTexture::BC5: - case QRhiTexture::BC6H: - case QRhiTexture::BC7: - qWarning("QRhiMetal: BCx compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; -#endif - -#ifndef Q_OS_MACOS - case QRhiTexture::ETC2_RGB8: - return srgb ? MTLPixelFormatETC2_RGB8_sRGB : MTLPixelFormatETC2_RGB8; - case QRhiTexture::ETC2_RGB8A1: - return srgb ? MTLPixelFormatETC2_RGB8A1_sRGB : MTLPixelFormatETC2_RGB8A1; - case QRhiTexture::ETC2_RGBA8: - return srgb ? MTLPixelFormatEAC_RGBA8_sRGB : MTLPixelFormatEAC_RGBA8; - - case QRhiTexture::ASTC_4x4: - return srgb ? MTLPixelFormatASTC_4x4_sRGB : MTLPixelFormatASTC_4x4_LDR; - case QRhiTexture::ASTC_5x4: - return srgb ? MTLPixelFormatASTC_5x4_sRGB : MTLPixelFormatASTC_5x4_LDR; - case QRhiTexture::ASTC_5x5: - return srgb ? MTLPixelFormatASTC_5x5_sRGB : MTLPixelFormatASTC_5x5_LDR; - case QRhiTexture::ASTC_6x5: - return srgb ? MTLPixelFormatASTC_6x5_sRGB : MTLPixelFormatASTC_6x5_LDR; - case QRhiTexture::ASTC_6x6: - return srgb ? MTLPixelFormatASTC_6x6_sRGB : MTLPixelFormatASTC_6x6_LDR; - case QRhiTexture::ASTC_8x5: - return srgb ? MTLPixelFormatASTC_8x5_sRGB : MTLPixelFormatASTC_8x5_LDR; - case QRhiTexture::ASTC_8x6: - return srgb ? MTLPixelFormatASTC_8x6_sRGB : MTLPixelFormatASTC_8x6_LDR; - case QRhiTexture::ASTC_8x8: - return srgb ? MTLPixelFormatASTC_8x8_sRGB : MTLPixelFormatASTC_8x8_LDR; - case QRhiTexture::ASTC_10x5: - return srgb ? MTLPixelFormatASTC_10x5_sRGB : MTLPixelFormatASTC_10x5_LDR; - case QRhiTexture::ASTC_10x6: - return srgb ? MTLPixelFormatASTC_10x6_sRGB : MTLPixelFormatASTC_10x6_LDR; - case QRhiTexture::ASTC_10x8: - return srgb ? MTLPixelFormatASTC_10x8_sRGB : MTLPixelFormatASTC_10x8_LDR; - case QRhiTexture::ASTC_10x10: - return srgb ? MTLPixelFormatASTC_10x10_sRGB : MTLPixelFormatASTC_10x10_LDR; - case QRhiTexture::ASTC_12x10: - return srgb ? MTLPixelFormatASTC_12x10_sRGB : MTLPixelFormatASTC_12x10_LDR; - case QRhiTexture::ASTC_12x12: - return srgb ? MTLPixelFormatASTC_12x12_sRGB : MTLPixelFormatASTC_12x12_LDR; -#else - case QRhiTexture::ETC2_RGB8: - case QRhiTexture::ETC2_RGB8A1: - case QRhiTexture::ETC2_RGBA8: - qWarning("QRhiMetal: ETC2 compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; - - case QRhiTexture::ASTC_4x4: - case QRhiTexture::ASTC_5x4: - case QRhiTexture::ASTC_5x5: - case QRhiTexture::ASTC_6x5: - case QRhiTexture::ASTC_6x6: - case QRhiTexture::ASTC_8x5: - case QRhiTexture::ASTC_8x6: - case QRhiTexture::ASTC_8x8: - case QRhiTexture::ASTC_10x5: - case QRhiTexture::ASTC_10x6: - case QRhiTexture::ASTC_10x8: - case QRhiTexture::ASTC_10x10: - case QRhiTexture::ASTC_12x10: - case QRhiTexture::ASTC_12x12: - qWarning("QRhiMetal: ASTC compression not supported on this platform"); - return MTLPixelFormatRGBA8Unorm; -#endif - - default: - Q_UNREACHABLE(); - return MTLPixelFormatRGBA8Unorm; - } -} - bool QMetalTexture::prepareBuild(QSize *adjustedSize) { if (d->tex) diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index cb4b777d88..30f5e8b74e 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -79,7 +79,8 @@ struct QMetalRenderBufferData; struct QMetalRenderBuffer : public QRhiRenderBuffer { QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags); + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint); ~QMetalRenderBuffer(); void release() override; bool build() override; @@ -349,7 +350,8 @@ public: QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) override; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) override; QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 7b18c9156b..b1ce9b7599 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -182,9 +182,10 @@ bool QRhiNull::isDeviceLost() const } QRhiRenderBuffer *QRhiNull::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return new QNullRenderBuffer(this, type, pixelSize, sampleCount, flags); + return new QNullRenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint); } QRhiTexture *QRhiNull::createTexture(QRhiTexture::Format format, const QSize &pixelSize, @@ -564,8 +565,9 @@ bool QNullBuffer::build() } QNullRenderBuffer::QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) - : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) + : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags, backingFormatHint) { } diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h index 0b3d40f1aa..347da4d71c 100644 --- a/src/gui/rhi/qrhinull_p_p.h +++ b/src/gui/rhi/qrhinull_p_p.h @@ -66,7 +66,8 @@ struct QNullBuffer : public QRhiBuffer struct QNullRenderBuffer : public QRhiRenderBuffer { QNullRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags); + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint); ~QNullRenderBuffer(); void release() override; bool build() override; @@ -207,7 +208,8 @@ public: QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) override; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) override; QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 49e634e248..16de7e0aea 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4084,9 +4084,10 @@ bool QRhiVulkan::isDeviceLost() const } QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, - int sampleCount, QRhiRenderBuffer::Flags flags) + int sampleCount, QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) { - return new QVkRenderBuffer(this, type, pixelSize, sampleCount, flags); + return new QVkRenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint); } QRhiTexture *QRhiVulkan::createTexture(QRhiTexture::Format format, const QSize &pixelSize, @@ -5241,8 +5242,9 @@ QRhiBuffer::NativeBuffer QVkBuffer::nativeBuffer() } QVkRenderBuffer::QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, Flags flags) - : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags) + int sampleCount, Flags flags, + QRhiTexture::Format backingFormatHint) + : QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags, backingFormatHint) { } @@ -5300,7 +5302,7 @@ bool QVkRenderBuffer::build() case QRhiRenderBuffer::Color: { if (!backingTexture) { - backingTexture = QRHI_RES(QVkTexture, rhiD->createTexture(QRhiTexture::RGBA8, + backingTexture = QRHI_RES(QVkTexture, rhiD->createTexture(backingFormat(), m_pixelSize, m_sampleCount, QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource)); @@ -5344,7 +5346,10 @@ bool QVkRenderBuffer::build() QRhiTexture::Format QVkRenderBuffer::backingFormat() const { - return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; + if (m_backingFormatHint != QRhiTexture::UnknownFormat) + return m_backingFormatHint; + else + return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat; } QVkTexture::QVkTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index d90b1d1364..1b2e4d0ebb 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -98,7 +98,8 @@ struct QVkTexture; struct QVkRenderBuffer : public QRhiRenderBuffer { QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, - int sampleCount, Flags flags); + int sampleCount, Flags flags, + QRhiTexture::Format backingFormatHint); ~QVkRenderBuffer(); void release() override; bool build() override; @@ -658,7 +659,8 @@ public: QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, - QRhiRenderBuffer::Flags flags) override; + QRhiRenderBuffer::Flags flags, + QRhiTexture::Format backingFormatHint) override; QRhiTexture *createTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount, |