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