summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/angle/checkout/src/libANGLE/ImageIndex.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
new file mode 100644
index 0000000000..55e0393fa4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
@@ -0,0 +1,388 @@
+//
+// 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::MakeBuffer()
+{
+ return ImageIndex(TextureType::Buffer, 0, kEntireLevel, 1);
+}
+
+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::MakeBuffer()
+{
+ return ImageIndexIterator(TextureType::Buffer, 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