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