blob: b8d2be0d3f5379f5ec79f33b56cbcc13456ff5e9 [file] [log] [blame]
#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