Edit

kc3-lang/angle/src/libANGLE/ImageIndex.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2020-07-24 11:47:12
    Hash : fbaae6ce
    Message : GL: Add support for GL_OES/EXT_texture_buffer This extension is core in 3.2 Based on a CL by Jonah Ryan-Davis. Bug: angleproject:3573 Bug: angleproject:4933 Change-Id: Ib5ce038414075a5cdce36e9404e25d7af33fb39c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2519401 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/libANGLE/ImageIndex.cpp
  • //
    // Copyright 2014 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // ImageIndex.cpp: Implementation for ImageIndex methods.
    
    #include "libANGLE/ImageIndex.h"
    
    #include "common/utilities.h"
    #include "libANGLE/Constants.h"
    #include "libANGLE/angletypes.h"
    
    #include <tuple>
    
    namespace gl
    {
    namespace
    {
    GLint TextureTargetToLayer(TextureTarget target)
    {
        switch (target)
        {
            case TextureTarget::CubeMapPositiveX:
                return 0;
            case TextureTarget::CubeMapNegativeX:
                return 1;
            case TextureTarget::CubeMapPositiveY:
                return 2;
            case TextureTarget::CubeMapNegativeY:
                return 3;
            case TextureTarget::CubeMapPositiveZ:
                return 4;
            case TextureTarget::CubeMapNegativeZ:
                return 5;
            case TextureTarget::External:
            case TextureTarget::Rectangle:
            case TextureTarget::_2D:
            case TextureTarget::VideoImage:
            case TextureTarget::_2DArray:
            case TextureTarget::_2DMultisample:
            case TextureTarget::_2DMultisampleArray:
            case TextureTarget::_3D:
            case TextureTarget::Buffer:
            case TextureTarget::CubeMapArray:
                return ImageIndex::kEntireLevel;
            default:
                UNREACHABLE();
                return 0;
        }
    }
    
    bool IsArrayTarget(TextureTarget target)
    {
        switch (target)
        {
            case TextureTarget::_2DArray:
            case TextureTarget::_2DMultisampleArray:
            case TextureTarget::CubeMapArray:
                return true;
            default:
                return false;
        }
    }
    }  // anonymous namespace
    
    TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex)
    {
        if (type == TextureType::CubeMap)
        {
            // As GL_TEXTURE_CUBE_MAP cannot be a texture target in texImage*D APIs, so we don't allow
            // an entire cube map to have a texture target.
            ASSERT(layerIndex != ImageIndex::kEntireLevel);
            return CubeFaceIndexToTextureTarget(layerIndex);
        }
        else
        {
            return NonCubeTextureTypeToTarget(type);
        }
    }
    
    ImageIndex::ImageIndex()
        : mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel)
    {}
    
    ImageIndex::ImageIndex(const ImageIndex &other) = default;
    
    ImageIndex &ImageIndex::operator=(const ImageIndex &other) = default;
    
    bool ImageIndex::hasLayer() const
    {
        return mLayerIndex != kEntireLevel;
    }
    
    bool ImageIndex::isLayered() const
    {
        switch (mType)
        {
            case TextureType::_2DArray:
            case TextureType::_2DMultisampleArray:
            case TextureType::CubeMap:
            case TextureType::_3D:
            case TextureType::CubeMapArray:
                return mLayerIndex == kEntireLevel;
            default:
                return false;
        }
    }
    
    bool ImageIndex::has3DLayer() const
    {
        // It's quicker to check != CubeMap than calling usesTex3D, which checks multiple types. This
        // ASSERT validates the check gives the same result.
        ASSERT(!hasLayer() || ((mType != TextureType::CubeMap) == usesTex3D()));
        return (hasLayer() && mType != TextureType::CubeMap);
    }
    
    bool ImageIndex::usesTex3D() const
    {
        return mType == TextureType::_3D || mType == TextureType::_2DArray ||
               mType == TextureType::_2DMultisampleArray || mType == TextureType::CubeMapArray;
    }
    
    TextureTarget ImageIndex::getTarget() const
    {
        return TextureTypeToTarget(mType, mLayerIndex);
    }
    
    gl::TextureTarget ImageIndex::getTargetOrFirstCubeFace() const
    {
        if (isEntireLevelCubeMap())
        {
            return gl::kCubeMapTextureTargetMin;
        }
        else
        {
            return getTarget();
        }
    }
    
    GLint ImageIndex::cubeMapFaceIndex() const
    {
        ASSERT(mType == TextureType::CubeMap);
        ASSERT(mLayerIndex == kEntireLevel || mLayerIndex < static_cast<GLint>(kCubeFaceCount));
        return mLayerIndex;
    }
    
    bool ImageIndex::valid() const
    {
        return mType != TextureType::InvalidEnum;
    }
    
    bool ImageIndex::isEntireLevelCubeMap() const
    {
        return mType == TextureType::CubeMap && mLayerIndex == ImageIndex::kEntireLevel;
    }
    
    ImageIndex ImageIndex::Make2D(GLint levelIndex)
    {
        return ImageIndex(TextureType::_2D, levelIndex, kEntireLevel, 1);
    }
    
    ImageIndex ImageIndex::MakeRectangle(GLint levelIndex)
    {
        return ImageIndex(TextureType::Rectangle, levelIndex, kEntireLevel, 1);
    }
    
    ImageIndex ImageIndex::MakeCubeMapFace(TextureTarget target, GLint levelIndex)
    {
        ASSERT(IsCubeMapFaceTarget(target));
        return ImageIndex(TextureType::CubeMap, levelIndex, TextureTargetToLayer(target), 1);
    }
    
    ImageIndex ImageIndex::Make2DArray(GLint levelIndex, GLint layerIndex)
    {
        return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, 1);
    }
    
    ImageIndex ImageIndex::Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint numLayers)
    {
        return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, numLayers);
    }
    
    ImageIndex ImageIndex::Make3D(GLint levelIndex, GLint layerIndex)
    {
        return ImageIndex(TextureType::_3D, levelIndex, layerIndex, 1);
    }
    
    ImageIndex ImageIndex::MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth)
    {
        return ImageIndex(TextureTargetToType(target), levelIndex, TextureTargetToLayer(target),
                          IsArrayTarget(target) ? depth : 1);
    }
    
    ImageIndex ImageIndex::MakeFromType(TextureType type,
                                        GLint levelIndex,
                                        GLint layerIndex,
                                        GLint layerCount)
    {
        GLint overrideLayerCount =
            (type == TextureType::CubeMap && layerIndex == kEntireLevel ? kCubeFaceCount : layerCount);
        return ImageIndex(type, levelIndex, layerIndex, overrideLayerCount);
    }
    
    ImageIndex ImageIndex::Make2DMultisample()
    {
        return ImageIndex(TextureType::_2DMultisample, 0, kEntireLevel, 1);
    }
    
    ImageIndex ImageIndex::Make2DMultisampleArray(GLint layerIndex)
    {
        return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, 1);
    }
    
    ImageIndex ImageIndex::Make2DMultisampleArrayRange(GLint layerIndex, GLint numLayers)
    {
        return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, numLayers);
    }
    
    bool ImageIndex::operator<(const ImageIndex &b) const
    {
        return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) <
               std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
    }
    
    bool ImageIndex::operator==(const ImageIndex &b) const
    {
        return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) ==
               std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
    }
    
    bool ImageIndex::operator!=(const ImageIndex &b) const
    {
        return !(*this == b);
    }
    
    ImageIndex::ImageIndex(TextureType type, GLint levelIndex, GLint layerIndex, GLint layerCount)
        : mType(type), mLevelIndex(levelIndex), mLayerIndex(layerIndex), mLayerCount(layerCount)
    {}
    
    ImageIndexIterator ImageIndex::getLayerIterator(GLint layerCount) const
    {
        ASSERT(mType != TextureType::_2D && !hasLayer());
        return ImageIndexIterator::MakeGeneric(mType, mLevelIndex, mLevelIndex + 1, 0, layerCount);
    }
    
    ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default;
    
    ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
    {
        return ImageIndexIterator(TextureType::_2D, Range<GLint>(minMip, maxMip),
                                  Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
                                  nullptr);
    }
    
    ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
    {
        return ImageIndexIterator(TextureType::Rectangle, Range<GLint>(minMip, maxMip),
                                  Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
                                  nullptr);
    }
    
    ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
    {
        return ImageIndexIterator(TextureType::CubeMap, Range<GLint>(minMip, maxMip),
                                  Range<GLint>(0, 6), nullptr);
    }
    
    ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip,
                                                  GLint maxMip,
                                                  GLint minLayer,
                                                  GLint maxLayer)
    {
        return ImageIndexIterator(TextureType::_3D, Range<GLint>(minMip, maxMip),
                                  Range<GLint>(minLayer, maxLayer), nullptr);
    }
    
    ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip,
                                                       GLint maxMip,
                                                       const GLsizei *layerCounts)
    {
        return ImageIndexIterator(TextureType::_2DArray, Range<GLint>(minMip, maxMip),
                                  Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
                                  layerCounts);
    }
    
    ImageIndexIterator ImageIndexIterator::Make2DMultisample()
    {
        return ImageIndexIterator(TextureType::_2DMultisample, Range<GLint>(0, 1),
                                  Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
                                  nullptr);
    }
    
    ImageIndexIterator ImageIndexIterator::Make2DMultisampleArray(const GLsizei *layerCounts)
    {
        return ImageIndexIterator(TextureType::_2DMultisampleArray, Range<GLint>(0, 1),
                                  Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
                                  layerCounts);
    }
    
    ImageIndexIterator ImageIndexIterator::MakeGeneric(TextureType type,
                                                       GLint minMip,
                                                       GLint maxMip,
                                                       GLint minLayer,
                                                       GLint maxLayer)
    {
        if (type == TextureType::CubeMap)
        {
            return MakeCube(minMip, maxMip);
        }
    
        return ImageIndexIterator(type, Range<GLint>(minMip, maxMip), Range<GLint>(minLayer, maxLayer),
                                  nullptr);
    }
    
    ImageIndexIterator::ImageIndexIterator(TextureType type,
                                           const Range<GLint> &mipRange,
                                           const Range<GLint> &layerRange,
                                           const GLsizei *layerCounts)
        : mMipRange(mipRange),
          mLayerRange(layerRange),
          mLayerCounts(layerCounts),
          mCurrentIndex(type, mipRange.low(), layerRange.low(), 1)
    {}
    
    GLint ImageIndexIterator::maxLayer() const
    {
        if (mLayerCounts)
        {
            ASSERT(mCurrentIndex.hasLayer());
            return (mCurrentIndex.getLevelIndex() < mMipRange.high())
                       ? mLayerCounts[mCurrentIndex.getLevelIndex()]
                       : 0;
        }
        return mLayerRange.high();
    }
    
    ImageIndex ImageIndexIterator::next()
    {
        ASSERT(hasNext());
    
        // Make a copy of the current index to return
        ImageIndex previousIndex = mCurrentIndex;
    
        // Iterate layers in the inner loop for now. We can add switchable
        // layer or mip iteration if we need it.
    
        if (mCurrentIndex.hasLayer() && mCurrentIndex.getLayerIndex() < maxLayer() - 1)
        {
            mCurrentIndex.mLayerIndex++;
        }
        else if (mCurrentIndex.mLevelIndex < mMipRange.high() - 1)
        {
            mCurrentIndex.mLayerIndex = mLayerRange.low();
            mCurrentIndex.mLevelIndex++;
        }
        else
        {
            mCurrentIndex = ImageIndex();
        }
    
        return previousIndex;
    }
    
    ImageIndex ImageIndexIterator::current() const
    {
        return mCurrentIndex;
    }
    
    bool ImageIndexIterator::hasNext() const
    {
        return mCurrentIndex.valid();
    }
    
    }  // namespace gl