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