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