diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2020-05-15 09:20:08 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2020-05-22 10:32:11 +0200 |
commit | 880f709fd079817eac3e798280b833ba13dd2515 (patch) | |
tree | 355f87ab10e99da92d2a04ef24fca8158ea58f26 /src | |
parent | 3ec0df4b5f9bf82918e0b783f547d2bc560f5ccf (diff) |
RHI: facilitate compressed atlas textures in gles2 backend
Since glCompressedTexImage2D() does not allow zero data, it could not
be executed during texture build. Instead it would be done during the
first subresource upload. This made atlasing clumsy, since one had to
introduce a fake upload of the full texture size before the subtexture
uploads. This commits lets the gles2 backend deal with that instead.
Introduces the UsedAsCompressedAtlas QRhiTexture::Flag for opting in
to this behavior.
Task-number: QTBUG-78582
Change-Id: Ib6e4ea637c62cc8a51bd9a4a06e59882f335f2a7
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 24 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 1 |
4 files changed, 29 insertions, 5 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index e92479bb4d..64d1d5a017 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -1496,9 +1496,6 @@ QRhiTextureRenderTargetDescription::QRhiTextureRenderTargetDescription(const QRh the size of the source image() must match the subresource. When providing raw data instead, sufficient number of bytes must be provided in data(). - \note With compressed textures the first upload must always match the - subresource size due to graphics API limitations with some backends. - sourceTopLeft() is supported only for QImage-based uploads, and specifies the top-left corner of the source rectangle. @@ -2197,6 +2194,9 @@ QRhiResource::Type QRhiRenderBuffer::resourceType() const \value UsedWithLoadStore The texture is going to be used with image load/store operations, for example, in a compute shader. + + \value UsedAsCompressedAtlas The texture has a compressed format and the + dimensions of subresource uploads may not match the texture size. */ /*! diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 71064cfc6a..12a294e8c2 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -727,7 +727,8 @@ public: sRGB = 1 << 4, UsedAsTransferSource = 1 << 5, UsedWithGenerateMips = 1 << 6, - UsedWithLoadStore = 1 << 7 + UsedWithLoadStore = 1 << 7, + UsedAsCompressedAtlas = 1 << 8 }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 373b66df89..d39892ac00 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1505,9 +1505,29 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb cmd.args.subImage.data = cbD->retainImage(img); cbD->commands.append(cmd); } else if (!rawData.isEmpty() && isCompressed) { + if (!texD->compressedAtlasBuilt && (texD->flags() & QRhiTexture::UsedAsCompressedAtlas)) { + // Build on first upload since glCompressedTexImage2D cannot take nullptr data + quint32 byteSize = 0; + compressedFormatInfo(texD->m_format, texD->m_pixelSize, nullptr, &byteSize, nullptr); + QByteArray zeroBuf(byteSize, 0); + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::CompressedImage; + cmd.args.compressedImage.target = texD->target; + cmd.args.compressedImage.texture = texD->texture; + cmd.args.compressedImage.faceTarget = faceTargetBase + uint(layer); + cmd.args.compressedImage.level = level; + cmd.args.compressedImage.glintformat = texD->glintformat; + cmd.args.compressedImage.w = texD->m_pixelSize.width(); + cmd.args.compressedImage.h = texD->m_pixelSize.height(); + cmd.args.compressedImage.size = byteSize; + cmd.args.compressedImage.data = cbD->retainData(zeroBuf); + cbD->commands.append(cmd); + texD->compressedAtlasBuilt = true; + } + const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize) : subresDesc.sourceSize(); - if (texD->specified) { + if (texD->specified || texD->compressedAtlasBuilt) { QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::CompressedSubImage; cmd.args.compressedSubImage.target = texD->target; @@ -3666,6 +3686,7 @@ void QGles2Texture::release() texture = 0; specified = false; + compressedAtlasBuilt = false; QRHI_RES_RHI(QRhiGles2); if (owns) @@ -3785,6 +3806,7 @@ bool QGles2Texture::buildFrom(QRhiTexture::NativeTexture src) texture = textureId; specified = true; + compressedAtlasBuilt = true; QRHI_RES_RHI(QRhiGles2); QRHI_PROF; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index e326b661d9..4f64c6d0a3 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -148,6 +148,7 @@ struct QGles2Texture : public QRhiTexture GLenum gltype; QGles2SamplerData samplerState; bool specified = false; + bool compressedAtlasBuilt = false; int mipLevelCount = 0; enum Access { |