Support uploading compressed 3D textures in gluTexture.
authorJarkko Pöyry <jpoyry@google.com>
Tue, 14 Apr 2015 01:56:11 +0000 (18:56 -0700)
committerJarkko Pöyry <jpoyry@google.com>
Tue, 14 Apr 2015 22:35:37 +0000 (15:35 -0700)
Change-Id: I0ef802ecb4b8066c540fdb8784e349062683e114

framework/opengl/gluTexture.cpp
framework/opengl/gluTexture.hpp

index 344a514..7ae0a3c 100644 (file)
@@ -610,6 +610,7 @@ void Texture2DArray::loadCompressed (int numLevels, const tcu::CompressedTexture
 
 Texture3D::Texture3D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int depth)
        : m_context                     (context)
+       , m_isCompressed        (false)
        , m_format                      (format)
        , m_refTexture          (mapGLTransferFormat(format, dataType), width, height, depth)
        , m_glTexture           (0)
@@ -622,6 +623,7 @@ Texture3D::Texture3D (const RenderContext& context, deUint32 format, deUint32 da
 
 Texture3D::Texture3D (const RenderContext& context, deUint32 sizedFormat, int width, int height, int depth)
        : m_context                     (context)
+       , m_isCompressed        (false)
        , m_format                      (sizedFormat)
        , m_refTexture          (mapGLInternalFormat(sizedFormat), width, height, depth)
        , m_glTexture           (0)
@@ -632,6 +634,36 @@ Texture3D::Texture3D (const RenderContext& context, deUint32 sizedFormat, int wi
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
 }
 
+Texture3D::Texture3D (const RenderContext&                                     context,
+                                         const ContextInfo&                                    contextInfo,
+                                         int                                                                   numLevels,
+                                         const tcu::CompressedTexture*                 levels,
+                                         const tcu::TexDecompressionParams&    decompressionParams)
+       : m_context                     (context)
+       , m_isCompressed        (true)
+       , m_format                      (getGLFormat(levels[0].getFormat()))
+       , m_refTexture          (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
+       , m_glTexture           (0)
+{
+       const glw::Functions& gl = context.getFunctions();
+
+       if (!contextInfo.isCompressedTextureFormatSupported(m_format))
+               throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
+
+       gl.genTextures(1, &m_glTexture);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
+
+       try
+       {
+               loadCompressed(numLevels, levels, decompressionParams);
+       }
+       catch (const std::exception&)
+       {
+               gl.deleteTextures(1, &m_glTexture);
+               throw;
+       }
+}
+
 Texture3D::~Texture3D (void)
 {
        if (m_glTexture)
@@ -642,6 +674,8 @@ void Texture3D::upload (void)
 {
        const glw::Functions& gl = m_context.getFunctions();
 
+       DE_ASSERT(!m_isCompressed);
+
        if (!gl.texImage3D)
                throw tcu::NotSupportedError("glTexImage3D() is not supported");
 
@@ -666,6 +700,37 @@ void Texture3D::upload (void)
        GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
 }
 
+void Texture3D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
+{
+       const glw::Functions&   gl                                      = m_context.getFunctions();
+       deUint32                                compressedFormat        = getGLFormat(levels[0].getFormat());
+
+       if (!gl.compressedTexImage3D)
+               throw tcu::NotSupportedError("glCompressedTexImage3D() is not supported");
+
+       TCU_CHECK(m_glTexture);
+       gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
+
+       for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
+       {
+               const tcu::CompressedTexture& level = levels[levelNdx];
+
+               // Decompress to reference texture.
+               m_refTexture.allocLevel(levelNdx);
+               tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
+               TCU_CHECK(level.getWidth()      == refLevelAccess.getWidth() &&
+                                 level.getHeight()     == refLevelAccess.getHeight() &&
+                                 level.getDepth()      == refLevelAccess.getDepth());
+               level.decompress(refLevelAccess, decompressionParams);
+
+               // Upload to GL texture in compressed form.
+               gl.compressedTexImage3D(GL_TEXTURE_3D, levelNdx, compressedFormat,
+                                                               level.getWidth(), level.getHeight(), level.getDepth(), 0 /* border */, level.getDataSize(), level.getData());
+       }
+
+       GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
+}
+
 // TextureCubeArray
 
 TextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 format, deUint32 dataType, int size, int numLayers)
index 45de10c..1a8d7db 100644 (file)
@@ -210,6 +210,7 @@ class Texture3D
 public:
                                                                Texture3D                       (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int depth);
                                                                Texture3D                       (const RenderContext& context, deUint32 internalFormat, int width, int height, int depth);
+                                                               Texture3D                       (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams = tcu::TexDecompressionParams());
                                                                ~Texture3D                      (void);
 
        void                                            upload                          (void);
@@ -222,8 +223,11 @@ private:
                                                                Texture3D                       (const Texture3D& other); // Not allowed!
        Texture3D&                                      operator=                       (const Texture3D& other); // Not allowed!
 
+       void                                            loadCompressed          (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams);
+
        const RenderContext&            m_context;
 
+       bool                                            m_isCompressed;
        deUint32                                        m_format;                       //!< Internal format.
 
        tcu::Texture3D                          m_refTexture;