summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2020-05-15 09:20:08 +0200
committerEirik Aavitsland <eirik.aavitsland@qt.io>2020-05-22 10:32:11 +0200
commit880f709fd079817eac3e798280b833ba13dd2515 (patch)
tree355f87ab10e99da92d2a04ef24fca8158ea58f26 /src
parent3ec0df4b5f9bf82918e0b783f547d2bc560f5ccf (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.cpp6
-rw-r--r--src/gui/rhi/qrhi_p.h3
-rw-r--r--src/gui/rhi/qrhigles2.cpp24
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h1
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 {