#ifndef _TCUTEXTURE_HPP #define _TCUTEXTURE_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Reference Texture Implementation. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "tcuVector.hpp" #include "rrGenericVector.hpp" #include "deArrayBuffer.hpp" #include <vector> #include <ostream> namespace tcu { /*--------------------------------------------------------------------*//*! * \brief Texture format *//*--------------------------------------------------------------------*/ class TextureFormat { public: enum ChannelOrder { R = 0, A, I, L, LA, RG, RA, RGB, RGBA, ARGB, BGR, BGRA, sR, sRG, sRGB, sRGBA, sBGR, sBGRA, D, S, DS, CHANNELORDER_LAST }; enum ChannelType { SNORM_INT8 = 0, SNORM_INT16, SNORM_INT32, UNORM_INT8, UNORM_INT16, UNORM_INT24, UNORM_INT32, UNORM_BYTE_44, UNORM_SHORT_565, UNORM_SHORT_555, UNORM_SHORT_4444, UNORM_SHORT_5551, UNORM_SHORT_1555, UNORM_INT_101010, SNORM_INT_1010102_REV, UNORM_INT_1010102_REV, UNSIGNED_BYTE_44, UNSIGNED_SHORT_565, UNSIGNED_SHORT_4444, UNSIGNED_SHORT_5551, SIGNED_INT_1010102_REV, UNSIGNED_INT_1010102_REV, UNSIGNED_INT_11F_11F_10F_REV, UNSIGNED_INT_999_E5_REV, UNSIGNED_INT_16_8_8, UNSIGNED_INT_24_8, UNSIGNED_INT_24_8_REV, SIGNED_INT8, SIGNED_INT16, SIGNED_INT32, UNSIGNED_INT8, UNSIGNED_INT16, UNSIGNED_INT24, UNSIGNED_INT32, HALF_FLOAT, FLOAT, FLOAT64, FLOAT_UNSIGNED_INT_24_8_REV, UNORM_SHORT_10, UNORM_SHORT_12, CHANNELTYPE_LAST }; ChannelOrder order; ChannelType type; TextureFormat (ChannelOrder order_, ChannelType type_) : order (order_) , type (type_) { } TextureFormat (void) : order (CHANNELORDER_LAST) , type (CHANNELTYPE_LAST) { } int getPixelSize (void) const; //!< Deprecated, use tcu::getPixelSize(fmt) bool operator== (const TextureFormat& other) const { return !(*this != other); } bool operator!= (const TextureFormat& other) const { return (order != other.order || type != other.type); } } DE_WARN_UNUSED_TYPE; bool isValid (TextureFormat format); int getPixelSize (TextureFormat format); int getNumUsedChannels (TextureFormat::ChannelOrder order); int getChannelSize (TextureFormat::ChannelType type); /*--------------------------------------------------------------------*//*! * \brief Texture swizzle *//*--------------------------------------------------------------------*/ struct TextureSwizzle { enum Channel { // \note CHANNEL_N must equal int N CHANNEL_0 = 0, CHANNEL_1, CHANNEL_2, CHANNEL_3, CHANNEL_ZERO, CHANNEL_ONE, CHANNEL_LAST }; Channel components[4]; }; //! get the swizzle used to expand texture data with a given channel order to RGBA form const TextureSwizzle& getChannelReadSwizzle (TextureFormat::ChannelOrder order); //! get the swizzle used to narrow RGBA form data to native texture data with a given channel order const TextureSwizzle& getChannelWriteSwizzle (TextureFormat::ChannelOrder order); /*--------------------------------------------------------------------*//*! * \brief Sampling parameters *//*--------------------------------------------------------------------*/ class Sampler { public: enum WrapMode { CLAMP_TO_EDGE = 0, //! Clamp to edge CLAMP_TO_BORDER, //! Use border color at edge REPEAT_GL, //! Repeat with OpenGL semantics REPEAT_CL, //! Repeat with OpenCL semantics MIRRORED_REPEAT_GL, //! Mirrored repeat with OpenGL semantics MIRRORED_REPEAT_CL, //! Mirrored repeat with OpenCL semantics MIRRORED_ONCE, //! Mirrored once in negative directions WRAPMODE_LAST }; enum FilterMode { NEAREST = 0, LINEAR, NEAREST_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_NEAREST, LINEAR_MIPMAP_LINEAR, FILTERMODE_LAST }; enum ReductionMode { WEIGHTED_AVERAGE = 0, MIN, MAX, REDUCTIONMODE_LAST }; enum CompareMode { COMPAREMODE_NONE = 0, COMPAREMODE_LESS, COMPAREMODE_LESS_OR_EQUAL, COMPAREMODE_GREATER, COMPAREMODE_GREATER_OR_EQUAL, COMPAREMODE_EQUAL, COMPAREMODE_NOT_EQUAL, COMPAREMODE_ALWAYS, COMPAREMODE_NEVER, COMPAREMODE_LAST }; enum DepthStencilMode { MODE_DEPTH = 0, MODE_STENCIL, MODE_LAST }; // Wrap control WrapMode wrapS; WrapMode wrapT; WrapMode wrapR; // Minifcation & magnification FilterMode minFilter; FilterMode magFilter; // min/max filtering reduction ReductionMode reductionMode; float lodThreshold; // lod <= lodThreshold ? magnified : minified // Coordinate normalization bool normalizedCoords; // Shadow comparison CompareMode compare; int compareChannel; // Border color. // \note It is setter's responsibility to guarantee that the values are representable // in sampled texture's internal format. // \note It is setter's responsibility to guarantee that the format is compatible with the // sampled texture's internal format. Otherwise results are undefined. rr::GenericVec4 borderColor; // Seamless cube map filtering bool seamlessCubeMap; // Depth stencil mode DepthStencilMode depthStencilMode; Sampler (WrapMode wrapS_, WrapMode wrapT_, WrapMode wrapR_, FilterMode minFilter_, FilterMode magFilter_, float lodThreshold_ = 0.0f, bool normalizedCoords_ = true, CompareMode compare_ = COMPAREMODE_NONE, int compareChannel_ = 0, const Vec4& borderColor_ = Vec4(0.0f, 0.0f, 0.0f, 0.0f), bool seamlessCubeMap_ = false, DepthStencilMode depthStencilMode_ = MODE_DEPTH, ReductionMode reductionMode_ = WEIGHTED_AVERAGE) : wrapS (wrapS_) , wrapT (wrapT_) , wrapR (wrapR_) , minFilter (minFilter_) , magFilter (magFilter_) , reductionMode (reductionMode_) , lodThreshold (lodThreshold_) , normalizedCoords (normalizedCoords_) , compare (compare_) , compareChannel (compareChannel_) , borderColor (borderColor_) , seamlessCubeMap (seamlessCubeMap_) , depthStencilMode (depthStencilMode_) { } Sampler (void) : wrapS (WRAPMODE_LAST) , wrapT (WRAPMODE_LAST) , wrapR (WRAPMODE_LAST) , minFilter (FILTERMODE_LAST) , magFilter (FILTERMODE_LAST) , reductionMode (REDUCTIONMODE_LAST) , lodThreshold (0.0f) , normalizedCoords (true) , compare (COMPAREMODE_NONE) , compareChannel (0) , borderColor (Vec4(0.0f, 0.0f, 0.0f, 0.0f)) , seamlessCubeMap (false) , depthStencilMode (MODE_DEPTH) { } } DE_WARN_UNUSED_TYPE; // Calculate pitches for pixel data with no padding. IVec3 calculatePackedPitch (const TextureFormat& format, const IVec3& size); class TextureLevel; /*--------------------------------------------------------------------*//*! * \brief Read-only pixel data access * * ConstPixelBufferAccess encapsulates pixel data pointer along with * format and layout information. It can be used for read-only access * to arbitrary pixel buffers. * * Access objects are like iterators or pointers. They can be passed around * as values and are valid as long as the storage doesn't change. *//*--------------------------------------------------------------------*/ class ConstPixelBufferAccess { public: ConstPixelBufferAccess (void); ConstPixelBufferAccess (const TextureLevel& level); ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, const void* data); ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const void* data); ConstPixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data); ConstPixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, const void* data); const TextureFormat& getFormat (void) const { return m_format; } const IVec3& getSize (void) const { return m_size; } int getWidth (void) const { return m_size.x(); } int getHeight (void) const { return m_size.y(); } int getDepth (void) const { return m_size.z(); } int getPixelPitch (void) const { return m_pitch.x(); } int getRowPitch (void) const { return m_pitch.y(); } int getSlicePitch (void) const { return m_pitch.z(); } const IVec3& getPitch (void) const { return m_pitch; } const void* getDataPtr (void) const { return m_data; } const void* getPixelPtr (int x, int y, int z = 0) const { return (const deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); } Vec4 getPixel (int x, int y, int z = 0) const; IVec4 getPixelInt (int x, int y, int z = 0) const; UVec4 getPixelUint (int x, int y, int z = 0) const { return getPixelInt(x, y, z).cast<deUint32>(); } template<typename T> Vector<T, 4> getPixelT (int x, int y, int z = 0) const; float getPixDepth (int x, int y, int z = 0) const; int getPixStencil (int x, int y, int z = 0) const; Vec4 sample1D (const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const; Vec4 sample2D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const; Vec4 sample3D (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const; Vec4 sample1DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const; Vec4 sample2DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const; Vec4 sample3DOffset (const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const; float sample1DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const; float sample2DCompare (const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const; protected: TextureFormat m_format; IVec3 m_size; IVec3 m_pitch; //!< (pixelPitch, rowPitch, slicePitch) mutable void* m_data; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief Read-write pixel data access * * This class extends read-only access object by providing write functionality. * * \note PixelBufferAccess may not have any data members nor add any * virtual functions. It must be possible to reinterpret_cast<> * PixelBufferAccess to ConstPixelBufferAccess. *//*--------------------------------------------------------------------*/ class PixelBufferAccess : public ConstPixelBufferAccess { public: PixelBufferAccess (void) {} PixelBufferAccess (TextureLevel& level); PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, void* data); PixelBufferAccess (const TextureFormat& format, const IVec3& size, void* data); PixelBufferAccess (const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data); PixelBufferAccess (const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data); void* getDataPtr (void) const { return m_data; } void* getPixelPtr (int x, int y, int z = 0) const { return (deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); } void setPixel (const tcu::Vec4& color, int x, int y, int z = 0) const; void setPixel (const tcu::IVec4& color, int x, int y, int z = 0) const; void setPixel (const tcu::UVec4& color, int x, int y, int z = 0) const { setPixel(color.cast<int>(), x, y, z); } void setPixDepth (float depth, int x, int y, int z = 0) const; void setPixStencil (int stencil, int x, int y, int z = 0) const; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief Generic pixel data container * * This container supports all valid TextureFormat combinations and * both 2D and 3D textures. To read or manipulate data access object must * be queried using getAccess(). *//*--------------------------------------------------------------------*/ class TextureLevel { public: TextureLevel (void); TextureLevel (const TextureFormat& format); TextureLevel (const TextureFormat& format, int width, int height, int depth = 1); ~TextureLevel (void); const IVec3& getSize (void) const { return m_size; } int getWidth (void) const { return m_size.x(); } int getHeight (void) const { return m_size.y(); } int getDepth (void) const { return m_size.z(); } bool isEmpty (void) const { return m_size.x() * m_size.y() * m_size.z() == 0; } const TextureFormat getFormat (void) const { return m_format; } void setStorage (const TextureFormat& format, int width, int heigth, int depth = 1); void setSize (int width, int height, int depth = 1); PixelBufferAccess getAccess (void) { return isEmpty() ? PixelBufferAccess() : PixelBufferAccess(m_format, m_size, calculatePackedPitch(m_format, m_size), getPtr()); } ConstPixelBufferAccess getAccess (void) const { return isEmpty() ? ConstPixelBufferAccess() : ConstPixelBufferAccess(m_format, m_size, calculatePackedPitch(m_format, m_size), getPtr()); } private: void* getPtr (void) { return m_data.getPtr(); } const void* getPtr (void) const { return m_data.getPtr(); } TextureFormat m_format; IVec3 m_size; de::ArrayBuffer<deUint8> m_data; friend class ConstPixelBufferAccess; } DE_WARN_UNUSED_TYPE; Vec4 sampleLevelArray1D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int level, float lod); Vec4 sampleLevelArray2D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod); Vec4 sampleLevelArray3D (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod); Vec4 sampleLevelArray1DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset); Vec4 sampleLevelArray2DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset); Vec4 sampleLevelArray3DOffset (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset); float sampleLevelArray1DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset); float sampleLevelArray2DCompare (const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset); Vec4 gatherArray2DOffsets (const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]); Vec4 gatherArray2DOffsetsCompare (const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4]); enum CubeFace { CUBEFACE_NEGATIVE_X = 0, CUBEFACE_POSITIVE_X, CUBEFACE_NEGATIVE_Y, CUBEFACE_POSITIVE_Y, CUBEFACE_NEGATIVE_Z, CUBEFACE_POSITIVE_Z, CUBEFACE_LAST }; /*--------------------------------------------------------------------*//*! * \brief Coordinates projected onto cube face. *//*--------------------------------------------------------------------*/ template<typename T> struct CubeFaceCoords { CubeFace face; T s; T t; CubeFaceCoords (CubeFace face_, T s_, T t_) : face(face_), s(s_), t(t_) {} CubeFaceCoords (CubeFace face_, const Vector<T, 2>& c) : face(face_), s(c.x()), t(c.y()) {} } DE_WARN_UNUSED_TYPE; typedef CubeFaceCoords<float> CubeFaceFloatCoords; typedef CubeFaceCoords<int> CubeFaceIntCoords; CubeFace selectCubeFace (const Vec3& coords); Vec2 projectToFace (CubeFace face, const Vec3& coords); CubeFaceFloatCoords getCubeFaceCoords (const Vec3& coords); CubeFaceIntCoords remapCubeEdgeCoords (const CubeFaceIntCoords& coords, int size); /*--------------------------------------------------------------------*//*! * \brief 1D Texture View *//*--------------------------------------------------------------------*/ class Texture1DView { public: Texture1DView (int numLevels, const ConstPixelBufferAccess* levels); int getNumLevels (void) const { return m_numLevels; } int getWidth (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const; protected: int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; inline Texture1DView::Texture1DView (int numLevels, const ConstPixelBufferAccess* levels) : m_numLevels (numLevels) , m_levels (levels) { DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels)); } inline Vec4 Texture1DView::sample (const Sampler& sampler, float s, float lod) const { return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, 0 /* depth */, lod); } inline Vec4 Texture1DView::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const { return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, 0)); } inline float Texture1DView::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const { return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, 0)); } inline float Texture1DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const { return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, 0)); } /*--------------------------------------------------------------------*//*! * \brief 2D Texture View *//*--------------------------------------------------------------------*/ class Texture2DView { public: Texture2DView (int numLevels, const ConstPixelBufferAccess* levels); int getNumLevels (void) const { return m_numLevels; } int getWidth (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } int getHeight (void) const { return m_numLevels > 0 ? m_levels[0].getHeight() : 0; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float t, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const; Vec4 gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const; Vec4 gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const; protected: int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; inline Texture2DView::Texture2DView (int numLevels, const ConstPixelBufferAccess* levels) : m_numLevels (numLevels) , m_levels (levels) { DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels)); } inline Vec4 Texture2DView::sample (const Sampler& sampler, float s, float t, float lod) const { return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, 0 /* depth */, lod); } inline Vec4 Texture2DView::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const { return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), 0)); } inline float Texture2DView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const { return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, 0)); } inline float Texture2DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const { return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), 0)); } inline Vec4 Texture2DView::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const { return gatherArray2DOffsets(m_levels[0], sampler, s, t, 0, componentNdx, offsets); } inline Vec4 Texture2DView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const { return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, 0, offsets); } /*--------------------------------------------------------------------*//*! * \brief Base class for textures that have single mip-map pyramid *//*--------------------------------------------------------------------*/ class TextureLevelPyramid { public: TextureLevelPyramid (const TextureFormat& format, int numLevels); TextureLevelPyramid (const TextureLevelPyramid& other); ~TextureLevelPyramid(void); const TextureFormat& getFormat (void) const { return m_format; } int getNumLevels (void) const { return (int)m_access.size(); } bool isLevelEmpty (int levelNdx) const { DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_data[(size_t)levelNdx].empty(); } const ConstPixelBufferAccess& getLevel (int levelNdx) const { DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_access[(size_t)levelNdx]; } const PixelBufferAccess& getLevel (int levelNdx) { DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_access[(size_t)levelNdx]; } const ConstPixelBufferAccess* getLevels (void) const { return &m_access[0]; } const PixelBufferAccess* getLevels (void) { return &m_access[0]; } void allocLevel (int levelNdx, int width, int height, int depth); void clearLevel (int levelNdx); TextureLevelPyramid& operator= (const TextureLevelPyramid& other); private: typedef de::ArrayBuffer<deUint8> LevelData; TextureFormat m_format; std::vector<LevelData> m_data; std::vector<PixelBufferAccess> m_access; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief 1D Texture reference implementation *//*--------------------------------------------------------------------*/ class Texture1D : private TextureLevelPyramid { public: Texture1D (const TextureFormat& format, int width); Texture1D (const Texture1D& other); ~Texture1D (void); int getWidth (void) const { return m_width; } const Texture1DView& getView (void) const { return m_view; } void allocLevel (int levelNdx); // Sampling Vec4 sample (const Sampler& sampler, float s, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const; using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Texture1D& operator= (const Texture1D& other); operator Texture1DView (void) const { return m_view; } private: int m_width; Texture1DView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture1D::sample (const Sampler& sampler, float s, float lod) const { return m_view.sample(sampler, s, lod); } inline Vec4 Texture1D::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const { return m_view.sampleOffset(sampler, s, lod, offset); } inline float Texture1D::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const { return m_view.sampleCompare(sampler, ref, s, lod); } inline float Texture1D::sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const { return m_view.sampleCompareOffset(sampler, ref, s, lod, offset); } /*--------------------------------------------------------------------*//*! * \brief 2D Texture reference implementation *//*--------------------------------------------------------------------*/ class Texture2D : private TextureLevelPyramid { public: Texture2D (const TextureFormat& format, int width, int height); Texture2D (const TextureFormat& format, int width, int height, int mipmaps); Texture2D (const Texture2D& other); ~Texture2D (void); int getWidth (void) const { return m_width; } int getHeight (void) const { return m_height; } const Texture2DView& getView (void) const { return m_view; } void allocLevel (int levelNdx); // Sampling Vec4 sample (const Sampler& sampler, float s, float t, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const; Vec4 gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const; Vec4 gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const; using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Texture2D& operator= (const Texture2D& other); operator Texture2DView (void) const { return m_view; } private: int m_width; int m_height; Texture2DView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture2D::sample (const Sampler& sampler, float s, float t, float lod) const { return m_view.sample(sampler, s, t, lod); } inline Vec4 Texture2D::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const { return m_view.sampleOffset(sampler, s, t, lod, offset); } inline float Texture2D::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const { return m_view.sampleCompare(sampler, ref, s, t, lod); } inline float Texture2D::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const { return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset); } inline Vec4 Texture2D::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const { return m_view.gatherOffsets(sampler, s, t, componentNdx, offsets); } inline Vec4 Texture2D::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const { return m_view.gatherOffsetsCompare(sampler, ref, s, t, offsets); } /*--------------------------------------------------------------------*//*! * \brief Cube Map Texture View *//*--------------------------------------------------------------------*/ class TextureCubeView { public: TextureCubeView (void); TextureCubeView (int numLevels, const ConstPixelBufferAccess* const (&levels)[CUBEFACE_LAST]); int getNumLevels (void) const { return m_numLevels; } int getSize (void) const { return m_numLevels > 0 ? m_levels[0][0].getWidth() : 0; } const ConstPixelBufferAccess& getLevelFace (int ndx, CubeFace face) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[face][ndx]; } const ConstPixelBufferAccess* getFaceLevels (CubeFace face) const { return m_levels[face]; } Vec4 sample (const Sampler& sampler, float s, float t, float p, float lod) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const; Vec4 gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const; Vec4 gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const; protected: int m_numLevels; const ConstPixelBufferAccess* m_levels[CUBEFACE_LAST]; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief Cube Map Texture reference implementation *//*--------------------------------------------------------------------*/ class TextureCube { public: TextureCube (const TextureFormat& format, int size); TextureCube (const TextureCube& other); ~TextureCube (void); const TextureFormat& getFormat (void) const { return m_format; } int getSize (void) const { return m_size; } int getNumLevels (void) const { return (int)m_access[0].size(); } const ConstPixelBufferAccess& getLevelFace (int ndx, CubeFace face) const { DE_ASSERT(de::inBounds(ndx, 0, getNumLevels())); return m_access[face][(size_t)ndx]; } const PixelBufferAccess& getLevelFace (int ndx, CubeFace face) { DE_ASSERT(de::inBounds(ndx, 0, getNumLevels())); return m_access[face][(size_t)ndx]; } void allocLevel (CubeFace face, int levelNdx); void clearLevel (CubeFace face, int levelNdx); bool isLevelEmpty (CubeFace face, int levelNdx) const { DE_ASSERT(de::inBounds(levelNdx, 0, getNumLevels())); return m_data[face][(size_t)levelNdx].empty(); } Vec4 sample (const Sampler& sampler, float s, float t, float p, float lod) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const; Vec4 gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const; Vec4 gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const; TextureCube& operator= (const TextureCube& other); operator TextureCubeView (void) const { return m_view; } private: typedef de::ArrayBuffer<deUint8> LevelData; TextureFormat m_format; int m_size; std::vector<LevelData> m_data[CUBEFACE_LAST]; std::vector<PixelBufferAccess> m_access[CUBEFACE_LAST]; TextureCubeView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 TextureCube::sample (const Sampler& sampler, float s, float t, float p, float lod) const { return m_view.sample(sampler, s, t, p, lod); } inline float TextureCube::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const { return m_view.sampleCompare(sampler, ref, s, t, r, lod); } inline Vec4 TextureCube::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const { return m_view.gather(sampler, s, t, r, componentNdx); } inline Vec4 TextureCube::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const { return m_view.gatherCompare(sampler, ref, s, t, r); } /*--------------------------------------------------------------------*//*! * \brief 1D Array Texture View *//*--------------------------------------------------------------------*/ class Texture1DArrayView { public: Texture1DArrayView (int numLevels, const ConstPixelBufferAccess* levels); int getWidth (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } int getNumLayers (void) const { return m_numLevels > 0 ? m_levels[0].getHeight() : 0; } int getNumLevels (void) const { return m_numLevels; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float t, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const; protected: int selectLayer (float r) const; int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief 2D Array Texture View *//*--------------------------------------------------------------------*/ class Texture2DArrayView { public: Texture2DArrayView (int numLevels, const ConstPixelBufferAccess* levels); int getWidth (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } int getHeight (void) const { return m_numLevels > 0 ? m_levels[0].getHeight() : 0; } int getNumLayers (void) const { return m_numLevels > 0 ? m_levels[0].getDepth() : 0; } int getNumLevels (void) const { return m_numLevels; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float t, float r, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const; Vec4 gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const; Vec4 gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const; protected: int selectLayer (float r) const; int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief 1D Array Texture reference implementation *//*--------------------------------------------------------------------*/ class Texture1DArray : private TextureLevelPyramid { public: Texture1DArray (const TextureFormat& format, int width, int numLayers); Texture1DArray (const Texture1DArray& other); ~Texture1DArray (void); int getWidth (void) const { return m_width; } int getNumLayers (void) const { return m_numLayers; } void allocLevel (int levelNdx); using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Vec4 sample (const Sampler& sampler, float s, float t, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const; Texture1DArray& operator= (const Texture1DArray& other); operator Texture1DArrayView (void) const { return m_view; } private: int m_width; int m_numLayers; Texture1DArrayView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture1DArray::sample (const Sampler& sampler, float s, float t, float lod) const { return m_view.sample(sampler, s, t, lod); } inline Vec4 Texture1DArray::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const { return m_view.sampleOffset(sampler, s, t, lod, offset); } inline float Texture1DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const { return m_view.sampleCompare(sampler, ref, s, t, lod); } inline float Texture1DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const { return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset); } /*--------------------------------------------------------------------*//*! * \brief 2D Array Texture reference implementation *//*--------------------------------------------------------------------*/ class Texture2DArray : private TextureLevelPyramid { public: Texture2DArray (const TextureFormat& format, int width, int height, int numLayers); Texture2DArray (const Texture2DArray& other); ~Texture2DArray (void); int getWidth (void) const { return m_width; } int getHeight (void) const { return m_height; } int getNumLayers (void) const { return m_numLayers; } void allocLevel (int levelNdx); using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Vec4 sample (const Sampler& sampler, float s, float t, float r, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const; Vec4 gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const; Vec4 gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const; Texture2DArray& operator= (const Texture2DArray& other); operator Texture2DArrayView (void) const { return m_view; } private: int m_width; int m_height; int m_numLayers; Texture2DArrayView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture2DArray::sample (const Sampler& sampler, float s, float t, float r, float lod) const { return m_view.sample(sampler, s, t, r, lod); } inline Vec4 Texture2DArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const { return m_view.sampleOffset(sampler, s, t, r, lod, offset); } inline float Texture2DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const { return m_view.sampleCompare(sampler, ref, s, t, r, lod); } inline float Texture2DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const { return m_view.sampleCompareOffset(sampler, ref, s, t, r, lod, offset); } inline Vec4 Texture2DArray::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const { return m_view.gatherOffsets(sampler, s, t, r, componentNdx, offsets); } inline Vec4 Texture2DArray::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const { return m_view.gatherOffsetsCompare(sampler, ref, s, t, r, offsets); } /*--------------------------------------------------------------------*//*! * \brief 3D Texture View *//*--------------------------------------------------------------------*/ class Texture3DView { public: Texture3DView (int numLevels, const ConstPixelBufferAccess* levels); int getWidth (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } int getHeight (void) const { return m_numLevels > 0 ? m_levels[0].getHeight() : 0; } int getDepth (void) const { return m_numLevels > 0 ? m_levels[0].getDepth() : 0; } int getNumLevels (void) const { return m_numLevels; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float t, float r, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const; protected: int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture3DView::sample (const Sampler& sampler, float s, float t, float r, float lod) const { return sampleLevelArray3D(m_levels, m_numLevels, sampler, s, t, r, lod); } inline Vec4 Texture3DView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const { return sampleLevelArray3DOffset(m_levels, m_numLevels, sampler, s, t, r, lod, offset); } /*--------------------------------------------------------------------*//*! * \brief 3D Texture reference implementation *//*--------------------------------------------------------------------*/ class Texture3D : private TextureLevelPyramid { public: Texture3D (const TextureFormat& format, int width, int height, int depth); Texture3D (const Texture3D& other); ~Texture3D (void); int getWidth (void) const { return m_width; } int getHeight (void) const { return m_height; } int getDepth (void) const { return m_depth; } void allocLevel (int levelNdx); using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Vec4 sample (const Sampler& sampler, float s, float t, float r, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const; Texture3D& operator= (const Texture3D& other); operator Texture3DView (void) const { return m_view; } private: int m_width; int m_height; int m_depth; Texture3DView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 Texture3D::sample (const Sampler& sampler, float s, float t, float r, float lod) const { return m_view.sample(sampler, s, t, r, lod); } inline Vec4 Texture3D::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const { return m_view.sampleOffset(sampler, s, t, r, lod, offset); } /*--------------------------------------------------------------------*//*! * \brief Cube Map Array Texture View *//*--------------------------------------------------------------------*/ class TextureCubeArrayView { public: TextureCubeArrayView (int numLevels, const ConstPixelBufferAccess* levels); int getSize (void) const { return m_numLevels > 0 ? m_levels[0].getWidth() : 0; } int getDepth (void) const { return m_numLevels > 0 ? m_levels[0].getDepth() : 0; } int getNumLayers (void) const { return getDepth() / 6; } int getNumLevels (void) const { return m_numLevels; } const ConstPixelBufferAccess& getLevel (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx]; } const ConstPixelBufferAccess* getLevels (void) const { return m_levels; } Vec4 sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const; protected: int selectLayer (float q) const; int m_numLevels; const ConstPixelBufferAccess* m_levels; } DE_WARN_UNUSED_TYPE; /*--------------------------------------------------------------------*//*! * \brief Cube Map Array Texture reference implementation *//*--------------------------------------------------------------------*/ class TextureCubeArray : private TextureLevelPyramid { public: TextureCubeArray (const TextureFormat& format, int size, int depth); TextureCubeArray (const TextureCubeArray& other); ~TextureCubeArray (void); int getSize (void) const { return m_size; } int getDepth (void) const { return m_depth; } void allocLevel (int levelNdx); using TextureLevelPyramid::getFormat; using TextureLevelPyramid::getNumLevels; using TextureLevelPyramid::getLevel; using TextureLevelPyramid::clearLevel; using TextureLevelPyramid::isLevelEmpty; Vec4 sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const; Vec4 sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const; float sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const; float sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const; TextureCubeArray& operator= (const TextureCubeArray& other); operator TextureCubeArrayView (void) const { return m_view; } private: int m_size; int m_depth; TextureCubeArrayView m_view; } DE_WARN_UNUSED_TYPE; inline Vec4 TextureCubeArray::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const { return m_view.sample(sampler, s, t, r, q, lod); } inline Vec4 TextureCubeArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const { return m_view.sampleOffset(sampler, s, t, r, q, lod, offset); } inline float TextureCubeArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const { return m_view.sampleCompare(sampler, ref, s, t, r, q, lod); } inline float TextureCubeArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const { return m_view.sampleCompareOffset(sampler, ref, s, t, r, q, lod, offset); } // Stream operators. std::ostream& operator<< (std::ostream& str, TextureFormat::ChannelOrder order); std::ostream& operator<< (std::ostream& str, TextureFormat::ChannelType type); std::ostream& operator<< (std::ostream& str, TextureFormat format); std::ostream& operator<< (std::ostream& str, CubeFace face); std::ostream& operator<< (std::ostream& str, const ConstPixelBufferAccess& access); } // tcu #endif // _TCUTEXTURE_HPP