diff options
Diffstat (limited to 'src/gui/opengl/qopengltexture.cpp')
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 470 |
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; } } |