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