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