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