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