1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 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 Texture access and query function tests.
24 *//*--------------------------------------------------------------------*/
25
26#include "vktShaderRenderTextureFunctionTests.hpp"
27#include "vktShaderRender.hpp"
28#include "gluTextureUtil.hpp"
29#include "tcuTexture.hpp"
30#include "tcuTextureUtil.hpp"
31#include "tcuTestLog.hpp"
32#include "tcuCommandLine.hpp"
33#include "glwEnums.hpp"
34#include "deMath.h"
35#include "vkBarrierUtil.hpp"
36#include "vkImageUtil.hpp"
37#include "vkQueryUtil.hpp"
38#include "vkObjUtil.hpp"
39#include "vkCmdUtil.hpp"
40#include <limits>
41
42namespace vkt
43{
44namespace sr
45{
46namespace
47{
48
49using tcu::Vec2;
50using tcu::Vec3;
51using tcu::Vec4;
52using tcu::IVec2;
53using tcu::IVec3;
54using tcu::IVec4;
55
56using std::vector;
57
58enum Function
59{
60	FUNCTION_TEXTURE = 0,		//!< texture(), textureOffset(), textureClampARB, textureOffsetClampARB
61	FUNCTION_TEXTUREPROJ,		//!< textureProj(), textureProjOffset()
62	FUNCTION_TEXTUREPROJ2,		//!< textureProj(sampler1D, vec2)
63	FUNCTION_TEXTUREPROJ3,		//!< textureProj(sampler2D, vec3)
64	FUNCTION_TEXTURELOD,		// ...
65	FUNCTION_TEXTUREPROJLOD,
66	FUNCTION_TEXTUREPROJLOD2,	//!< textureProjLod(sampler1D, vec2)
67	FUNCTION_TEXTUREPROJLOD3,	//!< textureProjLod(sampler2D, vec3)
68	FUNCTION_TEXTUREGRAD,		//!< textureGrad, textureGradOffset, textureGradClampARB, textureGradOffsetClampARB
69	FUNCTION_TEXTUREPROJGRAD,
70	FUNCTION_TEXTUREPROJGRAD2,	//!< textureProjGrad(sampler1D, vec2)
71	FUNCTION_TEXTUREPROJGRAD3,	//!< textureProjGrad(sampler2D, vec3)
72	FUNCTION_TEXELFETCH,
73
74	FUNCTION_LAST
75};
76
77inline bool functionHasAutoLod (glu::ShaderType shaderType, Function function)
78{
79	return shaderType == glu::SHADERTYPE_FRAGMENT &&
80		   (function == FUNCTION_TEXTURE		||
81			function == FUNCTION_TEXTUREPROJ	||
82			function == FUNCTION_TEXTUREPROJ2	||
83			function == FUNCTION_TEXTUREPROJ3);
84}
85
86inline bool functionHasProj (Function function)
87{
88	return function == FUNCTION_TEXTUREPROJ		||
89		   function == FUNCTION_TEXTUREPROJ2	||
90		   function == FUNCTION_TEXTUREPROJ3	||
91		   function == FUNCTION_TEXTUREPROJLOD	||
92		   function == FUNCTION_TEXTUREPROJLOD2	||
93		   function == FUNCTION_TEXTUREPROJLOD3	||
94		   function == FUNCTION_TEXTUREPROJGRAD	||
95		   function == FUNCTION_TEXTUREPROJGRAD2||
96		   function == FUNCTION_TEXTUREPROJGRAD3;
97}
98
99inline bool functionHasGrad (Function function)
100{
101	return function == FUNCTION_TEXTUREGRAD		||
102		   function == FUNCTION_TEXTUREPROJGRAD	||
103		   function == FUNCTION_TEXTUREPROJGRAD2||
104		   function == FUNCTION_TEXTUREPROJGRAD3;
105}
106
107inline bool functionHasLod (Function function)
108{
109	return function == FUNCTION_TEXTURELOD		||
110		   function == FUNCTION_TEXTUREPROJLOD	||
111		   function == FUNCTION_TEXTUREPROJLOD2	||
112		   function == FUNCTION_TEXTUREPROJLOD3	||
113		   function == FUNCTION_TEXELFETCH;
114}
115
116struct TextureLookupSpec
117{
118	Function		function;
119
120	tcu::Vec4		minCoord;
121	tcu::Vec4		maxCoord;
122
123	// Bias
124	bool			useBias;
125
126	// Bias or Lod for *Lod* functions
127	float			minLodBias;
128	float			maxLodBias;
129
130	// For *Grad* functions
131	tcu::Vec3		minDX;
132	tcu::Vec3		maxDX;
133	tcu::Vec3		minDY;
134	tcu::Vec3		maxDY;
135
136	bool			useOffset;
137	tcu::IVec3		offset;
138
139	// Lod clamp
140	bool			useClamp;
141	float			lodClamp;
142
143	TextureLookupSpec (void)
144		: function		(FUNCTION_LAST)
145		, minCoord		(0.0f)
146		, maxCoord		(1.0f)
147		, useBias		(false)
148		, minLodBias	(0.0f)
149		, maxLodBias	(0.0f)
150		, minDX			(0.0f)
151		, maxDX			(0.0f)
152		, minDY			(0.0f)
153		, maxDY			(0.0f)
154		, useOffset		(false)
155		, offset		(0)
156		, useClamp		(false)
157		, lodClamp		(0.0f)
158	{
159	}
160
161	TextureLookupSpec (Function				function_,
162					   const tcu::Vec4&		minCoord_,
163					   const tcu::Vec4&		maxCoord_,
164					   bool					useBias_,
165					   float				minLodBias_,
166					   float				maxLodBias_,
167					   const tcu::Vec3&		minDX_,
168					   const tcu::Vec3&		maxDX_,
169					   const tcu::Vec3&		minDY_,
170					   const tcu::Vec3&		maxDY_,
171					   bool					useOffset_,
172					   const tcu::IVec3&	offset_,
173					   bool					useClamp_,
174					   float				lodClamp_)
175		: function		(function_)
176		, minCoord		(minCoord_)
177		, maxCoord		(maxCoord_)
178		, useBias		(useBias_)
179		, minLodBias	(minLodBias_)
180		, maxLodBias	(maxLodBias_)
181		, minDX			(minDX_)
182		, maxDX			(maxDX_)
183		, minDY			(minDY_)
184		, maxDY			(maxDY_)
185		, useOffset		(useOffset_)
186		, offset		(offset_)
187		, useClamp		(useClamp_)
188		, lodClamp		(lodClamp_)
189	{
190	}
191};
192
193enum TextureType
194{
195	TEXTURETYPE_1D = 0,
196	TEXTURETYPE_2D,
197	TEXTURETYPE_3D,
198	TEXTURETYPE_CUBE_MAP,
199	TEXTURETYPE_1D_ARRAY,
200	TEXTURETYPE_2D_ARRAY,
201	TEXTURETYPE_CUBE_ARRAY,
202
203	TEXTURETYPE_LAST
204};
205
206struct TextureSpec
207{
208	TextureType			type;		//!< Texture type (2D, cubemap, ...)
209	deUint32			format;		//!< Internal format.
210	int					width;
211	int					height;
212	int					depth;
213	int					numLevels;
214	tcu::Sampler		sampler;
215
216	TextureSpec (void)
217		: type			(TEXTURETYPE_LAST)
218		, format		(GL_NONE)
219		, width			(0)
220		, height		(0)
221		, depth			(0)
222		, numLevels		(0)
223	{
224	}
225
226	TextureSpec (TextureType			type_,
227				 deUint32				format_,
228				 int					width_,
229				 int					height_,
230				 int					depth_,
231				 int					numLevels_,
232				 const tcu::Sampler&	sampler_)
233		: type			(type_)
234		, format		(format_)
235		, width			(width_)
236		, height		(height_)
237		, depth			(depth_)
238		, numLevels		(numLevels_)
239		, sampler		(sampler_)
240	{
241	}
242};
243
244struct TexLookupParams
245{
246	float				lod;
247	float				lodClamp;
248	tcu::IVec3			offset;
249	tcu::Vec4			scale;
250	tcu::Vec4			bias;
251
252	TexLookupParams (void)
253		: lod		(0.0f)
254		, lodClamp	(0.0f)
255		, offset	(0)
256		, scale		(1.0f)
257		, bias		(0.0f)
258	{
259	}
260};
261
262// \note LodMode and computeLodFromDerivates functions are copied from glsTextureTestUtil
263namespace TextureTestUtil
264{
265
266enum LodMode
267{
268	LODMODE_EXACT = 0,		//!< Ideal lod computation.
269	LODMODE_MIN_BOUND,		//!< Use estimation range minimum bound.
270	LODMODE_MAX_BOUND,		//!< Use estimation range maximum bound.
271
272	LODMODE_LAST
273};
274
275// 1D lookup LOD computation.
276
277float computeLodFromDerivates (LodMode mode, float dudx, float dudy)
278{
279	float p = 0.0f;
280	switch (mode)
281	{
282		// \note [mika] Min and max bounds equal to exact with 1D textures
283		case LODMODE_EXACT:
284		case LODMODE_MIN_BOUND:
285		case LODMODE_MAX_BOUND:
286			p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
287			break;
288
289		default:
290			DE_ASSERT(DE_FALSE);
291	}
292
293	return deFloatLog2(p);
294}
295
296// 2D lookup LOD computation.
297
298float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
299{
300	float p = 0.0f;
301	switch (mode)
302	{
303		case LODMODE_EXACT:
304			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy));
305			break;
306
307		case LODMODE_MIN_BOUND:
308		case LODMODE_MAX_BOUND:
309		{
310			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
311			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
312
313			p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
314			break;
315		}
316
317		default:
318			DE_ASSERT(DE_FALSE);
319	}
320
321	return deFloatLog2(p);
322}
323
324// 3D lookup LOD computation.
325
326float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
327{
328	float p = 0.0f;
329	switch (mode)
330	{
331		case LODMODE_EXACT:
332			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy));
333			break;
334
335		case LODMODE_MIN_BOUND:
336		case LODMODE_MAX_BOUND:
337		{
338			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
339			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
340			float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
341
342			p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
343			break;
344		}
345
346		default:
347			DE_ASSERT(DE_FALSE);
348	}
349
350	return deFloatLog2(p);
351}
352
353} // TextureTestUtil
354
355using namespace TextureTestUtil;
356
357static const LodMode DEFAULT_LOD_MODE = LODMODE_EXACT;
358
359inline float computeLodFromGrad2D (const ShaderEvalContext& c)
360{
361	float w = (float)c.textures[0].tex2D->getWidth();
362	float h = (float)c.textures[0].tex2D->getHeight();
363	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[2].x()*w, c.in[2].y()*h);
364}
365
366inline float computeLodFromGrad2DArray (const ShaderEvalContext& c)
367{
368	float w = (float)c.textures[0].tex2DArray->getWidth();
369	float h = (float)c.textures[0].tex2DArray->getHeight();
370	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[2].x()*w, c.in[2].y()*h);
371}
372
373inline float computeLodFromGrad3D (const ShaderEvalContext& c)
374{
375	float w = (float)c.textures[0].tex3D->getWidth();
376	float h = (float)c.textures[0].tex3D->getHeight();
377	float d = (float)c.textures[0].tex3D->getDepth();
378	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[1].y()*h, c.in[1].z()*d, c.in[2].x()*w, c.in[2].y()*h, c.in[2].z()*d);
379}
380
381inline float computeLodFromGradCube (const ShaderEvalContext& c)
382{
383	// \note Major axis is always -Z or +Z
384	float m = de::abs(c.in[0].z());
385	float d = (float)c.textures[0].texCube->getSize();
386	float s = d/(2.0f*m);
387	float t = d/(2.0f*m);
388	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*s, c.in[1].y()*t, c.in[2].x()*s, c.in[2].y()*t);
389}
390
391inline float computeLodFromGrad1D (const ShaderEvalContext& c)
392{
393	float w = (float)c.textures[0].tex1D->getWidth();
394	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
395}
396
397inline float computeLodFromGrad1DArray (const ShaderEvalContext& c)
398{
399	float w = (float)c.textures[0].tex1DArray->getWidth();
400	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
401}
402
403inline float computeLodFromGradCubeArray (const ShaderEvalContext& c)
404{
405	// \note Major axis is always -Z or +Z
406	float m = de::abs(c.in[0].z());
407	float d = (float)c.textures[0].texCubeArray->getSize();
408	float s = d/(2.0f*m);
409	float t = d/(2.0f*m);
410	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*s, c.in[1].y()*t, c.in[2].x()*s, c.in[2].y()*t);
411}
412
413typedef void (*TexEvalFunc) (ShaderEvalContext& c, const TexLookupParams& lookupParams);
414
415inline Vec4 texture2D			(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);					}
416inline Vec4 textureCube			(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);			}
417inline Vec4 texture2DArray		(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod);			}
418inline Vec4 texture3D			(const ShaderEvalContext& c, float s, float t, float r, float lod)			{ return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);				}
419inline Vec4 texture1D			(const ShaderEvalContext& c, float s, float lod)							{ return c.textures[0].tex1D->sample(c.textures[0].sampler, s, lod);					}
420inline Vec4 texture1DArray		(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex1DArray->sample(c.textures[0].sampler, s, t, lod);			}
421inline Vec4 textureCubeArray	(const ShaderEvalContext& c, float s, float t, float r, float q, float lod)	{ return c.textures[0].texCubeArray->sample(c.textures[0].sampler, s, t, r, q, lod);	}
422
423inline float texture2DShadow		(const ShaderEvalContext& c, float ref, float s, float t, float lod)					{ return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod);					}
424inline float textureCubeShadow		(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod)			{ return c.textures[0].texCube->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);			}
425inline float texture2DArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod)			{ return c.textures[0].tex2DArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);			}
426inline float texture1DShadow		(const ShaderEvalContext& c, float ref, float s, float lod)								{ return c.textures[0].tex1D->sampleCompare(c.textures[0].sampler, ref, s, lod);					}
427inline float texture1DArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float lod)					{ return c.textures[0].tex1DArray->sampleCompare(c.textures[0].sampler, ref, s, t, lod);			}
428inline float textureCubeArrayShadow	(const ShaderEvalContext& c, float ref, float s, float t, float r, float q, float lod)	{ return c.textures[0].texCubeArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, q, lod);	}
429
430inline Vec4 texture2DOffset			(const ShaderEvalContext& c, float s, float t, float lod, IVec2 offset)				{ return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);			}
431inline Vec4 texture2DArrayOffset	(const ShaderEvalContext& c, float s, float t, float r, float lod, IVec2 offset)	{ return c.textures[0].tex2DArray->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);	}
432inline Vec4 texture3DOffset			(const ShaderEvalContext& c, float s, float t, float r, float lod, IVec3 offset)	{ return c.textures[0].tex3D->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);		}
433inline Vec4 texture1DOffset			(const ShaderEvalContext& c, float s, float lod, deInt32 offset)					{ return c.textures[0].tex1D->sampleOffset(c.textures[0].sampler, s, lod, offset);				}
434inline Vec4 texture1DArrayOffset	(const ShaderEvalContext& c, float s, float t, float lod, deInt32 offset)			{ return c.textures[0].tex1DArray->sampleOffset(c.textures[0].sampler, s, t, lod, offset);		}
435
436inline float texture2DShadowOffset		(const ShaderEvalContext& c, float ref, float s, float t, float lod, IVec2 offset)			{ return c.textures[0].tex2D->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);			}
437inline float texture2DArrayShadowOffset	(const ShaderEvalContext& c, float ref, float s, float t, float r, float lod, IVec2 offset)	{ return c.textures[0].tex2DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, r, lod, offset);	}
438inline float texture1DShadowOffset		(const ShaderEvalContext& c, float ref, float s, float lod, deInt32 offset)					{ return c.textures[0].tex1D->sampleCompareOffset(c.textures[0].sampler, ref, s, lod, offset);				}
439inline float texture1DArrayShadowOffset	(const ShaderEvalContext& c, float ref, float s, float t, float lod, deInt32 offset)		{ return c.textures[0].tex1DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);		}
440
441// Eval functions.
442static void		evalTexture2D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
443static void		evalTextureCube					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
444static void		evalTexture2DArray				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
445static void		evalTexture3D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod)*p.scale + p.bias; }
446static void		evalTexture1D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), p.lod)*p.scale + p.bias; }
447static void		evalTexture1DArray				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod)*p.scale + p.bias; }
448static void		evalTextureCubeArray			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod)*p.scale + p.bias; }
449
450static void		evalTexture2DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
451static void		evalTextureCubeBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
452static void		evalTexture2DArrayBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
453static void		evalTexture3DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
454static void		evalTexture1DBias				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), p.lod+c.in[1].x())*p.scale + p.bias; }
455static void		evalTexture1DArrayBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
456static void		evalTextureCubeArrayBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
457
458static void		evalTexture2DProj3				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod)*p.scale + p.bias; }
459static void		evalTexture2DProj3Bias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x())*p.scale + p.bias; }
460static void		evalTexture2DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod)*p.scale + p.bias; }
461static void		evalTexture2DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
462static void		evalTexture3DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod)*p.scale + p.bias; }
463static void		evalTexture3DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
464static void		evalTexture1DProj2				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), p.lod)*p.scale + p.bias; }
465static void		evalTexture1DProj2Bias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), p.lod+c.in[1].x())*p.scale + p.bias; }
466static void		evalTexture1DProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), p.lod)*p.scale + p.bias; }
467static void		evalTexture1DProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x())*p.scale + p.bias; }
468
469static void		evalTexture2DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
470static void		evalTextureCubeLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
471static void		evalTexture2DArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
472static void		evalTexture3DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
473static void		evalTexture1DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), c.in[1].x())*p.scale + p.bias; }
474static void		evalTexture1DArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
475static void		evalTextureCubeArrayLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
476
477static void		evalTexture2DProjLod3			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x())*p.scale + p.bias; }
478static void		evalTexture2DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
479static void		evalTexture3DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
480static void		evalTexture1DProjLod2			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), c.in[1].x())*p.scale + p.bias; }
481static void		evalTexture1DProjLod			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), c.in[1].x())*p.scale + p.bias; }
482
483static void		evalTexture2DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
484static void		evalTextureCubeBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
485static void		evalTexture2DArrayBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
486static void		evalTexture3DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
487static void		evalTexture1DBiasClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
488static void		evalTexture1DArrayBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
489static void		evalTextureCubeArrayBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), de::max(p.lod+c.in[1].x(), p.lodClamp))*p.scale + p.bias; }
490
491// Offset variants
492
493static void		evalTexture2DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
494static void		evalTexture2DArrayOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
495static void		evalTexture3DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset)*p.scale + p.bias; }
496static void		evalTexture1DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), p.lod, p.offset.x())*p.scale + p.bias; }
497static void		evalTexture1DArrayOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.x())*p.scale + p.bias; }
498
499static void		evalTexture2DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
500static void		evalTexture2DArrayOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
501static void		evalTexture3DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
502static void		evalTexture1DOffsetBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
503static void		evalTexture1DArrayOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
504
505static void		evalTexture2DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
506static void		evalTexture2DArrayLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
507static void		evalTexture3DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x(), p.offset)*p.scale + p.bias; }
508static void		evalTexture1DLodOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
509static void		evalTexture1DArrayLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
510
511static void		evalTexture2DProj3Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
512static void		evalTexture2DProj3OffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
513static void		evalTexture2DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1))*p.scale + p.bias; }
514static void		evalTexture2DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
515static void		evalTexture3DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod, p.offset)*p.scale + p.bias; }
516static void		evalTexture3DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), p.lod+c.in[1].x(), p.offset)*p.scale + p.bias; }
517static void		evalTexture1DProj2Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), p.lod, p.offset.x())*p.scale + p.bias; }
518static void		evalTexture1DProj2OffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
519static void		evalTexture1DProjOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), p.lod, p.offset.x())*p.scale + p.bias; }
520static void		evalTexture1DProjOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.x())*p.scale + p.bias; }
521
522static void		evalTexture2DProjLod3Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
523static void		evalTexture2DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1))*p.scale + p.bias; }
524static void		evalTexture3DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), c.in[1].x(), p.offset)*p.scale + p.bias; }
525static void		evalTexture1DProjLod2Offset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
526static void		evalTexture1DProjLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), c.in[1].x(), p.offset.x())*p.scale + p.bias; }
527
528static void		evalTexture2DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
529static void		evalTexture2DArrayOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
530static void		evalTexture3DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset)*p.scale + p.bias; }
531static void		evalTexture1DOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x())*p.scale + p.bias; }
532static void		evalTexture1DArrayOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x())*p.scale + p.bias; }
533
534// Shadow variants
535
536static void		evalTexture2DShadow				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
537static void		evalTexture2DShadowBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x()); }
538
539static void		evalTextureCubeShadow			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
540static void		evalTextureCubeShadowBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod+c.in[1].x()); }
541
542static void		evalTexture2DArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod); }
543static void		evalTexture1DShadow				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod); }
544static void		evalTexture1DShadowBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod+c.in[1].x()); }
545static void		evalTexture1DArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod); }
546static void		evalTexture1DArrayShadowBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x()); }
547static void		evalTextureCubeArrayShadow		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), p.lod); }
548
549static void		evalTexture2DShadowLod				(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x()); }
550static void		evalTexture2DShadowLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.swizzle(0,1)); }
551static void		evalTexture1DShadowLod				(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), c.in[1].x()); }
552static void		evalTexture1DShadowLodOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[1].x(), p.offset.x()); }
553static void		evalTexture1DArrayShadowLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x()); }
554static void		evalTexture1DArrayShadowLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x()); }
555
556static void		evalTexture2DShadowProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod); }
557static void		evalTexture2DShadowProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x()); }
558static void		evalTexture1DShadowProj				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod); }
559static void		evalTexture1DShadowProjBias			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x()); }
560
561static void		evalTexture2DShadowProjLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x()); }
562static void		evalTexture2DShadowProjLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[1].x(), p.offset.swizzle(0,1)); }
563static void		evalTexture1DShadowProjLod			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[1].x()); }
564static void		evalTexture1DShadowProjLodOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[1].x(), p.offset.x()); }
565
566static void		evalTexture2DShadowOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0,1)); }
567static void		evalTexture2DShadowOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
568static void		evalTexture2DArrayShadowOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset.swizzle(0,1)); }
569static void		evalTexture1DShadowOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod, p.offset.x()); }
570static void		evalTexture1DShadowOffsetBias		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod+c.in[1].x(), p.offset.x()); }
571static void		evalTexture1DArrayShadowOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.x()); }
572static void		evalTexture1DArrayShadowOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod+c.in[1].x(), p.offset.x()); }
573
574static void		evalTexture2DShadowProjOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod, p.offset.swizzle(0,1)); }
575static void		evalTexture2DShadowProjOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.swizzle(0,1)); }
576static void		evalTexture1DShadowProjOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod, p.offset.x()); }
577static void		evalTexture1DShadowProjOffsetBias	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), p.lod+c.in[1].x(), p.offset.x()); }
578
579static void		evalTexture2DShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
580static void		evalTextureCubeShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
581static void		evalTexture1DShadowBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
582static void		evalTexture1DArrayShadowBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp)); }
583static void		evalTexture2DShadowOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.swizzle(0,1)); }
584static void		evalTexture1DShadowOffsetBiasClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x()); }
585static void		evalTexture1DArrayShadowOffsetBiasClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod+c.in[1].x(), p.lodClamp), p.offset.x()); }
586
587// Gradient variarts
588
589static void		evalTexture2DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c))*p.scale + p.bias; }
590static void		evalTextureCubeGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c))*p.scale + p.bias; }
591static void		evalTexture2DArrayGrad		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c))*p.scale + p.bias; }
592static void		evalTexture3DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c))*p.scale + p.bias; }
593static void		evalTexture1DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), computeLodFromGrad1D(c))*p.scale + p.bias; }
594static void		evalTexture1DArrayGrad		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c))*p.scale + p.bias; }
595static void		evalTextureCubeArrayGrad	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), computeLodFromGradCubeArray(c))*p.scale + p.bias; }
596
597static void		evalTexture2DShadowGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)); }
598static void		evalTextureCubeShadowGrad		(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c)); }
599static void		evalTexture2DArrayShadowGrad	(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c)); }
600static void		evalTexture1DShadowGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c)); }
601static void		evalTexture1DArrayShadowGrad	(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c)); }
602
603static void		evalTexture2DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
604static void		evalTexture2DArrayGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
605static void		evalTexture3DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
606static void		evalTexture1DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
607static void		evalTexture1DArrayGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c), p.offset.x())*p.scale + p.bias; }
608
609static void		evalTexture2DShadowGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
610static void		evalTexture2DArrayShadowGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c), p.offset.swizzle(0,1)); }
611static void		evalTexture1DShadowGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c), p.offset.x()); }
612static void		evalTexture1DArrayShadowGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c), p.offset.x()); }
613
614static void		evalTexture2DShadowProjGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture2DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c)); }
615static void		evalTexture2DShadowProjGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1)); }
616static void		evalTexture1DShadowProjGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c)); }
617static void		evalTexture1DShadowProjGradOffset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z()/c.in[0].w(), c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c), p.offset.x()); }
618
619static void		evalTexture2DProjGrad3			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c))*p.scale + p.bias; }
620static void		evalTexture2DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c))*p.scale + p.bias; }
621static void		evalTexture3DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c))*p.scale + p.bias; }
622static void		evalTexture1DProjGrad2			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].y(), computeLodFromGrad1D(c))*p.scale + p.bias; }
623static void		evalTexture1DProjGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c))*p.scale + p.bias; }
624
625static void		evalTexture2DProjGrad3Offset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].z(), c.in[0].y()/c.in[0].z(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
626static void		evalTexture2DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0,1))*p.scale + p.bias; }
627static void		evalTexture3DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x()/c.in[0].w(), c.in[0].y()/c.in[0].w(), c.in[0].z()/c.in[0].w(), computeLodFromGrad3D(c), p.offset)*p.scale + p.bias; }
628static void		evalTexture1DProjGrad2Offset	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].y(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
629static void		evalTexture1DProjGradOffset		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x()/c.in[0].w(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
630
631static void		evalTexture2DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2D(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp))*p.scale + p.bias; }
632static void		evalTextureCubeGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGradCube(c), p.lodClamp))*p.scale + p.bias; }
633static void		evalTexture2DArrayGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp))*p.scale + p.bias; }
634static void		evalTexture3DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp))*p.scale + p.bias; }
635static void		evalTexture1DGradClamp			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp))*p.scale + p.bias; }
636static void		evalTexture1DArrayGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp))*p.scale + p.bias; }
637static void		evalTextureCubeArrayGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), de::max(computeLodFromGradCubeArray(c), p.lodClamp))*p.scale + p.bias; }
638
639static void		evalTexture2DShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp)); }
640static void		evalTextureCubeShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGradCube(c), p.lodClamp)); }
641static void		evalTexture2DArrayShadowGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp)); }
642static void		evalTexture1DShadowGradClamp		(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp)); }
643static void		evalTexture1DArrayShadowGradClamp	(ShaderEvalContext& c, const TexLookupParams& p)		{ c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp)); }
644
645static void		evalTexture2DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
646static void		evalTexture2DArrayGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0,1))*p.scale + p.bias; }
647static void		evalTexture3DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp), p.offset)*p.scale + p.bias; }
648static void		evalTexture1DGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x())*p.scale + p.bias; }
649static void		evalTexture1DArrayGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp), p.offset.x())*p.scale + p.bias; }
650
651static void		evalTexture2DShadowGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp), p.offset.swizzle(0,1)); }
652static void		evalTexture2DArrayShadowGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0,1)); }
653static void		evalTexture1DShadowGradOffsetClamp		(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x()); }
654static void		evalTexture1DArrayShadowGradOffsetClamp	(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp), p.offset.x()); }
655
656// Texel fetch variants
657
658static void evalTexelFetch2D (ShaderEvalContext& c, const TexLookupParams& p)
659{
660	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
661	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
662	int	lod = deChopFloatToInt32(c.in[1].x());
663	c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y)*p.scale + p.bias;
664}
665
666static void evalTexelFetch2DArray (ShaderEvalContext& c, const TexLookupParams& p)
667{
668	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
669	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
670	int	l	= deChopFloatToInt32(c.in[0].z());
671	int	lod = deChopFloatToInt32(c.in[1].x());
672	c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l)*p.scale + p.bias;
673}
674
675static void evalTexelFetch3D (ShaderEvalContext& c, const TexLookupParams& p)
676{
677	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
678	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
679	int	z	= deChopFloatToInt32(c.in[0].z())+p.offset.z();
680	int	lod = deChopFloatToInt32(c.in[1].x());
681	c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z)*p.scale + p.bias;
682}
683
684static void evalTexelFetch1D (ShaderEvalContext& c, const TexLookupParams& p)
685{
686	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
687	int	lod = deChopFloatToInt32(c.in[1].x());
688	c.color = c.textures[0].tex1D->getLevel(lod).getPixel(x, 0)*p.scale + p.bias;
689}
690
691static void evalTexelFetch1DArray (ShaderEvalContext& c, const TexLookupParams& p)
692{
693	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
694	int	l	= deChopFloatToInt32(c.in[0].y());
695	int	lod = deChopFloatToInt32(c.in[1].x());
696	c.color = c.textures[0].tex1DArray->getLevel(lod).getPixel(x, l)*p.scale + p.bias;
697}
698
699class TexLookupEvaluator : public ShaderEvaluator
700{
701public:
702							TexLookupEvaluator		(TexEvalFunc evalFunc, const TexLookupParams& lookupParams) : m_evalFunc(evalFunc), m_lookupParams(lookupParams) {}
703	virtual					~TexLookupEvaluator		(void) {}
704
705	virtual void			evaluate				(ShaderEvalContext& ctx) const { m_evalFunc(ctx, m_lookupParams); }
706
707private:
708	TexEvalFunc				m_evalFunc;
709	const TexLookupParams&	m_lookupParams;
710};
711
712static void checkDeviceFeatures (Context& context, TextureType textureType)
713{
714	if (textureType == TEXTURETYPE_CUBE_ARRAY)
715	{
716		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
717
718		if (!deviceFeatures.imageCubeArray)
719			TCU_THROW(NotSupportedError, "Cube array is not supported");
720	}
721}
722
723static void checkMutableComparisonSamplersSupport(Context& context, const TextureSpec& textureSpec)
724{
725	// when compare mode is not none then ShaderRenderCaseInstance::createSamplerUniform
726	// uses mapSampler utill from vkImageUtil that sets compareEnable to true
727	// for portability this needs to be under feature flag
728#ifndef CTS_USES_VULKANSC
729	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
730	   !context.getPortabilitySubsetFeatures().mutableComparisonSamplers &&
731	   (textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE))
732	{
733		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: mutableComparisonSamplers are not supported by this implementation");
734	}
735#else
736	DE_UNREF(context);
737	DE_UNREF(textureSpec);
738#endif // CTS_USES_VULKANSC
739}
740
741class ShaderTextureFunctionInstance : public ShaderRenderCaseInstance
742{
743public:
744								ShaderTextureFunctionInstance		(Context&					context,
745																	 const bool					isVertexCase,
746																	 const ShaderEvaluator&		evaluator,
747																	 const UniformSetup&		uniformSetup,
748																	 const TextureLookupSpec&	lookupSpec,
749																	 const TextureSpec&			textureSpec,
750																	 const TexLookupParams&		lookupParams,
751																	 const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
752	virtual						~ShaderTextureFunctionInstance		(void);
753
754protected:
755	virtual void				setupUniforms						(const tcu::Vec4&);
756	void						initTexture							(void);
757private:
758	const TextureLookupSpec&	m_lookupSpec;
759	const TextureSpec&			m_textureSpec;
760	const TexLookupParams&		m_lookupParams;
761};
762
763ShaderTextureFunctionInstance::ShaderTextureFunctionInstance (Context&						context,
764															  const bool					isVertexCase,
765															  const ShaderEvaluator&		evaluator,
766															  const UniformSetup&			uniformSetup,
767															  const TextureLookupSpec&		lookupSpec,
768															  const TextureSpec&			textureSpec,
769															  const TexLookupParams&		lookupParams,
770															  const ImageBackingMode		imageBackingMode)
771	: ShaderRenderCaseInstance	(context, isVertexCase, evaluator, uniformSetup, DE_NULL, imageBackingMode,
772								(isVertexCase ? 92 : GRID_SIZE_DEFAULT_FRAGMENT))
773	, m_lookupSpec				(lookupSpec)
774	, m_textureSpec				(textureSpec)
775	, m_lookupParams			(lookupParams)
776{
777	checkDeviceFeatures(m_context, m_textureSpec.type);
778
779	if (lookupSpec.useClamp)
780	{
781		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
782
783		if (!deviceFeatures.shaderResourceMinLod)
784			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
785	}
786
787	{
788		// Base coord scale & bias
789		Vec4 s = m_lookupSpec.maxCoord-m_lookupSpec.minCoord;
790		Vec4 b = m_lookupSpec.minCoord;
791
792		float baseCoordTrans[] =
793		{
794			s.x(),		0.0f,		0.f,	b.x(),
795			0.f,		s.y(),		0.f,	b.y(),
796			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
797			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
798		};
799
800		m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
801
802		useAttribute(4u, A_IN0);
803	}
804
805	bool hasLodBias	= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
806	bool isGrad		= functionHasGrad(m_lookupSpec.function);
807	DE_ASSERT(!isGrad || !hasLodBias);
808
809	if (hasLodBias)
810	{
811		float s = m_lookupSpec.maxLodBias-m_lookupSpec.minLodBias;
812		float b = m_lookupSpec.minLodBias;
813		float lodCoordTrans[] =
814		{
815			s/2.0f,		s/2.0f,		0.f,	b,
816			0.0f,		0.0f,		0.0f,	0.0f,
817			0.0f,		0.0f,		0.0f,	0.0f,
818			0.0f,		0.0f,		0.0f,	0.0f
819		};
820
821		m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
822
823		useAttribute(5u, A_IN1);
824	}
825	else if (isGrad)
826	{
827		Vec3 sx = m_lookupSpec.maxDX-m_lookupSpec.minDX;
828		Vec3 sy = m_lookupSpec.maxDY-m_lookupSpec.minDY;
829		float gradDxTrans[] =
830		{
831			sx.x()/2.0f,	sx.x()/2.0f,	0.f,	m_lookupSpec.minDX.x(),
832			sx.y()/2.0f,	sx.y()/2.0f,	0.0f,	m_lookupSpec.minDX.y(),
833			sx.z()/2.0f,	sx.z()/2.0f,	0.0f,	m_lookupSpec.minDX.z(),
834			0.0f,			0.0f,			0.0f,	0.0f
835		};
836		float gradDyTrans[] =
837		{
838			-sy.x()/2.0f,	-sy.x()/2.0f,	0.f,	m_lookupSpec.maxDY.x(),
839			-sy.y()/2.0f,	-sy.y()/2.0f,	0.0f,	m_lookupSpec.maxDY.y(),
840			-sy.z()/2.0f,	-sy.z()/2.0f,	0.0f,	m_lookupSpec.maxDY.z(),
841			0.0f,			0.0f,			0.0f,	0.0f
842		};
843
844		m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
845		m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
846
847		useAttribute(5u, A_IN1);
848		useAttribute(6u, A_IN2);
849	}
850
851	initTexture();
852}
853
854ShaderTextureFunctionInstance::~ShaderTextureFunctionInstance (void)
855{
856}
857
858void ShaderTextureFunctionInstance::setupUniforms (const tcu::Vec4&)
859{
860	useSampler(0u, 0u);
861	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.scale.getPtr());
862	addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.bias.getPtr());
863}
864
865void ShaderTextureFunctionInstance::initTexture (void)
866{
867	static const IVec4		texCubeSwz[] =
868	{
869		IVec4(0,0,1,1),
870		IVec4(1,1,0,0),
871		IVec4(0,1,0,1),
872		IVec4(1,0,1,0),
873		IVec4(0,1,1,0),
874		IVec4(1,0,0,1)
875	};
876	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
877
878	tcu::TextureFormat		texFmt			= glu::mapGLInternalFormat(m_textureSpec.format);
879	tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
880	tcu::UVec2				viewportSize	= getViewportSize();
881	bool					isProj			= functionHasProj(m_lookupSpec.function);
882	bool					isAutoLod		= functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
883																 m_lookupSpec.function); // LOD can vary significantly
884	float					proj			= isProj ? 1.0f/m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ2 ? 1 : m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
885	TexLookupParams			lookupParams;
886
887	switch (m_textureSpec.type)
888	{
889		case TEXTURETYPE_2D:
890		{
891			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
892			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
893			Vec4								cBias			= fmtInfo.valueMin;
894			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
895			de::MovePtr<tcu::Texture2D>			texture2D;
896
897			texture2D = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(texFmt, m_textureSpec.width, m_textureSpec.height));
898
899			for (int level = 0; level < m_textureSpec.numLevels; level++)
900			{
901				float	fA		= float(level)*levelStep;
902				float	fB		= 1.0f-fA;
903				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
904				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
905
906				texture2D->allocLevel(level);
907				tcu::fillWithGrid(texture2D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
908			}
909
910			// Compute LOD.
911			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
912			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
913			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
914
915			// Append to texture list.
916			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2D.release(), m_textureSpec.sampler)));
917			break;
918		}
919
920		case TEXTURETYPE_CUBE_MAP:
921		{
922			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
923			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
924			Vec4								cBias			= fmtInfo.valueMin;
925			Vec4								cCorner			= cBias + cScale*0.5f;
926			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
927			de::MovePtr<tcu::TextureCube>		textureCube;
928
929			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
930			textureCube = de::MovePtr<tcu::TextureCube>(new tcu::TextureCube(texFmt, m_textureSpec.width));
931
932			for (int level = 0; level < m_textureSpec.numLevels; level++)
933			{
934				float	fA		= float(level)*levelStep;
935				float	fB		= 1.0f-fA;
936				Vec2	f		(fA, fB);
937
938				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
939				{
940					const IVec4&	swzA	= texCubeSwz[face];
941					IVec4			swzB	= 1-swzA;
942					Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
943					Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
944
945					textureCube->allocLevel((tcu::CubeFace)face, level);
946
947					{
948						const tcu::PixelBufferAccess	access		= textureCube->getLevelFace(level, (tcu::CubeFace)face);
949						const int						lastPix		= access.getWidth()-1;
950
951						tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
952
953						// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
954						access.setPixel(cCorner, 0, 0);
955						access.setPixel(cCorner, 0, lastPix);
956						access.setPixel(cCorner, lastPix, 0);
957						access.setPixel(cCorner, lastPix, lastPix);
958					}
959				}
960			}
961
962			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
963			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
964			DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
965			DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
966
967			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
968			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
969			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
970			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
971			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
972			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
973
974			// Append to texture list.
975			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCube.release(), m_textureSpec.sampler)));
976			break;
977		}
978
979		case TEXTURETYPE_2D_ARRAY:
980		{
981			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
982			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
983			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
984			Vec4								cBias			= fmtInfo.valueMin;
985			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
986			de::MovePtr<tcu::Texture2DArray>	texture2DArray;
987
988			texture2DArray = de::MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
989
990			for (int level = 0; level < m_textureSpec.numLevels; level++)
991			{
992				texture2DArray->allocLevel(level);
993				tcu::PixelBufferAccess levelAccess = texture2DArray->getLevel(level);
994
995				for (int layer = 0; layer < levelAccess.getDepth(); layer++)
996				{
997					float	fA		= (float)layer*layerStep + (float)level*levelStep;
998					float	fB		= 1.0f-fA;
999					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1000					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1001
1002					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), de::max(1, baseCellSize>>level), colorA, colorB);
1003				}
1004			}
1005
1006			// Compute LOD.
1007			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1008			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
1009			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1010
1011			// Append to texture list.
1012			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2DArray.release(), m_textureSpec.sampler)));
1013			break;
1014		}
1015
1016		case TEXTURETYPE_3D:
1017		{
1018			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1019			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1020			Vec4								cBias			= fmtInfo.valueMin;
1021			int									baseCellSize	= de::min(de::min(m_textureSpec.width/2, m_textureSpec.height/2), m_textureSpec.depth/2);
1022			de::MovePtr<tcu::Texture3D>			texture3D;
1023
1024			texture3D = de::MovePtr<tcu::Texture3D>(new tcu::Texture3D(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
1025
1026			for (int level = 0; level < m_textureSpec.numLevels; level++)
1027			{
1028				float	fA		= (float)level*levelStep;
1029				float	fB		= 1.0f-fA;
1030				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1031				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1032
1033				texture3D->allocLevel(level);
1034				tcu::fillWithGrid(texture3D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1035			}
1036
1037			// Compute LOD.
1038			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width		/ (float)viewportSize[0];
1039			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height		/ (float)viewportSize[1];
1040			float	dwdx	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[0];
1041			float	dwdy	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[1];
1042			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
1043
1044			// Append to texture list.
1045			m_textures.push_back(TextureBindingSp(new TextureBinding(texture3D.release(), m_textureSpec.sampler)));
1046			break;
1047		}
1048
1049		case TEXTURETYPE_1D:
1050		{
1051			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1052			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1053			Vec4								cBias			= fmtInfo.valueMin;
1054			int									baseCellSize	= m_textureSpec.width/4;
1055			de::MovePtr<tcu::Texture1D>			texture1D;
1056
1057			texture1D = de::MovePtr<tcu::Texture1D>(new tcu::Texture1D(texFmt, m_textureSpec.width));
1058
1059			for (int level = 0; level < m_textureSpec.numLevels; level++)
1060			{
1061				float	fA		= float(level)*levelStep;
1062				float	fB		= 1.0f-fA;
1063				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1064				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1065
1066				texture1D->allocLevel(level);
1067				tcu::fillWithGrid(texture1D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1068			}
1069
1070			// Compute LOD.
1071			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1072			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1073
1074			// Append to texture list.
1075			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1D.release(), m_textureSpec.sampler)));
1076			break;
1077		}
1078
1079		case TEXTURETYPE_1D_ARRAY:
1080		{
1081			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
1082			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
1083			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1084			Vec4								cBias			= fmtInfo.valueMin;
1085			int									baseCellSize	= m_textureSpec.width/4;
1086			de::MovePtr<tcu::Texture1DArray>	texture1DArray;
1087
1088			texture1DArray = de::MovePtr<tcu::Texture1DArray>(new tcu::Texture1DArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1089
1090			for (int level = 0; level < m_textureSpec.numLevels; level++)
1091			{
1092				texture1DArray->allocLevel(level);
1093				tcu::PixelBufferAccess levelAccess = texture1DArray->getLevel(level);
1094
1095				for (int layer = 0; layer < levelAccess.getHeight(); layer++)
1096				{
1097					float	fA		= (float)layer*layerStep + (float)level*levelStep;
1098					float	fB		= 1.0f-fA;
1099					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1100					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1101
1102					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, layer, 0, levelAccess.getWidth(), 1, 1), de::max(1, baseCellSize>>level), colorA, colorB);
1103				}
1104			}
1105
1106			// Compute LOD.
1107			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1108			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1109
1110			// Append to texture list.
1111			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1DArray.release(), m_textureSpec.sampler)));
1112			break;
1113		}
1114
1115		case TEXTURETYPE_CUBE_ARRAY:
1116		{
1117			float								layerStep			= 1.0f / (float)(m_textureSpec.depth/6);
1118			float								levelStep			= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*(m_textureSpec.depth/6));
1119			Vec4								cScale				= fmtInfo.valueMax-fmtInfo.valueMin;
1120			Vec4								cBias				= fmtInfo.valueMin;
1121			Vec4								cCorner				= cBias + cScale*0.5f;
1122			int									baseCellSize		= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
1123			de::MovePtr<tcu::TextureCubeArray>	textureCubeArray;
1124
1125			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
1126			DE_ASSERT(m_textureSpec.depth % 6 == 0);
1127
1128			textureCubeArray = de::MovePtr<tcu::TextureCubeArray>(new tcu::TextureCubeArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1129
1130			for (int level = 0; level < m_textureSpec.numLevels; level++)
1131			{
1132				float	fA		= float(level)*levelStep;
1133				float	fB		= 1.0f-fA;
1134				Vec2	f		(fA, fB);
1135
1136				textureCubeArray->allocLevel(level);
1137				tcu::PixelBufferAccess levelAccess = textureCubeArray->getLevel(level);
1138
1139				for (int layer = 0; layer < m_textureSpec.depth/6; layer++)
1140				{
1141					float layerCorr = 1.0f-(float)layer*layerStep;
1142
1143					for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1144					{
1145						const IVec4&	swzA	= texCubeSwz[face];
1146						IVec4			swzB	= 1-swzA;
1147						Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3])*layerCorr;
1148						Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3])*layerCorr;
1149
1150						{
1151							const tcu::PixelBufferAccess	access		= tcu::getSubregion(levelAccess, 0, 0, (layer*6)+face, levelAccess.getWidth(), levelAccess.getHeight(), 1);
1152							const int						lastPix		= access.getWidth()-1;
1153
1154							tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
1155
1156							// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
1157							access.setPixel(cCorner, 0, 0);
1158							access.setPixel(cCorner, 0, lastPix);
1159							access.setPixel(cCorner, lastPix, 0);
1160							access.setPixel(cCorner, lastPix, lastPix);
1161						}
1162					}
1163				}
1164			}
1165
1166			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
1167			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
1168			DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
1169			DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) && de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
1170
1171			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1172			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1173			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1174			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
1175			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
1176			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1177
1178			// Append to texture list.
1179			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCubeArray.release(), m_textureSpec.sampler)));
1180			break;
1181		}
1182
1183		default:
1184			DE_ASSERT(DE_FALSE);
1185	}
1186
1187	// Set lookup scale & bias
1188	lookupParams.scale		= fmtInfo.lookupScale;
1189	lookupParams.bias		= fmtInfo.lookupBias;
1190	lookupParams.offset		= m_lookupSpec.offset;
1191	lookupParams.lodClamp	= m_lookupSpec.lodClamp;
1192
1193	// \todo [dirnerakos] Avoid const cast somehow
1194	const_cast<TexLookupParams&>(m_lookupParams) = lookupParams;
1195}
1196
1197class ShaderTextureFunctionCase : public ShaderRenderCase
1198{
1199public:
1200								ShaderTextureFunctionCase		(tcu::TestContext&				testCtx,
1201																 const std::string&				name,
1202																 const TextureLookupSpec&		lookup,
1203																 const TextureSpec&				texture,
1204																 TexEvalFunc					evalFunc,
1205																 bool							isVertexCase);
1206	virtual						~ShaderTextureFunctionCase		(void);
1207
1208	virtual TestInstance*		createInstance					(Context& context) const;
1209	virtual void				checkSupport					(Context& context) const;
1210
1211protected:
1212	const TextureLookupSpec		m_lookupSpec;
1213	const TextureSpec			m_textureSpec;
1214	const TexLookupParams		m_lookupParams;
1215
1216	void						initShaderSources				(void);
1217};
1218
1219ShaderTextureFunctionCase::ShaderTextureFunctionCase (tcu::TestContext&				testCtx,
1220													  const std::string&			name,
1221													  const TextureLookupSpec&		lookup,
1222													  const TextureSpec&			texture,
1223													  TexEvalFunc					evalFunc,
1224													  bool							isVertexCase)
1225	: ShaderRenderCase		(testCtx, name, isVertexCase, new TexLookupEvaluator(evalFunc, m_lookupParams), NULL, NULL)
1226	, m_lookupSpec			(lookup)
1227	, m_textureSpec			(texture)
1228{
1229	initShaderSources();
1230}
1231
1232ShaderTextureFunctionCase::~ShaderTextureFunctionCase (void)
1233{
1234}
1235
1236TestInstance* ShaderTextureFunctionCase::createInstance (Context& context) const
1237{
1238	DE_ASSERT(m_evaluator != DE_NULL);
1239	DE_ASSERT(m_uniformSetup != DE_NULL);
1240	return new ShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
1241}
1242
1243void ShaderTextureFunctionCase::checkSupport(Context& context) const
1244{
1245	checkMutableComparisonSamplersSupport(context, m_textureSpec);
1246}
1247
1248void ShaderTextureFunctionCase::initShaderSources (void)
1249{
1250	Function			function			= m_lookupSpec.function;
1251	bool				isVtxCase			= m_isVertexCase;
1252	bool				isProj				= functionHasProj(function);
1253	bool				isGrad				= functionHasGrad(function);
1254	bool				isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1255	bool				is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1256	bool				is1DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_1D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1257	bool				isIntCoord			= function == FUNCTION_TEXELFETCH;
1258	bool				hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1259	int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_1D ? 1 :
1260											  m_textureSpec.type == TEXTURETYPE_1D_ARRAY || m_textureSpec.type == TEXTURETYPE_2D ? 2 :
1261											  m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? 4 :
1262											  3;
1263	int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : (is1DProj4 ? 3 : 1)) : 0) + (isShadow ? (m_textureSpec.type == TEXTURETYPE_1D ? 2 : 1) : 0);
1264	const bool			isCubeArrayShadow	= isShadow && m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY;
1265	glu::DataType		coordType			= glu::getDataTypeFloatVec(isCubeArrayShadow ? 4 : texCoordComps+extraCoordComps);
1266	glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
1267	const char*			coordTypeName		= glu::getDataTypeName(coordType);
1268	const char*			coordPrecName		= glu::getPrecisionName(coordPrec);
1269	tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
1270	glu::DataType		samplerType			= glu::TYPE_LAST;
1271	glu::DataType		gradType			= m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? glu::TYPE_FLOAT :
1272											  m_textureSpec.type == TEXTURETYPE_3D || m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? glu::TYPE_FLOAT_VEC3 :
1273											  glu::TYPE_FLOAT_VEC2;
1274	const char*			gradTypeName		= glu::getDataTypeName(gradType);
1275	const char*			baseFuncName		= DE_NULL;
1276
1277	DE_ASSERT(!isGrad || !hasLodBias);
1278
1279	switch (m_textureSpec.type)
1280	{
1281		case TEXTURETYPE_2D:			samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW			: glu::getSampler2DType(texFmt);		break;
1282		case TEXTURETYPE_CUBE_MAP:		samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW			: glu::getSamplerCubeType(texFmt);		break;
1283		case TEXTURETYPE_2D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW		: glu::getSampler2DArrayType(texFmt);	break;
1284		case TEXTURETYPE_3D:			DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);										break;
1285		case TEXTURETYPE_1D:			samplerType = isShadow ? glu::TYPE_SAMPLER_1D_SHADOW			: glu::getSampler1DType(texFmt);		break;
1286		case TEXTURETYPE_1D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_1D_ARRAY_SHADOW		: glu::getSampler1DArrayType(texFmt);	break;
1287		case TEXTURETYPE_CUBE_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW	: glu::getSamplerCubeArrayType(texFmt);	break;
1288		default:
1289			DE_ASSERT(DE_FALSE);
1290	}
1291
1292	switch (m_lookupSpec.function)
1293	{
1294		case FUNCTION_TEXTURE:			baseFuncName = "texture";			break;
1295		case FUNCTION_TEXTUREPROJ:		baseFuncName = "textureProj";		break;
1296		case FUNCTION_TEXTUREPROJ2:		baseFuncName = "textureProj";		break;
1297		case FUNCTION_TEXTUREPROJ3:		baseFuncName = "textureProj";		break;
1298		case FUNCTION_TEXTURELOD:		baseFuncName = "textureLod";		break;
1299		case FUNCTION_TEXTUREPROJLOD:	baseFuncName = "textureProjLod";	break;
1300		case FUNCTION_TEXTUREPROJLOD2:	baseFuncName = "textureProjLod";	break;
1301		case FUNCTION_TEXTUREPROJLOD3:	baseFuncName = "textureProjLod";	break;
1302		case FUNCTION_TEXTUREGRAD:		baseFuncName = "textureGrad";		break;
1303		case FUNCTION_TEXTUREPROJGRAD:	baseFuncName = "textureProjGrad";	break;
1304		case FUNCTION_TEXTUREPROJGRAD2:	baseFuncName = "textureProjGrad";	break;
1305		case FUNCTION_TEXTUREPROJGRAD3:	baseFuncName = "textureProjGrad";	break;
1306		case FUNCTION_TEXELFETCH:		baseFuncName = "texelFetch";		break;
1307		default:
1308			DE_ASSERT(DE_FALSE);
1309	}
1310
1311	std::ostringstream	vert;
1312	std::ostringstream	frag;
1313	std::ostringstream&	op		= isVtxCase ? vert : frag;
1314
1315	vert << "#version 450 core\n"
1316		 << "layout(location = 0) in highp vec4 a_position;\n"
1317		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
1318
1319	if (isGrad)
1320	{
1321		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
1322		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
1323	}
1324	else if (hasLodBias)
1325		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
1326
1327	frag << "#version 450 core\n";
1328
1329	if (m_lookupSpec.useClamp)
1330		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
1331
1332	frag  << "layout(location = 0) out mediump vec4 o_color;\n";
1333
1334	if (isVtxCase)
1335	{
1336		vert << "layout(location = 0) out mediump vec4 v_color;\n";
1337		frag << "layout(location = 0) in mediump vec4 v_color;\n";
1338	}
1339	else
1340	{
1341		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1342		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1343
1344		if (isGrad)
1345		{
1346			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1347			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1348			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1349			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1350		}
1351		else if (hasLodBias)
1352		{
1353			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
1354			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
1355		}
1356	}
1357
1358	// Uniforms
1359	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
1360	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
1361	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
1362
1363	vert << "out gl_PerVertex {\n"
1364		 << "\tvec4 gl_Position;\n"
1365		 << "};\n";
1366
1367	vert << "\nvoid main()\n{\n"
1368		 << "\tgl_Position = a_position;\n";
1369	frag << "\nvoid main()\n{\n";
1370
1371	if (isVtxCase)
1372		vert << "\tv_color = ";
1373	else
1374		frag << "\to_color = ";
1375
1376	// Op.
1377	{
1378		const char*	texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
1379		const char* gradX		= isVtxCase ? "a_in1" : "v_gradX";
1380		const char* gradY		= isVtxCase ? "a_in2" : "v_gradY";
1381		const char*	lodBias		= isVtxCase ? "a_in1" : "v_lodBias";
1382
1383		op << "vec4(" << baseFuncName;
1384		if (m_lookupSpec.useOffset)
1385			op << "Offset";
1386		if (m_lookupSpec.useClamp)
1387			op << "ClampARB";
1388		op << "(u_sampler, ";
1389
1390		if (isIntCoord)
1391			op << glu::getDataTypeName(glu::getDataTypeIntVec(texCoordComps+extraCoordComps)) << "(";
1392
1393		op << texCoord;
1394
1395		if (isIntCoord)
1396			op << ")";
1397
1398		if (isGrad)
1399			op << ", " << gradX << ", " << gradY;
1400
1401		if (functionHasLod(function))
1402		{
1403			if (isIntCoord)
1404				op << ", int(" << lodBias << ")";
1405			else
1406				op << ", " << lodBias;
1407		}
1408
1409		if (m_lookupSpec.useOffset)
1410		{
1411			int offsetComps = m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? 1 :
1412							  m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
1413
1414			op << ", " << glu::getDataTypeName(glu::getDataTypeIntVec(offsetComps)) << "(";
1415			for (int ndx = 0; ndx < offsetComps; ndx++)
1416			{
1417				if (ndx != 0)
1418					op << ", ";
1419				op << m_lookupSpec.offset[ndx];
1420			}
1421			op << ")";
1422		}
1423
1424		if (m_lookupSpec.useClamp)
1425			op << ", float(" << m_lookupSpec.lodClamp << ")";
1426
1427		if (isCubeArrayShadow && m_lookupSpec.function == FUNCTION_TEXTURE)
1428			op << ", " << texCoord << ".w";
1429
1430		if (m_lookupSpec.useBias)
1431			op << ", " << lodBias;
1432
1433		op << ")";
1434
1435		if (isShadow)
1436			op << ", 0.0, 0.0, 1.0)";
1437		else
1438			op << ")*u_scale + u_bias";
1439
1440		op << ";\n";
1441	}
1442
1443	if (isVtxCase)
1444		frag << "\to_color = v_color;\n";
1445	else
1446	{
1447		vert << "\tv_texCoord = a_in0;\n";
1448
1449		if (isGrad)
1450		{
1451			vert << "\tv_gradX = a_in1;\n";
1452			vert << "\tv_gradY = a_in2;\n";
1453		}
1454		else if (hasLodBias)
1455			vert << "\tv_lodBias = a_in1;\n";
1456	}
1457
1458	vert << "}\n";
1459	frag << "}\n";
1460
1461	m_vertShaderSource = vert.str();
1462	m_fragShaderSource = frag.str();
1463}
1464
1465enum QueryFunction
1466{
1467	QUERYFUNCTION_TEXTURESIZE = 0,
1468	QUERYFUNCTION_TEXTURESIZEMS,
1469	QUERYFUNCTION_TEXTUREQUERYLOD,
1470	QUERYFUNCTION_TEXTUREQUERYLEVELS,
1471	QUERYFUNCTION_TEXTURESAMPLES,
1472
1473	QUERYFUNCTION_LAST
1474};
1475
1476// test mode used to alter test behaviour
1477using TestMode = deUint32;
1478
1479enum QueryLodTestModes
1480{
1481	QLODTM_DEFAULT			= 0,		// uv coords have different values
1482	QLODTM_ZERO_UV_WIDTH				// all uv coords are 0; there were implementations that incorrectly returned 0 in that case instead of -maxSamplerLodBias or less
1483};
1484
1485class TextureQueryInstance : public ShaderRenderCaseInstance
1486{
1487public:
1488								TextureQueryInstance			(Context&					context,
1489																 const bool					isVertexCase,
1490																 const TextureSpec&			textureSpec);
1491	virtual						~TextureQueryInstance			(void);
1492
1493protected:
1494	virtual void				setupDefaultInputs				(void);
1495	virtual void				setupUniforms					(const tcu::Vec4&);
1496
1497	void						render							(void);
1498
1499protected:
1500	const TextureSpec&			m_textureSpec;
1501};
1502
1503TextureQueryInstance::TextureQueryInstance (Context&				context,
1504											const bool				isVertexCase,
1505											const TextureSpec&		textureSpec)
1506	: ShaderRenderCaseInstance	(context, isVertexCase, DE_NULL, DE_NULL, DE_NULL)
1507	, m_textureSpec				(textureSpec)
1508{
1509	m_colorFormat = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
1510
1511	checkDeviceFeatures(m_context, m_textureSpec.type);
1512}
1513
1514TextureQueryInstance::~TextureQueryInstance (void)
1515{
1516}
1517
1518void TextureQueryInstance::setupDefaultInputs (void)
1519{
1520	const deUint32		numVertices		= 4;
1521	const float			positions[]		=
1522	{
1523		-1.0f, -1.0f, 0.0f, 1.0f,
1524		-1.0f,  1.0f, 0.0f, 1.0f,
1525		 1.0f, -1.0f, 0.0f, 1.0f,
1526		 1.0f,  1.0f, 0.0f, 1.0f
1527	};
1528
1529	addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, positions);
1530}
1531
1532void TextureQueryInstance::setupUniforms (const tcu::Vec4&)
1533{
1534	useSampler(0u, 0u);
1535}
1536
1537void TextureQueryInstance::render (void)
1538{
1539	const deUint32		numVertices		= 4;
1540	const deUint32		numTriangles	= 2;
1541	const deUint16		indices[6]		= { 0, 1, 2, 2, 1, 3 };
1542
1543	ShaderRenderCaseInstance::setup();
1544
1545	ShaderRenderCaseInstance::render(numVertices, numTriangles, indices);
1546}
1547
1548static int getMaxTextureSize (TextureType type, const tcu::IVec3& textureSize)
1549{
1550	int		maxSize		= 0;
1551
1552	switch (type)
1553	{
1554		case TEXTURETYPE_1D:
1555		case TEXTURETYPE_1D_ARRAY:
1556			maxSize = textureSize.x();
1557			break;
1558
1559		case TEXTURETYPE_2D:
1560		case TEXTURETYPE_2D_ARRAY:
1561		case TEXTURETYPE_CUBE_MAP:
1562		case TEXTURETYPE_CUBE_ARRAY:
1563			maxSize = de::max(textureSize.x(), textureSize.y());
1564			break;
1565
1566		case TEXTURETYPE_3D:
1567			maxSize = de::max(textureSize.x(), de::max(textureSize.y(), textureSize.z()));
1568			break;
1569
1570		default:
1571			DE_ASSERT(false);
1572	}
1573
1574	return maxSize;
1575}
1576
1577static std::string getTextureSizeString (TextureType type, const tcu::IVec3& textureSize)
1578{
1579	std::ostringstream	str;
1580
1581	switch (type)
1582	{
1583		case TEXTURETYPE_1D:
1584			str << textureSize.x() << "x1";
1585			break;
1586
1587		case TEXTURETYPE_2D:
1588		case TEXTURETYPE_CUBE_MAP:
1589			str << textureSize.x() << "x" << textureSize.y();
1590			break;
1591
1592		case TEXTURETYPE_3D:
1593			str << textureSize.x() << "x" << textureSize.y() << "x" << textureSize.z();
1594			break;
1595
1596		case TEXTURETYPE_1D_ARRAY:
1597			str << textureSize.x() << "x1 with " << textureSize.z() << " layer(s)";
1598			break;
1599
1600		case TEXTURETYPE_2D_ARRAY:
1601		case TEXTURETYPE_CUBE_ARRAY:
1602			str << textureSize.x() << "x" << textureSize.y() << " with " << textureSize.z() << " layers(s)";
1603			break;
1604
1605		default:
1606			DE_ASSERT(false);
1607			break;
1608	}
1609
1610	return str.str();
1611}
1612
1613static bool isValidCase (TextureType type, const tcu::IVec3& textureSize, int lodBase)
1614{
1615	const bool	isSquare	= textureSize.x() == textureSize.y();
1616	const bool	isCubeArray	= isSquare && (textureSize.z() % 6) == 0;
1617	const int	maxSize		= getMaxTextureSize(type, textureSize);
1618	const bool	isBaseValid	= (maxSize >> lodBase) != 0;
1619
1620	if (!isBaseValid)
1621		return false;
1622	if (type == TEXTURETYPE_CUBE_MAP && !isSquare)
1623		return false;
1624	if (type == TEXTURETYPE_CUBE_ARRAY && !isCubeArray)
1625		return false;
1626
1627	return true;
1628}
1629
1630static TextureBindingSp createEmptyTexture (deUint32				format,
1631											TextureType				type,
1632											const tcu::IVec3&		textureSize,
1633											int						numLevels,
1634											int						lodBase,
1635											const tcu::Sampler&		sampler)
1636{
1637	const tcu::TextureFormat			texFmt				= glu::mapGLInternalFormat(format);
1638	const TextureBinding::Parameters	params				(lodBase);
1639	TextureBindingSp					textureBinding;
1640
1641	switch (type)
1642	{
1643
1644		case TEXTURETYPE_1D:
1645		{
1646			de::MovePtr<tcu::Texture1D>			texture		(new tcu::Texture1D(texFmt, textureSize.x()));
1647
1648			for (int level = 0; level < numLevels; level++)
1649				texture->allocLevel(level);
1650
1651			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1652			break;
1653		}
1654
1655		case TEXTURETYPE_2D:
1656		{
1657			de::MovePtr<tcu::Texture2D>			texture		(new tcu::Texture2D(texFmt, textureSize.x(), textureSize.y()));
1658
1659			for (int level = 0; level < numLevels; level++)
1660				texture->allocLevel(level);
1661
1662			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1663			break;
1664		}
1665
1666		case TEXTURETYPE_3D:
1667		{
1668			de::MovePtr<tcu::Texture3D>			texture		(new tcu::Texture3D(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1669
1670			for (int level = 0; level < numLevels; level++)
1671				texture->allocLevel(level);
1672
1673			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1674			break;
1675		}
1676
1677		case TEXTURETYPE_CUBE_MAP:
1678		{
1679			de::MovePtr<tcu::TextureCube>		texture		(new tcu::TextureCube(texFmt, textureSize.x()));
1680
1681			for (int level = 0; level < numLevels; level++)
1682				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1683					texture->allocLevel((tcu::CubeFace)face, level);
1684
1685			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1686			break;
1687		}
1688
1689		case TEXTURETYPE_1D_ARRAY:
1690		{
1691			de::MovePtr<tcu::Texture1DArray>	texture		(new tcu::Texture1DArray(texFmt, textureSize.x(), textureSize.z()));
1692
1693			for (int level = 0; level < numLevels; level++)
1694				texture->allocLevel(level);
1695
1696			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1697			break;
1698		}
1699
1700		case TEXTURETYPE_2D_ARRAY:
1701		{
1702			de::MovePtr<tcu::Texture2DArray>	texture		(new tcu::Texture2DArray(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1703
1704			for (int level = 0; level < numLevels; level++)
1705				texture->allocLevel(level);
1706
1707			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1708			break;
1709		}
1710
1711		case TEXTURETYPE_CUBE_ARRAY:
1712		{
1713			de::MovePtr<tcu::TextureCubeArray>	texture		(new tcu::TextureCubeArray(texFmt, textureSize.x(), textureSize.z()));
1714
1715			for (int level = 0; level < numLevels; level++)
1716				texture->allocLevel(level);
1717
1718			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1719			break;
1720		}
1721
1722		default:
1723			DE_ASSERT(false);
1724			break;
1725	}
1726
1727	textureBinding->setParameters(params);
1728	return textureBinding;
1729}
1730
1731static inline glu::DataType getTextureSizeFuncResultType (TextureType textureType)
1732{
1733	switch (textureType)
1734	{
1735		case TEXTURETYPE_1D:
1736			return glu::TYPE_INT;
1737
1738		case TEXTURETYPE_2D:
1739		case TEXTURETYPE_CUBE_MAP:
1740		case TEXTURETYPE_1D_ARRAY:
1741			return glu::TYPE_INT_VEC2;
1742
1743		case TEXTURETYPE_3D:
1744		case TEXTURETYPE_2D_ARRAY:
1745		case TEXTURETYPE_CUBE_ARRAY:
1746			return glu::TYPE_INT_VEC3;
1747
1748		default:
1749			DE_ASSERT(false);
1750			return glu::TYPE_LAST;
1751	}
1752}
1753
1754class TextureSizeInstance : public TextureQueryInstance
1755{
1756public:
1757								TextureSizeInstance				(Context&					context,
1758																 const bool					isVertexCase,
1759																 const TextureSpec&			textureSpec);
1760	virtual						~TextureSizeInstance			(void);
1761
1762	virtual tcu::TestStatus		iterate							(void);
1763
1764protected:
1765	virtual void				setupUniforms					(const tcu::Vec4& constCoords);
1766
1767private:
1768	struct TestSize
1769	{
1770		tcu::IVec3	textureSize;
1771		int			lod;
1772		int			lodBase;
1773		tcu::IVec3	expectedSize;
1774	};
1775
1776	void						initTexture						(void);
1777	bool						testTextureSize					(void);
1778
1779	TestSize					m_testSize;
1780	tcu::IVec3					m_expectedSize;
1781	int							m_iterationCounter;
1782};
1783
1784TextureSizeInstance::TextureSizeInstance (Context&					context,
1785										  const bool				isVertexCase,
1786										  const TextureSpec&		textureSpec)
1787	: TextureQueryInstance		(context, isVertexCase, textureSpec)
1788	, m_testSize				()
1789	, m_expectedSize			()
1790	, m_iterationCounter		(0)
1791{
1792	deMemset(&m_testSize, 0, sizeof(TestSize));
1793
1794#ifdef CTS_USES_VULKANSC
1795	const VkDevice			vkDevice			= getDevice();
1796	const DeviceInterface&	vk					= getDeviceInterface();
1797	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
1798	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
1799#endif // CTS_USES_VULKANSC
1800
1801	m_renderSize = tcu::UVec2(1, 1);
1802}
1803
1804TextureSizeInstance::~TextureSizeInstance (void)
1805{
1806}
1807
1808void TextureSizeInstance::setupUniforms (const tcu::Vec4& constCoords)
1809{
1810	TextureQueryInstance::setupUniforms(constCoords);
1811	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(int), &m_testSize.lod);
1812}
1813
1814void TextureSizeInstance::initTexture (void)
1815{
1816	tcu::TestLog&			log					= m_context.getTestContext().getLog();
1817	const int				numLevels			= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
1818	TextureBindingSp		textureBinding;
1819
1820	log << tcu::TestLog::Message << "Testing image size " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
1821	log << tcu::TestLog::Message << "Lod: " << m_testSize.lod << ", base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
1822
1823	switch (m_textureSpec.type)
1824	{
1825		case TEXTURETYPE_3D:
1826			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << "x" << m_testSize.expectedSize.z() << tcu::TestLog::EndMessage;
1827			break;
1828
1829		case TEXTURETYPE_2D:
1830			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1831			break;
1832
1833		case TEXTURETYPE_CUBE_MAP:
1834			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1835			break;
1836
1837		case TEXTURETYPE_2D_ARRAY:
1838			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1839			break;
1840
1841		case TEXTURETYPE_CUBE_ARRAY:
1842			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << (m_testSize.textureSize.z() / 6) << " cube(s)" << tcu::TestLog::EndMessage;
1843			break;
1844
1845		case TEXTURETYPE_1D:
1846			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << tcu::TestLog::EndMessage;
1847			break;
1848
1849		case TEXTURETYPE_1D_ARRAY:
1850			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1851			break;
1852
1853		default:
1854			DE_ASSERT(false);
1855			break;
1856	}
1857
1858	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
1859
1860	m_textures.clear();
1861	m_textures.push_back(textureBinding);
1862}
1863
1864tcu::TestStatus TextureSizeInstance::iterate (void)
1865{
1866	const TestSize testSizes[] =
1867	{
1868		{ tcu::IVec3(1, 2, 1),			0,		0,	tcu::IVec3(1, 2, 1)			},
1869		{ tcu::IVec3(1, 2, 1),			1,		0,	tcu::IVec3(1, 1, 1)			},
1870
1871		{ tcu::IVec3(1, 3, 2),			0,		0,	tcu::IVec3(1, 3, 2)			},
1872		{ tcu::IVec3(1, 3, 2),			1,		0,	tcu::IVec3(1, 1, 1)			},
1873
1874		{ tcu::IVec3(100, 31, 18),		0,		0,	tcu::IVec3(100, 31, 18)		},
1875		{ tcu::IVec3(100, 31, 18),		1,		0,	tcu::IVec3(50, 15, 9)		},
1876		{ tcu::IVec3(100, 31, 18),		2,		0,	tcu::IVec3(25, 7, 4)		},
1877		{ tcu::IVec3(100, 31, 18),		3,		0,	tcu::IVec3(12, 3, 2)		},
1878		{ tcu::IVec3(100, 31, 18),		4,		0,	tcu::IVec3(6, 1, 1)			},
1879		{ tcu::IVec3(100, 31, 18),		5,		0,	tcu::IVec3(3, 1, 1)			},
1880		{ tcu::IVec3(100, 31, 18),		6,		0,	tcu::IVec3(1, 1, 1)			},
1881
1882		{ tcu::IVec3(100, 128, 32),		0,		0,	tcu::IVec3(100, 128, 32)	},
1883		{ tcu::IVec3(100, 128, 32),		1,		0,	tcu::IVec3(50, 64, 16)		},
1884		{ tcu::IVec3(100, 128, 32),		2,		0,	tcu::IVec3(25, 32, 8)		},
1885		{ tcu::IVec3(100, 128, 32),		3,		0,	tcu::IVec3(12, 16, 4)		},
1886		{ tcu::IVec3(100, 128, 32),		4,		0,	tcu::IVec3(6, 8, 2)			},
1887		{ tcu::IVec3(100, 128, 32),		5,		0,	tcu::IVec3(3, 4, 1)			},
1888		{ tcu::IVec3(100, 128, 32),		6,		0,	tcu::IVec3(1, 2, 1)			},
1889		{ tcu::IVec3(100, 128, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1890
1891		// pow 2
1892		{ tcu::IVec3(128, 64, 32),		0,		0,	tcu::IVec3(128, 64, 32)		},
1893		{ tcu::IVec3(128, 64, 32),		1,		0,	tcu::IVec3(64, 32, 16)		},
1894		{ tcu::IVec3(128, 64, 32),		2,		0,	tcu::IVec3(32, 16, 8)		},
1895		{ tcu::IVec3(128, 64, 32),		3,		0,	tcu::IVec3(16, 8, 4)		},
1896		{ tcu::IVec3(128, 64, 32),		4,		0,	tcu::IVec3(8, 4, 2)			},
1897		{ tcu::IVec3(128, 64, 32),		5,		0,	tcu::IVec3(4, 2, 1)			},
1898		{ tcu::IVec3(128, 64, 32),		6,		0,	tcu::IVec3(2, 1, 1)			},
1899		{ tcu::IVec3(128, 64, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1900
1901		// w == h
1902		{ tcu::IVec3(1, 1, 1),			0,		0,	tcu::IVec3(1, 1, 1)			},
1903		{ tcu::IVec3(64, 64, 64),		0,		0,	tcu::IVec3(64, 64, 64)		},
1904		{ tcu::IVec3(64, 64, 64),		1,		0,	tcu::IVec3(32, 32, 32)		},
1905		{ tcu::IVec3(64, 64, 64),		2,		0,	tcu::IVec3(16, 16, 16)		},
1906		{ tcu::IVec3(64, 64, 64),		3,		0,	tcu::IVec3(8, 8, 8)			},
1907		{ tcu::IVec3(64, 64, 64),		4,		0,	tcu::IVec3(4, 4, 4)			},
1908
1909		// with lod base
1910		{ tcu::IVec3(100, 31, 18),		3,		1,	tcu::IVec3(6, 1, 1)			},
1911		{ tcu::IVec3(128, 64, 32),		3,		1,	tcu::IVec3(8, 4, 2)			},
1912		{ tcu::IVec3(64, 64, 64),		1,		1,	tcu::IVec3(16, 16, 16)		},
1913
1914		{ tcu::IVec3(100, 31, 18),		1,		2,	tcu::IVec3(12, 3, 2)		},
1915		{ tcu::IVec3(100, 31, 18),		2,		2,	tcu::IVec3(6, 1, 1)			},
1916		{ tcu::IVec3(100, 31, 18),		1,		4,	tcu::IVec3(3, 1, 1)			},
1917
1918		// out-of-range mip levels
1919		{ tcu::IVec3(1, 3, 2),			-7,		0,	tcu::IVec3(0, 0, 0)			},
1920		{ tcu::IVec3(1, 3, 2),			106,	0,	tcu::IVec3(0, 0, 0)			},
1921		{ tcu::IVec3(100, 31, 18),		7,		0,	tcu::IVec3(0, 0, 0)			},
1922		{ tcu::IVec3(32, 32, 12),		6,		0,	tcu::IVec3(0, 0, 0)			},
1923		{ tcu::IVec3(32, 32, 12),		-9,		0,	tcu::IVec3(0, 0, 0)			},
1924		{ tcu::IVec3(32, 32, 12),		4396,	0,	tcu::IVec3(0, 0, 0)			},
1925
1926		// w == h and d % 6 == 0 (for cube array)
1927		{ tcu::IVec3(1, 1, 6),			0,		0,	tcu::IVec3(1, 1, 6)			},
1928		{ tcu::IVec3(32, 32, 12),		0,		0,	tcu::IVec3(32, 32, 12)		},
1929		{ tcu::IVec3(32, 32, 12),		0,		1,	tcu::IVec3(16, 16, 6)		},
1930		{ tcu::IVec3(32, 32, 12),		1,		0,	tcu::IVec3(16, 16, 6)		},
1931		{ tcu::IVec3(32, 32, 12),		2,		0,	tcu::IVec3(8, 8, 3)			},
1932		{ tcu::IVec3(32, 32, 12),		3,		0,	tcu::IVec3(4, 4, 1)			},
1933		{ tcu::IVec3(32, 32, 12),		4,		0,	tcu::IVec3(2, 2, 1)			},
1934		{ tcu::IVec3(32, 32, 12),		5,		0,	tcu::IVec3(1, 1, 1)			},
1935	};
1936	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1937
1938	m_iterationCounter++;
1939
1940	if (m_iterationCounter == lastIterationIndex)
1941		return tcu::TestStatus::pass("Pass");
1942	else
1943	{
1944		// set current test size
1945		m_testSize = testSizes[m_iterationCounter - 1];
1946
1947		bool result = testTextureSize();
1948#ifdef CTS_USES_VULKANSC
1949		if (m_context.getTestContext().getCommandLine().isSubProcess())
1950#endif // CTS_USES_VULKANSC
1951		{
1952			if (!result)
1953				return tcu::TestStatus::fail("Got unexpected result");
1954		}
1955		return tcu::TestStatus::incomplete();
1956	}
1957}
1958
1959bool TextureSizeInstance::testTextureSize (void)
1960{
1961	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1962	bool					success			= true;
1963
1964	// skip incompatible cases
1965	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
1966		return true;
1967
1968	// setup texture
1969	initTexture();
1970
1971	// determine expected texture size
1972	switch (m_textureSpec.type)
1973	{
1974		case TEXTURETYPE_1D:
1975		case TEXTURETYPE_2D:
1976		case TEXTURETYPE_3D:
1977		case TEXTURETYPE_CUBE_MAP:
1978			m_expectedSize = m_testSize.expectedSize;
1979			break;
1980
1981		case TEXTURETYPE_1D_ARRAY:
1982			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.textureSize.z(), 0);
1983			break;
1984
1985		case TEXTURETYPE_2D_ARRAY:
1986			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z());
1987			break;
1988
1989		case TEXTURETYPE_CUBE_ARRAY:
1990			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z() / 6);
1991			break;
1992
1993		default:
1994			DE_ASSERT(false);
1995			break;
1996	}
1997
1998	// render
1999	TextureQueryInstance::render();
2000
2001	// test
2002	{
2003		const tcu::TextureLevel&	result				= getResultImage();
2004		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2005		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2006
2007		for (int ndx = 0; ndx < resultComponents; ndx++)
2008		{
2009			// We test all levels, but only compare results for valid LoDs. The others give
2010			// undefined values.
2011			const int	maxSize		= getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize);
2012			const bool	isLodValid	= (maxSize >> (m_testSize.lod + m_testSize.lodBase)) != 0;
2013			if (isLodValid && output[ndx] != m_expectedSize[ndx])
2014			{
2015				success = false;
2016				break;
2017			}
2018		}
2019
2020		if (success)
2021		{
2022			// success
2023			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2024		}
2025		else
2026		{
2027			// failure
2028			std::stringstream	resultSizeStr;
2029			switch (resultComponents)
2030			{
2031				case 1:
2032					resultSizeStr << output[0];
2033					break;
2034				case 2:
2035					resultSizeStr << output.toWidth<2>();
2036					break;
2037				case 3:
2038					resultSizeStr << output.toWidth<3>();
2039					break;
2040				default:
2041					DE_ASSERT(false);
2042					break;
2043			}
2044			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2045			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2046		}
2047	}
2048
2049	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2050
2051	return success;
2052}
2053
2054static vk::VkImageType getVkImageType (TextureType type)
2055{
2056	switch (type)
2057	{
2058		case TEXTURETYPE_1D:
2059		case TEXTURETYPE_1D_ARRAY:
2060			return vk::VK_IMAGE_TYPE_1D;
2061
2062		case TEXTURETYPE_2D:
2063		case TEXTURETYPE_2D_ARRAY:
2064		case TEXTURETYPE_CUBE_MAP:
2065		case TEXTURETYPE_CUBE_ARRAY:
2066			return vk::VK_IMAGE_TYPE_2D;
2067
2068		case TEXTURETYPE_3D:
2069			return vk::VK_IMAGE_TYPE_3D;
2070
2071		default:
2072			DE_ASSERT(false);
2073			return (vk::VkImageType)0;
2074	}
2075}
2076
2077class TextureSizeMSInstance : public TextureQueryInstance
2078{
2079public:
2080								TextureSizeMSInstance			(Context&					context,
2081																 const bool					isVertexCase,
2082																 const TextureSpec&			textureSpec);
2083	virtual						~TextureSizeMSInstance			(void);
2084
2085	virtual tcu::TestStatus		iterate							(void);
2086
2087private:
2088	void						initTexture						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2089	bool						testSize						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2090
2091	unsigned								m_iterationCounter;
2092	vector<vk::VkSampleCountFlagBits>		m_iterations;
2093};
2094
2095TextureSizeMSInstance::TextureSizeMSInstance	(Context&				context,
2096												const bool				isVertexCase,
2097												const TextureSpec&		textureSpec)
2098	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2099	, m_iterationCounter		(0)
2100{
2101	m_renderSize = tcu::UVec2(1, 1);
2102
2103	// determine available sample counts
2104	{
2105		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2106		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2107		vk::VkImageFormatProperties				properties;
2108
2109		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2110																					format,
2111																					imageType,
2112																					vk::VK_IMAGE_TILING_OPTIMAL,
2113																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2114																					(vk::VkImageCreateFlags)0,
2115																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2116			TCU_THROW(NotSupportedError, "Format not supported");
2117
2118		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2119		//       which invokes OpImageQuerySize against the image and checks the result.
2120		//
2121		//       Multisample images do not support a sample count of 1, so start from 2 samples.
2122		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2123		{
2124			vk::VK_SAMPLE_COUNT_2_BIT,
2125			vk::VK_SAMPLE_COUNT_4_BIT,
2126			vk::VK_SAMPLE_COUNT_8_BIT,
2127			vk::VK_SAMPLE_COUNT_16_BIT,
2128			vk::VK_SAMPLE_COUNT_32_BIT,
2129			vk::VK_SAMPLE_COUNT_64_BIT
2130		};
2131
2132		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2133		{
2134			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2135
2136			if ((properties.sampleCounts & flag) != 0)
2137				m_iterations.push_back(flag);
2138		}
2139
2140		if (m_iterations.empty())
2141		{
2142			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2143			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2144				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2145			{
2146				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2147			}
2148
2149			DE_ASSERT(false);
2150		}
2151	}
2152}
2153
2154TextureSizeMSInstance::~TextureSizeMSInstance (void)
2155{
2156}
2157
2158tcu::TestStatus TextureSizeMSInstance::iterate (void)
2159{
2160	const tcu::IVec3 testSizes[] =
2161	{
2162		tcu::IVec3(1, 1, 1),
2163		tcu::IVec3(1, 2, 1),
2164		tcu::IVec3(1, 3, 2),
2165		tcu::IVec3(1, 1, 6),
2166		tcu::IVec3(32, 32, 12),
2167		tcu::IVec3(64, 64, 64),
2168		tcu::IVec3(100, 31, 18),
2169		tcu::IVec3(100, 128, 32),
2170		tcu::IVec3(128, 64, 32),
2171	};
2172
2173	unsigned sampleIdx	= m_iterationCounter / DE_LENGTH_OF_ARRAY(testSizes);
2174	unsigned dimIdx		= m_iterationCounter % DE_LENGTH_OF_ARRAY(testSizes);
2175
2176	if (m_iterationCounter++ <  m_iterations.size() * DE_LENGTH_OF_ARRAY(testSizes))
2177	{
2178		bool result = testSize(m_iterations[sampleIdx], testSizes[dimIdx]);
2179#ifdef CTS_USES_VULKANSC
2180		if (m_context.getTestContext().getCommandLine().isSubProcess())
2181#endif // CTS_USES_VULKANSC
2182		{
2183			if (!result)
2184				return tcu::TestStatus::fail("Got unexpected result");
2185		}
2186		return tcu::TestStatus::incomplete();
2187	}
2188	else
2189		return tcu::TestStatus::pass("Pass");
2190}
2191
2192bool TextureSizeMSInstance::testSize (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2193{
2194	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2195
2196	// setup texture
2197	initTexture(samples, dim);
2198
2199	// render
2200	TextureQueryInstance::render();
2201
2202	// test
2203	{
2204		const tcu::TextureLevel&	result				= getResultImage();
2205		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2206		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2207
2208		bool success = true;
2209
2210		for (int ndx = 0; ndx < resultComponents; ndx++)
2211		{
2212			if (output[ndx] != dim[ndx])
2213			{
2214				success = false;
2215				break;
2216			}
2217		}
2218
2219		if (success)
2220		{
2221			// success
2222			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2223			return true;
2224		}
2225		else
2226		{
2227			// failure
2228			std::stringstream	resultSizeStr;
2229			switch (resultComponents)
2230			{
2231				case 1:
2232					resultSizeStr << output[0];
2233					break;
2234				case 2:
2235					resultSizeStr << output.toWidth<2>();
2236					break;
2237				case 3:
2238					resultSizeStr << output.toWidth<3>();
2239					break;
2240				default:
2241					DE_ASSERT(false);
2242					break;
2243			}
2244			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2245			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2246			return false;
2247		}
2248	}
2249}
2250
2251void TextureSizeMSInstance::initTexture (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2252{
2253	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2254	TextureBindingSp		textureBinding;
2255
2256	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2257
2258	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, dim) << ", samples: " << samples << tcu::TestLog::EndMessage;
2259
2260	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, dim, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2261
2262	m_textures.clear();
2263	m_textures.push_back(textureBinding);
2264
2265	// update samples count
2266	{
2267		DE_ASSERT(m_textures.size() == 1);
2268
2269		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2270
2271		params.initialization	= TextureBinding::INIT_CLEAR;
2272		params.samples			= samples;
2273
2274		m_textures[0]->setParameters(params);
2275	}
2276}
2277
2278class TextureSamplesInstance : public TextureQueryInstance
2279{
2280public:
2281								TextureSamplesInstance			(Context&					context,
2282																 const bool					isVertexCase,
2283																 const TextureSpec&			textureSpec);
2284	virtual						~TextureSamplesInstance			(void);
2285
2286	virtual tcu::TestStatus		iterate							(void);
2287
2288private:
2289	void						initTexture						(void);
2290
2291	int										m_iterationCounter;
2292	vector<vk::VkSampleCountFlagBits>		m_iterations;
2293};
2294
2295TextureSamplesInstance::TextureSamplesInstance (Context&				context,
2296												const bool				isVertexCase,
2297												const TextureSpec&		textureSpec)
2298	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2299	, m_iterationCounter		(0)
2300{
2301	m_renderSize = tcu::UVec2(1, 1);
2302
2303	// determine available sample counts
2304	{
2305		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2306		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2307		vk::VkImageFormatProperties				properties;
2308
2309		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2310																					format,
2311																					imageType,
2312																					vk::VK_IMAGE_TILING_OPTIMAL,
2313																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2314																					(vk::VkImageCreateFlags)0,
2315																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2316			TCU_THROW(NotSupportedError, "Format not supported");
2317
2318		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2319		//       which invokes OpImageQuerySamples against the image and checks the result.
2320		//
2321		//       Now, in the SPIR-V spec for the very operation we have the following language:
2322		//
2323		//       OpImageQuerySamples
2324		//       Query the number of samples available per texel fetch in a multisample image.
2325		//       Result Type must be a scalar integer type.
2326		//       The result is the number of samples.
2327		//       Image must be an object whose type is OpTypeImage.
2328		//       Its Dim operand must be one of 2D and **MS of 1(multisampled).
2329		//
2330		//       "MS of 1" implies the image must not be single-sample, meaning we must exclude
2331		//       VK_SAMPLE_COUNT_1_BIT in the sampleFlags array below, and may have to skip further testing.
2332		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2333		{
2334			vk::VK_SAMPLE_COUNT_2_BIT,
2335			vk::VK_SAMPLE_COUNT_4_BIT,
2336			vk::VK_SAMPLE_COUNT_8_BIT,
2337			vk::VK_SAMPLE_COUNT_16_BIT,
2338			vk::VK_SAMPLE_COUNT_32_BIT,
2339			vk::VK_SAMPLE_COUNT_64_BIT
2340		};
2341
2342		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2343		{
2344			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2345
2346			if ((properties.sampleCounts & flag) != 0)
2347				m_iterations.push_back(flag);
2348		}
2349
2350		if (m_iterations.empty())
2351		{
2352			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2353			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2354				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2355			{
2356				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2357			}
2358
2359			DE_ASSERT(false);
2360		}
2361	}
2362
2363	// setup texture
2364	initTexture();
2365}
2366
2367TextureSamplesInstance::~TextureSamplesInstance (void)
2368{
2369}
2370
2371tcu::TestStatus TextureSamplesInstance::iterate (void)
2372{
2373	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2374
2375	// update samples count
2376	{
2377		DE_ASSERT(m_textures.size() == 1);
2378
2379		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2380
2381		params.initialization	= TextureBinding::INIT_CLEAR;
2382		params.samples			= m_iterations[m_iterationCounter];
2383		log << tcu::TestLog::Message << "Expected samples: " << m_iterations[m_iterationCounter] << tcu::TestLog::EndMessage;
2384
2385		m_textures[0]->setParameters(params);
2386	}
2387
2388	// render
2389	TextureQueryInstance::render();
2390
2391	// test
2392	{
2393		const tcu::TextureLevel&	result				= getResultImage();
2394		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2395
2396#ifdef CTS_USES_VULKANSC
2397		if (m_context.getTestContext().getCommandLine().isSubProcess())
2398#endif // CTS_USES_VULKANSC
2399		{
2400			if (output.x() == (int)m_iterations[m_iterationCounter])
2401			{
2402				// success
2403				log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2404			}
2405			else
2406			{
2407				// failure
2408				log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2409				log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2410				return tcu::TestStatus::fail("Got unexpected result");
2411			}
2412		}
2413
2414		m_iterationCounter++;
2415		if (m_iterationCounter == (int)m_iterations.size())
2416			return tcu::TestStatus::pass("Pass");
2417		else
2418			return tcu::TestStatus::incomplete();
2419	}
2420}
2421
2422void TextureSamplesInstance::initTexture (void)
2423{
2424	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2425	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2426	TextureBindingSp		textureBinding;
2427
2428	DE_ASSERT(m_textures.empty());
2429	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2430
2431	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2432
2433	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2434
2435	m_textures.push_back(textureBinding);
2436}
2437
2438class TextureQueryLevelsInstance : public TextureQueryInstance
2439{
2440public:
2441								TextureQueryLevelsInstance		(Context&					context,
2442																 const bool					isVertexCase,
2443																 const TextureSpec&			textureSpec);
2444	virtual						~TextureQueryLevelsInstance		(void);
2445
2446	virtual tcu::TestStatus		iterate							(void);
2447
2448private:
2449	struct TestSize
2450	{
2451		tcu::IVec3	textureSize;
2452		int			lodBase;
2453	};
2454
2455	void						initTexture						(void);
2456	bool						testTextureLevels				(void);
2457
2458	TestSize					m_testSize;
2459	int							m_levels;
2460	int							m_iterationCounter;
2461};
2462
2463TextureQueryLevelsInstance::TextureQueryLevelsInstance (Context&				context,
2464														const bool				isVertexCase,
2465														const TextureSpec&		textureSpec)
2466	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2467	, m_testSize				()
2468	, m_levels					(0)
2469	, m_iterationCounter		(0)
2470{
2471	deMemset(&m_testSize, 0, sizeof(TestSize));
2472
2473	m_renderSize								= tcu::UVec2(1, 1);
2474
2475#ifdef CTS_USES_VULKANSC
2476	const VkDevice			vkDevice			= getDevice();
2477	const DeviceInterface&	vk					= getDeviceInterface();
2478	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
2479	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
2480#endif // CTS_USES_VULKANSC
2481}
2482
2483TextureQueryLevelsInstance::~TextureQueryLevelsInstance (void)
2484{
2485}
2486
2487tcu::TestStatus TextureQueryLevelsInstance::iterate (void)
2488{
2489	const TestSize testSizes[] =
2490	{
2491		{ tcu::IVec3(1, 2, 1),			0	},
2492		{ tcu::IVec3(1, 2, 1),			1	},
2493
2494		{ tcu::IVec3(1, 3, 2),			0	},
2495		{ tcu::IVec3(1, 3, 2),			1	},
2496
2497		{ tcu::IVec3(100, 31, 18),		0	},
2498		{ tcu::IVec3(100, 31, 18),		1	},
2499		{ tcu::IVec3(100, 31, 18),		2	},
2500		{ tcu::IVec3(100, 31, 18),		3	},
2501		{ tcu::IVec3(100, 31, 18),		4	},
2502		{ tcu::IVec3(100, 31, 18),		5	},
2503		{ tcu::IVec3(100, 31, 18),		6	},
2504
2505		{ tcu::IVec3(100, 128, 32),		0	},
2506		{ tcu::IVec3(100, 128, 32),		1	},
2507		{ tcu::IVec3(100, 128, 32),		2	},
2508		{ tcu::IVec3(100, 128, 32),		3	},
2509		{ tcu::IVec3(100, 128, 32),		4	},
2510		{ tcu::IVec3(100, 128, 32),		5	},
2511		{ tcu::IVec3(100, 128, 32),		6	},
2512		{ tcu::IVec3(100, 128, 32),		7	},
2513
2514		// pow 2
2515		{ tcu::IVec3(128, 64, 32),		0	},
2516		{ tcu::IVec3(128, 64, 32),		1	},
2517		{ tcu::IVec3(128, 64, 32),		2	},
2518		{ tcu::IVec3(128, 64, 32),		3	},
2519		{ tcu::IVec3(128, 64, 32),		4	},
2520		{ tcu::IVec3(128, 64, 32),		5	},
2521		{ tcu::IVec3(128, 64, 32),		6	},
2522		{ tcu::IVec3(128, 64, 32),		7	},
2523
2524		// w == h
2525		{ tcu::IVec3(1, 1, 1),			0	},
2526		{ tcu::IVec3(64, 64, 64),		0	},
2527		{ tcu::IVec3(64, 64, 64),		1	},
2528		{ tcu::IVec3(64, 64, 64),		2	},
2529		{ tcu::IVec3(64, 64, 64),		3	},
2530		{ tcu::IVec3(64, 64, 64),		4	},
2531		{ tcu::IVec3(64, 64, 64),		5	},
2532		{ tcu::IVec3(64, 64, 64),		6	},
2533
2534		// w == h and d % 6 == 0 (for cube array)
2535		{ tcu::IVec3(1, 1, 6),			0	},
2536		{ tcu::IVec3(32, 32, 12),		0	},
2537		{ tcu::IVec3(32, 32, 12),		1	},
2538		{ tcu::IVec3(32, 32, 12),		2	},
2539		{ tcu::IVec3(32, 32, 12),		3	},
2540		{ tcu::IVec3(32, 32, 12),		4	},
2541		{ tcu::IVec3(32, 32, 12),		5	},
2542	};
2543	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
2544
2545	m_iterationCounter++;
2546
2547	if (m_iterationCounter == lastIterationIndex)
2548		return tcu::TestStatus::pass("Pass");
2549	else
2550	{
2551		// set current test size
2552		m_testSize = testSizes[m_iterationCounter - 1];
2553
2554		bool result = testTextureLevels();
2555#ifdef CTS_USES_VULKANSC
2556		if (m_context.getTestContext().getCommandLine().isSubProcess())
2557#endif // CTS_USES_VULKANSC
2558		{
2559			if (!result)
2560				return tcu::TestStatus::fail("Got unexpected result");
2561		}
2562		return tcu::TestStatus::incomplete();
2563	}
2564}
2565
2566bool TextureQueryLevelsInstance::testTextureLevels (void)
2567{
2568	tcu::TestLog&			log				= m_context.getTestContext().getLog();
2569	bool					success			= true;
2570
2571	// skip incompatible cases
2572	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
2573		return true;
2574
2575	// setup texture
2576	initTexture();
2577
2578	// calculate accessible levels
2579	{
2580		const int	mipLevels	= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
2581
2582		m_levels = mipLevels - m_testSize.lodBase;
2583		DE_ASSERT(m_levels > 0);
2584
2585		log << tcu::TestLog::Message << "Expected levels: " << m_levels << tcu::TestLog::EndMessage;
2586	}
2587
2588	// render
2589	TextureQueryInstance::render();
2590
2591	// test
2592	{
2593		const tcu::TextureLevel&	result				= getResultImage();
2594		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2595
2596		if (output.x() == m_levels)
2597		{
2598			// success
2599			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2600		}
2601		else
2602		{
2603			// failure
2604			log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2605			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2606			success = false;
2607		}
2608	}
2609
2610	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2611
2612	return success;
2613}
2614
2615void TextureQueryLevelsInstance::initTexture (void)
2616{
2617	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2618	int						numLevels			= m_testSize.lodBase + 1;
2619	TextureBindingSp		textureBinding;
2620
2621	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
2622	log << tcu::TestLog::Message << "Base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
2623
2624	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
2625
2626	m_textures.clear();
2627	m_textures.push_back(textureBinding);
2628}
2629
2630static int getQueryLodFuncTextCoordComps (TextureType type)
2631{
2632	switch (type)
2633	{
2634		case TEXTURETYPE_1D:
2635		case TEXTURETYPE_1D_ARRAY:
2636			return 1;
2637
2638		case TEXTURETYPE_2D:
2639		case TEXTURETYPE_2D_ARRAY:
2640			return 2;
2641
2642		case TEXTURETYPE_3D:
2643		case TEXTURETYPE_CUBE_MAP:
2644		case TEXTURETYPE_CUBE_ARRAY:
2645			return 3;
2646
2647		default:
2648			DE_ASSERT(false);
2649			return 0;
2650	}
2651}
2652
2653class TextureQueryLodInstance : public TextureQueryInstance
2654{
2655public:
2656								TextureQueryLodInstance			(Context&					context,
2657																 const bool					isVertexCase,
2658																 const TextureSpec&			textureSpec,
2659																 const TestMode				mode);
2660	virtual						~TextureQueryLodInstance		(void);
2661
2662	virtual tcu::TestStatus		iterate							(void);
2663
2664protected:
2665	virtual void				setupDefaultInputs				(void);
2666
2667private:
2668	void						initTexture						(void);
2669	float						computeLevelFromLod				(float computedLod) const;
2670	vector<float>				computeQuadTexCoord				(void) const;
2671
2672	const TestMode				m_mode;
2673	tcu::Vec4					m_minCoord;
2674	tcu::Vec4					m_maxCoord;
2675	tcu::Vec2					m_lodBounds;
2676	tcu::Vec2					m_levelBounds;
2677};
2678
2679TextureQueryLodInstance::TextureQueryLodInstance (Context&					context,
2680												  const bool				isVertexCase,
2681												  const TextureSpec&		textureSpec,
2682												  const TestMode			mode)
2683	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2684	, m_mode					(mode)
2685	, m_minCoord				()
2686	, m_maxCoord				()
2687	, m_lodBounds				()
2688	, m_levelBounds				()
2689{
2690	// setup texture
2691	initTexture();
2692
2693	if (m_mode == QLODTM_DEFAULT)
2694	{
2695		const tcu::UVec2&	viewportSize	= getViewportSize();
2696		const float			lodEps			= (1.0f / float(1u << m_context.getDeviceProperties().limits.mipmapPrecisionBits)) + 0.008f;
2697
2698		// init min/max coords and calculate lod and accessed level
2699		switch (m_textureSpec.type)
2700		{
2701			case TEXTURETYPE_1D:
2702			case TEXTURETYPE_1D_ARRAY:
2703			{
2704				m_minCoord = Vec4(-0.2f, 0.0f, 0.0f, 0.0f);
2705				m_maxCoord = Vec4( 1.5f, 0.0f, 0.0f, 0.0f);
2706
2707				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2708
2709				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f)-lodEps;
2710				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f)+lodEps;
2711				break;
2712			}
2713
2714			case TEXTURETYPE_2D:
2715			case TEXTURETYPE_2D_ARRAY:
2716			{
2717				m_minCoord = Vec4(-0.2f, -0.4f, 0.0f, 0.0f);
2718				m_maxCoord = Vec4( 1.5f,  2.3f, 0.0f, 0.0f);
2719
2720				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2721				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height	/ (float)viewportSize[1];
2722
2723				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2724				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2725				break;
2726			}
2727
2728			case TEXTURETYPE_CUBE_MAP:
2729			case TEXTURETYPE_CUBE_ARRAY:
2730			{
2731				m_minCoord = Vec4(-1.0f, -1.0f, 1.01f, 0.0f);
2732				m_maxCoord = Vec4( 1.0f,  1.0f, 1.01f, 0.0f);
2733
2734				// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
2735				DE_ASSERT(de::abs(m_minCoord[2] - m_maxCoord[2]) < 0.005);
2736				DE_ASSERT(de::abs(m_minCoord[0]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[0]) < de::abs(m_minCoord[2]));
2737				DE_ASSERT(de::abs(m_minCoord[1]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[1]) < de::abs(m_minCoord[2]));
2738
2739				tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_minCoord[1], m_minCoord[2]));
2740				tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_maxCoord[0], m_minCoord[1], m_minCoord[2]));
2741				tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_maxCoord[1], m_minCoord[2]));
2742				float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
2743				float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
2744
2745				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2746				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2747				break;
2748			}
2749
2750			case TEXTURETYPE_3D:
2751			{
2752				m_minCoord = Vec4(-1.2f, -1.4f, 0.1f, 0.0f);
2753				m_maxCoord = Vec4( 1.5f,  2.3f, 2.3f, 0.0f);
2754
2755				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width		/ (float)viewportSize[0];
2756				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height		/ (float)viewportSize[1];
2757				const float	dwdx	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[0];
2758				const float	dwdy	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[1];
2759
2760				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)-lodEps;
2761				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)+lodEps;
2762				break;
2763			}
2764
2765			default:
2766				DE_ASSERT(false);
2767				break;
2768		}
2769
2770		m_levelBounds[0] = computeLevelFromLod(m_lodBounds[0]);
2771		m_levelBounds[1] = computeLevelFromLod(m_lodBounds[1]);
2772
2773		return;
2774	}
2775
2776	if (m_mode == QLODTM_ZERO_UV_WIDTH)
2777	{
2778		// setup same texture coordinates that will result in pmax
2779		// beeing 0 and as a result lambda being -inf; on most
2780		// implementations lambda is computed as fixed-point, so
2781		// infinities can't be returned, instead -maxSamplerLodBias or less
2782		// should be returned
2783
2784		m_minCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2785		m_maxCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2786
2787		m_lodBounds[0]		= -std::numeric_limits<float>::infinity();
2788		m_lodBounds[1]		= -context.getDeviceProperties().limits.maxSamplerLodBias;
2789		m_levelBounds[0]	= 0.0f;
2790		m_levelBounds[1]	= 0.0f;
2791
2792		return;
2793	}
2794
2795	DE_ASSERT(false);
2796}
2797
2798TextureQueryLodInstance::~TextureQueryLodInstance (void)
2799{
2800}
2801
2802tcu::TestStatus TextureQueryLodInstance::iterate (void)
2803{
2804	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2805
2806	log << tcu::TestLog::Message << "Expected: level in range " << m_levelBounds << ", lod in range " << m_lodBounds << tcu::TestLog::EndMessage;
2807
2808	// render
2809	TextureQueryInstance::render();
2810
2811	// test
2812	{
2813		const tcu::TextureLevel&	result		= getResultImage();
2814		const tcu::Vec4				output		= result.getAccess().getPixel(0, 0);
2815		const float					resLevel	= output.x();
2816		const float					resLod		= output.y();
2817
2818		if (de::inRange(resLevel, m_levelBounds[0], m_levelBounds[1]) && de::inRange(resLod, m_lodBounds[0], m_lodBounds[1]))
2819		{
2820			// success
2821			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2822			return tcu::TestStatus::pass("Pass");
2823		}
2824		else
2825		{
2826			// failure
2827			log << tcu::TestLog::Message << "Result: level: " << resLevel << ", lod: " << resLod << tcu::TestLog::EndMessage;
2828			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2829			return tcu::TestStatus::fail("Got unexpected result");
2830		}
2831	}
2832}
2833
2834void TextureQueryLodInstance::setupDefaultInputs (void)
2835{
2836	TextureQueryInstance::setupDefaultInputs();
2837
2838	const deUint32			numVertices			= 4;
2839	const vector<float>		texCoord			= computeQuadTexCoord();
2840	const int				texCoordComps		= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2841	const vk::VkFormat		coordFormats[]		=
2842	{
2843		vk::VK_FORMAT_R32_SFLOAT,
2844		vk::VK_FORMAT_R32G32_SFLOAT,
2845		vk::VK_FORMAT_R32G32B32_SFLOAT
2846	};
2847
2848	DE_ASSERT(de::inRange(texCoordComps, 1, 3));
2849	DE_ASSERT((int)texCoord.size() == texCoordComps * 4);
2850
2851	addAttribute(1u, coordFormats[texCoordComps - 1], (deUint32)(texCoordComps * sizeof(float)), numVertices, texCoord.data());
2852}
2853
2854void TextureQueryLodInstance::initTexture (void)
2855{
2856	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2857	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2858	TextureBindingSp		textureBinding;
2859
2860	DE_ASSERT(m_textures.empty());
2861
2862	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2863
2864	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2865
2866	m_textures.push_back(textureBinding);
2867}
2868
2869float TextureQueryLodInstance::computeLevelFromLod (float computedLod) const
2870{
2871	const int	maxAccessibleLevel	= m_textureSpec.numLevels - 1;
2872
2873	// Clamp the computed LOD to the range of accessible levels.
2874	computedLod = deFloatClamp(computedLod, 0.0f, (float)maxAccessibleLevel);
2875
2876	// Return a value according to the min filter.
2877	switch (m_textureSpec.sampler.minFilter)
2878	{
2879		case tcu::Sampler::LINEAR:
2880		case tcu::Sampler::NEAREST:
2881			return 0.0f;
2882
2883		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
2884		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
2885			return deFloatClamp(deFloatCeil(computedLod + 0.5f) - 1.0f, 0.0f, (float)maxAccessibleLevel);
2886
2887		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
2888		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
2889			return computedLod;
2890
2891		default:
2892			DE_ASSERT(false);
2893			return 0.0f;
2894	}
2895}
2896
2897vector<float> TextureQueryLodInstance::computeQuadTexCoord (void) const
2898{
2899	vector<float>	res;
2900	tcu::Mat4		coordTransMat;
2901
2902	{
2903		Vec4 s = m_maxCoord - m_minCoord;
2904		Vec4 b = m_minCoord;
2905
2906		float baseCoordTrans[] =
2907		{
2908			s.x(),		0.0f,		0.f,	b.x(),
2909			0.f,		s.y(),		0.f,	b.y(),
2910			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
2911			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
2912		};
2913
2914		coordTransMat = tcu::Mat4(baseCoordTrans);
2915	}
2916
2917	const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2918	Vec4			coords[4]		=
2919	{
2920		coordTransMat * tcu::Vec4(0, 0, 0, 1),
2921		coordTransMat * tcu::Vec4(0, 1, 0, 1),
2922		coordTransMat * tcu::Vec4(1, 0, 0, 1),
2923		coordTransMat * tcu::Vec4(1, 1, 0, 1)
2924	};
2925
2926	res.resize(4 * texCoordComps);
2927
2928	for (int ndx = 0; ndx < 4; ndx++)
2929		deMemcpy(&res[ndx * texCoordComps], coords[ndx].getPtr(), texCoordComps * sizeof(float));
2930
2931	return res;
2932}
2933
2934class TextureQueryCase : public ShaderRenderCase
2935{
2936public:
2937								TextureQueryCase				(tcu::TestContext&			testCtx,
2938																 const std::string&			name,
2939																 const std::string&			samplerType,
2940																 const TextureSpec&			texture,
2941																 bool						isVertexCase,
2942																 QueryFunction				function,
2943																 TestMode					mode = 0);
2944	virtual						~TextureQueryCase				(void);
2945
2946	virtual TestInstance*		createInstance					(Context& context) const;
2947	virtual void				checkSupport					(Context& context) const;
2948
2949protected:
2950	void						initShaderSources				(void);
2951
2952	const std::string			m_samplerTypeStr;
2953	const TextureSpec			m_textureSpec;
2954	const QueryFunction			m_function;
2955	const TestMode				m_mode;
2956};
2957
2958TextureQueryCase::TextureQueryCase (tcu::TestContext&		testCtx,
2959									const std::string&		name,
2960									const std::string&		samplerType,
2961									const TextureSpec&		texture,
2962									bool					isVertexCase,
2963									QueryFunction			function,
2964									TestMode				mode)
2965	: ShaderRenderCase	(testCtx, name, isVertexCase, (ShaderEvaluator*)DE_NULL, DE_NULL, DE_NULL)
2966	, m_samplerTypeStr	(samplerType)
2967	, m_textureSpec		(texture)
2968	, m_function		(function)
2969	, m_mode			(mode)
2970{
2971	initShaderSources();
2972}
2973
2974TextureQueryCase::~TextureQueryCase (void)
2975{
2976}
2977
2978TestInstance* TextureQueryCase::createInstance (Context& context) const
2979{
2980	switch (m_function)
2981	{
2982		case QUERYFUNCTION_TEXTURESIZE:				return new TextureSizeInstance(context, m_isVertexCase, m_textureSpec);
2983		case QUERYFUNCTION_TEXTURESIZEMS:			return new TextureSizeMSInstance(context, m_isVertexCase, m_textureSpec);
2984		case QUERYFUNCTION_TEXTUREQUERYLOD:			return new TextureQueryLodInstance(context, m_isVertexCase, m_textureSpec, m_mode);
2985		case QUERYFUNCTION_TEXTUREQUERYLEVELS:		return new TextureQueryLevelsInstance(context, m_isVertexCase, m_textureSpec);
2986		case QUERYFUNCTION_TEXTURESAMPLES:			return new TextureSamplesInstance(context, m_isVertexCase, m_textureSpec);
2987		default:
2988			DE_ASSERT(false);
2989			return DE_NULL;
2990	}
2991}
2992
2993void TextureQueryCase::checkSupport(Context& context) const
2994{
2995	checkMutableComparisonSamplersSupport(context, m_textureSpec);
2996}
2997
2998void TextureQueryCase::initShaderSources (void)
2999{
3000	std::ostringstream		vert;
3001	std::ostringstream		frag;
3002	std::ostringstream&		op			= m_isVertexCase ? vert : frag;
3003
3004	DE_ASSERT(m_function != QUERYFUNCTION_TEXTUREQUERYLOD || !m_isVertexCase);
3005
3006	vert << "#version 450 core\n"
3007		 << "layout(location = 0) in highp vec4 a_position;\n";
3008
3009	frag << "#version 450 core\n"
3010		 << "layout(location = 0) out mediump vec4 o_color;\n";
3011
3012	if (m_isVertexCase)
3013	{
3014		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3015		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3016	}
3017
3018	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3019	{
3020		const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
3021		const char*		coordTypeName	= glu::getDataTypeName(glu::getDataTypeFloatVec(texCoordComps));
3022
3023		vert << "layout (location = 1) in highp " << coordTypeName << " a_texCoord;\n";
3024		vert << "layout (location = 0) out highp " << coordTypeName << " v_texCoord;\n";
3025		frag << "layout (location = 0) in highp " << coordTypeName << " v_texCoord;\n";
3026	}
3027
3028	// uniforms
3029	op << "layout(set = 0, binding = 0) uniform highp " << m_samplerTypeStr << " u_sampler;\n";
3030	if (m_function == QUERYFUNCTION_TEXTURESIZE)
3031		op << "layout(set = 0, binding = 1) uniform buf0 { highp int u_lod; };\n";
3032
3033	vert << "out gl_PerVertex {\n"
3034		 << "\tvec4 gl_Position;\n"
3035		 << "};\n";
3036
3037	vert << "\nvoid main()\n{\n"
3038		 << "\tgl_Position = a_position;\n";
3039	frag << "\nvoid main()\n{\n";
3040
3041	if (m_isVertexCase)
3042		vert << "\tv_color = ";
3043	else
3044		frag << "\to_color = ";
3045
3046	// op
3047	{
3048		op << "vec4(";
3049
3050		switch (m_function)
3051		{
3052			case QUERYFUNCTION_TEXTURESIZE:
3053			{
3054				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3055
3056				op << "textureSize(u_sampler, u_lod)";
3057				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3058					op << ", 0.0";
3059				op << ", 1.0";
3060
3061				break;
3062			}
3063
3064			case QUERYFUNCTION_TEXTURESIZEMS:
3065			{
3066				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3067
3068				op << "textureSize(u_sampler)";
3069				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3070					op << ", 0.0";
3071				op << ", 1.0";
3072
3073				break;
3074			}
3075
3076			case QUERYFUNCTION_TEXTUREQUERYLOD:
3077				op << "textureQueryLod(u_sampler, v_texCoord), 0.0, 1.0";
3078				break;
3079
3080			case QUERYFUNCTION_TEXTUREQUERYLEVELS:
3081				op << "textureQueryLevels(u_sampler), 0.0, 0.0, 1.0";
3082				break;
3083
3084			case QUERYFUNCTION_TEXTURESAMPLES:
3085				op << "textureSamples(u_sampler), 0.0, 0.0, 1.0";
3086				break;
3087
3088			default:
3089				DE_ASSERT(false);
3090				break;
3091		}
3092
3093		op << ");\n";
3094	}
3095
3096	if (m_isVertexCase)
3097		frag << "\to_color = v_color;\n";
3098
3099	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3100		vert << "\tv_texCoord = a_texCoord;\n";
3101
3102	vert << "}\n";
3103	frag << "}\n";
3104
3105	m_vertShaderSource = vert.str();
3106	m_fragShaderSource = frag.str();
3107}
3108
3109namespace SpecialCases
3110{
3111using namespace vk;
3112
3113void textureSizeOOBPrograms(vk::SourceCollections& programCollection)
3114{
3115	programCollection.glslSources.add("comp") << glu::ComputeSource("#version 450\n"
3116		"layout(local_size_x = 1) in;\n"
3117		"layout(binding = 0) buffer InBuffer\n"
3118		"{\n"
3119		"  highp int lods[];\n"
3120		"};\n"
3121		"layout(binding = 1) buffer OutBuffer\n"
3122		"{\n"
3123		"  highp ivec2 results[];\n"
3124		"};\n"
3125		"layout(binding = 2) uniform sampler2D u_image;\n"
3126		"void main(void)\n"
3127		"{\n"
3128		"  uint invocationNdx = gl_WorkGroupID.x;\n"
3129		"  int lod = lods[invocationNdx];\n"
3130		"  results[invocationNdx] = textureSize(u_image, lod);\n"
3131		"}\n");
3132}
3133
3134tcu::TestStatus textureSizeOOBTest(Context& context)
3135{
3136	// run few shader invocations, some invocations have in-bounds lod values, some out of bounds
3137
3138	const int		testedLods[]	= { 0, 10, 0, 1, 50, 0, 1, 2, -1, 0 };
3139	const IVec2		imageSize		= { 16, 8 };
3140
3141	const DeviceInterface&	vk					= context.getDeviceInterface();
3142	const VkDevice			device				= context.getDevice();
3143	const VkQueue			queue				= context.getUniversalQueue();
3144	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
3145	Allocator&				allocator			= context.getDefaultAllocator();
3146
3147	// create input and output buffers
3148	const VkDeviceSize		bufferSizeBytes		= sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods) * 2;
3149	VkBufferCreateInfo		bufferCreateInfo	= makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3150	BufferWithMemory		inBuffer			(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3151	BufferWithMemory		outBuffer			(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3152
3153	// write data to input buffer
3154	auto& inAlloc = inBuffer.getAllocation();
3155	deMemcpy(inAlloc.getHostPtr(), testedLods, sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods));
3156	flushAlloc(vk, device, inAlloc);
3157
3158	// create image, we do not need to fill it with data for this test
3159	const VkImageCreateInfo imageCreateInfo
3160	{
3161		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
3162		DE_NULL,														// const void*				pNext;
3163		0u,																// VkImageCreateFlags		flags;
3164		VK_IMAGE_TYPE_2D,												// VkImageType				imageType;
3165		VK_FORMAT_R8G8B8A8_UNORM,										// VkFormat					format;
3166		vk::makeExtent3D(imageSize.x(), imageSize.y(), 1),				// VkExtent3D				extent;
3167		3u,																// deUint32					mipLevels;
3168		1u,																// deUint32					arrayLayers;
3169		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
3170		VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
3171		VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,	// VkImageUsageFlags		usage;
3172		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
3173		0u,																// deUint32					queueFamilyIndexCount;
3174		DE_NULL,														// const deUint32*			pQueueFamilyIndices;
3175		VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout			initialLayout;
3176	};
3177	const ImageWithMemory			image				(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any);
3178	const VkImageSubresourceRange	subresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 3u, 0u, 1u));
3179	const Unique<VkImageView>		imageView			(makeImageView(vk, device, *image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, subresourceRange));
3180
3181	// create sampler with everything set to 0 as we wont use it in test
3182	const VkSamplerCreateInfo		samplerCreateInfo	= initVulkanStructure();
3183	const Unique<VkSampler>			sampler				(createSampler(vk, device, &samplerCreateInfo));
3184
3185	// create descriptors
3186	const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
3187		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
3188		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
3189		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
3190
3191	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
3192		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3193		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3194		.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
3195		.build(vk, device));
3196
3197	const Unique<VkDescriptorSet>	descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
3198	const VkDescriptorBufferInfo	inDescriptorInfo	= makeDescriptorBufferInfo(*inBuffer, 0ull, bufferSizeBytes);
3199	const VkDescriptorBufferInfo	outDescriptorInfo	= makeDescriptorBufferInfo(*outBuffer, 0ull, bufferSizeBytes);
3200	const VkDescriptorImageInfo		imageDescriptorInfo	= makeDescriptorImageInfo(*sampler, *imageView, VK_IMAGE_LAYOUT_GENERAL);
3201	DescriptorSetUpdateBuilder()
3202		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inDescriptorInfo)
3203		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outDescriptorInfo)
3204		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageDescriptorInfo)
3205		.update(vk, device);
3206
3207	// perform the computation
3208	const Unique<VkShaderModule>	shaderModule	(createShaderModule(vk, device, context.getBinaryCollection().get("comp"), 0u));
3209	const Unique<VkPipelineLayout>	pipelineLayout	(makePipelineLayout(vk, device, *descriptorSetLayout));
3210	const Unique<VkPipeline>		pipeline		(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
3211	const VkImageMemoryBarrier		layoutBarrier	(makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, *image, subresourceRange));
3212	const VkBufferMemoryBarrier		outBarrier		(makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *outBuffer, 0ull, bufferSizeBytes));
3213	const Unique<VkCommandPool>		cmdPool			(makeCommandPool(vk, device, queueFamilyIndex));
3214	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3215
3216	// start recording commands
3217	beginCommandBuffer(vk, *cmdBuffer);
3218
3219	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &layoutBarrier);
3220	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3221	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
3222	vk.cmdDispatch(*cmdBuffer, DE_LENGTH_OF_ARRAY(testedLods), 1, 1);
3223	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, DE_NULL, 1, &outBarrier, 0, DE_NULL);
3224
3225	endCommandBuffer(vk, *cmdBuffer);
3226	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
3227
3228	// validate the results
3229	const Allocation& bufferAllocation = outBuffer.getAllocation();
3230	invalidateAlloc(vk, device, bufferAllocation);
3231
3232	std::map<int, IVec2> expectedLodSize
3233	{
3234		{ 0, { 16, 8 } },
3235		{ 1, {  8, 4 } },
3236		{ 2, {  4, 2 } },
3237	};
3238	bool			testFailed	= false;
3239	tcu::TestLog&	log			= context.getTestContext().getLog();
3240	const int*		bufferPtr	= static_cast<int*>(bufferAllocation.getHostPtr());
3241
3242	for (deUint32 lodNdx = 0; lodNdx < DE_LENGTH_OF_ARRAY(testedLods); ++lodNdx)
3243	{
3244		const int returnedWidth		= bufferPtr[2 * lodNdx + 0];
3245		const int returnedHeight	= bufferPtr[2 * lodNdx + 1];
3246		const int usedLod			= testedLods[lodNdx];
3247
3248		if ((usedLod >= 0) && (usedLod < 3))
3249		{
3250			const auto& expectedSize = expectedLodSize[usedLod];
3251			if ((returnedWidth != expectedSize.x()) || (returnedHeight != expectedSize.y()))
3252			{
3253				log << tcu::TestLog::Message << "Wrong size for invocation " << lodNdx << ", expected " << expectedSize
3254					<< " got (" << returnedWidth << ", " << returnedHeight << ")" << tcu::TestLog::EndMessage;
3255				testFailed = true;
3256			}
3257		}
3258	}
3259
3260	if (testFailed)
3261		return tcu::TestStatus::fail("Fail");
3262	return tcu::TestStatus::pass("Pass");
3263}
3264
3265} // SpecialCases
3266
3267class ShaderTextureFunctionTests : public tcu::TestCaseGroup
3268{
3269public:
3270									ShaderTextureFunctionTests		(tcu::TestContext& context);
3271	virtual							~ShaderTextureFunctionTests		(void);
3272	virtual void					init							(void);
3273
3274private:
3275									ShaderTextureFunctionTests		(const ShaderTextureFunctionTests&);		// not allowed!
3276	ShaderTextureFunctionTests&		operator=						(const ShaderTextureFunctionTests&);		// not allowed!
3277};
3278
3279ShaderTextureFunctionTests::ShaderTextureFunctionTests (tcu::TestContext& context)
3280	: TestCaseGroup(context, "texture_functions")
3281{
3282}
3283
3284ShaderTextureFunctionTests::~ShaderTextureFunctionTests (void)
3285{
3286}
3287
3288enum CaseFlags
3289{
3290	VERTEX		= (1<<0),
3291	FRAGMENT	= (1<<1),
3292	BOTH		= VERTEX|FRAGMENT
3293};
3294
3295struct TexFuncCaseSpec
3296{
3297	const char*			name;
3298	TextureLookupSpec	lookupSpec;
3299	TextureSpec			texSpec;
3300	TexEvalFunc			evalFunc;
3301	deUint32			flags;
3302};
3303
3304#define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3305	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, false, 0.0f), TEXSPEC, EVALFUNC, FLAGS }
3306#define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3307	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, false, 0.0f), TEXSPEC, EVALFUNC, FLAGS }
3308#define CLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3309	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, true, LODCLAMP), TEXSPEC, EVALFUNC, FLAGS }
3310#define GRADCLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3311	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, true, LODCLAMP), TEXSPEC, EVALFUNC, FLAGS }
3312
3313#ifndef CTS_USES_VULKANSC
3314
3315class SparseShaderTextureFunctionInstance : public ShaderTextureFunctionInstance
3316{
3317public:
3318				SparseShaderTextureFunctionInstance		(Context&					context,
3319														const bool					isVertexCase,
3320														const ShaderEvaluator&		evaluator,
3321														const UniformSetup&			uniformSetup,
3322														const TextureLookupSpec&	lookupSpec,
3323														const TextureSpec&			textureSpec,
3324														const TexLookupParams&		lookupParams,
3325														const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_SPARSE);
3326	virtual		~SparseShaderTextureFunctionInstance	(void);
3327};
3328
3329SparseShaderTextureFunctionInstance::SparseShaderTextureFunctionInstance (Context&					context,
3330																		 const bool					isVertexCase,
3331																		 const ShaderEvaluator&		evaluator,
3332																		 const UniformSetup&		uniformSetup,
3333																		 const TextureLookupSpec&	lookupSpec,
3334																		 const TextureSpec&			textureSpec,
3335																		 const TexLookupParams&		lookupParams,
3336																		 const ImageBackingMode		imageBackingMode)
3337	: ShaderTextureFunctionInstance (context, isVertexCase, evaluator, uniformSetup, lookupSpec, textureSpec, lookupParams, imageBackingMode)
3338{
3339	if (lookupSpec.useClamp)
3340	{
3341		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
3342
3343		if (!deviceFeatures.shaderResourceMinLod)
3344			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
3345	}
3346}
3347
3348SparseShaderTextureFunctionInstance::~SparseShaderTextureFunctionInstance (void)
3349{
3350}
3351
3352class SparseShaderTextureFunctionCase : public ShaderTextureFunctionCase
3353{
3354public:
3355							SparseShaderTextureFunctionCase		(tcu::TestContext&			testCtx,
3356																const std::string&			name,
3357																const TextureLookupSpec&	lookup,
3358																const TextureSpec&			texture,
3359																TexEvalFunc					evalFunc,
3360																bool						isVertexCase);
3361
3362	virtual					~SparseShaderTextureFunctionCase	(void);
3363
3364	virtual	TestInstance*	createInstance						(Context& context) const;
3365	virtual	void			checkSupport						(Context& context) const;
3366protected:
3367	void					initShaderSources					(void);
3368};
3369
3370SparseShaderTextureFunctionCase::SparseShaderTextureFunctionCase (tcu::TestContext&				testCtx,
3371																  const std::string&			name,
3372																  const TextureLookupSpec&		lookup,
3373																  const TextureSpec&			texture,
3374																  TexEvalFunc					evalFunc,
3375																  bool							isVertexCase)
3376	: ShaderTextureFunctionCase		(testCtx, name, lookup, texture, evalFunc, isVertexCase)
3377{
3378	initShaderSources();
3379}
3380
3381void SparseShaderTextureFunctionCase::initShaderSources (void)
3382{
3383	const Function				function			= m_lookupSpec.function;
3384	const bool					isVtxCase			= m_isVertexCase;
3385	const bool					isProj				= functionHasProj(function);
3386	const bool					isGrad				= functionHasGrad(function);
3387	const bool					isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
3388	const bool					is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
3389	const bool					isIntCoord			= function == FUNCTION_TEXELFETCH;
3390	const bool					hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
3391	const int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
3392	const int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
3393	const glu::DataType			coordType			= glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
3394	const glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
3395	const char*					coordTypeName		= glu::getDataTypeName(coordType);
3396	const char*					coordPrecName		= glu::getPrecisionName(coordPrec);
3397	const tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
3398	glu::DataType				samplerType			= glu::TYPE_LAST;
3399	const glu::DataType			gradType			= (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
3400	const char*					gradTypeName		= glu::getDataTypeName(gradType);
3401	const char*					baseFuncName		= DE_NULL;
3402
3403	DE_ASSERT(!isGrad || !hasLodBias);
3404
3405	switch (m_textureSpec.type)
3406	{
3407		case TEXTURETYPE_2D:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW		: glu::getSampler2DType(texFmt);		break;
3408		case TEXTURETYPE_CUBE_MAP:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW		: glu::getSamplerCubeType(texFmt);		break;
3409		case TEXTURETYPE_2D_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	: glu::getSampler2DArrayType(texFmt);	break;
3410		case TEXTURETYPE_3D:		DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);									break;
3411		default:
3412			DE_ASSERT(DE_FALSE);
3413	}
3414
3415	// Not supported cases
3416	switch (m_lookupSpec.function)
3417	{
3418		case FUNCTION_TEXTURE:			baseFuncName = "sparseTexture";			break;
3419		case FUNCTION_TEXTURELOD:		baseFuncName = "sparseTextureLod";		break;
3420		case FUNCTION_TEXTUREGRAD:		baseFuncName = "sparseTextureGrad";		break;
3421		case FUNCTION_TEXELFETCH:		baseFuncName = "sparseTexelFetch";		break;
3422		default:
3423			DE_ASSERT(DE_FALSE);
3424	}
3425
3426	std::ostringstream	vert;
3427	std::ostringstream	frag;
3428	std::ostringstream&	op		= isVtxCase ? vert : frag;
3429
3430	vert << "#version 450\n"
3431		 << "#extension GL_ARB_sparse_texture2 : require\n"
3432		 << "layout(location = 0) in highp vec4 a_position;\n"
3433		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
3434
3435	if (isGrad)
3436	{
3437		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
3438		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
3439	}
3440	else if (hasLodBias)
3441		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
3442
3443	frag << "#version 450\n"
3444		 << "#extension GL_ARB_sparse_texture2 : require\n";
3445
3446	if (m_lookupSpec.useClamp)
3447		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
3448
3449	frag << "layout(location = 0) out mediump vec4 o_color;\n";
3450
3451	if (isVtxCase)
3452	{
3453		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3454		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3455	}
3456	else
3457	{
3458		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3459		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3460
3461		if (isGrad)
3462		{
3463			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3464			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3465			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3466			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3467		}
3468		else if (hasLodBias)
3469		{
3470			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
3471			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
3472		}
3473	}
3474
3475	// Uniforms
3476	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
3477	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
3478	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
3479
3480	vert << "out gl_PerVertex {\n"
3481		 << "	vec4 gl_Position;\n"
3482		 << "};\n";
3483	vert << "\nvoid main()\n{\n"
3484		 << "\tgl_Position = a_position;\n";
3485	frag << "\nvoid main()\n{\n";
3486
3487	// Op.
3488	{
3489		// Texel declaration
3490		if (isShadow)
3491			op << "\tfloat texel;\n";
3492		else
3493			op << "\tvec4 texel;\n";
3494
3495		const char*	const texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
3496		const char* const gradX		= isVtxCase ? "a_in1" : "v_gradX";
3497		const char* const gradY		= isVtxCase ? "a_in2" : "v_gradY";
3498		const char*	const lodBias	= isVtxCase ? "a_in1" : "v_lodBias";
3499
3500		op << "\tint success = " << baseFuncName;
3501
3502		if (m_lookupSpec.useOffset)
3503			op << "Offset";
3504
3505		if (m_lookupSpec.useClamp)
3506			op << "Clamp";
3507
3508		op << "ARB(u_sampler, ";
3509
3510		if (isIntCoord)
3511			op << "ivec" << (texCoordComps+extraCoordComps) << "(";
3512
3513		op << texCoord;
3514
3515		if (isIntCoord)
3516			op << ")";
3517
3518		if (isGrad)
3519			op << ", " << gradX << ", " << gradY;
3520
3521		if (functionHasLod(function))
3522		{
3523			if (isIntCoord)
3524				op << ", int(" << lodBias << ")";
3525			else
3526				op << ", " << lodBias;
3527		}
3528
3529		if (m_lookupSpec.useOffset)
3530		{
3531			int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
3532
3533			op << ", ivec" << offsetComps << "(";
3534			for (int ndx = 0; ndx < offsetComps; ndx++)
3535			{
3536				if (ndx != 0)
3537					op << ", ";
3538				op << m_lookupSpec.offset[ndx];
3539			}
3540			op << ")";
3541		}
3542
3543		if (m_lookupSpec.useClamp)
3544			op << ", float(" << m_lookupSpec.lodClamp << ")";
3545
3546		op << ", texel";
3547
3548		if (m_lookupSpec.useBias)
3549			op << ", " << lodBias;
3550
3551		op << ");\n";
3552
3553		// Check sparse validity, and handle each case
3554		op << "\tif (sparseTexelsResidentARB(success))\n";
3555
3556		if (isVtxCase)
3557			vert << "\t\tv_color = ";
3558		else
3559			frag << "\t\to_color = ";
3560
3561		if (isShadow)
3562			op << "vec4(texel, 0.0, 0.0, 1.0);\n";
3563		else
3564			op << "vec4(texel * u_scale + u_bias);\n";
3565
3566		op << "\telse\n";
3567
3568		// This color differs from the used colors
3569		if (isVtxCase)
3570			vert << "\t\tv_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3571		else
3572			frag << "\t\to_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3573	}
3574
3575	if (isVtxCase)
3576		frag << "\to_color = v_color;\n";
3577	else
3578	{
3579		vert << "\tv_texCoord = a_in0;\n";
3580
3581		if (isGrad)
3582		{
3583			vert << "\tv_gradX = a_in1;\n";
3584			vert << "\tv_gradY = a_in2;\n";
3585		}
3586		else if (hasLodBias)
3587			vert << "\tv_lodBias = a_in1;\n";
3588	}
3589
3590	vert << "}\n";
3591	frag << "}\n";
3592
3593	m_vertShaderSource = vert.str();
3594	m_fragShaderSource = frag.str();
3595}
3596
3597SparseShaderTextureFunctionCase::~SparseShaderTextureFunctionCase ()
3598{
3599}
3600
3601TestInstance* SparseShaderTextureFunctionCase::createInstance (Context& context) const
3602{
3603	DE_ASSERT(m_evaluator != DE_NULL);
3604	DE_ASSERT(m_uniformSetup != DE_NULL);
3605	return new SparseShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
3606}
3607
3608void SparseShaderTextureFunctionCase::checkSupport(Context& context) const
3609{
3610	checkMutableComparisonSamplersSupport(context, m_textureSpec);
3611}
3612
3613#endif // CTS_USES_VULKANSC
3614
3615static void createCaseGroup (tcu::TestCaseGroup* parent, const char* groupName, const TexFuncCaseSpec* cases, int numCases)
3616{
3617	de::MovePtr<tcu::TestCaseGroup>	group	(new tcu::TestCaseGroup(parent->getTestContext(), groupName));
3618
3619	for (int ndx = 0; ndx < numCases; ndx++)
3620	{
3621		std::string	name			= cases[ndx].name;
3622#ifndef CTS_USES_VULKANSC
3623		bool		sparseSupported	= !functionHasProj(cases[ndx].lookupSpec.function)		&&
3624									  TEXTURETYPE_1D			!= cases[ndx].texSpec.type	&&
3625									  TEXTURETYPE_1D_ARRAY		!= cases[ndx].texSpec.type	&&
3626									  TEXTURETYPE_CUBE_ARRAY	!= cases[ndx].texSpec.type;
3627#endif // CTS_USES_VULKANSC
3628
3629		if (cases[ndx].flags & VERTEX)
3630		{
3631#ifndef CTS_USES_VULKANSC
3632			if (sparseSupported)
3633				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_vertex"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3634#endif // CTS_USES_VULKANSC
3635
3636			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_vertex"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3637		}
3638
3639		if (cases[ndx].flags & FRAGMENT)
3640		{
3641#ifndef CTS_USES_VULKANSC
3642			if (sparseSupported)
3643				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_fragment"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3644#endif // CTS_USES_VULKANSC
3645
3646			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_fragment"), cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3647		}
3648	}
3649
3650	parent->addChild(group.release());
3651}
3652
3653void ShaderTextureFunctionTests::init (void)
3654{
3655	// Samplers
3656	static const tcu::Sampler	samplerNearestNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3657														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3658														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3659														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3660	static const tcu::Sampler	samplerLinearNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3661														 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
3662														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3663														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3664	static const tcu::Sampler	samplerNearestMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3665														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3666														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3667														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3668	static const tcu::Sampler	samplerLinearMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3669														 tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR,
3670														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3671														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3672
3673	static const tcu::Sampler	samplerShadowNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3674														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3675														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3676														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3677	static const tcu::Sampler	samplerShadowMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3678														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3679														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3680														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3681
3682	static const tcu::Sampler	samplerTexelFetch		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3683														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3684														 00.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3685														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3686
3687	// Default textures.
3688	//												Type					Format					W		H		D	L	Sampler
3689	static const TextureSpec tex2DFixed				(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	1,	samplerLinearNoMipmap);
3690	static const TextureSpec tex2DFloat				(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	1,	samplerLinearNoMipmap);
3691	static const TextureSpec tex2DInt				(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	1,	samplerNearestNoMipmap);
3692	static const TextureSpec tex2DUint				(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	1,	samplerNearestNoMipmap);
3693	static const TextureSpec tex2DMipmapFixed		(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerLinearMipmap);
3694	static const TextureSpec tex2DMipmapFloat		(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerLinearMipmap);
3695	static const TextureSpec tex2DMipmapInt			(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerNearestMipmap);
3696	static const TextureSpec tex2DMipmapUint		(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerNearestMipmap);
3697
3698	static const TextureSpec tex2DShadow			(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3699	static const TextureSpec tex2DMipmapShadow		(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3700
3701	static const TextureSpec tex2DTexelFetchFixed	(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerTexelFetch);
3702	static const TextureSpec tex2DTexelFetchFloat	(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerTexelFetch);
3703	static const TextureSpec tex2DTexelFetchInt		(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerTexelFetch);
3704	static const TextureSpec tex2DTexelFetchUint	(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerTexelFetch);
3705
3706	static const TextureSpec texCubeFixed			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	1,	samplerLinearNoMipmap);
3707	static const TextureSpec texCubeFloat			(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	256,	256,	1,	1,	samplerLinearNoMipmap);
3708	static const TextureSpec texCubeInt				(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	1,	samplerNearestNoMipmap);
3709	static const TextureSpec texCubeUint			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	1,	samplerNearestNoMipmap);
3710	static const TextureSpec texCubeMipmapFixed		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	9,	samplerLinearMipmap);
3711	static const TextureSpec texCubeMipmapFloat		(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	128,	128,	1,	8,	samplerLinearMipmap);
3712	static const TextureSpec texCubeMipmapInt		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	9,	samplerNearestMipmap);
3713	static const TextureSpec texCubeMipmapUint		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	9,	samplerNearestMipmap);
3714
3715	static const TextureSpec texCubeShadow			(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3716	static const TextureSpec texCubeMipmapShadow	(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3717
3718	static const TextureSpec tex2DArrayFixed		(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	1,	samplerLinearNoMipmap);
3719	static const TextureSpec tex2DArrayFloat		(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	1,	samplerLinearNoMipmap);
3720	static const TextureSpec tex2DArrayInt			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	1,	samplerNearestNoMipmap);
3721	static const TextureSpec tex2DArrayUint			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	1,	samplerNearestNoMipmap);
3722	static const TextureSpec tex2DArrayMipmapFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerLinearMipmap);
3723	static const TextureSpec tex2DArrayMipmapFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerLinearMipmap);
3724	static const TextureSpec tex2DArrayMipmapInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerNearestMipmap);
3725	static const TextureSpec tex2DArrayMipmapUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerNearestMipmap);
3726
3727	static const TextureSpec tex2DArrayShadow		(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	1,	samplerShadowNoMipmap);
3728	static const TextureSpec tex2DArrayMipmapShadow	(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	8,	samplerShadowMipmap);
3729
3730	static const TextureSpec tex2DArrayTexelFetchFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerTexelFetch);
3731	static const TextureSpec tex2DArrayTexelFetchFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerTexelFetch);
3732	static const TextureSpec tex2DArrayTexelFetchInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerTexelFetch);
3733	static const TextureSpec tex2DArrayTexelFetchUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerTexelFetch);
3734
3735	static const TextureSpec tex3DFixed				(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	1,	samplerLinearNoMipmap);
3736	static const TextureSpec tex3DFloat				(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	1,	samplerLinearNoMipmap);
3737	static const TextureSpec tex3DInt				(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	1,	samplerNearestNoMipmap);
3738	static const TextureSpec tex3DUint				(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	1,	samplerNearestNoMipmap);
3739	static const TextureSpec tex3DMipmapFixed		(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerLinearMipmap);
3740	static const TextureSpec tex3DMipmapFloat		(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerLinearMipmap);
3741	static const TextureSpec tex3DMipmapInt			(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerNearestMipmap);
3742	static const TextureSpec tex3DMipmapUint		(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerNearestMipmap);
3743
3744	static const TextureSpec tex3DTexelFetchFixed	(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerTexelFetch);
3745	static const TextureSpec tex3DTexelFetchFloat	(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerTexelFetch);
3746	static const TextureSpec tex3DTexelFetchInt		(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerTexelFetch);
3747	static const TextureSpec tex3DTexelFetchUint	(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerTexelFetch);
3748
3749	static const TextureSpec tex1DFixed				(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	1,	samplerLinearNoMipmap);
3750	static const TextureSpec tex1DFloat				(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	1,	samplerLinearNoMipmap);
3751	static const TextureSpec tex1DInt				(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	1,	samplerNearestNoMipmap);
3752	static const TextureSpec tex1DUint				(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	1,	samplerNearestNoMipmap);
3753	static const TextureSpec tex1DMipmapFixed		(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerLinearMipmap);
3754	static const TextureSpec tex1DMipmapFloat		(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerLinearMipmap);
3755	static const TextureSpec tex1DMipmapInt			(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerNearestMipmap);
3756	static const TextureSpec tex1DMipmapUint		(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerNearestMipmap);
3757
3758	static const TextureSpec tex1DShadow			(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	1,	samplerShadowNoMipmap);
3759	static const TextureSpec tex1DMipmapShadow		(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	9,	samplerShadowMipmap);
3760
3761	static const TextureSpec tex1DTexelFetchFixed	(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerTexelFetch);
3762	static const TextureSpec tex1DTexelFetchFloat	(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerTexelFetch);
3763	static const TextureSpec tex1DTexelFetchInt		(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerTexelFetch);
3764	static const TextureSpec tex1DTexelFetchUint	(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerTexelFetch);
3765
3766	static const TextureSpec tex1DArrayFixed		(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	1,	samplerLinearNoMipmap);
3767	static const TextureSpec tex1DArrayFloat		(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	1,	samplerLinearNoMipmap);
3768	static const TextureSpec tex1DArrayInt			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	1,	samplerNearestNoMipmap);
3769	static const TextureSpec tex1DArrayUint			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	1,	samplerNearestNoMipmap);
3770	static const TextureSpec tex1DArrayMipmapFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerLinearMipmap);
3771	static const TextureSpec tex1DArrayMipmapFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerLinearMipmap);
3772	static const TextureSpec tex1DArrayMipmapInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerNearestMipmap);
3773	static const TextureSpec tex1DArrayMipmapUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerNearestMipmap);
3774
3775	static const TextureSpec tex1DArrayShadow		(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	1,	samplerShadowNoMipmap);
3776	static const TextureSpec tex1DArrayMipmapShadow	(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	9,	samplerShadowMipmap);
3777
3778	static const TextureSpec tex1DArrayTexelFetchFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerTexelFetch);
3779	static const TextureSpec tex1DArrayTexelFetchFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerTexelFetch);
3780	static const TextureSpec tex1DArrayTexelFetchInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerTexelFetch);
3781	static const TextureSpec tex1DArrayTexelFetchUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerTexelFetch);
3782
3783	static const TextureSpec texCubeArrayFixed			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	1,	samplerLinearNoMipmap);
3784	static const TextureSpec texCubeArrayFloat			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	1,	samplerLinearNoMipmap);
3785	static const TextureSpec texCubeArrayInt			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	1,	samplerNearestNoMipmap);
3786	static const TextureSpec texCubeArrayUint			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	1,	samplerNearestNoMipmap);
3787	static const TextureSpec texCubeArrayMipmapFixed	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	7,	samplerLinearMipmap);
3788	static const TextureSpec texCubeArrayMipmapFloat	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	7,	samplerLinearMipmap);
3789	static const TextureSpec texCubeArrayMipmapInt		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	7,	samplerNearestMipmap);
3790	static const TextureSpec texCubeArrayMipmapUint		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	7,	samplerNearestMipmap);
3791
3792	static const TextureSpec texCubeArrayShadow			(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	1,	samplerShadowNoMipmap);
3793	static const TextureSpec texCubeArrayMipmapShadow	(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	7,	samplerShadowMipmap);
3794
3795	// texture() cases
3796	static const TexFuncCaseSpec textureCases[] =
3797	{
3798		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
3799		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2D,			VERTEX),
3800		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2D,			FRAGMENT),
3801		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2D,			VERTEX),
3802		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2D,			FRAGMENT),
3803		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2D,			VERTEX),
3804		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2D,			FRAGMENT),
3805		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2D,			VERTEX),
3806		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2D,			FRAGMENT),
3807
3808		CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DBias,		FRAGMENT),
3809		CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DBias,		FRAGMENT),
3810		CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DBias,		FRAGMENT),
3811		CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DBias,		FRAGMENT),
3812
3813		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeFixed,			evalTextureCube,		VERTEX),
3814		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCube,		FRAGMENT),
3815		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeFloat,			evalTextureCube,		VERTEX),
3816		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCube,		FRAGMENT),
3817		CASE_SPEC(isamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeInt,				evalTextureCube,		VERTEX),
3818		CASE_SPEC(isamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCube,		FRAGMENT),
3819		CASE_SPEC(usamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeUint,			evalTextureCube,		VERTEX),
3820		CASE_SPEC(usamplercube,					FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCube,		FRAGMENT),
3821
3822		CASE_SPEC(samplercube_bias_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeBias,	FRAGMENT),
3823		CASE_SPEC(samplercube_bias_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeBias,	FRAGMENT),
3824		CASE_SPEC(isamplercube_bias,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeBias,	FRAGMENT),
3825		CASE_SPEC(usamplercube_bias,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeBias,	FRAGMENT),
3826
3827		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayFixed,		evalTexture2DArray,		VERTEX),
3828		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArray,		FRAGMENT),
3829		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayFloat,		evalTexture2DArray,		VERTEX),
3830		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArray,		FRAGMENT),
3831		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayInt,			evalTexture2DArray,		VERTEX),
3832		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArray,		FRAGMENT),
3833		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayUint,			evalTexture2DArray,		VERTEX),
3834		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArray,		FRAGMENT),
3835
3836		CASE_SPEC(sampler2darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayBias,	FRAGMENT),
3837		CASE_SPEC(sampler2darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayBias,	FRAGMENT),
3838		CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayBias,	FRAGMENT),
3839		CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayBias,	FRAGMENT),
3840
3841		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFixed,				evalTexture3D,			VERTEX),
3842		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3D,			FRAGMENT),
3843		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFloat,				evalTexture3D,			VERTEX),
3844		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3D,			FRAGMENT),
3845		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DInt,				evalTexture3D,			VERTEX),
3846		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3D,			FRAGMENT),
3847		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DUint,				evalTexture3D,			VERTEX),
3848		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3D,			FRAGMENT),
3849
3850		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DBias,		FRAGMENT),
3851		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DBias,		FRAGMENT),
3852		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DBias,		FRAGMENT),
3853		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DBias,		FRAGMENT),
3854
3855		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1D,			VERTEX),
3856		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1D,			FRAGMENT),
3857		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1D,			VERTEX),
3858		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1D,			FRAGMENT),
3859		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1D,			VERTEX),
3860		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1D,			FRAGMENT),
3861		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1D,			VERTEX),
3862		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1D,			FRAGMENT),
3863
3864		CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DBias,		FRAGMENT),
3865		CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DBias,		FRAGMENT),
3866		CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DBias,		FRAGMENT),
3867		CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DBias,		FRAGMENT),
3868
3869		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayFixed,		evalTexture1DArray,		VERTEX),
3870		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArray,		FRAGMENT),
3871		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayFloat,		evalTexture1DArray,		VERTEX),
3872		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArray,		FRAGMENT),
3873		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayInt,			evalTexture1DArray,		VERTEX),
3874		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArray,		FRAGMENT),
3875		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayUint,			evalTexture1DArray,		VERTEX),
3876		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArray,		FRAGMENT),
3877
3878		CASE_SPEC(sampler1darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayBias,	FRAGMENT),
3879		CASE_SPEC(sampler1darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayBias,	FRAGMENT),
3880		CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayBias,	FRAGMENT),
3881		CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayBias,	FRAGMENT),
3882
3883		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayFixed,			evalTextureCubeArray,		VERTEX),
3884		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArray,		FRAGMENT),
3885		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayFloat,			evalTextureCubeArray,		VERTEX),
3886		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArray,		FRAGMENT),
3887		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayInt,			evalTextureCubeArray,		VERTEX),
3888		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArray,		FRAGMENT),
3889		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayUint,			evalTextureCubeArray,		VERTEX),
3890		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArray,		FRAGMENT),
3891
3892		CASE_SPEC(samplercubearray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayBias,	FRAGMENT),
3893		CASE_SPEC(samplercubearray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayBias,	FRAGMENT),
3894		CASE_SPEC(isamplercubearray_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayBias,	FRAGMENT),
3895		CASE_SPEC(usamplercubearray_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayBias,	FRAGMENT),
3896
3897		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DShadow,			evalTexture2DShadow,			VERTEX),
3898		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadow,			FRAGMENT),
3899		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowBias,		FRAGMENT),
3900
3901		CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeShadow,			evalTextureCubeShadow,			VERTEX),
3902		CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadow,			FRAGMENT),
3903		CASE_SPEC(samplercubeshadow_bias,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadowBias,		FRAGMENT),
3904
3905		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayShadow,		evalTexture2DArrayShadow,		VERTEX),
3906		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadow,		FRAGMENT),
3907
3908		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DShadow,			evalTexture1DShadow,			VERTEX),
3909		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadow,			FRAGMENT),
3910		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowBias,		FRAGMENT),
3911
3912		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayShadow,		evalTexture1DArrayShadow,		VERTEX),
3913		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadow,		FRAGMENT),
3914		CASE_SPEC(sampler1darrayshadow_bias,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowBias,	FRAGMENT),
3915
3916		CASE_SPEC(samplercubearrayshadow,		FUNCTION_TEXTURE,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	texCubeArrayMipmapShadow,	evalTextureCubeArrayShadow,		FRAGMENT),
3917	};
3918	createCaseGroup(this, "texture", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
3919
3920	// textureClampARB() cases
3921	static const TexFuncCaseSpec textureClampARBCases[] =
3922	{
3923		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		LodClamp	Format					EvalFunc							Flags
3924		CLAMP_CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DMipmapFixed,			evalTexture2DBiasClamp,				FRAGMENT),
3925		CLAMP_CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DMipmapFloat,			evalTexture2DBiasClamp,				FRAGMENT),
3926		CLAMP_CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapInt,				evalTexture2DBiasClamp,				FRAGMENT),
3927		CLAMP_CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapUint,			evalTexture2DBiasClamp,				FRAGMENT),
3928
3929		CLAMP_CASE_SPEC(samplercube_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f, 1.0f, 1.01f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeMipmapFixed,			evalTextureCubeBiasClamp,			FRAGMENT),
3930		CLAMP_CASE_SPEC(samplercube_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f, 1.0f, 1.01f, 0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeMipmapFloat,			evalTextureCubeBiasClamp,			FRAGMENT),
3931		CLAMP_CASE_SPEC(isamplercube_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f, 6.0f, 6.01f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	6.0f,	texCubeMipmapInt,			evalTextureCubeBiasClamp,			FRAGMENT),
3932		CLAMP_CASE_SPEC(usamplercube_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f, 6.0f, 6.01f, 0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	6.0f,	texCubeMipmapUint,			evalTextureCubeBiasClamp,			FRAGMENT),
3933
3934		CLAMP_CASE_SPEC(sampler2darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3935		CLAMP_CASE_SPEC(sampler2darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3936		CLAMP_CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3937		CLAMP_CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayBiasClamp,		FRAGMENT),
3938
3939		CLAMP_CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-10.0f,	10.0f,	false,	IVec3(0),	0.0f,	tex3DMipmapFixed,			evalTexture3DBiasClamp,				FRAGMENT),
3940		CLAMP_CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-10.0f,	10.0f,	false,	IVec3(0),	0.0f,	tex3DMipmapFloat,			evalTexture3DBiasClamp,				FRAGMENT),
3941		CLAMP_CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	0.0f,	8.0f,	false,	IVec3(0),	5.0f,	tex3DMipmapInt,				evalTexture3DBiasClamp,				FRAGMENT),
3942		CLAMP_CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	0.0f,	8.0f,	false,	IVec3(0),	5.0f,	tex3DMipmapUint,			evalTexture3DBiasClamp,				FRAGMENT),
3943
3944		CLAMP_CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	tex1DMipmapFixed,			evalTexture1DBiasClamp,				FRAGMENT),
3945		CLAMP_CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	false,	IVec3(0),	4.0f,	tex1DMipmapFloat,			evalTexture1DBiasClamp,				FRAGMENT),
3946		CLAMP_CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapInt,				evalTexture1DBiasClamp,				FRAGMENT),
3947		CLAMP_CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapUint,			evalTexture1DBiasClamp,				FRAGMENT),
3948
3949		CLAMP_CASE_SPEC(sampler1darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3950		CLAMP_CASE_SPEC(sampler1darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3951		CLAMP_CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3952		CLAMP_CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayBiasClamp,		FRAGMENT),
3953
3954		CLAMP_CASE_SPEC(samplercubearray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f,  1.0f, 1.01f,  2.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	3.0f,	texCubeArrayMipmapFixed,	evalTextureCubeArrayBiasClamp,		FRAGMENT),
3955		CLAMP_CASE_SPEC(samplercubearray_bias_float,	FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f, 0.0f),	Vec4(1.0f,  1.0f, 1.01f,  2.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	3.0f,	texCubeArrayMipmapFloat,	evalTextureCubeArrayBiasClamp,		FRAGMENT),
3956		CLAMP_CASE_SPEC(isamplercubearray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f,  6.0f, 6.01f,  2.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeArrayMipmapInt,		evalTextureCubeArrayBiasClamp,		FRAGMENT),
3957		CLAMP_CASE_SPEC(usamplercubearray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 6.01f, 0.0f),	Vec4(6.0f,  6.0f, 6.01f,  2.0f),	true,	2.0f,	5.0f,	false,	IVec3(0),	4.0f,	texCubeArrayMipmapUint,		evalTextureCubeArrayBiasClamp,		FRAGMENT),
3958
3959		CLAMP_CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  1.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex2DMipmapShadow,			evalTexture2DShadowBiasClamp,		FRAGMENT),
3960		CLAMP_CASE_SPEC(samplercubeshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f, 0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	texCubeMipmapShadow,		evalTextureCubeShadowBiasClamp,		FRAGMENT),
3961		CLAMP_CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  0.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DMipmapShadow,			evalTexture1DShadowBiasClamp,		FRAGMENT),
3962		CLAMP_CASE_SPEC(sampler1darrayshadow_bias,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  4.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	false,	IVec3(0),	7.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowBiasClamp,	FRAGMENT),
3963	};
3964	createCaseGroup(this, "textureclamp", textureClampARBCases, DE_LENGTH_OF_ARRAY(textureClampARBCases));
3965
3966	// textureOffset() cases
3967	// \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
3968	static const TexFuncCaseSpec textureOffsetCases[] =
3969	{
3970		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
3971		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DOffset,			VERTEX),
3972		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DOffset,			FRAGMENT),
3973		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DOffset,			VERTEX),
3974		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DOffset,			FRAGMENT),
3975		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DOffset,			VERTEX),
3976		CASE_SPEC(isampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DOffset,			FRAGMENT),
3977		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DOffset,			VERTEX),
3978		CASE_SPEC(usampler2d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DOffset,			FRAGMENT),
3979
3980		CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DOffsetBias,		FRAGMENT),
3981		CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DOffsetBias,		FRAGMENT),
3982		CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DOffsetBias,		FRAGMENT),
3983		CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DOffsetBias,		FRAGMENT),
3984
3985		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFixed,		evalTexture2DArrayOffset,		VERTEX),
3986		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayOffset,		FRAGMENT),
3987		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFloat,		evalTexture2DArrayOffset,		VERTEX),
3988		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayOffset,		FRAGMENT),
3989		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayInt,			evalTexture2DArrayOffset,		VERTEX),
3990		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayOffset,		FRAGMENT),
3991		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayUint,			evalTexture2DArrayOffset,		VERTEX),
3992		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayOffset,		FRAGMENT),
3993
3994		CASE_SPEC(sampler2darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayFixed,		evalTexture2DArrayOffsetBias,	FRAGMENT),
3995		CASE_SPEC(sampler2darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DArrayFloat,		evalTexture2DArrayOffsetBias,	FRAGMENT),
3996		CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayInt,			evalTexture2DArrayOffsetBias,	FRAGMENT),
3997		CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DArrayUint,			evalTexture2DArrayOffsetBias,	FRAGMENT),
3998
3999		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DOffset,			VERTEX),
4000		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DOffset,			FRAGMENT),
4001		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DOffset,			VERTEX),
4002		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DOffset,			FRAGMENT),
4003		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DOffset,			VERTEX),
4004		CASE_SPEC(isampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DOffset,			FRAGMENT),
4005		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DOffset,			VERTEX),
4006		CASE_SPEC(usampler3d,					FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DOffset,			FRAGMENT),
4007
4008		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DOffsetBias,		FRAGMENT),
4009		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	1.0f,	true,	IVec3(7, 3, -8),	tex3DFloat,				evalTexture3DOffsetBias,		FRAGMENT),
4010		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DInt,				evalTexture3DOffsetBias,		FRAGMENT),
4011		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DOffsetBias,		FRAGMENT),
4012
4013		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DOffset,			VERTEX),
4014		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapFixed,		evalTexture1DOffset,			FRAGMENT),
4015		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DOffset,			VERTEX),
4016		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapFloat,		evalTexture1DOffset,			FRAGMENT),
4017		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DOffset,			VERTEX),
4018		CASE_SPEC(isampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapInt,			evalTexture1DOffset,			FRAGMENT),
4019		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DOffset,			VERTEX),
4020		CASE_SPEC(usampler1d,					FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapUint,		evalTexture1DOffset,			FRAGMENT),
4021
4022		CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DOffsetBias,		FRAGMENT),
4023		CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DFloat,				evalTexture1DOffsetBias,		FRAGMENT),
4024		CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DOffsetBias,		FRAGMENT),
4025		CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DUint,				evalTexture1DOffsetBias,		FRAGMENT),
4026
4027		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFixed,		evalTexture1DArrayOffset,		VERTEX),
4028		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayOffset,		FRAGMENT),
4029		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFloat,		evalTexture1DArrayOffset,		VERTEX),
4030		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayOffset,		FRAGMENT),
4031		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayInt,			evalTexture1DArrayOffset,		VERTEX),
4032		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayOffset,		FRAGMENT),
4033		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayUint,			evalTexture1DArrayOffset,		VERTEX),
4034		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayOffset,		FRAGMENT),
4035
4036		CASE_SPEC(sampler1darray_bias_fixed,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayFixed,		evalTexture1DArrayOffsetBias,	FRAGMENT),
4037		CASE_SPEC(sampler1darray_bias_float,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayFloat,		evalTexture1DArrayOffsetBias,	FRAGMENT),
4038		CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayInt,			evalTexture1DArrayOffsetBias,	FRAGMENT),
4039		CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayUint,			evalTexture1DArrayOffsetBias,	FRAGMENT),
4040
4041		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowOffset,			VERTEX),
4042		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowOffset,			FRAGMENT),
4043		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowOffsetBias,		FRAGMENT),
4044		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayShadow,		evalTexture2DArrayShadowOffset,		VERTEX),
4045		CASE_SPEC(sampler2darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowOffset,		FRAGMENT),
4046		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowOffset,			VERTEX),
4047		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowOffset,			FRAGMENT),
4048		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowOffsetBias,		FRAGMENT),
4049		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayShadow,		evalTexture1DArrayShadowOffset,		VERTEX),
4050		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3( 7, 0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowOffset,		FRAGMENT),
4051		CASE_SPEC(sampler1darrayshadow_bias,	FUNCTION_TEXTURE,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayShadow,		evalTexture1DArrayShadowOffsetBias,	FRAGMENT),
4052	};
4053	createCaseGroup(this, "textureoffset", textureOffsetCases, DE_LENGTH_OF_ARRAY(textureOffsetCases));
4054
4055	// textureOffsetClampARB() cases
4056	static const TexFuncCaseSpec textureOffsetClampARBCases[] =
4057	{
4058		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				LodClamp	Format					EvalFunc									Flags
4059		CLAMP_CASE_SPEC(sampler2d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFixed,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4060		CLAMP_CASE_SPEC(sampler2d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(1.0f, 1.0f, 0.0f, 0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFloat,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4061		CLAMP_CASE_SPEC(isampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DMipmapInt,				evalTexture2DOffsetBiasClamp,				FRAGMENT),
4062		CLAMP_CASE_SPEC(usampler2d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(6.0f, 6.0f, 0.0f, 0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DMipmapUint,			evalTexture2DOffsetBiasClamp,				FRAGMENT),
4063
4064		CLAMP_CASE_SPEC(sampler2darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4065		CLAMP_CASE_SPEC(sampler2darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4066		CLAMP_CASE_SPEC(isampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4067		CLAMP_CASE_SPEC(usampler2darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(7, -8, 0),	7.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayOffsetBiasClamp,			FRAGMENT),
4068
4069		CLAMP_CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-12.0f,	12.0f,	true,	IVec3(-8, 7, 3),	2.0f,	tex3DMipmapFixed,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4070		CLAMP_CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 1.0f, 4.0f,  0.0f),		true,	-12.0f,	12.0f,	true,	IVec3(-8, 7, 3),	2.0f,	tex3DMipmapFloat,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4071		CLAMP_CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	-5.0f,	5.0f,	true,	IVec3(-8, 7, 3),	1.0f,	tex3DMipmapInt,				evalTexture3DOffsetBiasClamp,				FRAGMENT),
4072		CLAMP_CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 6.0f, 4.0f,  0.0f),		true,	-5.0f,	5.0f,	true,	IVec3(-8, 7, 3),	1.0f,	tex3DMipmapUint,			evalTexture3DOffsetBiasClamp,				FRAGMENT),
4073
4074		CLAMP_CASE_SPEC(sampler1d_bias_fixed,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	4.0f,	tex1DMipmapFixed,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4075		CLAMP_CASE_SPEC(sampler1d_bias_float,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f, 0.0f, 0.0f,  0.0f),		true,	0.0f,	5.0f,	true,	IVec3( 7, 0, 0),	4.0f,	tex1DMipmapFloat,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4076		CLAMP_CASE_SPEC(isampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DMipmapInt,				evalTexture1DOffsetBiasClamp,				FRAGMENT),
4077		CLAMP_CASE_SPEC(usampler1d_bias,				FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f, 0.0f, 0.0f,  0.0f),		true,	2.0f,	5.0f,	true,	IVec3( 7, 0, 0),	7.0f,	tex1DMipmapUint,			evalTexture1DOffsetBiasClamp,				FRAGMENT),
4078
4079		CLAMP_CASE_SPEC(sampler1darray_bias_fixed,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4080		CLAMP_CASE_SPEC(sampler1darray_bias_float,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(1.0f,  4.0f,  0.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3( 7, 0, 0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4081		CLAMP_CASE_SPEC(isampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4082		CLAMP_CASE_SPEC(usampler1darray_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4(6.0f,  4.0f,  0.0f,  0.0f),	true,	2.0f,	5.0f,	true,	IVec3( 7, 0, 0),	7.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayOffsetBiasClamp,			FRAGMENT),
4083
4084		CLAMP_CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  1.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 7, 0),	7.0f,	tex2DMipmapShadow,			evalTexture2DShadowOffsetBiasClamp,			FRAGMENT),
4085		CLAMP_CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  0.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DMipmapShadow,			evalTexture1DShadowOffsetBiasClamp,			FRAGMENT),
4086		CLAMP_CASE_SPEC(sampler1darrayshadow_bias,		FUNCTION_TEXTURE,	Vec4(0.0f, 0.0f, 0.0f,  0.0f),	Vec4( 1.0f,  4.0f,  1.0f,  0.0f),	true,	0.0f,	5.0f,	true,	IVec3(-8, 0, 0),	7.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowOffsetBiasClamp,	FRAGMENT),
4087	};
4088	createCaseGroup(this, "textureoffsetclamp", textureOffsetClampARBCases, DE_LENGTH_OF_ARRAY(textureOffsetClampARBCases));
4089
4090	// textureProj() cases
4091	// \note Currently uses constant divider!
4092	static const TexFuncCaseSpec textureProjCases[] =
4093	{
4094		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
4095		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2DProj3,		VERTEX),
4096		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj3,		FRAGMENT),
4097		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2DProj3,		VERTEX),
4098		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj3,		FRAGMENT),
4099		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2DProj3,		VERTEX),
4100		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj3,		FRAGMENT),
4101		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2DProj3,		VERTEX),
4102		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj3,		FRAGMENT),
4103
4104		CASE_SPEC(sampler2d_vec3_bias_fixed,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj3Bias,	FRAGMENT),
4105		CASE_SPEC(sampler2d_vec3_bias_float,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj3Bias,	FRAGMENT),
4106		CASE_SPEC(isampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj3Bias,	FRAGMENT),
4107		CASE_SPEC(usampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj3Bias,	FRAGMENT),
4108
4109		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFixed,				evalTexture2DProj,		VERTEX),
4110		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProj,		FRAGMENT),
4111		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DFloat,				evalTexture2DProj,		VERTEX),
4112		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProj,		FRAGMENT),
4113		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DInt,				evalTexture2DProj,		VERTEX),
4114		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProj,		FRAGMENT),
4115		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DUint,				evalTexture2DProj,		VERTEX),
4116		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProj,		FRAGMENT),
4117
4118		CASE_SPEC(sampler2d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjBias,	FRAGMENT),
4119		CASE_SPEC(sampler2d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjBias,	FRAGMENT),
4120		CASE_SPEC(isampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjBias,	FRAGMENT),
4121		CASE_SPEC(usampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjBias,	FRAGMENT),
4122
4123		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFixed,				evalTexture3DProj,		VERTEX),
4124		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProj,		FRAGMENT),
4125		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DFloat,				evalTexture3DProj,		VERTEX),
4126		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProj,		FRAGMENT),
4127		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DInt,				evalTexture3DProj,		VERTEX),
4128		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProj,		FRAGMENT),
4129		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DUint,				evalTexture3DProj,		VERTEX),
4130		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProj,		FRAGMENT),
4131
4132		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjBias,	FRAGMENT),
4133		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	1.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjBias,	FRAGMENT),
4134		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjBias,	FRAGMENT),
4135		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjBias,	FRAGMENT),
4136
4137		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1DProj2,		VERTEX),
4138		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj2,		FRAGMENT),
4139		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1DProj2,		VERTEX),
4140		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj2,		FRAGMENT),
4141		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1DProj2,		VERTEX),
4142		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj2,		FRAGMENT),
4143		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1DProj2,		VERTEX),
4144		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj2,		FRAGMENT),
4145
4146		CASE_SPEC(sampler1d_vec2_bias_fixed,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj2Bias,	FRAGMENT),
4147		CASE_SPEC(sampler1d_vec2_bias_float,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj2Bias,	FRAGMENT),
4148		CASE_SPEC(isampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj2Bias,	FRAGMENT),
4149		CASE_SPEC(usampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj2Bias,	FRAGMENT),
4150
4151		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFixed,				evalTexture1DProj,		VERTEX),
4152		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProj,		FRAGMENT),
4153		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DFloat,				evalTexture1DProj,		VERTEX),
4154		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProj,		FRAGMENT),
4155		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DInt,				evalTexture1DProj,		VERTEX),
4156		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProj,		FRAGMENT),
4157		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DUint,				evalTexture1DProj,		VERTEX),
4158		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProj,		FRAGMENT),
4159
4160		CASE_SPEC(sampler1d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjBias,	FRAGMENT),
4161		CASE_SPEC(sampler1d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjBias,	FRAGMENT),
4162		CASE_SPEC(isampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjBias,	FRAGMENT),
4163		CASE_SPEC(usampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjBias,	FRAGMENT),
4164
4165		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DShadow,			evalTexture2DShadowProj,		VERTEX),
4166		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProj,		FRAGMENT),
4167		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjBias,	FRAGMENT),
4168		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DShadow,			evalTexture1DShadowProj,		VERTEX),
4169		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProj,		FRAGMENT),
4170		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjBias,	FRAGMENT),
4171	};
4172	createCaseGroup(this, "textureproj", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
4173
4174	// textureProjOffset() cases
4175	// \note Currently uses constant divider!
4176	static const TexFuncCaseSpec textureProjOffsetCases[] =
4177	{
4178		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4179		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProj3Offset,		VERTEX),
4180		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DProj3Offset,		FRAGMENT),
4181		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DProj3Offset,		VERTEX),
4182		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProj3Offset,		FRAGMENT),
4183		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProj3Offset,		VERTEX),
4184		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DProj3Offset,		FRAGMENT),
4185		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DProj3Offset,		VERTEX),
4186		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProj3Offset,		FRAGMENT),
4187
4188		CASE_SPEC(sampler2d_vec3_bias_fixed,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4189		CASE_SPEC(sampler2d_vec3_bias_float,	FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4190		CASE_SPEC(isampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4191		CASE_SPEC(usampler2d_vec3_bias,			FUNCTION_TEXTUREPROJ3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DProj3OffsetBias,	FRAGMENT),
4192
4193		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProjOffset,		VERTEX),
4194		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFixed,		evalTexture2DProjOffset,		FRAGMENT),
4195		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DFloat,				evalTexture2DProjOffset,		VERTEX),
4196		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjOffset,		FRAGMENT),
4197		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProjOffset,		VERTEX),
4198		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapInt,			evalTexture2DProjOffset,		FRAGMENT),
4199		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DUint,				evalTexture2DProjOffset,		VERTEX),
4200		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjOffset,		FRAGMENT),
4201
4202		CASE_SPEC(sampler2d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DFixed,				evalTexture2DProjOffsetBias,	FRAGMENT),
4203		CASE_SPEC(sampler2d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DFloat,				evalTexture2DProjOffsetBias,	FRAGMENT),
4204		CASE_SPEC(isampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DInt,				evalTexture2DProjOffsetBias,	FRAGMENT),
4205		CASE_SPEC(usampler2d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7, -8, 0),	tex2DUint,				evalTexture2DProjOffsetBias,	FRAGMENT),
4206
4207		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DProjOffset,		VERTEX),
4208		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFixed,		evalTexture3DProjOffset,		FRAGMENT),
4209		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DFloat,				evalTexture3DProjOffset,		VERTEX),
4210		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFloat,		evalTexture3DProjOffset,		FRAGMENT),
4211		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DInt,				evalTexture3DProjOffset,		VERTEX),
4212		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DProjOffset,		FRAGMENT),
4213		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DProjOffset,		VERTEX),
4214		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJ,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  2.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DProjOffset,		FRAGMENT),
4215
4216		CASE_SPEC(sampler3d_bias_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DFixed,				evalTexture3DProjOffsetBias,	FRAGMENT),
4217		CASE_SPEC(sampler3d_bias_float,			FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(7, 3, -8),	tex3DFloat,				evalTexture3DProjOffsetBias,	FRAGMENT),
4218		CASE_SPEC(isampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DInt,				evalTexture3DProjOffsetBias,	FRAGMENT),
4219		CASE_SPEC(usampler3d_bias,				FUNCTION_TEXTUREPROJ,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 3),	tex3DUint,				evalTexture3DProjOffsetBias,	FRAGMENT),
4220
4221		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProj2Offset,		VERTEX),
4222		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFixed,		evalTexture1DProj2Offset,		FRAGMENT),
4223		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DProj2Offset,		VERTEX),
4224		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProj2Offset,		FRAGMENT),
4225		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProj2Offset,		VERTEX),
4226		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapInt,			evalTexture1DProj2Offset,		FRAGMENT),
4227		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DProj2Offset,		VERTEX),
4228		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProj2Offset,		FRAGMENT),
4229
4230		CASE_SPEC(sampler1d_vec2_bias_fixed,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4231		CASE_SPEC(sampler1d_vec2_bias_float,	FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DFloat,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4232		CASE_SPEC(isampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4233		CASE_SPEC(usampler1d_vec2_bias,			FUNCTION_TEXTUREPROJ2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DUint,				evalTexture1DProj2OffsetBias,	FRAGMENT),
4234
4235		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProjOffset,		VERTEX),
4236		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFixed,		evalTexture1DProjOffset,		FRAGMENT),
4237		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DFloat,				evalTexture1DProjOffset,		VERTEX),
4238		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjOffset,		FRAGMENT),
4239		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProjOffset,		VERTEX),
4240		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapInt,			evalTexture1DProjOffset,		FRAGMENT),
4241		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DUint,				evalTexture1DProjOffset,		VERTEX),
4242		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjOffset,		FRAGMENT),
4243
4244		CASE_SPEC(sampler1d_vec4_bias_fixed,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DFixed,				evalTexture1DProjOffsetBias,	FRAGMENT),
4245		CASE_SPEC(sampler1d_vec4_bias_float,	FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DFloat,				evalTexture1DProjOffsetBias,	FRAGMENT),
4246		CASE_SPEC(isampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DInt,				evalTexture1DProjOffsetBias,	FRAGMENT),
4247		CASE_SPEC(usampler1d_vec4_bias,			FUNCTION_TEXTUREPROJ,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(7,  0, 0),	tex1DUint,				evalTexture1DProjOffsetBias,	FRAGMENT),
4248
4249		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowProjOffset,		VERTEX),
4250		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjOffset,		FRAGMENT),
4251		CASE_SPEC(sampler2dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DShadow,			evalTexture2DShadowProjOffsetBias,	FRAGMENT),
4252		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowProjOffset,		VERTEX),
4253		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	false,	0.0f,	0.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjOffset,		FRAGMENT),
4254		CASE_SPEC(sampler1dshadow_bias,			FUNCTION_TEXTUREPROJ,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,   0.0f, 1.5f,  1.5f),	true,	-2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DShadow,			evalTexture1DShadowProjOffsetBias,	FRAGMENT),
4255	};
4256	createCaseGroup(this, "textureprojoffset", textureProjOffsetCases, DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
4257
4258	// textureLod() cases
4259	static const TexFuncCaseSpec textureLodCases[] =
4260	{
4261		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
4262		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DLod,		BOTH),
4263		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DLod,		BOTH),
4264		CASE_SPEC(isampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DLod,		BOTH),
4265		CASE_SPEC(usampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DLod,		BOTH),
4266
4267		CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeLod,		BOTH),
4268		CASE_SPEC(samplercube_float,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeLod,		BOTH),
4269		CASE_SPEC(isamplercube,					FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeLod,		BOTH),
4270		CASE_SPEC(usamplercube,					FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeLod,		BOTH),
4271
4272		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayLod,	BOTH),
4273		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayLod,	BOTH),
4274		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayLod,	BOTH),
4275		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayLod,	BOTH),
4276
4277		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DLod,		BOTH),
4278		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DLod,		BOTH),
4279		CASE_SPEC(isampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DLod,		BOTH),
4280		CASE_SPEC(usampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DLod,		BOTH),
4281
4282		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DLod,		BOTH),
4283		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DLod,		BOTH),
4284		CASE_SPEC(isampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DLod,		BOTH),
4285		CASE_SPEC(usampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DLod,		BOTH),
4286
4287		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayLod,	BOTH),
4288		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayLod,	BOTH),
4289		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayLod,	BOTH),
4290		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayLod,	BOTH),
4291
4292		CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayLod,	BOTH),
4293		CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayLod,	BOTH),
4294		CASE_SPEC(isamplercubearray,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayLod,	BOTH),
4295		CASE_SPEC(usamplercubearray,			FUNCTION_TEXTURELOD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayLod,	BOTH),
4296
4297		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowLod,			BOTH),
4298		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowLod,			BOTH),
4299		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowLod,	BOTH),
4300	};
4301	createCaseGroup(this, "texturelod", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
4302
4303	// textureLodOffset() cases
4304	static const TexFuncCaseSpec textureLodOffsetCases[] =
4305	{
4306		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4307		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DLodOffset,			BOTH),
4308		CASE_SPEC(sampler2d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DLodOffset,			BOTH),
4309		CASE_SPEC(isampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DLodOffset,			BOTH),
4310		CASE_SPEC(usampler2d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DLodOffset,			BOTH),
4311
4312		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayLodOffset,	BOTH),
4313		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayLodOffset,	BOTH),
4314		CASE_SPEC(isampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayLodOffset,	BOTH),
4315		CASE_SPEC(usampler2darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	false,	-1.0f,	8.0f,	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayLodOffset,	BOTH),
4316
4317		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DLodOffset,			BOTH),
4318		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DLodOffset,			BOTH),
4319		CASE_SPEC(isampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DLodOffset,			BOTH),
4320		CASE_SPEC(usampler3d,					FUNCTION_TEXTURELOD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapUint,		evalTexture3DLodOffset,			BOTH),
4321
4322		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DLodOffset,			BOTH),
4323		CASE_SPEC(sampler1d_float,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DLodOffset,			BOTH),
4324		CASE_SPEC(isampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DLodOffset,			BOTH),
4325		CASE_SPEC(usampler1d,					FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DLodOffset,			BOTH),
4326
4327		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayLodOffset,	BOTH),
4328		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayLodOffset,	BOTH),
4329		CASE_SPEC(isampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayLodOffset,	BOTH),
4330		CASE_SPEC(usampler1darray,				FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayLodOffset,	BOTH),
4331
4332		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowLodOffset,		BOTH),
4333		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTURELOD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowLodOffset,		BOTH),
4334		CASE_SPEC(sampler1darrayshadow,			FUNCTION_TEXTURELOD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowLodOffset,	BOTH),
4335	};
4336	createCaseGroup(this, "texturelodoffset", textureLodOffsetCases, DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
4337
4338	// textureProjLod() cases
4339	static const TexFuncCaseSpec textureProjLodCases[] =
4340	{
4341		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc					Flags
4342		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjLod3,		BOTH),
4343		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjLod3,		BOTH),
4344		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjLod3,		BOTH),
4345		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjLod3,		BOTH),
4346
4347		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjLod,		BOTH),
4348		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjLod,		BOTH),
4349		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjLod,		BOTH),
4350		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjLod,		BOTH),
4351
4352		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjLod,		BOTH),
4353		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjLod,		BOTH),
4354		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjLod,		BOTH),
4355		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjLod,		BOTH),
4356
4357		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjLod2,		BOTH),
4358		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjLod2,		BOTH),
4359		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjLod2,		BOTH),
4360		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjLod2,		BOTH),
4361
4362		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjLod,		BOTH),
4363		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjLod,		BOTH),
4364		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjLod,		BOTH),
4365		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjLod,		BOTH),
4366
4367		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjLod,	BOTH),
4368		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjLod,	BOTH),
4369	};
4370	createCaseGroup(this, "textureprojlod", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
4371
4372	// textureProjLodOffset() cases
4373	static const TexFuncCaseSpec textureProjLodOffsetCases[] =
4374	{
4375		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc								Flags
4376		CASE_SPEC(sampler2d_vec3_fixed,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjLod3Offset,	BOTH),
4377		CASE_SPEC(sampler2d_vec3_float,			FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjLod3Offset,	BOTH),
4378		CASE_SPEC(isampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjLod3Offset,	BOTH),
4379		CASE_SPEC(usampler2d_vec3,				FUNCTION_TEXTUREPROJLOD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjLod3Offset,	BOTH),
4380
4381		CASE_SPEC(sampler2d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjLodOffset,		BOTH),
4382		CASE_SPEC(sampler2d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjLodOffset,		BOTH),
4383		CASE_SPEC(isampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjLodOffset,		BOTH),
4384		CASE_SPEC(usampler2d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjLodOffset,		BOTH),
4385
4386		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DProjLodOffset,		BOTH),
4387		CASE_SPEC(sampler3d_float,				FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DProjLodOffset,		BOTH),
4388		CASE_SPEC(isampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(3, -8, 7),	tex3DMipmapInt,			evalTexture3DProjLodOffset,		BOTH),
4389		CASE_SPEC(usampler3d,					FUNCTION_TEXTUREPROJLOD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	false,	-1.0f,	7.0f,	true,	IVec3(-8, 7, 3),	tex3DMipmapUint,		evalTexture3DProjLodOffset,		BOTH),
4390
4391		CASE_SPEC(sampler1d_vec2_fixed,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DProjLod2Offset,	BOTH),
4392		CASE_SPEC(sampler1d_vec2_float,			FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjLod2Offset,	BOTH),
4393		CASE_SPEC(isampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DProjLod2Offset,	BOTH),
4394		CASE_SPEC(usampler1d_vec2,				FUNCTION_TEXTUREPROJLOD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjLod2Offset,	BOTH),
4395
4396		CASE_SPEC(sampler1d_vec4_fixed,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DProjLodOffset,		BOTH),
4397		CASE_SPEC(sampler1d_vec4_float,			FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DProjLodOffset,		BOTH),
4398		CASE_SPEC(isampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DProjLodOffset,		BOTH),
4399		CASE_SPEC(usampler1d_vec4,				FUNCTION_TEXTUREPROJLOD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DProjLodOffset,		BOTH),
4400
4401		CASE_SPEC(sampler2dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.6f,  0.0f,  1.5f),	Vec4(-2.25f, -3.45f, 1.5f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjLodOffset,	BOTH),
4402		CASE_SPEC(sampler1dshadow,				FUNCTION_TEXTUREPROJLOD,	Vec4( 0.2f, 0.0f,  0.0f,  1.5f),	Vec4(-2.25f,  0.0f,  1.5f,  1.5f),	false,	-1.0f,	9.0f,	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjLodOffset,	BOTH),
4403	};
4404	createCaseGroup(this, "textureprojlodoffset", textureProjLodOffsetCases, DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
4405
4406	// textureGrad() cases
4407	// \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
4408	static const TexFuncCaseSpec textureGradCases[] =
4409	{
4410		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc				Flags
4411		GRAD_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DGrad,		BOTH),
4412		GRAD_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DGrad,		BOTH),
4413		GRAD_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DGrad,		BOTH),
4414		GRAD_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DGrad,		BOTH),
4415
4416		GRAD_CASE_SPEC(samplercube_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapFixed,		evalTextureCubeGrad,	BOTH),
4417		GRAD_CASE_SPEC(samplercube_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapFloat,		evalTextureCubeGrad,	BOTH),
4418		GRAD_CASE_SPEC(isamplercube,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapInt,		evalTextureCubeGrad,	BOTH),
4419		GRAD_CASE_SPEC(usamplercube,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	texCubeMipmapUint,		evalTextureCubeGrad,	BOTH),
4420
4421		GRAD_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapFixed,	evalTexture2DArrayGrad,	BOTH),
4422		GRAD_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapFloat,	evalTexture2DArrayGrad,	BOTH),
4423		GRAD_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapInt,	evalTexture2DArrayGrad,	BOTH),
4424		GRAD_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapUint,	evalTexture2DArrayGrad,	BOTH),
4425
4426		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DGrad,		BOTH),
4427		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DGrad,		VERTEX),
4428		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DGrad,		FRAGMENT),
4429		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DGrad,		BOTH),
4430		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DGrad,		VERTEX),
4431		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DGrad,		FRAGMENT),
4432
4433		GRAD_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DGrad,		BOTH),
4434		GRAD_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DGrad,		BOTH),
4435		GRAD_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DGrad,		BOTH),
4436		GRAD_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DGrad,		BOTH),
4437
4438		GRAD_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapFixed,	evalTexture1DArrayGrad,	BOTH),
4439		GRAD_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapFloat,	evalTexture1DArrayGrad,	BOTH),
4440		GRAD_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapInt,	evalTexture1DArrayGrad,	BOTH),
4441		GRAD_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapUint,	evalTexture1DArrayGrad,	BOTH),
4442
4443		GRAD_CASE_SPEC(samplercubearray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapFixed,	evalTextureCubeArrayGrad,	BOTH),
4444		GRAD_CASE_SPEC(samplercubearray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapFloat,	evalTextureCubeArrayGrad,	BOTH),
4445		GRAD_CASE_SPEC(isamplercubearray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapInt,		evalTextureCubeArrayGrad,	BOTH),
4446		GRAD_CASE_SPEC(usamplercubearray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	texCubeArrayMipmapUint,		evalTextureCubeArrayGrad,	BOTH),
4447
4448		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowGrad,		BOTH),
4449		GRAD_CASE_SPEC(samplercubeshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, 0.0f),	Vec4( 1.0f,  1.0f,  1.01f, 1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	texCubeMipmapShadow,	evalTextureCubeShadowGrad,		BOTH),
4450		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGrad,	VERTEX),
4451		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f, -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGrad,	FRAGMENT),
4452		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowGrad,		BOTH),
4453		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGrad,	VERTEX),
4454		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGrad,	FRAGMENT),
4455	};
4456	createCaseGroup(this, "texturegrad", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
4457
4458	// textureGradClampARB() cases
4459	static const TexFuncCaseSpec textureGradClampCases[] =
4460	{
4461		//		  Name									Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		LodClamp	Format					EvalFunc						Flags
4462		GRADCLAMP_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapFixed,			evalTexture2DGradClamp,				FRAGMENT),
4463		GRADCLAMP_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapFloat,			evalTexture2DGradClamp,				FRAGMENT),
4464		GRADCLAMP_CASE_SPEC(isampler2d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapInt,				evalTexture2DGradClamp,				FRAGMENT),
4465		GRADCLAMP_CASE_SPEC(usampler2d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapUint,			evalTexture2DGradClamp,				FRAGMENT),
4466
4467		GRADCLAMP_CASE_SPEC(samplercube_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapFixed,			evalTextureCubeGradClamp,			FRAGMENT),
4468		GRADCLAMP_CASE_SPEC(samplercube_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapFloat,			evalTextureCubeGradClamp,			FRAGMENT),
4469		GRADCLAMP_CASE_SPEC(isamplercube,				FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapInt,			evalTextureCubeGradClamp,			FRAGMENT),
4470		GRADCLAMP_CASE_SPEC(usamplercube,				FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f,  0.0f),	Vec4( 1.0f,  1.0f, -1.01f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapUint,			evalTextureCubeGradClamp,			FRAGMENT),
4471
4472		GRADCLAMP_CASE_SPEC(sampler2darray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFixed,		evalTexture2DArrayGradClamp,		FRAGMENT),
4473		GRADCLAMP_CASE_SPEC(sampler2darray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapFloat,		evalTexture2DArrayGradClamp,		FRAGMENT),
4474		GRADCLAMP_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapInt,		evalTexture2DArrayGradClamp,		FRAGMENT),
4475		GRADCLAMP_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapUint,		evalTexture2DArrayGradClamp,		FRAGMENT),
4476
4477		GRADCLAMP_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapFixed,			evalTexture3DGradClamp,			FRAGMENT),
4478		GRADCLAMP_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapFloat,			evalTexture3DGradClamp,				FRAGMENT),
4479		GRADCLAMP_CASE_SPEC(isampler3d,					FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex3DMipmapInt,				evalTexture3DGradClamp,				FRAGMENT),
4480		GRADCLAMP_CASE_SPEC(usampler3d,					FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	5.0f,	tex3DMipmapUint,			evalTexture3DGradClamp,				FRAGMENT),
4481
4482		GRADCLAMP_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapFixed,			evalTexture1DGradClamp,				FRAGMENT),
4483		GRADCLAMP_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapFloat,			evalTexture1DGradClamp,				FRAGMENT),
4484		GRADCLAMP_CASE_SPEC(isampler1d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapInt,				evalTexture1DGradClamp,				FRAGMENT),
4485		GRADCLAMP_CASE_SPEC(usampler1d,					FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapUint,			evalTexture1DGradClamp,				FRAGMENT),
4486
4487		GRADCLAMP_CASE_SPEC(sampler1darray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFixed,		evalTexture1DArrayGradClamp,		FRAGMENT),
4488		GRADCLAMP_CASE_SPEC(sampler1darray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapFloat,		evalTexture1DArrayGradClamp,		FRAGMENT),
4489		GRADCLAMP_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapInt,		evalTexture1DArrayGradClamp,		FRAGMENT),
4490		GRADCLAMP_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapUint,		evalTexture1DArrayGradClamp,		FRAGMENT),
4491
4492		GRADCLAMP_CASE_SPEC(samplercubearray_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapFixed,	evalTextureCubeArrayGradClamp,		FRAGMENT),
4493		GRADCLAMP_CASE_SPEC(samplercubearray_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapFloat,	evalTextureCubeArrayGradClamp,		FRAGMENT),
4494		GRADCLAMP_CASE_SPEC(isamplercubearray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f, -0.5f),	Vec4( 1.0f,  1.0f,  1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapInt,		evalTextureCubeArrayGradClamp,		FRAGMENT),
4495		GRADCLAMP_CASE_SPEC(usamplercubearray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f, -1.01f, -0.5f),	Vec4( 1.0f,  1.0f, -1.01f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	4.0f,	texCubeArrayMipmapUint,		evalTextureCubeArrayGradClamp,		FRAGMENT),
4496
4497		GRADCLAMP_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DMipmapShadow,			evalTexture2DShadowGradClamp,		FRAGMENT),
4498		GRADCLAMP_CASE_SPEC(samplercubeshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-1.0f, -1.0f,  1.01f,  0.0f),	Vec4( 1.0f,  1.0f,  1.01f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	texCubeMipmapShadow,		evalTextureCubeShadowGradClamp,		FRAGMENT),
4499		GRADCLAMP_CASE_SPEC(sampler2darrayshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	5.0f,	tex2DArrayMipmapShadow,		evalTexture2DArrayShadowGradClamp,	FRAGMENT),
4500		GRADCLAMP_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DMipmapShadow,			evalTexture1DShadowGradClamp,		FRAGMENT),
4501		GRADCLAMP_CASE_SPEC(sampler1darrayshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	5.0f,	tex1DArrayMipmapShadow,		evalTexture1DArrayShadowGradClamp,	FRAGMENT),
4502	};
4503	createCaseGroup(this, "texturegradclamp", textureGradClampCases, DE_LENGTH_OF_ARRAY(textureGradClampCases));
4504
4505	// textureGradOffset() cases
4506	static const TexFuncCaseSpec textureGradOffsetCases[] =
4507	{
4508		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4509		GRAD_CASE_SPEC(sampler2d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DGradOffset,			BOTH),
4510		GRAD_CASE_SPEC(sampler2d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DGradOffset,			BOTH),
4511		GRAD_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DGradOffset,			BOTH),
4512		GRAD_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DGradOffset,			BOTH),
4513
4514		GRAD_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapFixed,	evalTexture2DArrayGradOffset,		BOTH),
4515		GRAD_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapFloat,	evalTexture2DArrayGradOffset,		BOTH),
4516		GRAD_CASE_SPEC(isampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapInt,	evalTexture2DArrayGradOffset,		BOTH),
4517		GRAD_CASE_SPEC(usampler2darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapUint,	evalTexture2DArrayGradOffset,		BOTH),
4518
4519		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DGradOffset,			BOTH),
4520		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DGradOffset,			VERTEX),
4521		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	tex3DMipmapFloat,		evalTexture3DGradOffset,			FRAGMENT),
4522		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapInt,			evalTexture3DGradOffset,			BOTH),
4523		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DGradOffset,			VERTEX),
4524		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	tex3DMipmapUint,		evalTexture3DGradOffset,			FRAGMENT),
4525
4526		GRAD_CASE_SPEC(sampler1d_fixed,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapFixed,		evalTexture1DGradOffset,			BOTH),
4527		GRAD_CASE_SPEC(sampler1d_float,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapFloat,		evalTexture1DGradOffset,			BOTH),
4528		GRAD_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapInt,			evalTexture1DGradOffset,			BOTH),
4529		GRAD_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapUint,		evalTexture1DGradOffset,			BOTH),
4530
4531		GRAD_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapFixed,	evalTexture1DArrayGradOffset,		BOTH),
4532		GRAD_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapFloat,	evalTexture1DArrayGradOffset,		BOTH),
4533		GRAD_CASE_SPEC(isampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapInt,	evalTexture1DArrayGradOffset,		BOTH),
4534		GRAD_CASE_SPEC(usampler1darray,			FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapUint,	evalTexture1DArrayGradOffset,		BOTH),
4535
4536		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowGradOffset,		VERTEX),
4537		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowGradOffset,		FRAGMENT),
4538		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffset,	VERTEX),
4539		GRAD_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffset,	FRAGMENT),
4540		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DMipmapShadow,		evalTexture1DShadowGradOffset,		VERTEX),
4541		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DMipmapShadow,		evalTexture1DShadowGradOffset,		FRAGMENT),
4542		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffset,	VERTEX),
4543		GRAD_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffset,	FRAGMENT),
4544	};
4545	createCaseGroup(this, "texturegradoffset", textureGradOffsetCases, DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
4546
4547	// textureGradOffsetClampARB() cases
4548	static const TexFuncCaseSpec textureGradOffsetClampCases[] =
4549	{
4550		//		  Name								Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				LodClamp	Format				EvalFunc									Flags
4551		GRADCLAMP_CASE_SPEC(sampler2d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DMipmapFixed,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4552		GRADCLAMP_CASE_SPEC(sampler2d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapFloat,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4553		GRADCLAMP_CASE_SPEC(isampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DMipmapInt,			evalTexture2DGradOffsetClamp,				FRAGMENT),
4554		GRADCLAMP_CASE_SPEC(usampler2d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapUint,		evalTexture2DGradOffsetClamp,				FRAGMENT),
4555
4556		GRADCLAMP_CASE_SPEC(sampler2darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DArrayMipmapFixed,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4557		GRADCLAMP_CASE_SPEC(sampler2darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapFloat,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4558		GRADCLAMP_CASE_SPEC(isampler2darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	5.0f,	tex2DArrayMipmapInt,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4559		GRADCLAMP_CASE_SPEC(usampler2darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapUint,	evalTexture2DArrayGradOffsetClamp,			FRAGMENT),
4560
4561		GRADCLAMP_CASE_SPEC(sampler3d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	5.0f,	tex3DMipmapFixed,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4562		GRADCLAMP_CASE_SPEC(sampler3d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	5.0f,	tex3DMipmapFloat,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4563		GRADCLAMP_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	5.0f,	tex3DMipmapInt,			evalTexture3DGradOffsetClamp,				FRAGMENT),
4564		GRADCLAMP_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -1.4f,  0.1f,  0.0f),	Vec4( 1.5f,  2.3f,  2.3f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	5.0f,	tex3DMipmapUint,		evalTexture3DGradOffsetClamp,				FRAGMENT),
4565
4566		GRADCLAMP_CASE_SPEC(sampler1d_fixed,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DMipmapFixed,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4567		GRADCLAMP_CASE_SPEC(sampler1d_float,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapFloat,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4568		GRADCLAMP_CASE_SPEC(isampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DMipmapInt,			evalTexture1DGradOffsetClamp,				FRAGMENT),
4569		GRADCLAMP_CASE_SPEC(usampler1d,				FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapUint,		evalTexture1DGradOffsetClamp,				FRAGMENT),
4570
4571		GRADCLAMP_CASE_SPEC(sampler1darray_fixed,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapFixed,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4572		GRADCLAMP_CASE_SPEC(sampler1darray_float,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapFloat,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4573		GRADCLAMP_CASE_SPEC(isampler1darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 0, 0),	5.0f,	tex1DArrayMipmapInt,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4574		GRADCLAMP_CASE_SPEC(usampler1darray,		FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,   0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapUint,	evalTexture1DArrayGradOffsetClamp,			FRAGMENT),
4575
4576		GRADCLAMP_CASE_SPEC(sampler2dshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f, -0.4f,  0.0f,  0.0f),	Vec4( 1.5f,  2.3f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DMipmapShadow,		evalTexture2DShadowGradOffsetClamp,			FRAGMENT),
4577		GRADCLAMP_CASE_SPEC(sampler2darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.4f,  -0.5f,  0.0f),	Vec4( 1.5f,  2.3f,  3.5f,  1.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	5.0f,	tex2DArrayMipmapShadow,	evalTexture2DArrayShadowGradOffsetClamp,	FRAGMENT),
4578		GRADCLAMP_CASE_SPEC(sampler1dshadow,		FUNCTION_TEXTUREGRAD,	Vec4(-0.2f,  0.0f,  0.0f,  0.0f),	Vec4( 1.5f,  0.0f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DMipmapShadow,		evalTexture1DShadowGradOffsetClamp,			FRAGMENT),
4579		GRADCLAMP_CASE_SPEC(sampler1darrayshadow,	FUNCTION_TEXTUREGRAD,	Vec4(-1.2f, -0.5f,  0.0f,  0.0f),	Vec4( 1.5f,  3.5f,  1.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7,  0, 0),	5.0f,	tex1DArrayMipmapShadow,	evalTexture1DArrayShadowGradOffsetClamp,	FRAGMENT),
4580	};
4581	createCaseGroup(this, "texturegradoffsetclamp", textureGradOffsetClampCases, DE_LENGTH_OF_ARRAY(textureGradOffsetClampCases));
4582
4583
4584	// textureProjGrad() cases
4585	static const TexFuncCaseSpec textureProjGradCases[] =
4586	{
4587		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc					Flags
4588		GRAD_CASE_SPEC(sampler2d_vec3_fixed,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjGrad3,		BOTH),
4589		GRAD_CASE_SPEC(sampler2d_vec3_float,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjGrad3,		BOTH),
4590		GRAD_CASE_SPEC(isampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjGrad3,		BOTH),
4591		GRAD_CASE_SPEC(usampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjGrad3,		BOTH),
4592
4593		GRAD_CASE_SPEC(sampler2d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFixed,		evalTexture2DProjGrad,		BOTH),
4594		GRAD_CASE_SPEC(sampler2d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapFloat,		evalTexture2DProjGrad,		BOTH),
4595		GRAD_CASE_SPEC(isampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapInt,			evalTexture2DProjGrad,		BOTH),
4596		GRAD_CASE_SPEC(usampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapUint,		evalTexture2DProjGrad,		BOTH),
4597
4598		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFixed,		evalTexture3DProjGrad,		BOTH),
4599		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjGrad,		VERTEX),
4600		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapFloat,		evalTexture3DProjGrad,		FRAGMENT),
4601		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex3DMipmapInt,			evalTexture3DProjGrad,		BOTH),
4602		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjGrad,		VERTEX),
4603		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	false,	IVec3(0),	tex3DMipmapUint,		evalTexture3DProjGrad,		FRAGMENT),
4604
4605		GRAD_CASE_SPEC(sampler1d_vec2_fixed,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjGrad2,		BOTH),
4606		GRAD_CASE_SPEC(sampler1d_vec2_float,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjGrad2,		BOTH),
4607		GRAD_CASE_SPEC(isampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjGrad2,		BOTH),
4608		GRAD_CASE_SPEC(usampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjGrad2,		BOTH),
4609
4610		GRAD_CASE_SPEC(sampler1d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFixed,		evalTexture1DProjGrad,		BOTH),
4611		GRAD_CASE_SPEC(sampler1d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapFloat,		evalTexture1DProjGrad,		BOTH),
4612		GRAD_CASE_SPEC(isampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapInt,			evalTexture1DProjGrad,		BOTH),
4613		GRAD_CASE_SPEC(usampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapUint,		evalTexture1DProjGrad,		BOTH),
4614
4615		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjGrad,	VERTEX),
4616		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	false,	IVec3(0),	tex2DMipmapShadow,		evalTexture2DShadowProjGrad,	FRAGMENT),
4617		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjGrad,	VERTEX),
4618		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	false,	IVec3(0),	tex1DMipmapShadow,		evalTexture1DShadowProjGrad,	FRAGMENT),
4619	};
4620	createCaseGroup(this, "textureprojgrad", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
4621
4622	// textureProjGradOffset() cases
4623	static const TexFuncCaseSpec textureProjGradOffsetCases[] =
4624	{
4625		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4626		GRAD_CASE_SPEC(sampler2d_vec3_fixed,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjGrad3Offset,		BOTH),
4627		GRAD_CASE_SPEC(sampler2d_vec3_float,	FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjGrad3Offset,		BOTH),
4628		GRAD_CASE_SPEC(isampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjGrad3Offset,		BOTH),
4629		GRAD_CASE_SPEC(usampler2d_vec3,			FUNCTION_TEXTUREPROJGRAD3,	Vec4(-0.3f, -0.6f,  1.5f,  0.0f),	Vec4(2.25f, 3.45f,  1.5f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjGrad3Offset,		BOTH),
4630
4631		GRAD_CASE_SPEC(sampler2d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapFixed,		evalTexture2DProjGradOffset,		BOTH),
4632		GRAD_CASE_SPEC(sampler2d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapFloat,		evalTexture2DProjGradOffset,		BOTH),
4633		GRAD_CASE_SPEC(isampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapInt,			evalTexture2DProjGradOffset,		BOTH),
4634		GRAD_CASE_SPEC(usampler2d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f, -0.6f,  0.0f,  1.5f),	Vec4(2.25f, 3.45f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapUint,		evalTexture2DProjGradOffset,		BOTH),
4635
4636		GRAD_CASE_SPEC(sampler3d_fixed,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapFixed,		evalTexture3DProjGradOffset,		BOTH),
4637		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapFloat,		evalTexture3DProjGradOffset,		VERTEX),
4638		GRAD_CASE_SPEC(sampler3d_float,			FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.2f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(3, -8, 7),	tex3DMipmapFloat,		evalTexture3DProjGradOffset,		FRAGMENT),
4639		GRAD_CASE_SPEC(isampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 3),	tex3DMipmapInt,			evalTexture3DProjGradOffset,		BOTH),
4640		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.2f,  0.0f),	true,	IVec3(7, 3, -8),	tex3DMipmapUint,		evalTexture3DProjGradOffset,		VERTEX),
4641		GRAD_CASE_SPEC(usampler3d,				FUNCTION_TEXTUREPROJGRAD,	Vec4(0.9f, 1.05f, -0.08f, -0.75f),	Vec4(-1.13f, -1.7f, -1.7f, -0.75f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f, -0.2f),	true,	IVec3(3, -8, 7),	tex3DMipmapUint,		evalTexture3DProjGradOffset,		FRAGMENT),
4642
4643		GRAD_CASE_SPEC(sampler1d_vec2_fixed,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapFixed,		evalTexture1DProjGrad2Offset,		BOTH),
4644		GRAD_CASE_SPEC(sampler1d_vec2_float,	FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapFloat,		evalTexture1DProjGrad2Offset,		BOTH),
4645		GRAD_CASE_SPEC(isampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapInt,			evalTexture1DProjGrad2Offset,		BOTH),
4646		GRAD_CASE_SPEC(usampler1d_vec2,			FUNCTION_TEXTUREPROJGRAD2,	Vec4(-0.3f,  1.5f,  0.0f,  0.0f),	Vec4(2.25f,  1.5f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapUint,		evalTexture1DProjGrad2Offset,		BOTH),
4647
4648		GRAD_CASE_SPEC(sampler1d_vec4_fixed,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapFixed,		evalTexture1DProjGradOffset,		BOTH),
4649		GRAD_CASE_SPEC(sampler1d_vec4_float,	FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapFloat,		evalTexture1DProjGradOffset,		BOTH),
4650		GRAD_CASE_SPEC(isampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapInt,			evalTexture1DProjGradOffset,		BOTH),
4651		GRAD_CASE_SPEC(usampler1d_vec4,			FUNCTION_TEXTUREPROJGRAD,	Vec4(-0.3f,  0.0f,  0.0f,  1.5f),	Vec4(2.25f,  0.0f,  0.0f,  1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapUint,		evalTexture1DProjGradOffset,		BOTH),
4652
4653		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjGradOffset,	VERTEX),
4654		GRAD_CASE_SPEC(sampler2dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.6f,  0.0f,  -1.5f),	Vec4(-2.25f, -3.45f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f, -0.2f,  0.0f),	true,	IVec3(7, -8, 0),	tex2DMipmapShadow,		evalTexture2DShadowProjGradOffset,	FRAGMENT),
4655		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.2f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	true,	IVec3(-8, 7, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjGradOffset,	VERTEX),
4656		GRAD_CASE_SPEC(sampler1dshadow,			FUNCTION_TEXTUREPROJGRAD,	Vec4( 0.2f, 0.0f,  0.0f,  -1.5f),	Vec4(-2.25f,   0.0f, -1.5f, -1.5f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3( 0.0f,  0.0f,  0.0f),	Vec3(-0.2f,  0.0f,  0.0f),	true,	IVec3(7, -8, 0),	tex1DMipmapShadow,		evalTexture1DShadowProjGradOffset,	FRAGMENT),
4657	};
4658	createCaseGroup(this, "textureprojgradoffset", textureProjGradOffsetCases, DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
4659
4660	// texelFetch() cases
4661	// \note Level is constant across quad
4662	static const TexFuncCaseSpec texelFetchCases[] =
4663	{
4664		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4665		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f, 255.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DTexelFetchFixed,		evalTexelFetch2D,		BOTH),
4666		CASE_SPEC(sampler2d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f, 127.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex2DTexelFetchFloat,		evalTexelFetch2D,		BOTH),
4667		CASE_SPEC(isampler2d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,  63.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex2DTexelFetchInt,			evalTexelFetch2D,		BOTH),
4668		CASE_SPEC(usampler2d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,  15.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex2DTexelFetchUint,		evalTexelFetch2D,		BOTH),
4669
4670		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f, 127.9f,  3.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex2DArrayTexelFetchFixed,	evalTexelFetch2DArray,	BOTH),
4671		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,  63.9f,  3.9f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex2DArrayTexelFetchFloat,	evalTexelFetch2DArray,	BOTH),
4672		CASE_SPEC(isampler2darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 31.9f,  31.9f,  3.9f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex2DArrayTexelFetchInt,	evalTexelFetch2DArray,	BOTH),
4673		CASE_SPEC(usampler2darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,  15.9f,  3.9f,  0.0f),	false,	3.0f,	3.0f,	false,	IVec3(0),	tex2DArrayTexelFetchUint,	evalTexelFetch2DArray,	BOTH),
4674
4675		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(63.9f,  31.9f,  31.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DTexelFetchFixed,		evalTexelFetch3D,		BOTH),
4676		CASE_SPEC(sampler3d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(31.9f,  15.9f,  15.9f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex3DTexelFetchFloat,		evalTexelFetch3D,		BOTH),
4677		CASE_SPEC(isampler3d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(15.9f,   7.9f,   7.9f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex3DTexelFetchInt,			evalTexelFetch3D,		BOTH),
4678		CASE_SPEC(usampler3d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(63.9f,  31.9f,  31.9f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex3DTexelFetchUint,		evalTexelFetch3D,		BOTH),
4679
4680		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f,   0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DTexelFetchFixed,		evalTexelFetch1D,		BOTH),
4681		CASE_SPEC(sampler1d_float,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f,   0.0f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex1DTexelFetchFloat,		evalTexelFetch1D,		BOTH),
4682		CASE_SPEC(isampler1d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,   0.0f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex1DTexelFetchInt,			evalTexelFetch1D,		BOTH),
4683		CASE_SPEC(usampler1d,					FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,   0.0f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex1DTexelFetchUint,		evalTexelFetch1D,		BOTH),
4684
4685		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(255.9f,   3.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	false,	IVec3(0),	tex1DArrayTexelFetchFixed,	evalTexelFetch1DArray,	BOTH),
4686		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4(127.9f,   3.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	false,	IVec3(0),	tex1DArrayTexelFetchFloat,	evalTexelFetch1DArray,	BOTH),
4687		CASE_SPEC(isampler1darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 63.9f,   3.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	false,	IVec3(0),	tex1DArrayTexelFetchInt,	evalTexelFetch1DArray,	BOTH),
4688		CASE_SPEC(usampler1darray,				FUNCTION_TEXELFETCH,	Vec4(0.0f, 0.0f, 0.0f, 0.0f),	Vec4( 15.9f,   3.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	false,	IVec3(0),	tex1DArrayTexelFetchUint,	evalTexelFetch1DArray,	BOTH),
4689	};
4690	createCaseGroup(this, "texelfetch", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
4691
4692	// texelFetchOffset() cases
4693	static const TexFuncCaseSpec texelFetchOffsetCases[] =
4694	{
4695		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4696		CASE_SPEC(sampler2d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4(263.9f, 248.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DTexelFetchFixed,		evalTexelFetch2D,		BOTH),
4697		CASE_SPEC(sampler2d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(120.9f, 135.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, -8, 0),	tex2DTexelFetchFloat,		evalTexelFetch2D,		BOTH),
4698		CASE_SPEC(isampler2d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4( 71.9f,  56.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DTexelFetchInt,			evalTexelFetch2D,		BOTH),
4699		CASE_SPEC(usampler2d,					FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(  8.9f,  23.9f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	true,	IVec3(7, -8, 0),	tex2DTexelFetchUint,		evalTexelFetch2D,		BOTH),
4700
4701		CASE_SPEC(sampler2darray_fixed,			FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4(135.9f, 120.9f,  3.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayTexelFetchFixed,	evalTexelFetch2DArray,	BOTH),
4702		CASE_SPEC(sampler2darray_float,			FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4( 56.9f,  71.9f,  3.9f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, -8, 0),	tex2DArrayTexelFetchFloat,	evalTexelFetch2DArray,	BOTH),
4703		CASE_SPEC(isampler2darray,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, 0.0f, 0.0f),	Vec4( 39.9f,  24.9f,  3.9f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 7, 0),	tex2DArrayTexelFetchInt,	evalTexelFetch2DArray,	BOTH),
4704		CASE_SPEC(usampler2darray,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  8.0f, 0.0f, 0.0f),	Vec4(  8.9f,  23.9f,  3.9f,  0.0f),	false,	3.0f,	3.0f,	true,	IVec3(7, -8, 0),	tex2DArrayTexelFetchUint,	evalTexelFetch2DArray,	BOTH),
4705
4706		CASE_SPEC(sampler3d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, -3.0f, 0.0f),Vec4(71.9f,  24.9f,  28.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DTexelFetchFixed,		evalTexelFetch3D,		BOTH),
4707		CASE_SPEC(sampler3d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f, -3.0f,  8.0f, 0.0f),Vec4(24.9f,  12.9f,  23.9f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7, 3, -8),	tex3DTexelFetchFloat,		evalTexelFetch3D,		BOTH),
4708		CASE_SPEC(isampler3d,					FUNCTION_TEXELFETCH,	Vec4(-3.0f,  8.0f, -7.0f, 0.0f),Vec4(12.9f,  15.9f,   0.9f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(3, -8, 7),	tex3DTexelFetchInt,			evalTexelFetch3D,		BOTH),
4709		CASE_SPEC(usampler3d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f, -7.0f, -3.0f, 0.0f),Vec4(71.9f,  24.9f,  28.9f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 7, 3),	tex3DTexelFetchUint,		evalTexelFetch3D,		BOTH),
4710
4711		CASE_SPEC(sampler1d_fixed,				FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4(263.9f,   0.0f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DTexelFetchFixed,		evalTexelFetch1D,		BOTH),
4712		CASE_SPEC(sampler1d_float,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(120.9f,   0.0f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7,  0, 0),	tex1DTexelFetchFloat,		evalTexelFetch1D,		BOTH),
4713		CASE_SPEC(isampler1d,					FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4( 71.9f,   0.0f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DTexelFetchInt,			evalTexelFetch1D,		BOTH),
4714		CASE_SPEC(usampler1d,					FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(  8.9f,   0.0f,  0.0f,  0.0f),	false,	4.0f,	4.0f,	true,	IVec3(7,  0, 0),	tex1DTexelFetchUint,		evalTexelFetch1D,		BOTH),
4715
4716		CASE_SPEC(sampler1darray_fixed,			FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4(135.9f,   3.9f,  0.0f,  0.0f),	false,	0.0f,	0.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayTexelFetchFixed,	evalTexelFetch1DArray,	BOTH),
4717		CASE_SPEC(sampler1darray_float,			FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4( 56.9f,   3.9f,  0.0f,  0.0f),	false,	1.0f,	1.0f,	true,	IVec3(7,  0, 0),	tex1DArrayTexelFetchFloat,	evalTexelFetch1DArray,	BOTH),
4718		CASE_SPEC(isampler1darray,				FUNCTION_TEXELFETCH,	Vec4( 8.0f,  0.0f, 0.0f, 0.0f),	Vec4( 39.9f,   3.9f,  0.0f,  0.0f),	false,	2.0f,	2.0f,	true,	IVec3(-8, 0, 0),	tex1DArrayTexelFetchInt,	evalTexelFetch1DArray,	BOTH),
4719		CASE_SPEC(usampler1darray,				FUNCTION_TEXELFETCH,	Vec4(-7.0f,  0.0f, 0.0f, 0.0f),	Vec4(  8.9f,   3.9f,  0.0f,  0.0f),	false,	3.0f,	3.0f,	true,	IVec3(7,  0, 0),	tex1DArrayTexelFetchUint,	evalTexelFetch1DArray,	BOTH),
4720	};
4721	createCaseGroup(this, "texelfetchoffset", texelFetchOffsetCases, DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
4722
4723	// texture query functions
4724	{
4725		struct TexQueryFuncCaseSpec
4726		{
4727			const char*		name;
4728			const char*		samplerName;
4729			TextureSpec		textureSpec;
4730		};
4731
4732		de::MovePtr<tcu::TestCaseGroup>			queryGroup	(new tcu::TestCaseGroup(m_testCtx, "query"));
4733
4734		// textureSize() cases
4735		{
4736			const TexQueryFuncCaseSpec textureSizeCases[] =
4737			{
4738				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4739				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4740				{ "isampler2d",					"isampler2D",				tex2DInt			},
4741				{ "usampler2d",					"usampler2D",				tex2DUint			},
4742				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4743				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4744				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4745				{ "isampler3d",					"isampler3D",				tex3DInt			},
4746				{ "usampler3d",					"usampler3D",				tex3DUint			},
4747				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4748				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4749				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4750				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4751				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4752				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4753				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4754				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4755				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4756				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4757				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4758				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4759				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4760				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4761				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4762				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4763				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4764				{ "isampler1d",					"isampler1D",				tex1DInt			},
4765				{ "usampler1d",					"usampler1D",				tex1DUint			},
4766				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4767				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4768				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4769				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4770				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4771				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4772			};
4773
4774			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesize"));
4775
4776			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
4777			{
4778				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeCases[ndx];
4779
4780				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZE));
4781				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZE));
4782			}
4783
4784			// additional coverage for textureSize special cases
4785			addFunctionCaseWithPrograms(group.get(), "oob_lod", SpecialCases::textureSizeOOBPrograms, SpecialCases::textureSizeOOBTest);
4786
4787			queryGroup->addChild(group.release());
4788		}
4789
4790		// textureSize() cases for multisample textures
4791		{
4792			const TexQueryFuncCaseSpec textureSizeMSCases[] =
4793			{
4794				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4795				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4796				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4797				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4798				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4799				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4800				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4801				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4802			};
4803
4804			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesizems"));
4805
4806			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeMSCases); ++ndx)
4807			{
4808				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeMSCases[ndx];
4809
4810				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZEMS));
4811				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZEMS));
4812			}
4813
4814			queryGroup->addChild(group.release());
4815		}
4816
4817		// textureSamples() cases
4818		{
4819			const TexQueryFuncCaseSpec textureSamplesCases[] =
4820			{
4821				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4822				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4823				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4824				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4825				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4826				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4827				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4828				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4829			};
4830
4831			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesamples"));
4832
4833			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSamplesCases); ++ndx)
4834			{
4835				const TexQueryFuncCaseSpec&		caseSpec	= textureSamplesCases[ndx];
4836
4837				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESAMPLES));
4838				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESAMPLES));
4839			}
4840
4841			queryGroup->addChild(group.release());
4842		}
4843
4844		// textureQueryLevels() cases
4845		{
4846			const TexQueryFuncCaseSpec textureQueryLevelsCases[] =
4847			{
4848				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4849				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4850				{ "isampler2d",					"isampler2D",				tex2DInt			},
4851				{ "usampler2d",					"usampler2D",				tex2DUint			},
4852				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4853				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4854				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4855				{ "isampler3d",					"isampler3D",				tex3DInt			},
4856				{ "usampler3d",					"usampler3D",				tex3DUint			},
4857				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4858				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4859				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4860				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4861				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4862				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4863				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4864				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4865				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4866				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4867				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4868				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4869				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4870				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4871				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4872				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4873				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4874				{ "isampler1d",					"isampler1D",				tex1DInt			},
4875				{ "usampler1d",					"usampler1D",				tex1DUint			},
4876				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4877				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4878				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4879				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4880				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4881				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4882			};
4883
4884			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylevels"));
4885
4886			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLevelsCases); ++ndx)
4887			{
4888				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLevelsCases[ndx];
4889
4890				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"), caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTUREQUERYLEVELS));
4891				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLEVELS));
4892			}
4893
4894			queryGroup->addChild(group.release());
4895		}
4896
4897		// textureQueryLod() cases
4898		{
4899			const TexQueryFuncCaseSpec textureQueryLodCases[] =
4900			{
4901				{ "sampler2d_fixed",			"sampler2D",				tex2DMipmapFixed			},
4902				{ "sampler2d_float",			"sampler2D",				tex2DMipmapFloat			},
4903				{ "isampler2d",					"isampler2D",				tex2DMipmapInt				},
4904				{ "usampler2d",					"usampler2D",				tex2DMipmapUint				},
4905				{ "sampler2dshadow",			"sampler2DShadow",			tex2DMipmapShadow			},
4906				{ "sampler3d_fixed",			"sampler3D",				tex3DMipmapFixed			},
4907				{ "sampler3d_float",			"sampler3D",				tex3DMipmapFloat			},
4908				{ "isampler3d",					"isampler3D",				tex3DMipmapInt				},
4909				{ "usampler3d",					"usampler3D",				tex3DMipmapUint				},
4910				{ "samplercube_fixed",			"samplerCube",				texCubeMipmapFixed			},
4911				{ "samplercube_float",			"samplerCube",				texCubeMipmapFloat			},
4912				{ "isamplercube",				"isamplerCube",				texCubeMipmapInt			},
4913				{ "usamplercube",				"usamplerCube",				texCubeMipmapUint			},
4914				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeMipmapShadow			},
4915				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayMipmapFixed		},
4916				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayMipmapFloat		},
4917				{ "isampler2darray",			"isampler2DArray",			tex2DArrayMipmapInt			},
4918				{ "usampler2darray",			"usampler2DArray",			tex2DArrayMipmapUint		},
4919				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayMipmapShadow		},
4920				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayMipmapFixed		},
4921				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayMipmapFloat		},
4922				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayMipmapInt		},
4923				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayMipmapUint		},
4924				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayMipmapShadow	},
4925				{ "sampler1d_fixed",			"sampler1D",				tex1DMipmapFixed			},
4926				{ "sampler1d_float",			"sampler1D",				tex1DMipmapFloat			},
4927				{ "isampler1d",					"isampler1D",				tex1DMipmapInt				},
4928				{ "usampler1d",					"usampler1D",				tex1DMipmapUint				},
4929				{ "sampler1dshadow",			"sampler1DShadow",			tex1DMipmapShadow			},
4930				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayMipmapFixed		},
4931				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayMipmapFloat		},
4932				{ "isampler1darray",			"isampler1DArray",			tex1DArrayMipmapInt			},
4933				{ "usampler1darray",			"usampler1DArray",			tex1DArrayMipmapUint		},
4934				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayMipmapShadow		},
4935			};
4936
4937			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylod"));
4938
4939			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLodCases); ++ndx)
4940			{
4941				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLodCases[ndx];
4942
4943				// available only in fragment shader
4944				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD));
4945				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_zero_uv_width_fragment"), caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD, QLODTM_ZERO_UV_WIDTH));
4946			}
4947
4948			queryGroup->addChild(group.release());
4949		}
4950
4951		addChild(queryGroup.release());
4952	}
4953}
4954
4955} // anonymous
4956
4957tcu::TestCaseGroup* createTextureFunctionTests (tcu::TestContext& testCtx)
4958{
4959	return new ShaderTextureFunctionTests(testCtx);
4960}
4961
4962} // sr
4963} // vkt
4964