Home | History | Annotate | Download | only in common
      1 #ifndef _TCUTEXTURE_HPP
      2 #define _TCUTEXTURE_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program Tester Core
      5  * ----------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Reference Texture Implementation.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "tcuVector.hpp"
     28 #include "deArrayBuffer.hpp"
     29 
     30 #include <vector>
     31 #include <ostream>
     32 
     33 namespace tcu
     34 {
     35 
     36 /*--------------------------------------------------------------------*//*!
     37  * \brief Texture format
     38  *//*--------------------------------------------------------------------*/
     39 class TextureFormat
     40 {
     41 public:
     42 	enum ChannelOrder
     43 	{
     44 		R = 0,
     45 		A,
     46 		I,
     47 		L,
     48 		LA,
     49 		RG,
     50 		RA,
     51 		RGB,
     52 		RGBA,
     53 		ARGB,
     54 		BGRA,
     55 
     56 		sRGB,
     57 		sRGBA,
     58 
     59 		D,
     60 		S,
     61 		DS,
     62 
     63 		CHANNELORDER_LAST
     64 	};
     65 
     66 	enum ChannelType
     67 	{
     68 		SNORM_INT8 = 0,
     69 		SNORM_INT16,
     70 		SNORM_INT32,
     71 		UNORM_INT8,
     72 		UNORM_INT16,
     73 		UNORM_INT32,
     74 		UNORM_SHORT_565,
     75 		UNORM_SHORT_555,
     76 		UNORM_SHORT_4444,
     77 		UNORM_SHORT_5551,
     78 		UNORM_INT_101010,
     79 		UNORM_INT_1010102_REV,
     80 		UNSIGNED_INT_1010102_REV,
     81 		UNSIGNED_INT_11F_11F_10F_REV,
     82 		UNSIGNED_INT_999_E5_REV,
     83 		UNSIGNED_INT_24_8,
     84 		SIGNED_INT8,
     85 		SIGNED_INT16,
     86 		SIGNED_INT32,
     87 		UNSIGNED_INT8,
     88 		UNSIGNED_INT16,
     89 		UNSIGNED_INT32,
     90 		HALF_FLOAT,
     91 		FLOAT,
     92 		FLOAT_UNSIGNED_INT_24_8_REV,
     93 
     94 		CHANNELTYPE_LAST
     95 	};
     96 
     97 	ChannelOrder	order;
     98 	ChannelType		type;
     99 
    100 	TextureFormat (ChannelOrder order_, ChannelType type_)
    101 		: order	(order_)
    102 		, type	(type_)
    103 	{
    104 	}
    105 
    106 	TextureFormat (void)
    107 		: order	(CHANNELORDER_LAST)
    108 		, type	(CHANNELTYPE_LAST)
    109 	{
    110 	}
    111 
    112 	int getPixelSize (void) const;
    113 
    114 	bool operator== (const TextureFormat& other) const { return !(*this != other); }
    115 	bool operator!= (const TextureFormat& other) const
    116 	{
    117 		return (order != other.order || type != other.type);
    118 	}
    119 };
    120 
    121 /*--------------------------------------------------------------------*//*!
    122  * \brief Sampling parameters
    123  *//*--------------------------------------------------------------------*/
    124 class Sampler
    125 {
    126 public:
    127 	enum WrapMode
    128 	{
    129 		CLAMP_TO_EDGE = 0,	//! Clamp to edge
    130 		CLAMP_TO_BORDER,	//! Use border color at edge
    131 		REPEAT_GL,			//! Repeat with OpenGL semantics
    132 		REPEAT_CL,			//! Repeat with OpenCL semantics
    133 		MIRRORED_REPEAT_GL,	//! Mirrored repeat with OpenGL semantics
    134 		MIRRORED_REPEAT_CL, //! Mirrored repeat with OpenCL semantics
    135 
    136 		WRAPMODE_LAST
    137 	};
    138 
    139 	enum FilterMode
    140 	{
    141 		NEAREST = 0,
    142 		LINEAR,
    143 
    144 		NEAREST_MIPMAP_NEAREST,
    145 		NEAREST_MIPMAP_LINEAR,
    146 		LINEAR_MIPMAP_NEAREST,
    147 		LINEAR_MIPMAP_LINEAR,
    148 
    149 		FILTERMODE_LAST
    150 	};
    151 
    152 	enum CompareMode
    153 	{
    154 		COMPAREMODE_NONE = 0,
    155 		COMPAREMODE_LESS,
    156 		COMPAREMODE_LESS_OR_EQUAL,
    157 		COMPAREMODE_GREATER,
    158 		COMPAREMODE_GREATER_OR_EQUAL,
    159 		COMPAREMODE_EQUAL,
    160 		COMPAREMODE_NOT_EQUAL,
    161 		COMPAREMODE_ALWAYS,
    162 		COMPAREMODE_NEVER,
    163 
    164 		COMPAREMODE_LAST
    165 	};
    166 
    167 	// Wrap control
    168 	WrapMode		wrapS;
    169 	WrapMode		wrapT;
    170 	WrapMode		wrapR;
    171 
    172 	// Minifcation & magnification
    173 	FilterMode		minFilter;
    174 	FilterMode		magFilter;
    175 	float			lodThreshold;		// lod <= lodThreshold ? magnified : minified
    176 
    177 	// Coordinate normalization
    178 	bool			normalizedCoords;
    179 
    180 	// Shadow comparison
    181 	CompareMode		compare;
    182 	int				compareChannel;
    183 
    184 	// Border color
    185 	Vec4			borderColor;
    186 
    187 	// Seamless cube map filtering
    188 	bool			seamlessCubeMap;
    189 
    190 	Sampler (WrapMode		wrapS_,
    191 			 WrapMode		wrapT_,
    192 			 WrapMode		wrapR_,
    193 			 FilterMode		minFilter_,
    194 			 FilterMode		magFilter_,
    195 			 float			lodThreshold_		= 0.0f,
    196 			 bool			normalizedCoords_	= true,
    197 			 CompareMode	compare_			= COMPAREMODE_NONE,
    198 			 int			compareChannel_		= 0,
    199 			 const Vec4&	borderColor_		= Vec4(0.0f, 0.0f, 0.0f, 0.0f),
    200 			 bool			seamlessCubeMap_	= false)
    201 		: wrapS				(wrapS_)
    202 		, wrapT				(wrapT_)
    203 		, wrapR				(wrapR_)
    204 		, minFilter			(minFilter_)
    205 		, magFilter			(magFilter_)
    206 		, lodThreshold		(lodThreshold_)
    207 		, normalizedCoords	(normalizedCoords_)
    208 		, compare			(compare_)
    209 		, compareChannel	(compareChannel_)
    210 		, borderColor		(borderColor_)
    211 		, seamlessCubeMap	(seamlessCubeMap_)
    212 	{
    213 	}
    214 
    215 	Sampler (void)
    216 		: wrapS				(WRAPMODE_LAST)
    217 		, wrapT				(WRAPMODE_LAST)
    218 		, wrapR				(WRAPMODE_LAST)
    219 		, minFilter			(FILTERMODE_LAST)
    220 		, magFilter			(FILTERMODE_LAST)
    221 		, lodThreshold		(0.0f)
    222 		, normalizedCoords	(true)
    223 		, compare			(COMPAREMODE_NONE)
    224 		, compareChannel	(0)
    225 		, borderColor		(0.0f, 0.0f, 0.0f, 0.0f)
    226 		, seamlessCubeMap	(false)
    227 	{
    228 	}
    229 };
    230 
    231 class TextureLevel;
    232 
    233 /*--------------------------------------------------------------------*//*!
    234  * \brief Read-only pixel data access
    235  *
    236  * ConstPixelBufferAccess encapsulates pixel data pointer along with
    237  * format and layout information. It can be used for read-only access
    238  * to arbitrary pixel buffers.
    239  *
    240  * Access objects are like iterators or pointers. They can be passed around
    241  * as values and are valid as long as the storage doesn't change.
    242  *//*--------------------------------------------------------------------*/
    243 class ConstPixelBufferAccess
    244 {
    245 public:
    246 							ConstPixelBufferAccess		(void);
    247 							ConstPixelBufferAccess		(const TextureLevel& level);
    248 							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, const void* data);
    249 							ConstPixelBufferAccess		(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, const void* data);
    250 
    251 	const TextureFormat&	getFormat					(void) const	{ return m_format;		}
    252 	int						getWidth					(void) const	{ return m_width;		}
    253 	int						getHeight					(void) const	{ return m_height;		}
    254 	int						getDepth					(void) const	{ return m_depth;		}
    255 	int						getRowPitch					(void) const	{ return m_rowPitch;	}
    256 	int						getSlicePitch				(void) const	{ return m_slicePitch;	}
    257 
    258 	const void*				getDataPtr					(void) const	{ return m_data;		}
    259 	int						getDataSize					(void) const	{ return m_depth*m_slicePitch;	}
    260 
    261 	Vec4					getPixel					(int x, int y, int z = 0) const;
    262 	IVec4					getPixelInt					(int x, int y, int z = 0) const;
    263 	UVec4					getPixelUint				(int x, int y, int z = 0) const { return getPixelInt(x, y, z).cast<deUint32>(); }
    264 
    265 	template<typename T>
    266 	Vector<T, 4>			getPixelT					(int x, int y, int z = 0) const;
    267 
    268 	float					getPixDepth					(int x, int y, int z = 0) const;
    269 	int						getPixStencil				(int x, int y, int z = 0) const;
    270 
    271 	Vec4					sample1D					(const Sampler& sampler, Sampler::FilterMode filter, float s, int level) const;
    272 	Vec4					sample2D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, int depth) const;
    273 	Vec4					sample3D					(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r) const;
    274 
    275 	Vec4					sample1DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, const IVec2& offset) const;
    276 	Vec4					sample2DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, const IVec3& offset) const;
    277 	Vec4					sample3DOffset				(const Sampler& sampler, Sampler::FilterMode filter, float s, float t, float r, const IVec3& offset) const;
    278 
    279 	float					sample1DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, const IVec2& offset) const;
    280 	float					sample2DCompare				(const Sampler& sampler, Sampler::FilterMode filter, float ref, float s, float t, const IVec3& offset) const;
    281 
    282 protected:
    283 	TextureFormat			m_format;
    284 	int						m_width;
    285 	int						m_height;
    286 	int						m_depth;
    287 	int						m_rowPitch;
    288 	int						m_slicePitch;
    289 	mutable void*			m_data;
    290 };
    291 
    292 /*--------------------------------------------------------------------*//*!
    293  * \brief Read-write pixel data access
    294  *
    295  * This class extends read-only access object by providing write functionality.
    296  *
    297  * \note PixelBufferAccess may not have any data members nor add any
    298  *		 virtual functions. It must be possible to reinterpret_cast<>
    299  *		 PixelBufferAccess to ConstPixelBufferAccess.
    300  *//*--------------------------------------------------------------------*/
    301 class PixelBufferAccess : public ConstPixelBufferAccess
    302 {
    303 public:
    304 							PixelBufferAccess			(void) {}
    305 							PixelBufferAccess			(TextureLevel& level);
    306 							PixelBufferAccess			(const TextureFormat& format, int width, int height, int depth, void* data);
    307 							PixelBufferAccess			(const TextureFormat& format, int width, int height, int depth, int rowPitch, int slicePitch, void* data);
    308 
    309 	void*					getDataPtr					(void) const { return m_data; }
    310 
    311 	void					setPixels					(const void* buf, int bufSize) const;
    312 	void					setPixel					(const tcu::Vec4& color, int x, int y, int z = 0) const;
    313 	void					setPixel					(const tcu::IVec4& color, int x, int y, int z = 0) const;
    314 	void					setPixel					(const tcu::UVec4& color, int x, int y, int z = 0) const { setPixel(color.cast<int>(), x, y, z); }
    315 
    316 	void					setPixDepth					(float depth, int x, int y, int z = 0) const;
    317 	void					setPixStencil				(int stencil, int x, int y, int z = 0) const;
    318 };
    319 
    320 /*--------------------------------------------------------------------*//*!
    321  * \brief Generic pixel data container
    322  *
    323  * This container supports all valid TextureFormat combinations and
    324  * both 2D and 3D textures. To read or manipulate data access object must
    325  * be queried using getAccess().
    326  *//*--------------------------------------------------------------------*/
    327 class TextureLevel
    328 {
    329 public:
    330 							TextureLevel		(void);
    331 							TextureLevel		(const TextureFormat& format);
    332 							TextureLevel		(const TextureFormat& format, int width, int height, int depth = 1);
    333 							~TextureLevel		(void);
    334 
    335 	int						getWidth			(void) const	{ return m_width;	}
    336 	int						getHeight			(void) const	{ return m_height;	}
    337 	int						getDepth			(void) const	{ return m_depth;	}
    338 	bool					isEmpty				(void) const	{ return m_width == 0 || m_height == 0 || m_depth == 0; }
    339 	const TextureFormat		getFormat			(void) const	{ return m_format;	}
    340 
    341 	void					setStorage			(const TextureFormat& format, int width, int heigth, int depth = 1);
    342 	void					setSize				(int width, int height, int depth = 1);
    343 
    344 	PixelBufferAccess		getAccess			(void)			{ return PixelBufferAccess(m_format, m_width, m_height, m_depth, getPtr());			}
    345 	ConstPixelBufferAccess	getAccess			(void) const	{ return ConstPixelBufferAccess(m_format, m_width, m_height, m_depth, getPtr());	}
    346 
    347 private:
    348 	void*					getPtr				(void)			{ return m_data.getPtr(); }
    349 	const void*				getPtr				(void) const	{ return m_data.getPtr(); }
    350 
    351 	TextureFormat			m_format;
    352 	int						m_width;
    353 	int						m_height;
    354 	int						m_depth;
    355 	de::ArrayBuffer<deUint8> m_data;
    356 
    357 	friend class ConstPixelBufferAccess;
    358 };
    359 
    360 Vec4	sampleLevelArray1D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, int level, float lod);
    361 Vec4	sampleLevelArray2D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, int depth, float lod);
    362 Vec4	sampleLevelArray3D				(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod);
    363 
    364 Vec4	sampleLevelArray1DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float lod, const IVec2& offset);
    365 Vec4	sampleLevelArray2DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float lod, const IVec3& offset);
    366 Vec4	sampleLevelArray3DOffset		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset);
    367 
    368 float	sampleLevelArray1DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float lod, const IVec2& offset);
    369 float	sampleLevelArray2DCompare		(const ConstPixelBufferAccess* levels, int numLevels, const Sampler& sampler, float ref, float s, float t, float lod, const IVec3& offset);
    370 
    371 Vec4	gatherArray2DOffsets			(const ConstPixelBufferAccess& src, const Sampler& sampler, float s, float t, int depth, int componentNdx, const IVec2 (&offsets)[4]);
    372 Vec4	gatherArray2DOffsetsCompare		(const ConstPixelBufferAccess& src, const Sampler& sampler, float ref, float s, float t, int depth, const IVec2 (&offsets)[4]);
    373 
    374 enum CubeFace
    375 {
    376 	CUBEFACE_NEGATIVE_X = 0,
    377 	CUBEFACE_POSITIVE_X,
    378 	CUBEFACE_NEGATIVE_Y,
    379 	CUBEFACE_POSITIVE_Y,
    380 	CUBEFACE_NEGATIVE_Z,
    381 	CUBEFACE_POSITIVE_Z,
    382 
    383 	CUBEFACE_LAST
    384 };
    385 
    386 /*--------------------------------------------------------------------*//*!
    387  * \brief Coordinates projected onto cube face.
    388  *//*--------------------------------------------------------------------*/
    389 template<typename T>
    390 struct CubeFaceCoords
    391 {
    392 	CubeFace		face;
    393 	T				s;
    394 	T				t;
    395 
    396 					CubeFaceCoords		(CubeFace face_, T s_, T t_) : face(face_), s(s_), t(t_) {}
    397 					CubeFaceCoords		(CubeFace face_, const Vector<T, 2>& c) : face(face_), s(c.x()), t(c.y()) {}
    398 };
    399 
    400 typedef CubeFaceCoords<float>	CubeFaceFloatCoords;
    401 typedef CubeFaceCoords<int>		CubeFaceIntCoords;
    402 
    403 CubeFace				selectCubeFace			(const Vec3& coords);
    404 Vec2					projectToFace			(CubeFace face, const Vec3& coords);
    405 CubeFaceFloatCoords		getCubeFaceCoords		(const Vec3& coords);
    406 CubeFaceIntCoords		remapCubeEdgeCoords		(const CubeFaceIntCoords& coords, int size);
    407 
    408 /*--------------------------------------------------------------------*//*!
    409  * \brief 1D Texture View
    410  *//*--------------------------------------------------------------------*/
    411 class Texture1DView
    412 {
    413 public:
    414 									Texture1DView		(int numLevels, const ConstPixelBufferAccess* levels);
    415 
    416 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    417 	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
    418 	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
    419 	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
    420 
    421 	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
    422 	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
    423 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float lod) const;
    424 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const;
    425 
    426 protected:
    427 	int								m_numLevels;
    428 	const ConstPixelBufferAccess*	m_levels;
    429 };
    430 
    431 inline Texture1DView::Texture1DView (int numLevels, const ConstPixelBufferAccess* levels)
    432 	: m_numLevels	(numLevels)
    433 	, m_levels		(levels)
    434 {
    435 	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
    436 }
    437 
    438 inline Vec4 Texture1DView::sample (const Sampler& sampler, float s, float lod) const
    439 {
    440 	return sampleLevelArray1D(m_levels, m_numLevels, sampler, s, 0 /* depth */, lod);
    441 }
    442 
    443 inline Vec4 Texture1DView::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
    444 {
    445 	return sampleLevelArray1DOffset(m_levels, m_numLevels, sampler, s, lod, IVec2(offset, 0));
    446 }
    447 
    448 inline float Texture1DView::sampleCompare (const Sampler& sampler, float ref, float s, float lod) const
    449 {
    450 	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(0, 0));
    451 }
    452 
    453 inline float Texture1DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float lod, deInt32 offset) const
    454 {
    455 	return sampleLevelArray1DCompare(m_levels, m_numLevels, sampler, ref, s, lod, IVec2(offset, 0));
    456 }
    457 
    458 /*--------------------------------------------------------------------*//*!
    459  * \brief 2D Texture View
    460  *//*--------------------------------------------------------------------*/
    461 class Texture2DView
    462 {
    463 public:
    464 									Texture2DView		(int numLevels, const ConstPixelBufferAccess* levels);
    465 
    466 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    467 	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
    468 	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
    469 	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
    470 	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
    471 
    472 	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
    473 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
    474 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
    475 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
    476 
    477 	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
    478 	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
    479 
    480 protected:
    481 	int								m_numLevels;
    482 	const ConstPixelBufferAccess*	m_levels;
    483 };
    484 
    485 inline Texture2DView::Texture2DView (int numLevels, const ConstPixelBufferAccess* levels)
    486 	: m_numLevels	(numLevels)
    487 	, m_levels		(levels)
    488 {
    489 	DE_ASSERT(m_numLevels >= 0 && ((m_numLevels == 0) == !m_levels));
    490 }
    491 
    492 inline Vec4 Texture2DView::sample (const Sampler& sampler, float s, float t, float lod) const
    493 {
    494 	return sampleLevelArray2D(m_levels, m_numLevels, sampler, s, t, 0 /* depth */, lod);
    495 }
    496 
    497 inline Vec4 Texture2DView::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
    498 {
    499 	return sampleLevelArray2DOffset(m_levels, m_numLevels, sampler, s, t, lod, IVec3(offset.x(), offset.y(), 0));
    500 }
    501 
    502 inline float Texture2DView::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
    503 {
    504 	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(0, 0, 0));
    505 }
    506 
    507 inline float Texture2DView::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
    508 {
    509 	return sampleLevelArray2DCompare(m_levels, m_numLevels, sampler, ref, s, t, lod, IVec3(offset.x(), offset.y(), 0));
    510 }
    511 
    512 inline Vec4 Texture2DView::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
    513 {
    514 	return gatherArray2DOffsets(m_levels[0], sampler, s, t, 0, componentNdx, offsets);
    515 }
    516 
    517 inline Vec4 Texture2DView::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
    518 {
    519 	return gatherArray2DOffsetsCompare(m_levels[0], sampler, ref, s, t, 0, offsets);
    520 }
    521 
    522 /*--------------------------------------------------------------------*//*!
    523  * \brief Base class for textures that have single mip-map pyramid
    524  *//*--------------------------------------------------------------------*/
    525 class TextureLevelPyramid
    526 {
    527 public:
    528 									TextureLevelPyramid	(const TextureFormat& format, int numLevels);
    529 									TextureLevelPyramid	(const TextureLevelPyramid& other);
    530 									~TextureLevelPyramid(void);
    531 
    532 	const TextureFormat&			getFormat			(void) const			{ return m_format;					}
    533 	bool							isLevelEmpty		(int levelNdx) const	{ return m_data[levelNdx].empty();	}
    534 
    535 	int								getNumLevels		(void) const			{ return (int)m_access.size();		}
    536 	const ConstPixelBufferAccess&	getLevel			(int ndx) const			{ return m_access[ndx];				}
    537 	const PixelBufferAccess&		getLevel			(int ndx)				{ return m_access[ndx];				}
    538 
    539 	const ConstPixelBufferAccess*	getLevels			(void) const			{ return &m_access[0];				}
    540 	const PixelBufferAccess*		getLevels			(void)					{ return &m_access[0];				}
    541 
    542 	void							allocLevel			(int levelNdx, int width, int height, int depth);
    543 	void							clearLevel			(int levelNdx);
    544 
    545 	TextureLevelPyramid&			operator=			(const TextureLevelPyramid& other);
    546 
    547 private:
    548 	typedef de::ArrayBuffer<deUint8> LevelData;
    549 
    550 	TextureFormat					m_format;
    551 	std::vector<LevelData>			m_data;
    552 	std::vector<PixelBufferAccess>	m_access;
    553 };
    554 
    555 /*--------------------------------------------------------------------*//*!
    556  * \brief 1D Texture reference implementation
    557  *//*--------------------------------------------------------------------*/
    558 class Texture1D : private TextureLevelPyramid
    559 {
    560 public:
    561 									Texture1D			(const TextureFormat& format, int width);
    562 									Texture1D			(const Texture1D& other);
    563 									~Texture1D			(void);
    564 
    565 	int								getWidth			(void) const	{ return m_width;	}
    566 	const Texture1DView&			getView				(void) const	{ return m_view;	}
    567 
    568 	void							allocLevel			(int levelNdx);
    569 
    570 	// Sampling
    571 	Vec4							sample				(const Sampler& sampler, float s, float lod) const;
    572 	Vec4							sampleOffset		(const Sampler& sampler, float s, float lod, deInt32 offset) const;
    573 
    574 	using TextureLevelPyramid::getFormat;
    575 	using TextureLevelPyramid::getNumLevels;
    576 	using TextureLevelPyramid::getLevel;
    577 	using TextureLevelPyramid::clearLevel;
    578 	using TextureLevelPyramid::isLevelEmpty;
    579 
    580 	Texture1D&						operator=			(const Texture1D& other);
    581 
    582 	operator Texture1DView (void) const { return m_view; }
    583 
    584 private:
    585 	int								m_width;
    586 	Texture1DView					m_view;
    587 };
    588 
    589 inline Vec4 Texture1D::sample (const Sampler& sampler, float s, float lod) const
    590 {
    591 	return m_view.sample(sampler, s, lod);
    592 }
    593 
    594 inline Vec4 Texture1D::sampleOffset (const Sampler& sampler, float s, float lod, deInt32 offset) const
    595 {
    596 	return m_view.sampleOffset(sampler, s, lod, offset);
    597 }
    598 
    599 /*--------------------------------------------------------------------*//*!
    600  * \brief 2D Texture reference implementation
    601  *//*--------------------------------------------------------------------*/
    602 class Texture2D : private TextureLevelPyramid
    603 {
    604 public:
    605 									Texture2D			(const TextureFormat& format, int width, int height);
    606 									Texture2D			(const Texture2D& other);
    607 									~Texture2D			(void);
    608 
    609 	int								getWidth			(void) const	{ return m_width;	}
    610 	int								getHeight			(void) const	{ return m_height;	}
    611 	const Texture2DView&			getView				(void) const	{ return m_view;	}
    612 
    613 	void							allocLevel			(int levelNdx);
    614 
    615 	// Sampling
    616 	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
    617 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const;
    618 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
    619 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const;
    620 
    621 	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const;
    622 	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const;
    623 
    624 	using TextureLevelPyramid::getFormat;
    625 	using TextureLevelPyramid::getNumLevels;
    626 	using TextureLevelPyramid::getLevel;
    627 	using TextureLevelPyramid::clearLevel;
    628 	using TextureLevelPyramid::isLevelEmpty;
    629 
    630 	Texture2D&						operator=			(const Texture2D& other);
    631 
    632 	operator Texture2DView (void) const { return m_view; }
    633 
    634 private:
    635 	int								m_width;
    636 	int								m_height;
    637 	Texture2DView					m_view;
    638 };
    639 
    640 inline Vec4 Texture2D::sample (const Sampler& sampler, float s, float t, float lod) const
    641 {
    642 	return m_view.sample(sampler, s, t, lod);
    643 }
    644 
    645 inline Vec4 Texture2D::sampleOffset (const Sampler& sampler, float s, float t, float lod, const IVec2& offset) const
    646 {
    647 	return m_view.sampleOffset(sampler, s, t, lod, offset);
    648 }
    649 
    650 inline float Texture2D::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
    651 {
    652 	return m_view.sampleCompare(sampler, ref, s, t, lod);
    653 }
    654 
    655 inline float Texture2D::sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, const IVec2& offset) const
    656 {
    657 	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
    658 }
    659 
    660 inline Vec4 Texture2D::gatherOffsets (const Sampler& sampler, float s, float t, int componentNdx, const IVec2 (&offsets)[4]) const
    661 {
    662 	return m_view.gatherOffsets(sampler, s, t, componentNdx, offsets);
    663 }
    664 
    665 inline Vec4 Texture2D::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, const IVec2 (&offsets)[4]) const
    666 {
    667 	return m_view.gatherOffsetsCompare(sampler, ref, s, t, offsets);
    668 }
    669 
    670 /*--------------------------------------------------------------------*//*!
    671  * \brief Cube Map Texture View
    672  *//*--------------------------------------------------------------------*/
    673 class TextureCubeView
    674 {
    675 public:
    676 									TextureCubeView		(void);
    677 									TextureCubeView		(int numLevels, const ConstPixelBufferAccess* const (&levels)[CUBEFACE_LAST]);
    678 
    679 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    680 	int								getSize				(void) const	{ return m_numLevels > 0 ? m_levels[0][0].getWidth() : 0;	}
    681 	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[face][ndx];	}
    682 	const ConstPixelBufferAccess*	getFaceLevels		(CubeFace face) const			{ return m_levels[face];					}
    683 
    684 	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
    685 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
    686 
    687 	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
    688 	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
    689 
    690 protected:
    691 	int								m_numLevels;
    692 	const ConstPixelBufferAccess*	m_levels[CUBEFACE_LAST];
    693 };
    694 
    695 /*--------------------------------------------------------------------*//*!
    696  * \brief Cube Map Texture reference implementation
    697  *//*--------------------------------------------------------------------*/
    698 class TextureCube
    699 {
    700 public:
    701 									TextureCube			(const TextureFormat& format, int size);
    702 									TextureCube			(const TextureCube& other);
    703 									~TextureCube		(void);
    704 
    705 	const TextureFormat&			getFormat			(void) const	{ return m_format;	}
    706 	int								getSize				(void) const	{ return m_size;	}
    707 
    708 	int								getNumLevels		(void) const					{ return (int)m_access[0].size();	}
    709 	const ConstPixelBufferAccess&	getLevelFace		(int ndx, CubeFace face) const	{ return m_access[face][ndx];		}
    710 	const PixelBufferAccess&		getLevelFace		(int ndx, CubeFace face)		{ return m_access[face][ndx];		}
    711 
    712 	void							allocLevel			(CubeFace face, int levelNdx);
    713 	void							clearLevel			(CubeFace face, int levelNdx);
    714 	bool							isLevelEmpty		(CubeFace face, int levelNdx) const		{ return m_data[face][levelNdx].empty();	}
    715 
    716 	Vec4							sample				(const Sampler& sampler, float s, float t, float p, float lod) const;
    717 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
    718 
    719 	Vec4							gather				(const Sampler& sampler, float s, float t, float r, int componentNdx) const;
    720 	Vec4							gatherCompare		(const Sampler& sampler, float ref, float s, float t, float r) const;
    721 
    722 	TextureCube&					operator=			(const TextureCube& other);
    723 
    724 	operator TextureCubeView (void) const { return m_view; }
    725 
    726 private:
    727 	typedef de::ArrayBuffer<deUint8> LevelData;
    728 
    729 	TextureFormat					m_format;
    730 	int								m_size;
    731 	std::vector<LevelData>			m_data[CUBEFACE_LAST];
    732 	std::vector<PixelBufferAccess>	m_access[CUBEFACE_LAST];
    733 	TextureCubeView					m_view;
    734 };
    735 
    736 inline Vec4 TextureCube::sample (const Sampler& sampler, float s, float t, float p, float lod) const
    737 {
    738 	return m_view.sample(sampler, s, t, p, lod);
    739 }
    740 
    741 inline float TextureCube::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
    742 {
    743 	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
    744 }
    745 
    746 inline Vec4 TextureCube::gather (const Sampler& sampler, float s, float t, float r, int componentNdx) const
    747 {
    748 	return m_view.gather(sampler, s, t, r, componentNdx);
    749 }
    750 
    751 inline Vec4 TextureCube::gatherCompare (const Sampler& sampler, float ref, float s, float t, float r) const
    752 {
    753 	return m_view.gatherCompare(sampler, ref, s, t, r);
    754 }
    755 
    756 /*--------------------------------------------------------------------*//*!
    757  * \brief 1D Array Texture View
    758  *//*--------------------------------------------------------------------*/
    759 class Texture1DArrayView
    760 {
    761 public:
    762 									Texture1DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
    763 
    764 	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
    765 	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
    766 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    767 	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
    768 	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
    769 
    770 	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
    771 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
    772 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
    773 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
    774 
    775 protected:
    776 	int								selectLayer			(float r) const;
    777 
    778 	int								m_numLevels;
    779 	const ConstPixelBufferAccess*	m_levels;
    780 };
    781 
    782 /*--------------------------------------------------------------------*//*!
    783  * \brief 2D Array Texture View
    784  *//*--------------------------------------------------------------------*/
    785 class Texture2DArrayView
    786 {
    787 public:
    788 									Texture2DArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
    789 
    790 	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
    791 	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
    792 	int								getNumLayers		(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
    793 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    794 	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
    795 	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
    796 
    797 	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
    798 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
    799 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
    800 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
    801 
    802 	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
    803 	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
    804 
    805 protected:
    806 	int								selectLayer			(float r) const;
    807 
    808 	int								m_numLevels;
    809 	const ConstPixelBufferAccess*	m_levels;
    810 };
    811 
    812 /*--------------------------------------------------------------------*//*!
    813  * \brief 1D Array Texture reference implementation
    814  *//*--------------------------------------------------------------------*/
    815 class Texture1DArray : private TextureLevelPyramid
    816 {
    817 public:
    818 									Texture1DArray		(const TextureFormat& format, int width, int numLayers);
    819 									Texture1DArray		(const Texture1DArray& other);
    820 									~Texture1DArray		(void);
    821 
    822 	int								getWidth			(void) const	{ return m_width;		}
    823 	int								getNumLayers		(void) const	{ return m_numLayers;	}
    824 
    825 	void							allocLevel			(int levelNdx);
    826 
    827 	using TextureLevelPyramid::getFormat;
    828 	using TextureLevelPyramid::getNumLevels;
    829 	using TextureLevelPyramid::getLevel;
    830 	using TextureLevelPyramid::clearLevel;
    831 	using TextureLevelPyramid::isLevelEmpty;
    832 
    833 	Vec4							sample				(const Sampler& sampler, float s, float t, float lod) const;
    834 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float lod, deInt32 offset) const;
    835 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float lod) const;
    836 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const;
    837 
    838 	Texture1DArray&					operator=			(const Texture1DArray& other);
    839 
    840 	operator Texture1DArrayView (void) const { return m_view; }
    841 
    842 private:
    843 	int								m_width;
    844 	int								m_numLayers;
    845 	Texture1DArrayView				m_view;
    846 };
    847 
    848 inline Vec4 Texture1DArray::sample (const Sampler& sampler, float s, float t, float lod) const
    849 {
    850 	return m_view.sample(sampler, s, t, lod);
    851 }
    852 
    853 inline Vec4 Texture1DArray::sampleOffset (const Sampler& sampler, float s, float t, float lod, deInt32 offset) const
    854 {
    855 	return m_view.sampleOffset(sampler, s, t, lod, offset);
    856 }
    857 
    858 inline float Texture1DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float lod) const
    859 {
    860 	return m_view.sampleCompare(sampler, ref, s, t, lod);
    861 }
    862 
    863 inline float Texture1DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float lod, deInt32 offset) const
    864 {
    865 	return m_view.sampleCompareOffset(sampler, ref, s, t, lod, offset);
    866 }
    867 
    868 /*--------------------------------------------------------------------*//*!
    869  * \brief 2D Array Texture reference implementation
    870  *//*--------------------------------------------------------------------*/
    871 class Texture2DArray : private TextureLevelPyramid
    872 {
    873 public:
    874 									Texture2DArray		(const TextureFormat& format, int width, int height, int numLayers);
    875 									Texture2DArray		(const Texture2DArray& other);
    876 									~Texture2DArray		(void);
    877 
    878 	int								getWidth			(void) const	{ return m_width;		}
    879 	int								getHeight			(void) const	{ return m_height;		}
    880 	int								getNumLayers		(void) const	{ return m_numLayers;	}
    881 
    882 	void							allocLevel			(int levelNdx);
    883 
    884 	using TextureLevelPyramid::getFormat;
    885 	using TextureLevelPyramid::getNumLevels;
    886 	using TextureLevelPyramid::getLevel;
    887 	using TextureLevelPyramid::clearLevel;
    888 	using TextureLevelPyramid::isLevelEmpty;
    889 
    890 	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
    891 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const;
    892 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float lod) const;
    893 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const;
    894 
    895 	Vec4							gatherOffsets		(const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const;
    896 	Vec4							gatherOffsetsCompare(const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const;
    897 
    898 	Texture2DArray&					operator=			(const Texture2DArray& other);
    899 
    900 	operator Texture2DArrayView (void) const { return m_view; }
    901 
    902 private:
    903 	int								m_width;
    904 	int								m_height;
    905 	int								m_numLayers;
    906 	Texture2DArrayView				m_view;
    907 };
    908 
    909 inline Vec4 Texture2DArray::sample (const Sampler& sampler, float s, float t, float r, float lod) const
    910 {
    911 	return m_view.sample(sampler, s, t, r, lod);
    912 }
    913 
    914 inline Vec4 Texture2DArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec2& offset) const
    915 {
    916 	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
    917 }
    918 
    919 inline float Texture2DArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float lod) const
    920 {
    921 	return m_view.sampleCompare(sampler, ref, s, t, r, lod);
    922 }
    923 
    924 inline float Texture2DArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float lod, const IVec2& offset) const
    925 {
    926 	return m_view.sampleCompareOffset(sampler, ref, s, t, r, lod, offset);
    927 }
    928 
    929 inline Vec4 Texture2DArray::gatherOffsets (const Sampler& sampler, float s, float t, float r, int componentNdx, const IVec2 (&offsets)[4]) const
    930 {
    931 	return m_view.gatherOffsets(sampler, s, t, r, componentNdx, offsets);
    932 }
    933 
    934 inline Vec4 Texture2DArray::gatherOffsetsCompare (const Sampler& sampler, float ref, float s, float t, float r, const IVec2 (&offsets)[4]) const
    935 {
    936 	return m_view.gatherOffsetsCompare(sampler, ref, s, t, r, offsets);
    937 }
    938 
    939 /*--------------------------------------------------------------------*//*!
    940  * \brief 3D Texture View
    941  *//*--------------------------------------------------------------------*/
    942 class Texture3DView
    943 {
    944 public:
    945 									Texture3DView		(int numLevels, const ConstPixelBufferAccess* levels);
    946 
    947 	int								getWidth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
    948 	int								getHeight			(void) const	{ return m_numLevels > 0 ? m_levels[0].getHeight()	: 0;	}
    949 	int								getDepth			(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
    950 	int								getNumLevels		(void) const	{ return m_numLevels;										}
    951 	const ConstPixelBufferAccess&	getLevel			(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
    952 	const ConstPixelBufferAccess*	getLevels			(void) const	{ return m_levels;											}
    953 
    954 	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
    955 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
    956 
    957 protected:
    958 	int								m_numLevels;
    959 	const ConstPixelBufferAccess*	m_levels;
    960 };
    961 
    962 inline Vec4 Texture3DView::sample (const Sampler& sampler, float s, float t, float r, float lod) const
    963 {
    964 	return sampleLevelArray3D(m_levels, m_numLevels, sampler, s, t, r, lod);
    965 }
    966 
    967 inline Vec4 Texture3DView::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
    968 {
    969 	return sampleLevelArray3DOffset(m_levels, m_numLevels, sampler, s, t, r, lod, offset);
    970 }
    971 
    972 /*--------------------------------------------------------------------*//*!
    973  * \brief 3D Texture reference implementation
    974  *//*--------------------------------------------------------------------*/
    975 class Texture3D : private TextureLevelPyramid
    976 {
    977 public:
    978 									Texture3D			(const TextureFormat& format, int width, int height, int depth);
    979 									Texture3D			(const Texture3D& other);
    980 									~Texture3D			(void);
    981 
    982 	int								getWidth			(void) const	{ return m_width;	}
    983 	int								getHeight			(void) const	{ return m_height;	}
    984 	int								getDepth			(void) const	{ return m_depth;	}
    985 
    986 	void							allocLevel			(int levelNdx);
    987 
    988 	using TextureLevelPyramid::getFormat;
    989 	using TextureLevelPyramid::getNumLevels;
    990 	using TextureLevelPyramid::getLevel;
    991 	using TextureLevelPyramid::clearLevel;
    992 	using TextureLevelPyramid::isLevelEmpty;
    993 
    994 	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float lod) const;
    995 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const;
    996 
    997 	Texture3D&						operator=			(const Texture3D& other);
    998 
    999 	operator Texture3DView (void) const { return m_view; }
   1000 
   1001 private:
   1002 	int								m_width;
   1003 	int								m_height;
   1004 	int								m_depth;
   1005 	Texture3DView					m_view;
   1006 };
   1007 
   1008 inline Vec4 Texture3D::sample (const Sampler& sampler, float s, float t, float r, float lod) const
   1009 {
   1010 	return m_view.sample(sampler, s, t, r, lod);
   1011 }
   1012 
   1013 inline Vec4 Texture3D::sampleOffset (const Sampler& sampler, float s, float t, float r, float lod, const IVec3& offset) const
   1014 {
   1015 	return m_view.sampleOffset(sampler, s, t, r, lod, offset);
   1016 }
   1017 
   1018 /*--------------------------------------------------------------------*//*!
   1019  * \brief Cube Map Array Texture View
   1020  *//*--------------------------------------------------------------------*/
   1021 class TextureCubeArrayView
   1022 {
   1023 public:
   1024 									TextureCubeArrayView	(int numLevels, const ConstPixelBufferAccess* levels);
   1025 
   1026 	int								getSize					(void) const	{ return m_numLevels > 0 ? m_levels[0].getWidth()	: 0;	}
   1027 	int								getDepth				(void) const	{ return m_numLevels > 0 ? m_levels[0].getDepth()	: 0;	}
   1028 	int								getNumLayers			(void) const	{ return getDepth()	/ 6;	}
   1029 	int								getNumLevels			(void) const	{ return m_numLevels;										}
   1030 	const ConstPixelBufferAccess&	getLevel				(int ndx) const	{ DE_ASSERT(de::inBounds(ndx, 0, m_numLevels)); return m_levels[ndx];	}
   1031 	const ConstPixelBufferAccess*	getLevels				(void) const	{ return m_levels;											}
   1032 
   1033 	Vec4							sample					(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
   1034 	Vec4							sampleOffset			(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
   1035 	float							sampleCompare			(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
   1036 	float							sampleCompareOffset		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
   1037 
   1038 protected:
   1039 	int								selectLayer				(float q) const;
   1040 
   1041 	int								m_numLevels;
   1042 	const ConstPixelBufferAccess*	m_levels;
   1043 };
   1044 
   1045 /*--------------------------------------------------------------------*//*!
   1046  * \brief Cube Map Array Texture reference implementation
   1047  *//*--------------------------------------------------------------------*/
   1048 class TextureCubeArray : private TextureLevelPyramid
   1049 {
   1050 public:
   1051 									TextureCubeArray	(const TextureFormat& format, int size, int depth);
   1052 									TextureCubeArray	(const TextureCubeArray& other);
   1053 									~TextureCubeArray	(void);
   1054 
   1055 	int								getSize				(void) const	{ return m_size;	}
   1056 	int								getDepth			(void) const	{ return m_depth;	}
   1057 
   1058 	void							allocLevel			(int levelNdx);
   1059 
   1060 	using TextureLevelPyramid::getFormat;
   1061 	using TextureLevelPyramid::getNumLevels;
   1062 	using TextureLevelPyramid::getLevel;
   1063 	using TextureLevelPyramid::clearLevel;
   1064 	using TextureLevelPyramid::isLevelEmpty;
   1065 
   1066 	Vec4							sample				(const Sampler& sampler, float s, float t, float r, float q, float lod) const;
   1067 	Vec4							sampleOffset		(const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const;
   1068 	float							sampleCompare		(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const;
   1069 	float							sampleCompareOffset	(const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const;
   1070 
   1071 	TextureCubeArray&				operator=			(const TextureCubeArray& other);
   1072 
   1073 	operator TextureCubeArrayView (void) const { return m_view; }
   1074 
   1075 private:
   1076 	int								m_size;
   1077 	int								m_depth;
   1078 	TextureCubeArrayView			m_view;
   1079 };
   1080 
   1081 inline Vec4 TextureCubeArray::sample (const Sampler& sampler, float s, float t, float r, float q, float lod) const
   1082 {
   1083 	return m_view.sample(sampler, s, t, r, q, lod);
   1084 }
   1085 
   1086 inline Vec4 TextureCubeArray::sampleOffset (const Sampler& sampler, float s, float t, float r, float q, float lod, const IVec2& offset) const
   1087 {
   1088 	return m_view.sampleOffset(sampler, s, t, r, q, lod, offset);
   1089 }
   1090 
   1091 inline float TextureCubeArray::sampleCompare (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod) const
   1092 {
   1093 	return m_view.sampleCompare(sampler, ref, s, t, r, q, lod);
   1094 }
   1095 
   1096 inline float TextureCubeArray::sampleCompareOffset (const Sampler& sampler, float ref, float s, float t, float r, float q, float lod, const IVec2& offset) const
   1097 {
   1098 	return m_view.sampleCompareOffset(sampler, ref, s, t, r, q, lod, offset);
   1099 }
   1100 
   1101 // Stream operators.
   1102 std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelOrder order);
   1103 std::ostream&		operator<<		(std::ostream& str, TextureFormat::ChannelType type);
   1104 std::ostream&		operator<<		(std::ostream& str, TextureFormat format);
   1105 std::ostream&		operator<<		(std::ostream& str, CubeFace face);
   1106 std::ostream&		operator<<		(std::ostream& str, const ConstPixelBufferAccess& access);
   1107 
   1108 } // tcu
   1109 
   1110 #endif // _TCUTEXTURE_HPP
   1111