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