summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl/qopengltexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl/qopengltexture.cpp')
-rw-r--r--src/gui/opengl/qopengltexture.cpp470
1 files changed, 440 insertions, 30 deletions
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index f6083b8cf9..8ba139d003 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -294,16 +294,166 @@ int QOpenGLTexturePrivate::evaluateMipLevels() const
}
}
-void QOpenGLTexturePrivate::allocateStorage()
+static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat)
+{
+ switch (internalFormat) {
+ case QOpenGLTexture::NoFormat:
+ return false;
+
+ case QOpenGLTexture::R8_UNorm:
+ case QOpenGLTexture::RG8_UNorm:
+ case QOpenGLTexture::RGB8_UNorm:
+ case QOpenGLTexture::RGBA8_UNorm:
+ case QOpenGLTexture::R16_UNorm:
+ case QOpenGLTexture::RG16_UNorm:
+ case QOpenGLTexture::RGB16_UNorm:
+ case QOpenGLTexture::RGBA16_UNorm:
+ case QOpenGLTexture::R8_SNorm:
+ case QOpenGLTexture::RG8_SNorm:
+ case QOpenGLTexture::RGB8_SNorm:
+ case QOpenGLTexture::RGBA8_SNorm:
+ case QOpenGLTexture::R16_SNorm:
+ case QOpenGLTexture::RG16_SNorm:
+ case QOpenGLTexture::RGB16_SNorm:
+ case QOpenGLTexture::RGBA16_SNorm:
+ case QOpenGLTexture::R8U:
+ case QOpenGLTexture::RG8U:
+ case QOpenGLTexture::RGB8U:
+ case QOpenGLTexture::RGBA8U:
+ case QOpenGLTexture::R16U:
+ case QOpenGLTexture::RG16U:
+ case QOpenGLTexture::RGB16U:
+ case QOpenGLTexture::RGBA16U:
+ case QOpenGLTexture::R32U:
+ case QOpenGLTexture::RG32U:
+ case QOpenGLTexture::RGB32U:
+ case QOpenGLTexture::RGBA32U:
+ case QOpenGLTexture::R8I:
+ case QOpenGLTexture::RG8I:
+ case QOpenGLTexture::RGB8I:
+ case QOpenGLTexture::RGBA8I:
+ case QOpenGLTexture::R16I:
+ case QOpenGLTexture::RG16I:
+ case QOpenGLTexture::RGB16I:
+ case QOpenGLTexture::RGBA16I:
+ case QOpenGLTexture::R32I:
+ case QOpenGLTexture::RG32I:
+ case QOpenGLTexture::RGB32I:
+ case QOpenGLTexture::RGBA32I:
+ case QOpenGLTexture::R16F:
+ case QOpenGLTexture::RG16F:
+ case QOpenGLTexture::RGB16F:
+ case QOpenGLTexture::RGBA16F:
+ case QOpenGLTexture::R32F:
+ case QOpenGLTexture::RG32F:
+ case QOpenGLTexture::RGB32F:
+ case QOpenGLTexture::RGBA32F:
+ case QOpenGLTexture::RGB9E5:
+ case QOpenGLTexture::RG11B10F:
+ case QOpenGLTexture::RG3B2:
+ case QOpenGLTexture::R5G6B5:
+ case QOpenGLTexture::RGB5A1:
+ case QOpenGLTexture::RGBA4:
+ case QOpenGLTexture::RGB10A2:
+
+ case QOpenGLTexture::D16:
+ case QOpenGLTexture::D24:
+ case QOpenGLTexture::D32:
+ case QOpenGLTexture::D32F:
+
+ case QOpenGLTexture::D24S8:
+ case QOpenGLTexture::D32FS8X24:
+
+ case QOpenGLTexture::S8:
+
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::RGBA_DXT1:
+ case QOpenGLTexture::RGBA_DXT3:
+ case QOpenGLTexture::RGBA_DXT5:
+ case QOpenGLTexture::R_ATI1N_UNorm:
+ case QOpenGLTexture::R_ATI1N_SNorm:
+ case QOpenGLTexture::RG_ATI2N_UNorm:
+ case QOpenGLTexture::RG_ATI2N_SNorm:
+ case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_UNorm:
+ case QOpenGLTexture::SRGB8:
+ case QOpenGLTexture::SRGB8_Alpha8:
+ case QOpenGLTexture::SRGB_DXT1:
+ case QOpenGLTexture::SRGB_Alpha_DXT1:
+ case QOpenGLTexture::SRGB_Alpha_DXT3:
+ case QOpenGLTexture::SRGB_Alpha_DXT5:
+ case QOpenGLTexture::SRGB_BP_UNorm:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
+ return true;
+
+ case QOpenGLTexture::DepthFormat:
+ case QOpenGLTexture::AlphaFormat:
+
+ case QOpenGLTexture::RGBFormat:
+ case QOpenGLTexture::RGBAFormat:
+
+ case QOpenGLTexture::LuminanceFormat:
+
+ case QOpenGLTexture::LuminanceAlphaFormat:
+ return false;
+ }
+
+ Q_UNREACHABLE();
+ return false;
+}
+
+static bool isTextureTargetMultisample(QOpenGLTexture::Target target)
+{
+ switch (target) {
+ case QOpenGLTexture::Target1D:
+ case QOpenGLTexture::Target1DArray:
+ case QOpenGLTexture::Target2D:
+ case QOpenGLTexture::Target2DArray:
+ case QOpenGLTexture::Target3D:
+ case QOpenGLTexture::TargetCubeMap:
+ case QOpenGLTexture::TargetCubeMapArray:
+ return false;
+
+ case QOpenGLTexture::Target2DMultisample:
+ case QOpenGLTexture::Target2DMultisampleArray:
+ return true;
+
+ case QOpenGLTexture::TargetRectangle:
+ case QOpenGLTexture::TargetBuffer:
+ return false;
+ }
+
+ Q_UNREACHABLE();
+ return false;
+}
+
+void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
{
// Resolve the actual number of mipmap levels we can use
mipLevels = evaluateMipLevels();
- // Use immutable storage whenever possible, falling back to mutable when not available
- if (features.testFlag(QOpenGLTexture::ImmutableStorage))
+ // Use immutable storage whenever possible, falling back to mutable
+ // Note that if multisample textures are not supported at all, we'll still fail into
+ // the mutable storage allocation
+ const bool useImmutableStorage = isSizedTextureFormat(format)
+ && (isTextureTargetMultisample(target)
+ ? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)
+ : features.testFlag(QOpenGLTexture::ImmutableStorage));
+
+ if (useImmutableStorage)
allocateImmutableStorage();
else
- allocateMutableStorage();
+ allocateMutableStorage(pixelFormat, pixelType);
}
static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat)
@@ -313,59 +463,167 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen
return QOpenGLTexture::NoSourceFormat;
case QOpenGLTexture::R8_UNorm:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG8_UNorm:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB8_UNorm:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA8_UNorm:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::R16_UNorm:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG16_UNorm:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB16_UNorm:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA16_UNorm:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::R8_SNorm:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG8_SNorm:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB8_SNorm:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA8_SNorm:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::R16_SNorm:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG16_SNorm:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB16_SNorm:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA16_SNorm:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::R8U:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG8U:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB8U:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA8U:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R16U:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG16U:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB16U:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA16U:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R32U:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG32U:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB32U:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA32U:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R8I:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG8I:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB8I:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA8I:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R16I:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG16I:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB16I:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA16I:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R32I:
+ return QOpenGLTexture::Red_Integer;
+
case QOpenGLTexture::RG32I:
+ return QOpenGLTexture::RG_Integer;
+
case QOpenGLTexture::RGB32I:
+ return QOpenGLTexture::RGB_Integer;
+
case QOpenGLTexture::RGBA32I:
+ return QOpenGLTexture::RGBA_Integer;
+
case QOpenGLTexture::R16F:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG16F:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB16F:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA16F:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::R32F:
+ return QOpenGLTexture::Red;
+
case QOpenGLTexture::RG32F:
+ return QOpenGLTexture::RG;
+
case QOpenGLTexture::RGB32F:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBA32F:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::RGB9E5:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RG11B10F:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RG3B2:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::R5G6B5:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGB5A1:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::RGBA4:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::RGB10A2:
return QOpenGLTexture::RGBA;
@@ -402,6 +660,26 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen
case QOpenGLTexture::SRGB_BP_UNorm:
return QOpenGLTexture::RGBA;
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ return QOpenGLTexture::Red;
+
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ return QOpenGLTexture::RG;
+
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ return QOpenGLTexture::RGB;
+
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
+ return QOpenGLTexture::RGBA;
+
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
+ return QOpenGLTexture::RGBA;
+
case QOpenGLTexture::DepthFormat:
return QOpenGLTexture::Depth;
@@ -437,6 +715,8 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::RG16_UNorm:
case QOpenGLTexture::RGB16_UNorm:
case QOpenGLTexture::RGBA16_UNorm:
+ return QOpenGLTexture::UInt8;
+
case QOpenGLTexture::R8_SNorm:
case QOpenGLTexture::RG8_SNorm:
case QOpenGLTexture::RGB8_SNorm:
@@ -445,6 +725,8 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::RG16_SNorm:
case QOpenGLTexture::RGB16_SNorm:
case QOpenGLTexture::RGBA16_SNorm:
+ return QOpenGLTexture::Int8;
+
case QOpenGLTexture::R8U:
case QOpenGLTexture::RG8U:
case QOpenGLTexture::RGB8U:
@@ -457,6 +739,8 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::RG32U:
case QOpenGLTexture::RGB32U:
case QOpenGLTexture::RGBA32U:
+ return QOpenGLTexture::UInt8;
+
case QOpenGLTexture::R8I:
case QOpenGLTexture::RG8I:
case QOpenGLTexture::RGB8I:
@@ -469,28 +753,50 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::RG32I:
case QOpenGLTexture::RGB32I:
case QOpenGLTexture::RGBA32I:
+ return QOpenGLTexture::Int8;
+
case QOpenGLTexture::R16F:
case QOpenGLTexture::RG16F:
case QOpenGLTexture::RGB16F:
case QOpenGLTexture::RGBA16F:
+ return QOpenGLTexture::Float16;
+
case QOpenGLTexture::R32F:
case QOpenGLTexture::RG32F:
case QOpenGLTexture::RGB32F:
case QOpenGLTexture::RGBA32F:
+ return QOpenGLTexture::Float32;
+
case QOpenGLTexture::RGB9E5:
+ return QOpenGLTexture::UInt16_RGB5A1_Rev;
+
case QOpenGLTexture::RG11B10F:
+ return QOpenGLTexture::UInt32_RG11B10F;
+
case QOpenGLTexture::RG3B2:
+ return QOpenGLTexture::UInt8_RG3B2;
+
case QOpenGLTexture::R5G6B5:
+ return QOpenGLTexture::UInt16_R5G6B5;
+
case QOpenGLTexture::RGB5A1:
+ return QOpenGLTexture::UInt16_RGB5A1;
+
case QOpenGLTexture::RGBA4:
+ return QOpenGLTexture::UInt16_RGBA4;
+
case QOpenGLTexture::RGB10A2:
- return QOpenGLTexture::UInt8;
+ return QOpenGLTexture::UInt32_RGB10A2;
case QOpenGLTexture::D16:
+ return QOpenGLTexture::UInt16;
+
case QOpenGLTexture::D24:
case QOpenGLTexture::D32:
+ return QOpenGLTexture::UInt32;
+
case QOpenGLTexture::D32F:
- return QOpenGLTexture::UInt8;
+ return QOpenGLTexture::Float32;
case QOpenGLTexture::D24S8:
return QOpenGLTexture::UInt32_D24S8;
@@ -519,6 +825,16 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
case QOpenGLTexture::SRGB_Alpha_DXT3:
case QOpenGLTexture::SRGB_Alpha_DXT5:
case QOpenGLTexture::SRGB_BP_UNorm:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
return QOpenGLTexture::UInt8;
case QOpenGLTexture::DepthFormat:
@@ -534,11 +850,8 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe
return QOpenGLTexture::NoPixelType;
}
-void QOpenGLTexturePrivate::allocateMutableStorage()
+void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
{
- const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(format);
- const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(format);
-
switch (target) {
case QOpenGLTexture::TargetBuffer:
// Buffer textures get their storage from an external OpenGL buffer
@@ -747,7 +1060,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
break;
case QOpenGLTexture::Target2DMultisample:
- if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
+ if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)) {
texFuncs->glTextureStorage2DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1],
fixedSamplePositions);
@@ -758,7 +1071,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
break;
case QOpenGLTexture::Target2DMultisampleArray:
- if (features.testFlag(QOpenGLTexture::TextureMultisample)
+ if (features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage)
&& features.testFlag(QOpenGLTexture::TextureArrays)) {
texFuncs->glTextureStorage3DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1], layers,
@@ -1525,6 +1838,16 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
\value RGB_BP_UNSIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
\value RGB_BP_SIGNED_FLOAT Equivalent to GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
\value RGB_BP_UNorm Equivalent to GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
+ \value R11_EAC_UNorm Equivalent to GL_COMPRESSED_R11_EAC
+ \value R11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_R11_EAC
+ \value RG11_EAC_UNorm Equivalent to GL_COMPRESSED_RG11_EAC
+ \value RG11_EAC_SNorm Equivalent to GL_COMPRESSED_SIGNED_RG11_EAC
+ \value RGB8_ETC2 Equivalent to GL_COMPRESSED_RGB8_ETC2
+ \value SRGB8_ETC2 Equivalent to GL_COMPRESSED_SRGB8_ETC2
+ \value RGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+ \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
+ \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC
+ \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
\value SRGB8 Equivalent to GL_SRGB8
\value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8
@@ -2050,6 +2373,16 @@ void QOpenGLTexture::setFormat(TextureFormat format)
d->formatClass = FormatClass_S3TC_DXT5_RGBA;
break;
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC:
case RG3B2:
case R5G6B5:
case RGB5A1:
@@ -2436,17 +2769,58 @@ bool QOpenGLTexture::isFixedSamplePositions() const
Once storage has been allocated for the texture then pixel data
can be uploaded via one of the setData() overloads.
+ \note If immutable texture storage is not available,
+ then a default pixel format and pixel type will be used to
+ create the mutable storage. You can use the other
+ allocateStorage() overload to specify exactly the pixel format
+ and the pixel type to use when allocating mutable storage;
+ this is particulary useful under certain OpenGL ES implementations
+ (notably, OpenGL ES 2), where the pixel format and the pixel type
+ used at allocation time must perfectly match the format
+ and the type passed to any subsequent setData() call.
+
\sa isStorageAllocated(), setData()
*/
void QOpenGLTexture::allocateStorage()
{
Q_D(QOpenGLTexture);
if (d->create()) {
- d->allocateStorage();
+ const QOpenGLTexture::PixelFormat pixelFormat = pixelFormatCompatibleWithInternalFormat(d->format);
+ const QOpenGLTexture::PixelType pixelType = pixelTypeCompatibleWithInternalFormat(d->format);
+ d->allocateStorage(pixelFormat, pixelType);
}
}
/*!
+ \since 5.5
+
+ Allocates server-side storage for this texture object taking
+ into account, the format, dimensions, mipmap levels, array
+ layers and cubemap faces.
+
+ Once storage has been allocated it is no longer possible to change
+ these properties.
+
+ If supported QOpenGLTexture makes use of immutable texture
+ storage. However, if immutable texture storage is not available,
+ then the specified \a pixelFormat and \a pixelType will be used
+ to allocate mutable storage; note that in certain OpenGL implementations
+ (notably, OpenGL ES 2) they must perfectly match the format
+ and the type passed to any subsequent setData() call.
+
+ Once storage has been allocated for the texture then pixel data
+ can be uploaded via one of the setData() overloads.
+
+ \sa isStorageAllocated(), setData()
+*/
+void QOpenGLTexture::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType)
+{
+ Q_D(QOpenGLTexture);
+ if (d->create())
+ d->allocateStorage(pixelFormat, pixelType);
+}
+
+/*!
Returns \c true if server-side storage for this texture as been
allocated.
@@ -2547,7 +2921,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
Q_ASSERT(d->textureId);
if (!isStorageAllocated()) {
qWarning("Cannot set data on a texture that does not have storage allocated.\n"
- "To do so call allocate() before this function");
+ "To do so call allocateStorage() before this function");
return;
}
d->setData(mipLevel, layer, cubeFace, sourceFormat, sourceType, data, options);
@@ -2605,7 +2979,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
Q_ASSERT(d->textureId);
if (!isStorageAllocated()) {
qWarning("Cannot set data on a texture that does not have storage allocated.\n"
- "To do so call allocate() before this function");
+ "To do so call allocateStorage() before this function");
return;
}
d->setData(mipLevel, layer, cubeFace, sourceFormat, sourceType, data, options);
@@ -2670,7 +3044,7 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
setSize(image.width(), image.height());
setMipLevels(genMipMaps == GenerateMipMaps ? maximumMipLevels() : 1);
- allocateStorage();
+ allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
// Upload pixel data and generate mipmaps
QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
@@ -2697,7 +3071,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cube
Q_ASSERT(d->textureId);
if (!isStorageAllocated()) {
qWarning("Cannot set data on a texture that does not have storage allocated.\n"
- "To do so call allocate() before this function");
+ "To do so call allocateStorage() before this function");
return;
}
d->setCompressedData(mipLevel, layer, cubeFace, dataSize, data, options);
@@ -2748,7 +3122,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cube
Q_ASSERT(d->textureId);
if (!isStorageAllocated()) {
qWarning("Cannot set data on a texture that does not have storage allocated.\n"
- "To do so call allocate() before this function");
+ "To do so call allocateStorage() before this function");
return;
}
d->setCompressedData(mipLevel, layer, cubeFace, dataSize, data, options);
@@ -2826,7 +3200,8 @@ bool QOpenGLTexture::hasFeature(Feature feature)
case ImmutableStorage:
supported = f.version() >= qMakePair(4, 2)
- || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"));
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"))
+ || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"));
break;
case TextureCubeMapArrays:
@@ -2873,9 +3248,6 @@ bool QOpenGLTexture::hasFeature(Feature feature)
case MaxFeatureFlag:
break;
-
- default:
- break;
}
}
@@ -2883,21 +3255,59 @@ bool QOpenGLTexture::hasFeature(Feature feature)
#endif
{
switch (feature) {
+ case ImmutableStorage:
+ supported = f.version() >= qMakePair(3, 0)
+ || ctx->hasExtension(QByteArrayLiteral("EXT_texture_storage"));
+ break;
+
+ case ImmutableMultisampleStorage:
+ supported = f.version() >= qMakePair(3, 1);
+ break;
+
+ case TextureRectangle:
+ break;
+
+ case TextureArrays:
+ supported = f.version() >= qMakePair(3, 0);
+ break;
+
case Texture3D:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
+ supported = f.version() >= qMakePair(3, 0)
+ || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
+ break;
+
+ case TextureMultisample:
+ supported = f.version() >= qMakePair(3, 1);
break;
+
+ case TextureBuffer:
+ break;
+
+ case TextureCubeMapArrays:
+ break;
+
+ case Swizzle:
+ supported = f.version() >= qMakePair(3, 0);
+ break;
+
+ case StencilTexturing:
+ break;
+
case AnisotropicFiltering:
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
break;
+
case NPOTTextures:
case NPOTTextureRepeat:
- supported = f.version() >= qMakePair(3,0);
- if (!supported) {
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
- if (!supported)
- supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
- }
- default:
+ supported = f.version() >= qMakePair(3,0)
+ || ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"))
+ || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ break;
+
+ case Texture1D:
+ break;
+
+ case MaxFeatureFlag:
break;
}
}