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