• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "vkImageUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include <limits>
38 
39 namespace vkt
40 {
41 namespace sr
42 {
43 namespace
44 {
45 
46 using tcu::Vec2;
47 using tcu::Vec3;
48 using tcu::Vec4;
49 using tcu::IVec2;
50 using tcu::IVec3;
51 using tcu::IVec4;
52 
53 using std::vector;
54 
55 enum Function
56 {
57 	FUNCTION_TEXTURE = 0,		//!< texture(), textureOffset(), textureClampARB, textureOffsetClampARB
58 	FUNCTION_TEXTUREPROJ,		//!< textureProj(), textureProjOffset()
59 	FUNCTION_TEXTUREPROJ2,		//!< textureProj(sampler1D, vec2)
60 	FUNCTION_TEXTUREPROJ3,		//!< textureProj(sampler2D, vec3)
61 	FUNCTION_TEXTURELOD,		// ...
62 	FUNCTION_TEXTUREPROJLOD,
63 	FUNCTION_TEXTUREPROJLOD2,	//!< textureProjLod(sampler1D, vec2)
64 	FUNCTION_TEXTUREPROJLOD3,	//!< textureProjLod(sampler2D, vec3)
65 	FUNCTION_TEXTUREGRAD,		//!< textureGrad, textureGradOffset, textureGradClampARB, textureGradOffsetClampARB
66 	FUNCTION_TEXTUREPROJGRAD,
67 	FUNCTION_TEXTUREPROJGRAD2,	//!< textureProjGrad(sampler1D, vec2)
68 	FUNCTION_TEXTUREPROJGRAD3,	//!< textureProjGrad(sampler2D, vec3)
69 	FUNCTION_TEXELFETCH,
70 
71 	FUNCTION_LAST
72 };
73 
functionHasAutoLod(glu::ShaderType shaderType,Function function)74 inline bool functionHasAutoLod (glu::ShaderType shaderType, Function function)
75 {
76 	return shaderType == glu::SHADERTYPE_FRAGMENT &&
77 		   (function == FUNCTION_TEXTURE		||
78 			function == FUNCTION_TEXTUREPROJ	||
79 			function == FUNCTION_TEXTUREPROJ2	||
80 			function == FUNCTION_TEXTUREPROJ3);
81 }
82 
functionHasProj(Function function)83 inline bool functionHasProj (Function function)
84 {
85 	return function == FUNCTION_TEXTUREPROJ		||
86 		   function == FUNCTION_TEXTUREPROJ2	||
87 		   function == FUNCTION_TEXTUREPROJ3	||
88 		   function == FUNCTION_TEXTUREPROJLOD	||
89 		   function == FUNCTION_TEXTUREPROJLOD2	||
90 		   function == FUNCTION_TEXTUREPROJLOD3	||
91 		   function == FUNCTION_TEXTUREPROJGRAD	||
92 		   function == FUNCTION_TEXTUREPROJGRAD2||
93 		   function == FUNCTION_TEXTUREPROJGRAD3;
94 }
95 
functionHasGrad(Function function)96 inline bool functionHasGrad (Function function)
97 {
98 	return function == FUNCTION_TEXTUREGRAD		||
99 		   function == FUNCTION_TEXTUREPROJGRAD	||
100 		   function == FUNCTION_TEXTUREPROJGRAD2||
101 		   function == FUNCTION_TEXTUREPROJGRAD3;
102 }
103 
functionHasLod(Function function)104 inline bool functionHasLod (Function function)
105 {
106 	return function == FUNCTION_TEXTURELOD		||
107 		   function == FUNCTION_TEXTUREPROJLOD	||
108 		   function == FUNCTION_TEXTUREPROJLOD2	||
109 		   function == FUNCTION_TEXTUREPROJLOD3	||
110 		   function == FUNCTION_TEXELFETCH;
111 }
112 
113 struct TextureLookupSpec
114 {
115 	Function		function;
116 
117 	tcu::Vec4		minCoord;
118 	tcu::Vec4		maxCoord;
119 
120 	// Bias
121 	bool			useBias;
122 
123 	// Bias or Lod for *Lod* functions
124 	float			minLodBias;
125 	float			maxLodBias;
126 
127 	// For *Grad* functions
128 	tcu::Vec3		minDX;
129 	tcu::Vec3		maxDX;
130 	tcu::Vec3		minDY;
131 	tcu::Vec3		maxDY;
132 
133 	bool			useOffset;
134 	tcu::IVec3		offset;
135 
136 	// Lod clamp
137 	bool			useClamp;
138 	float			lodClamp;
139 
TextureLookupSpecvkt::sr::__anon5a39cfe70111::TextureLookupSpec140 	TextureLookupSpec (void)
141 		: function		(FUNCTION_LAST)
142 		, minCoord		(0.0f)
143 		, maxCoord		(1.0f)
144 		, useBias		(false)
145 		, minLodBias	(0.0f)
146 		, maxLodBias	(0.0f)
147 		, minDX			(0.0f)
148 		, maxDX			(0.0f)
149 		, minDY			(0.0f)
150 		, maxDY			(0.0f)
151 		, useOffset		(false)
152 		, offset		(0)
153 		, useClamp		(false)
154 		, lodClamp		(0.0f)
155 	{
156 	}
157 
TextureLookupSpecvkt::sr::__anon5a39cfe70111::TextureLookupSpec158 	TextureLookupSpec (Function				function_,
159 					   const tcu::Vec4&		minCoord_,
160 					   const tcu::Vec4&		maxCoord_,
161 					   bool					useBias_,
162 					   float				minLodBias_,
163 					   float				maxLodBias_,
164 					   const tcu::Vec3&		minDX_,
165 					   const tcu::Vec3&		maxDX_,
166 					   const tcu::Vec3&		minDY_,
167 					   const tcu::Vec3&		maxDY_,
168 					   bool					useOffset_,
169 					   const tcu::IVec3&	offset_,
170 					   bool					useClamp_,
171 					   float				lodClamp_)
172 		: function		(function_)
173 		, minCoord		(minCoord_)
174 		, maxCoord		(maxCoord_)
175 		, useBias		(useBias_)
176 		, minLodBias	(minLodBias_)
177 		, maxLodBias	(maxLodBias_)
178 		, minDX			(minDX_)
179 		, maxDX			(maxDX_)
180 		, minDY			(minDY_)
181 		, maxDY			(maxDY_)
182 		, useOffset		(useOffset_)
183 		, offset		(offset_)
184 		, useClamp		(useClamp_)
185 		, lodClamp		(lodClamp_)
186 	{
187 	}
188 };
189 
190 enum TextureType
191 {
192 	TEXTURETYPE_1D = 0,
193 	TEXTURETYPE_2D,
194 	TEXTURETYPE_3D,
195 	TEXTURETYPE_CUBE_MAP,
196 	TEXTURETYPE_1D_ARRAY,
197 	TEXTURETYPE_2D_ARRAY,
198 	TEXTURETYPE_CUBE_ARRAY,
199 
200 	TEXTURETYPE_LAST
201 };
202 
203 struct TextureSpec
204 {
205 	TextureType			type;		//!< Texture type (2D, cubemap, ...)
206 	deUint32			format;		//!< Internal format.
207 	int					width;
208 	int					height;
209 	int					depth;
210 	int					numLevels;
211 	tcu::Sampler		sampler;
212 
TextureSpecvkt::sr::__anon5a39cfe70111::TextureSpec213 	TextureSpec (void)
214 		: type			(TEXTURETYPE_LAST)
215 		, format		(GL_NONE)
216 		, width			(0)
217 		, height		(0)
218 		, depth			(0)
219 		, numLevels		(0)
220 	{
221 	}
222 
TextureSpecvkt::sr::__anon5a39cfe70111::TextureSpec223 	TextureSpec (TextureType			type_,
224 				 deUint32				format_,
225 				 int					width_,
226 				 int					height_,
227 				 int					depth_,
228 				 int					numLevels_,
229 				 const tcu::Sampler&	sampler_)
230 		: type			(type_)
231 		, format		(format_)
232 		, width			(width_)
233 		, height		(height_)
234 		, depth			(depth_)
235 		, numLevels		(numLevels_)
236 		, sampler		(sampler_)
237 	{
238 	}
239 };
240 
241 struct TexLookupParams
242 {
243 	float				lod;
244 	float				lodClamp;
245 	tcu::IVec3			offset;
246 	tcu::Vec4			scale;
247 	tcu::Vec4			bias;
248 
TexLookupParamsvkt::sr::__anon5a39cfe70111::TexLookupParams249 	TexLookupParams (void)
250 		: lod		(0.0f)
251 		, lodClamp	(0.0f)
252 		, offset	(0)
253 		, scale		(1.0f)
254 		, bias		(0.0f)
255 	{
256 	}
257 };
258 
259 // \note LodMode and computeLodFromDerivates functions are copied from glsTextureTestUtil
260 namespace TextureTestUtil
261 {
262 
263 enum LodMode
264 {
265 	LODMODE_EXACT = 0,		//!< Ideal lod computation.
266 	LODMODE_MIN_BOUND,		//!< Use estimation range minimum bound.
267 	LODMODE_MAX_BOUND,		//!< Use estimation range maximum bound.
268 
269 	LODMODE_LAST
270 };
271 
272 // 1D lookup LOD computation.
273 
computeLodFromDerivates(LodMode mode,float dudx,float dudy)274 float computeLodFromDerivates (LodMode mode, float dudx, float dudy)
275 {
276 	float p = 0.0f;
277 	switch (mode)
278 	{
279 		// \note [mika] Min and max bounds equal to exact with 1D textures
280 		case LODMODE_EXACT:
281 		case LODMODE_MIN_BOUND:
282 		case LODMODE_MAX_BOUND:
283 			p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
284 			break;
285 
286 		default:
287 			DE_ASSERT(DE_FALSE);
288 	}
289 
290 	return deFloatLog2(p);
291 }
292 
293 // 2D lookup LOD computation.
294 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dudy,float dvdy)295 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
296 {
297 	float p = 0.0f;
298 	switch (mode)
299 	{
300 		case LODMODE_EXACT:
301 			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy));
302 			break;
303 
304 		case LODMODE_MIN_BOUND:
305 		case LODMODE_MAX_BOUND:
306 		{
307 			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
308 			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
309 
310 			p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
311 			break;
312 		}
313 
314 		default:
315 			DE_ASSERT(DE_FALSE);
316 	}
317 
318 	return deFloatLog2(p);
319 }
320 
321 // 3D lookup LOD computation.
322 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dwdx,float dudy,float dvdy,float dwdy)323 float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
324 {
325 	float p = 0.0f;
326 	switch (mode)
327 	{
328 		case LODMODE_EXACT:
329 			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy));
330 			break;
331 
332 		case LODMODE_MIN_BOUND:
333 		case LODMODE_MAX_BOUND:
334 		{
335 			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
336 			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
337 			float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
338 
339 			p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
340 			break;
341 		}
342 
343 		default:
344 			DE_ASSERT(DE_FALSE);
345 	}
346 
347 	return deFloatLog2(p);
348 }
349 
350 } // TextureTestUtil
351 
352 using namespace TextureTestUtil;
353 
354 static const LodMode DEFAULT_LOD_MODE = LODMODE_EXACT;
355 
computeLodFromGrad2D(const ShaderEvalContext & c)356 inline float computeLodFromGrad2D (const ShaderEvalContext& c)
357 {
358 	float w = (float)c.textures[0].tex2D->getWidth();
359 	float h = (float)c.textures[0].tex2D->getHeight();
360 	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);
361 }
362 
computeLodFromGrad2DArray(const ShaderEvalContext & c)363 inline float computeLodFromGrad2DArray (const ShaderEvalContext& c)
364 {
365 	float w = (float)c.textures[0].tex2DArray->getWidth();
366 	float h = (float)c.textures[0].tex2DArray->getHeight();
367 	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);
368 }
369 
computeLodFromGrad3D(const ShaderEvalContext & c)370 inline float computeLodFromGrad3D (const ShaderEvalContext& c)
371 {
372 	float w = (float)c.textures[0].tex3D->getWidth();
373 	float h = (float)c.textures[0].tex3D->getHeight();
374 	float d = (float)c.textures[0].tex3D->getDepth();
375 	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);
376 }
377 
computeLodFromGradCube(const ShaderEvalContext & c)378 inline float computeLodFromGradCube (const ShaderEvalContext& c)
379 {
380 	// \note Major axis is always -Z or +Z
381 	float m = de::abs(c.in[0].z());
382 	float d = (float)c.textures[0].texCube->getSize();
383 	float s = d/(2.0f*m);
384 	float t = d/(2.0f*m);
385 	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);
386 }
387 
computeLodFromGrad1D(const ShaderEvalContext & c)388 inline float computeLodFromGrad1D (const ShaderEvalContext& c)
389 {
390 	float w = (float)c.textures[0].tex1D->getWidth();
391 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
392 }
393 
computeLodFromGrad1DArray(const ShaderEvalContext & c)394 inline float computeLodFromGrad1DArray (const ShaderEvalContext& c)
395 {
396 	float w = (float)c.textures[0].tex1DArray->getWidth();
397 	return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x()*w, c.in[2].x()*w);
398 }
399 
computeLodFromGradCubeArray(const ShaderEvalContext & c)400 inline float computeLodFromGradCubeArray (const ShaderEvalContext& c)
401 {
402 	// \note Major axis is always -Z or +Z
403 	float m = de::abs(c.in[0].z());
404 	float d = (float)c.textures[0].texCubeArray->getSize();
405 	float s = d/(2.0f*m);
406 	float t = d/(2.0f*m);
407 	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);
408 }
409 
410 typedef void (*TexEvalFunc) (ShaderEvalContext& c, const TexLookupParams& lookupParams);
411 
texture2D(const ShaderEvalContext & c,float s,float t,float lod)412 inline Vec4 texture2D			(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);					}
textureCube(const ShaderEvalContext & c,float s,float t,float r,float lod)413 inline 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);			}
texture2DArray(const ShaderEvalContext & c,float s,float t,float r,float lod)414 inline 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);			}
texture3D(const ShaderEvalContext & c,float s,float t,float r,float lod)415 inline 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);				}
texture1D(const ShaderEvalContext & c,float s,float lod)416 inline Vec4 texture1D			(const ShaderEvalContext& c, float s, float lod)							{ return c.textures[0].tex1D->sample(c.textures[0].sampler, s, lod);					}
texture1DArray(const ShaderEvalContext & c,float s,float t,float lod)417 inline Vec4 texture1DArray		(const ShaderEvalContext& c, float s, float t, float lod)					{ return c.textures[0].tex1DArray->sample(c.textures[0].sampler, s, t, lod);			}
textureCubeArray(const ShaderEvalContext & c,float s,float t,float r,float q,float lod)418 inline 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);	}
419 
texture2DShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)420 inline 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);					}
textureCubeShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)421 inline 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);			}
texture2DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)422 inline 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);			}
texture1DShadow(const ShaderEvalContext & c,float ref,float s,float lod)423 inline float texture1DShadow		(const ShaderEvalContext& c, float ref, float s, float lod)								{ return c.textures[0].tex1D->sampleCompare(c.textures[0].sampler, ref, s, lod);					}
texture1DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)424 inline 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);			}
textureCubeArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float q,float lod)425 inline 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);	}
426 
texture2DOffset(const ShaderEvalContext & c,float s,float t,float lod,IVec2 offset)427 inline 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);			}
texture2DArrayOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec2 offset)428 inline 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);	}
texture3DOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec3 offset)429 inline 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);		}
texture1DOffset(const ShaderEvalContext & c,float s,float lod,deInt32 offset)430 inline Vec4 texture1DOffset			(const ShaderEvalContext& c, float s, float lod, deInt32 offset)					{ return c.textures[0].tex1D->sampleOffset(c.textures[0].sampler, s, lod, offset);				}
texture1DArrayOffset(const ShaderEvalContext & c,float s,float t,float lod,deInt32 offset)431 inline 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);		}
432 
texture2DShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,IVec2 offset)433 inline 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);			}
texture2DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod,IVec2 offset)434 inline 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);	}
texture1DShadowOffset(const ShaderEvalContext & c,float ref,float s,float lod,deInt32 offset)435 inline 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);				}
texture1DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,deInt32 offset)436 inline 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);		}
437 
438 // Eval functions.
evalTexture2D(ShaderEvalContext & c,const TexLookupParams & p)439 static 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; }
evalTextureCube(ShaderEvalContext & c,const TexLookupParams & p)440 static 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; }
evalTexture2DArray(ShaderEvalContext & c,const TexLookupParams & p)441 static 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; }
evalTexture3D(ShaderEvalContext & c,const TexLookupParams & p)442 static 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; }
evalTexture1D(ShaderEvalContext & c,const TexLookupParams & p)443 static void		evalTexture1D					(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), p.lod)*p.scale + p.bias; }
evalTexture1DArray(ShaderEvalContext & c,const TexLookupParams & p)444 static 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; }
evalTextureCubeArray(ShaderEvalContext & c,const TexLookupParams & p)445 static 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; }
446 
evalTexture2DBias(ShaderEvalContext & c,const TexLookupParams & p)447 static 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; }
evalTextureCubeBias(ShaderEvalContext & c,const TexLookupParams & p)448 static 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; }
evalTexture2DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)449 static 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; }
evalTexture3DBias(ShaderEvalContext & c,const TexLookupParams & p)450 static 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; }
evalTexture1DBias(ShaderEvalContext & c,const TexLookupParams & p)451 static 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; }
evalTexture1DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)452 static 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; }
evalTextureCubeArrayBias(ShaderEvalContext & c,const TexLookupParams & p)453 static 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; }
454 
evalTexture2DProj3(ShaderEvalContext & c,const TexLookupParams & p)455 static 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; }
evalTexture2DProj3Bias(ShaderEvalContext & c,const TexLookupParams & p)456 static 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; }
evalTexture2DProj(ShaderEvalContext & c,const TexLookupParams & p)457 static 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; }
evalTexture2DProjBias(ShaderEvalContext & c,const TexLookupParams & p)458 static 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; }
evalTexture3DProj(ShaderEvalContext & c,const TexLookupParams & p)459 static 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; }
evalTexture3DProjBias(ShaderEvalContext & c,const TexLookupParams & p)460 static 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; }
evalTexture1DProj2(ShaderEvalContext & c,const TexLookupParams & p)461 static 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; }
evalTexture1DProj2Bias(ShaderEvalContext & c,const TexLookupParams & p)462 static 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; }
evalTexture1DProj(ShaderEvalContext & c,const TexLookupParams & p)463 static 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; }
evalTexture1DProjBias(ShaderEvalContext & c,const TexLookupParams & p)464 static 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; }
465 
evalTexture2DLod(ShaderEvalContext & c,const TexLookupParams & p)466 static 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; }
evalTextureCubeLod(ShaderEvalContext & c,const TexLookupParams & p)467 static 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; }
evalTexture2DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)468 static 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; }
evalTexture3DLod(ShaderEvalContext & c,const TexLookupParams & p)469 static 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; }
evalTexture1DLod(ShaderEvalContext & c,const TexLookupParams & p)470 static void		evalTexture1DLod				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), c.in[1].x())*p.scale + p.bias; }
evalTexture1DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)471 static 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; }
evalTextureCubeArrayLod(ShaderEvalContext & c,const TexLookupParams & p)472 static 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; }
473 
evalTexture2DProjLod3(ShaderEvalContext & c,const TexLookupParams & p)474 static 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; }
evalTexture2DProjLod(ShaderEvalContext & c,const TexLookupParams & p)475 static 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; }
evalTexture3DProjLod(ShaderEvalContext & c,const TexLookupParams & p)476 static 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; }
evalTexture1DProjLod2(ShaderEvalContext & c,const TexLookupParams & p)477 static 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; }
evalTexture1DProjLod(ShaderEvalContext & c,const TexLookupParams & p)478 static 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; }
479 
evalTexture2DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)480 static 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; }
evalTextureCubeBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)481 static 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; }
evalTexture2DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)482 static 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; }
evalTexture3DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)483 static 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; }
evalTexture1DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)484 static 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; }
evalTexture1DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)485 static 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; }
evalTextureCubeArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)486 static 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; }
487 
488 // Offset variants
489 
evalTexture2DOffset(ShaderEvalContext & c,const TexLookupParams & p)490 static 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; }
evalTexture2DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)491 static 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; }
evalTexture3DOffset(ShaderEvalContext & c,const TexLookupParams & p)492 static 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; }
evalTexture1DOffset(ShaderEvalContext & c,const TexLookupParams & p)493 static void		evalTexture1DOffset				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), p.lod, p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)494 static 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; }
495 
evalTexture2DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)496 static 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; }
evalTexture2DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)497 static 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; }
evalTexture3DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)498 static 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; }
evalTexture1DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)499 static 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; }
evalTexture1DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)500 static 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; }
501 
evalTexture2DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)502 static 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; }
evalTexture2DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)503 static 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; }
evalTexture3DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)504 static 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; }
evalTexture1DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)505 static 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; }
evalTexture1DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)506 static 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; }
507 
evalTexture2DProj3Offset(ShaderEvalContext & c,const TexLookupParams & p)508 static 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; }
evalTexture2DProj3OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)509 static 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; }
evalTexture2DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)510 static 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; }
evalTexture2DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)511 static 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; }
evalTexture3DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)512 static 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; }
evalTexture3DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)513 static 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; }
evalTexture1DProj2Offset(ShaderEvalContext & c,const TexLookupParams & p)514 static 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; }
evalTexture1DProj2OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)515 static 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; }
evalTexture1DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)516 static 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; }
evalTexture1DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)517 static 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; }
518 
evalTexture2DProjLod3Offset(ShaderEvalContext & c,const TexLookupParams & p)519 static 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; }
evalTexture2DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)520 static 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; }
evalTexture3DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)521 static 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; }
evalTexture1DProjLod2Offset(ShaderEvalContext & c,const TexLookupParams & p)522 static 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; }
evalTexture1DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)523 static 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; }
524 
evalTexture2DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)525 static 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; }
evalTexture2DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)526 static 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; }
evalTexture3DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)527 static 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; }
evalTexture1DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)528 static 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; }
evalTexture1DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)529 static 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; }
530 
531 // Shadow variants
532 
evalTexture2DShadow(ShaderEvalContext & c,const TexLookupParams & p)533 static 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); }
evalTexture2DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)534 static 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()); }
535 
evalTextureCubeShadow(ShaderEvalContext & c,const TexLookupParams & p)536 static 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); }
evalTextureCubeShadowBias(ShaderEvalContext & c,const TexLookupParams & p)537 static 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()); }
538 
evalTexture2DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)539 static 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); }
evalTexture1DShadow(ShaderEvalContext & c,const TexLookupParams & p)540 static void		evalTexture1DShadow				(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod); }
evalTexture1DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)541 static 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()); }
evalTexture1DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)542 static 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); }
evalTexture1DArrayShadowBias(ShaderEvalContext & c,const TexLookupParams & p)543 static 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()); }
evalTextureCubeArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)544 static 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); }
545 
evalTexture2DShadowLod(ShaderEvalContext & c,const TexLookupParams &)546 static 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()); }
evalTexture2DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)547 static 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)); }
evalTexture1DShadowLod(ShaderEvalContext & c,const TexLookupParams &)548 static void		evalTexture1DShadowLod				(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), c.in[1].x()); }
evalTexture1DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)549 static 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()); }
evalTexture1DArrayShadowLod(ShaderEvalContext & c,const TexLookupParams &)550 static 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()); }
evalTexture1DArrayShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)551 static 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()); }
552 
evalTexture2DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)553 static 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); }
evalTexture2DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)554 static 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()); }
evalTexture1DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)555 static 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); }
evalTexture1DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)556 static 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()); }
557 
evalTexture2DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)558 static 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()); }
evalTexture2DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)559 static 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)); }
evalTexture1DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)560 static 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()); }
evalTexture1DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)561 static 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()); }
562 
evalTexture2DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)563 static 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)); }
evalTexture2DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)564 static 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)); }
evalTexture2DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)565 static 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)); }
evalTexture1DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)566 static 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()); }
evalTexture1DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)567 static 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()); }
evalTexture1DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)568 static 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()); }
evalTexture1DArrayShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)569 static 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()); }
570 
evalTexture2DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)571 static 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)); }
evalTexture2DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)572 static 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)); }
evalTexture1DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)573 static 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()); }
evalTexture1DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)574 static 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()); }
575 
evalTexture2DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)576 static 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)); }
evalTextureCubeShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)577 static 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)); }
evalTexture1DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)578 static 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)); }
evalTexture1DArrayShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)579 static 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)); }
evalTexture2DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)580 static 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)); }
evalTexture1DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)581 static 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()); }
evalTexture1DArrayShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)582 static 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()); }
583 
584 // Gradient variarts
585 
evalTexture2DGrad(ShaderEvalContext & c,const TexLookupParams & p)586 static 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; }
evalTextureCubeGrad(ShaderEvalContext & c,const TexLookupParams & p)587 static 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; }
evalTexture2DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)588 static 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; }
evalTexture3DGrad(ShaderEvalContext & c,const TexLookupParams & p)589 static 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; }
evalTexture1DGrad(ShaderEvalContext & c,const TexLookupParams & p)590 static void		evalTexture1DGrad			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1D(c, c.in[0].x(), computeLodFromGrad1D(c))*p.scale + p.bias; }
evalTexture1DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)591 static 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; }
evalTextureCubeArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)592 static 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; }
593 
evalTexture2DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)594 static 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)); }
evalTextureCubeShadowGrad(ShaderEvalContext & c,const TexLookupParams &)595 static 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)); }
evalTexture2DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)596 static 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)); }
evalTexture1DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)597 static void		evalTexture1DShadowGrad			(ShaderEvalContext& c, const TexLookupParams&)		{ c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c)); }
evalTexture1DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)598 static 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)); }
599 
evalTexture2DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)600 static 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; }
evalTexture2DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)601 static 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; }
evalTexture3DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)602 static 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; }
evalTexture1DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)603 static void		evalTexture1DGradOffset			(ShaderEvalContext& c, const TexLookupParams& p)	{ c.color = texture1DOffset(c, c.in[0].x(), computeLodFromGrad1D(c), p.offset.x())*p.scale + p.bias; }
evalTexture1DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)604 static 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; }
605 
evalTexture2DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)606 static 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)); }
evalTexture2DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)607 static 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)); }
evalTexture1DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)608 static 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()); }
evalTexture1DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)609 static 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()); }
610 
evalTexture2DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)611 static 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)); }
evalTexture2DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)612 static 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)); }
evalTexture1DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)613 static 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)); }
evalTexture1DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)614 static 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()); }
615 
evalTexture2DProjGrad3(ShaderEvalContext & c,const TexLookupParams & p)616 static 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; }
evalTexture2DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)617 static 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; }
evalTexture3DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)618 static 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; }
evalTexture1DProjGrad2(ShaderEvalContext & c,const TexLookupParams & p)619 static 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; }
evalTexture1DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)620 static 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; }
621 
evalTexture2DProjGrad3Offset(ShaderEvalContext & c,const TexLookupParams & p)622 static 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; }
evalTexture2DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)623 static 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; }
evalTexture3DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)624 static 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; }
evalTexture1DProjGrad2Offset(ShaderEvalContext & c,const TexLookupParams & p)625 static 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; }
evalTexture1DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)626 static 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; }
627 
evalTexture2DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)628 static 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; }
evalTextureCubeGradClamp(ShaderEvalContext & c,const TexLookupParams & p)629 static 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; }
evalTexture2DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)630 static 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; }
evalTexture3DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)631 static 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; }
evalTexture1DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)632 static 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; }
evalTexture1DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)633 static 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; }
evalTextureCubeArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)634 static 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; }
635 
evalTexture2DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)636 static 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)); }
evalTextureCubeShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)637 static 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)); }
evalTexture2DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)638 static 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)); }
evalTexture1DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)639 static 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)); }
evalTexture1DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)640 static 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)); }
641 
evalTexture2DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)642 static 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; }
evalTexture2DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)643 static 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; }
evalTexture3DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)644 static 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; }
evalTexture1DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)645 static 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; }
evalTexture1DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)646 static 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; }
647 
evalTexture2DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)648 static 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)); }
evalTexture2DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)649 static 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)); }
evalTexture1DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)650 static 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()); }
evalTexture1DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)651 static 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()); }
652 
653 // Texel fetch variants
654 
evalTexelFetch2D(ShaderEvalContext & c,const TexLookupParams & p)655 static void evalTexelFetch2D (ShaderEvalContext& c, const TexLookupParams& p)
656 {
657 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
658 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
659 	int	lod = deChopFloatToInt32(c.in[1].x());
660 	c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y)*p.scale + p.bias;
661 }
662 
evalTexelFetch2DArray(ShaderEvalContext & c,const TexLookupParams & p)663 static void evalTexelFetch2DArray (ShaderEvalContext& c, const TexLookupParams& p)
664 {
665 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
666 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
667 	int	l	= deChopFloatToInt32(c.in[0].z());
668 	int	lod = deChopFloatToInt32(c.in[1].x());
669 	c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l)*p.scale + p.bias;
670 }
671 
evalTexelFetch3D(ShaderEvalContext & c,const TexLookupParams & p)672 static void evalTexelFetch3D (ShaderEvalContext& c, const TexLookupParams& p)
673 {
674 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
675 	int	y	= deChopFloatToInt32(c.in[0].y())+p.offset.y();
676 	int	z	= deChopFloatToInt32(c.in[0].z())+p.offset.z();
677 	int	lod = deChopFloatToInt32(c.in[1].x());
678 	c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z)*p.scale + p.bias;
679 }
680 
evalTexelFetch1D(ShaderEvalContext & c,const TexLookupParams & p)681 static void evalTexelFetch1D (ShaderEvalContext& c, const TexLookupParams& p)
682 {
683 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
684 	int	lod = deChopFloatToInt32(c.in[1].x());
685 	c.color = c.textures[0].tex1D->getLevel(lod).getPixel(x, 0)*p.scale + p.bias;
686 }
687 
evalTexelFetch1DArray(ShaderEvalContext & c,const TexLookupParams & p)688 static void evalTexelFetch1DArray (ShaderEvalContext& c, const TexLookupParams& p)
689 {
690 	int	x	= deChopFloatToInt32(c.in[0].x())+p.offset.x();
691 	int	l	= deChopFloatToInt32(c.in[0].y());
692 	int	lod = deChopFloatToInt32(c.in[1].x());
693 	c.color = c.textures[0].tex1DArray->getLevel(lod).getPixel(x, l)*p.scale + p.bias;
694 }
695 
696 class TexLookupEvaluator : public ShaderEvaluator
697 {
698 public:
TexLookupEvaluator(TexEvalFunc evalFunc,const TexLookupParams & lookupParams)699 							TexLookupEvaluator		(TexEvalFunc evalFunc, const TexLookupParams& lookupParams) : m_evalFunc(evalFunc), m_lookupParams(lookupParams) {}
~TexLookupEvaluator(void)700 	virtual					~TexLookupEvaluator		(void) {}
701 
evaluate(ShaderEvalContext & ctx) const702 	virtual void			evaluate				(ShaderEvalContext& ctx) const { m_evalFunc(ctx, m_lookupParams); }
703 
704 private:
705 	TexEvalFunc				m_evalFunc;
706 	const TexLookupParams&	m_lookupParams;
707 };
708 
checkDeviceFeatures(Context & context,TextureType textureType)709 static void checkDeviceFeatures (Context& context, TextureType textureType)
710 {
711 	if (textureType == TEXTURETYPE_CUBE_ARRAY)
712 	{
713 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
714 
715 		if (!deviceFeatures.imageCubeArray)
716 			TCU_THROW(NotSupportedError, "Cube array is not supported");
717 	}
718 }
719 
checkMutableComparisonSamplersSupport(Context & context,const TextureSpec & textureSpec)720 static void checkMutableComparisonSamplersSupport(Context& context, const TextureSpec& textureSpec)
721 {
722 	// when compare mode is not none then ShaderRenderCaseInstance::createSamplerUniform
723 	// uses mapSampler utill from vkImageUtil that sets compareEnable to true
724 	// for portability this needs to be under feature flag
725 #ifndef CTS_USES_VULKANSC
726 	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
727 	   !context.getPortabilitySubsetFeatures().mutableComparisonSamplers &&
728 	   (textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE))
729 	{
730 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: mutableComparisonSamplers are not supported by this implementation");
731 	}
732 #else
733 	DE_UNREF(context);
734 	DE_UNREF(textureSpec);
735 #endif // CTS_USES_VULKANSC
736 }
737 
738 class ShaderTextureFunctionInstance : public ShaderRenderCaseInstance
739 {
740 public:
741 								ShaderTextureFunctionInstance		(Context&					context,
742 																	 const bool					isVertexCase,
743 																	 const ShaderEvaluator&		evaluator,
744 																	 const UniformSetup&		uniformSetup,
745 																	 const TextureLookupSpec&	lookupSpec,
746 																	 const TextureSpec&			textureSpec,
747 																	 const TexLookupParams&		lookupParams,
748 																	 const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
749 	virtual						~ShaderTextureFunctionInstance		(void);
750 
751 protected:
752 	virtual void				setupUniforms						(const tcu::Vec4&);
753 	void						initTexture							(void);
754 private:
755 	const TextureLookupSpec&	m_lookupSpec;
756 	const TextureSpec&			m_textureSpec;
757 	const TexLookupParams&		m_lookupParams;
758 };
759 
ShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)760 ShaderTextureFunctionInstance::ShaderTextureFunctionInstance (Context&						context,
761 															  const bool					isVertexCase,
762 															  const ShaderEvaluator&		evaluator,
763 															  const UniformSetup&			uniformSetup,
764 															  const TextureLookupSpec&		lookupSpec,
765 															  const TextureSpec&			textureSpec,
766 															  const TexLookupParams&		lookupParams,
767 															  const ImageBackingMode		imageBackingMode)
768 	: ShaderRenderCaseInstance	(context, isVertexCase, evaluator, uniformSetup, DE_NULL, imageBackingMode,
769 								(isVertexCase ? 92 : GRID_SIZE_DEFAULT_FRAGMENT))
770 	, m_lookupSpec				(lookupSpec)
771 	, m_textureSpec				(textureSpec)
772 	, m_lookupParams			(lookupParams)
773 {
774 	checkDeviceFeatures(m_context, m_textureSpec.type);
775 
776 	if (lookupSpec.useClamp)
777 	{
778 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
779 
780 		if (!deviceFeatures.shaderResourceMinLod)
781 			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
782 	}
783 
784 	{
785 		// Base coord scale & bias
786 		Vec4 s = m_lookupSpec.maxCoord-m_lookupSpec.minCoord;
787 		Vec4 b = m_lookupSpec.minCoord;
788 
789 		float baseCoordTrans[] =
790 		{
791 			s.x(),		0.0f,		0.f,	b.x(),
792 			0.f,		s.y(),		0.f,	b.y(),
793 			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
794 			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
795 		};
796 
797 		m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
798 
799 		useAttribute(4u, A_IN0);
800 	}
801 
802 	bool hasLodBias	= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
803 	bool isGrad		= functionHasGrad(m_lookupSpec.function);
804 	DE_ASSERT(!isGrad || !hasLodBias);
805 
806 	if (hasLodBias)
807 	{
808 		float s = m_lookupSpec.maxLodBias-m_lookupSpec.minLodBias;
809 		float b = m_lookupSpec.minLodBias;
810 		float lodCoordTrans[] =
811 		{
812 			s/2.0f,		s/2.0f,		0.f,	b,
813 			0.0f,		0.0f,		0.0f,	0.0f,
814 			0.0f,		0.0f,		0.0f,	0.0f,
815 			0.0f,		0.0f,		0.0f,	0.0f
816 		};
817 
818 		m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
819 
820 		useAttribute(5u, A_IN1);
821 	}
822 	else if (isGrad)
823 	{
824 		Vec3 sx = m_lookupSpec.maxDX-m_lookupSpec.minDX;
825 		Vec3 sy = m_lookupSpec.maxDY-m_lookupSpec.minDY;
826 		float gradDxTrans[] =
827 		{
828 			sx.x()/2.0f,	sx.x()/2.0f,	0.f,	m_lookupSpec.minDX.x(),
829 			sx.y()/2.0f,	sx.y()/2.0f,	0.0f,	m_lookupSpec.minDX.y(),
830 			sx.z()/2.0f,	sx.z()/2.0f,	0.0f,	m_lookupSpec.minDX.z(),
831 			0.0f,			0.0f,			0.0f,	0.0f
832 		};
833 		float gradDyTrans[] =
834 		{
835 			-sy.x()/2.0f,	-sy.x()/2.0f,	0.f,	m_lookupSpec.maxDY.x(),
836 			-sy.y()/2.0f,	-sy.y()/2.0f,	0.0f,	m_lookupSpec.maxDY.y(),
837 			-sy.z()/2.0f,	-sy.z()/2.0f,	0.0f,	m_lookupSpec.maxDY.z(),
838 			0.0f,			0.0f,			0.0f,	0.0f
839 		};
840 
841 		m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
842 		m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
843 
844 		useAttribute(5u, A_IN1);
845 		useAttribute(6u, A_IN2);
846 	}
847 
848 	initTexture();
849 }
850 
~ShaderTextureFunctionInstance(void)851 ShaderTextureFunctionInstance::~ShaderTextureFunctionInstance (void)
852 {
853 }
854 
setupUniforms(const tcu::Vec4 &)855 void ShaderTextureFunctionInstance::setupUniforms (const tcu::Vec4&)
856 {
857 	useSampler(0u, 0u);
858 	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.scale.getPtr());
859 	addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.bias.getPtr());
860 }
861 
initTexture(void)862 void ShaderTextureFunctionInstance::initTexture (void)
863 {
864 	static const IVec4		texCubeSwz[] =
865 	{
866 		IVec4(0,0,1,1),
867 		IVec4(1,1,0,0),
868 		IVec4(0,1,0,1),
869 		IVec4(1,0,1,0),
870 		IVec4(0,1,1,0),
871 		IVec4(1,0,0,1)
872 	};
873 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
874 
875 	tcu::TextureFormat		texFmt			= glu::mapGLInternalFormat(m_textureSpec.format);
876 	tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
877 	tcu::UVec2				viewportSize	= getViewportSize();
878 	bool					isProj			= functionHasProj(m_lookupSpec.function);
879 	bool					isAutoLod		= functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
880 																 m_lookupSpec.function); // LOD can vary significantly
881 	float					proj			= isProj ? 1.0f/m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ2 ? 1 : m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
882 	TexLookupParams			lookupParams;
883 
884 	switch (m_textureSpec.type)
885 	{
886 		case TEXTURETYPE_2D:
887 		{
888 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
889 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
890 			Vec4								cBias			= fmtInfo.valueMin;
891 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
892 			de::MovePtr<tcu::Texture2D>			texture2D;
893 
894 			texture2D = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(texFmt, m_textureSpec.width, m_textureSpec.height));
895 
896 			for (int level = 0; level < m_textureSpec.numLevels; level++)
897 			{
898 				float	fA		= float(level)*levelStep;
899 				float	fB		= 1.0f-fA;
900 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
901 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
902 
903 				texture2D->allocLevel(level);
904 				tcu::fillWithGrid(texture2D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
905 			}
906 
907 			// Compute LOD.
908 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
909 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
910 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
911 
912 			// Append to texture list.
913 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2D.release(), m_textureSpec.sampler)));
914 			break;
915 		}
916 
917 		case TEXTURETYPE_CUBE_MAP:
918 		{
919 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
920 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
921 			Vec4								cBias			= fmtInfo.valueMin;
922 			Vec4								cCorner			= cBias + cScale*0.5f;
923 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
924 			de::MovePtr<tcu::TextureCube>		textureCube;
925 
926 			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
927 			textureCube = de::MovePtr<tcu::TextureCube>(new tcu::TextureCube(texFmt, m_textureSpec.width));
928 
929 			for (int level = 0; level < m_textureSpec.numLevels; level++)
930 			{
931 				float	fA		= float(level)*levelStep;
932 				float	fB		= 1.0f-fA;
933 				Vec2	f		(fA, fB);
934 
935 				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
936 				{
937 					const IVec4&	swzA	= texCubeSwz[face];
938 					IVec4			swzB	= 1-swzA;
939 					Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
940 					Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
941 
942 					textureCube->allocLevel((tcu::CubeFace)face, level);
943 
944 					{
945 						const tcu::PixelBufferAccess	access		= textureCube->getLevelFace(level, (tcu::CubeFace)face);
946 						const int						lastPix		= access.getWidth()-1;
947 
948 						tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
949 
950 						// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
951 						access.setPixel(cCorner, 0, 0);
952 						access.setPixel(cCorner, 0, lastPix);
953 						access.setPixel(cCorner, lastPix, 0);
954 						access.setPixel(cCorner, lastPix, lastPix);
955 					}
956 				}
957 			}
958 
959 			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
960 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
961 			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]));
962 			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]));
963 
964 			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
965 			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
966 			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
967 			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
968 			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
969 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
970 
971 			// Append to texture list.
972 			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCube.release(), m_textureSpec.sampler)));
973 			break;
974 		}
975 
976 		case TEXTURETYPE_2D_ARRAY:
977 		{
978 			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
979 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
980 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
981 			Vec4								cBias			= fmtInfo.valueMin;
982 			int									baseCellSize	= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
983 			de::MovePtr<tcu::Texture2DArray>	texture2DArray;
984 
985 			texture2DArray = de::MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
986 
987 			for (int level = 0; level < m_textureSpec.numLevels; level++)
988 			{
989 				texture2DArray->allocLevel(level);
990 				tcu::PixelBufferAccess levelAccess = texture2DArray->getLevel(level);
991 
992 				for (int layer = 0; layer < levelAccess.getDepth(); layer++)
993 				{
994 					float	fA		= (float)layer*layerStep + (float)level*levelStep;
995 					float	fB		= 1.0f-fA;
996 					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
997 					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
998 
999 					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), de::max(1, baseCellSize>>level), colorA, colorB);
1000 				}
1001 			}
1002 
1003 			// Compute LOD.
1004 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1005 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height	/ (float)viewportSize[1];
1006 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1007 
1008 			// Append to texture list.
1009 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture2DArray.release(), m_textureSpec.sampler)));
1010 			break;
1011 		}
1012 
1013 		case TEXTURETYPE_3D:
1014 		{
1015 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1016 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1017 			Vec4								cBias			= fmtInfo.valueMin;
1018 			int									baseCellSize	= de::min(de::min(m_textureSpec.width/2, m_textureSpec.height/2), m_textureSpec.depth/2);
1019 			de::MovePtr<tcu::Texture3D>			texture3D;
1020 
1021 			texture3D = de::MovePtr<tcu::Texture3D>(new tcu::Texture3D(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
1022 
1023 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1024 			{
1025 				float	fA		= (float)level*levelStep;
1026 				float	fB		= 1.0f-fA;
1027 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1028 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1029 
1030 				texture3D->allocLevel(level);
1031 				tcu::fillWithGrid(texture3D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1032 			}
1033 
1034 			// Compute LOD.
1035 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width		/ (float)viewportSize[0];
1036 			float	dvdy	= (m_lookupSpec.maxCoord[1]-m_lookupSpec.minCoord[1])*proj*(float)m_textureSpec.height		/ (float)viewportSize[1];
1037 			float	dwdx	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[0];
1038 			float	dwdy	= (m_lookupSpec.maxCoord[2]-m_lookupSpec.minCoord[2])*0.5f*proj*(float)m_textureSpec.depth	/ (float)viewportSize[1];
1039 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
1040 
1041 			// Append to texture list.
1042 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture3D.release(), m_textureSpec.sampler)));
1043 			break;
1044 		}
1045 
1046 		case TEXTURETYPE_1D:
1047 		{
1048 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels-1);
1049 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1050 			Vec4								cBias			= fmtInfo.valueMin;
1051 			int									baseCellSize	= m_textureSpec.width/4;
1052 			de::MovePtr<tcu::Texture1D>			texture1D;
1053 
1054 			texture1D = de::MovePtr<tcu::Texture1D>(new tcu::Texture1D(texFmt, m_textureSpec.width));
1055 
1056 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1057 			{
1058 				float	fA		= float(level)*levelStep;
1059 				float	fB		= 1.0f-fA;
1060 				Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1061 				Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1062 
1063 				texture1D->allocLevel(level);
1064 				tcu::fillWithGrid(texture1D->getLevel(level), de::max(1, baseCellSize>>level), colorA, colorB);
1065 			}
1066 
1067 			// Compute LOD.
1068 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1069 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1070 
1071 			// Append to texture list.
1072 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1D.release(), m_textureSpec.sampler)));
1073 			break;
1074 		}
1075 
1076 		case TEXTURETYPE_1D_ARRAY:
1077 		{
1078 			float								layerStep		= 1.0f / (float)m_textureSpec.depth;
1079 			float								levelStep		= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*m_textureSpec.depth);
1080 			Vec4								cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
1081 			Vec4								cBias			= fmtInfo.valueMin;
1082 			int									baseCellSize	= m_textureSpec.width/4;
1083 			de::MovePtr<tcu::Texture1DArray>	texture1DArray;
1084 
1085 			texture1DArray = de::MovePtr<tcu::Texture1DArray>(new tcu::Texture1DArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1086 
1087 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1088 			{
1089 				texture1DArray->allocLevel(level);
1090 				tcu::PixelBufferAccess levelAccess = texture1DArray->getLevel(level);
1091 
1092 				for (int layer = 0; layer < levelAccess.getHeight(); layer++)
1093 				{
1094 					float	fA		= (float)layer*layerStep + (float)level*levelStep;
1095 					float	fB		= 1.0f-fA;
1096 					Vec4	colorA	= cBias + cScale*Vec4(fA, fB, fA, fB);
1097 					Vec4	colorB	= cBias + cScale*Vec4(fB, fA, fB, fA);
1098 
1099 					tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, layer, 0, levelAccess.getWidth(), 1, 1), de::max(1, baseCellSize>>level), colorA, colorB);
1100 				}
1101 			}
1102 
1103 			// Compute LOD.
1104 			float	dudx	= (m_lookupSpec.maxCoord[0]-m_lookupSpec.minCoord[0])*proj*(float)m_textureSpec.width	/ (float)viewportSize[0];
1105 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1106 
1107 			// Append to texture list.
1108 			m_textures.push_back(TextureBindingSp(new TextureBinding(texture1DArray.release(), m_textureSpec.sampler)));
1109 			break;
1110 		}
1111 
1112 		case TEXTURETYPE_CUBE_ARRAY:
1113 		{
1114 			float								layerStep			= 1.0f / (float)(m_textureSpec.depth/6);
1115 			float								levelStep			= isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels-1)*(m_textureSpec.depth/6));
1116 			Vec4								cScale				= fmtInfo.valueMax-fmtInfo.valueMin;
1117 			Vec4								cBias				= fmtInfo.valueMin;
1118 			Vec4								cCorner				= cBias + cScale*0.5f;
1119 			int									baseCellSize		= de::min(m_textureSpec.width/4, m_textureSpec.height/4);
1120 			de::MovePtr<tcu::TextureCubeArray>	textureCubeArray;
1121 
1122 			DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
1123 			DE_ASSERT(m_textureSpec.depth % 6 == 0);
1124 
1125 			textureCubeArray = de::MovePtr<tcu::TextureCubeArray>(new tcu::TextureCubeArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1126 
1127 			for (int level = 0; level < m_textureSpec.numLevels; level++)
1128 			{
1129 				float	fA		= float(level)*levelStep;
1130 				float	fB		= 1.0f-fA;
1131 				Vec2	f		(fA, fB);
1132 
1133 				textureCubeArray->allocLevel(level);
1134 				tcu::PixelBufferAccess levelAccess = textureCubeArray->getLevel(level);
1135 
1136 				for (int layer = 0; layer < m_textureSpec.depth/6; layer++)
1137 				{
1138 					float layerCorr = 1.0f-(float)layer*layerStep;
1139 
1140 					for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1141 					{
1142 						const IVec4&	swzA	= texCubeSwz[face];
1143 						IVec4			swzB	= 1-swzA;
1144 						Vec4			colorA	= cBias + cScale*f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3])*layerCorr;
1145 						Vec4			colorB	= cBias + cScale*f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3])*layerCorr;
1146 
1147 						{
1148 							const tcu::PixelBufferAccess	access		= tcu::getSubregion(levelAccess, 0, 0, (layer*6)+face, levelAccess.getWidth(), levelAccess.getHeight(), 1);
1149 							const int						lastPix		= access.getWidth()-1;
1150 
1151 							tcu::fillWithGrid(access, de::max(1, baseCellSize>>level), colorA, colorB);
1152 
1153 							// Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
1154 							access.setPixel(cCorner, 0, 0);
1155 							access.setPixel(cCorner, 0, lastPix);
1156 							access.setPixel(cCorner, lastPix, 0);
1157 							access.setPixel(cCorner, lastPix, lastPix);
1158 						}
1159 					}
1160 				}
1161 			}
1162 
1163 			// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
1164 			DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
1165 			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]));
1166 			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]));
1167 
1168 			tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1169 			tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.maxCoord[0]*proj, m_lookupSpec.minCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1170 			tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_lookupSpec.minCoord[0]*proj, m_lookupSpec.maxCoord[1]*proj, m_lookupSpec.minCoord[2]*proj));
1171 			float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
1172 			float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
1173 			lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1174 
1175 			// Append to texture list.
1176 			m_textures.push_back(TextureBindingSp(new TextureBinding(textureCubeArray.release(), m_textureSpec.sampler)));
1177 			break;
1178 		}
1179 
1180 		default:
1181 			DE_ASSERT(DE_FALSE);
1182 	}
1183 
1184 	// Set lookup scale & bias
1185 	lookupParams.scale		= fmtInfo.lookupScale;
1186 	lookupParams.bias		= fmtInfo.lookupBias;
1187 	lookupParams.offset		= m_lookupSpec.offset;
1188 	lookupParams.lodClamp	= m_lookupSpec.lodClamp;
1189 
1190 	// \todo [dirnerakos] Avoid const cast somehow
1191 	const_cast<TexLookupParams&>(m_lookupParams) = lookupParams;
1192 }
1193 
1194 class ShaderTextureFunctionCase : public ShaderRenderCase
1195 {
1196 public:
1197 								ShaderTextureFunctionCase		(tcu::TestContext&				testCtx,
1198 																 const std::string&				name,
1199 																 const std::string&				desc,
1200 																 const TextureLookupSpec&		lookup,
1201 																 const TextureSpec&				texture,
1202 																 TexEvalFunc					evalFunc,
1203 																 bool							isVertexCase);
1204 	virtual						~ShaderTextureFunctionCase		(void);
1205 
1206 	virtual TestInstance*		createInstance					(Context& context) const;
1207 	virtual void				checkSupport					(Context& context) const;
1208 
1209 protected:
1210 	const TextureLookupSpec		m_lookupSpec;
1211 	const TextureSpec			m_textureSpec;
1212 	const TexLookupParams		m_lookupParams;
1213 
1214 	void						initShaderSources				(void);
1215 };
1216 
ShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const std::string & desc,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)1217 ShaderTextureFunctionCase::ShaderTextureFunctionCase (tcu::TestContext&				testCtx,
1218 													  const std::string&			name,
1219 													  const std::string&			desc,
1220 													  const TextureLookupSpec&		lookup,
1221 													  const TextureSpec&			texture,
1222 													  TexEvalFunc					evalFunc,
1223 													  bool							isVertexCase)
1224 	: ShaderRenderCase		(testCtx, name, desc, isVertexCase, new TexLookupEvaluator(evalFunc, m_lookupParams), NULL, NULL)
1225 	, m_lookupSpec			(lookup)
1226 	, m_textureSpec			(texture)
1227 {
1228 	initShaderSources();
1229 }
1230 
~ShaderTextureFunctionCase(void)1231 ShaderTextureFunctionCase::~ShaderTextureFunctionCase (void)
1232 {
1233 }
1234 
createInstance(Context & context) const1235 TestInstance* ShaderTextureFunctionCase::createInstance (Context& context) const
1236 {
1237 	DE_ASSERT(m_evaluator != DE_NULL);
1238 	DE_ASSERT(m_uniformSetup != DE_NULL);
1239 	return new ShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
1240 }
1241 
checkSupport(Context & context) const1242 void ShaderTextureFunctionCase::checkSupport(Context& context) const
1243 {
1244 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
1245 }
1246 
initShaderSources(void)1247 void ShaderTextureFunctionCase::initShaderSources (void)
1248 {
1249 	Function			function			= m_lookupSpec.function;
1250 	bool				isVtxCase			= m_isVertexCase;
1251 	bool				isProj				= functionHasProj(function);
1252 	bool				isGrad				= functionHasGrad(function);
1253 	bool				isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1254 	bool				is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1255 	bool				is1DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_1D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
1256 	bool				isIntCoord			= function == FUNCTION_TEXELFETCH;
1257 	bool				hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1258 	int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_1D ? 1 :
1259 											  m_textureSpec.type == TEXTURETYPE_1D_ARRAY || m_textureSpec.type == TEXTURETYPE_2D ? 2 :
1260 											  m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? 4 :
1261 											  3;
1262 	int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : (is1DProj4 ? 3 : 1)) : 0) + (isShadow ? (m_textureSpec.type == TEXTURETYPE_1D ? 2 : 1) : 0);
1263 	const bool			isCubeArrayShadow	= isShadow && m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY;
1264 	glu::DataType		coordType			= glu::getDataTypeFloatVec(isCubeArrayShadow ? 4 : texCoordComps+extraCoordComps);
1265 	glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
1266 	const char*			coordTypeName		= glu::getDataTypeName(coordType);
1267 	const char*			coordPrecName		= glu::getPrecisionName(coordPrec);
1268 	tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
1269 	glu::DataType		samplerType			= glu::TYPE_LAST;
1270 	glu::DataType		gradType			= m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? glu::TYPE_FLOAT :
1271 											  m_textureSpec.type == TEXTURETYPE_3D || m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ? glu::TYPE_FLOAT_VEC3 :
1272 											  glu::TYPE_FLOAT_VEC2;
1273 	const char*			gradTypeName		= glu::getDataTypeName(gradType);
1274 	const char*			baseFuncName		= DE_NULL;
1275 
1276 	DE_ASSERT(!isGrad || !hasLodBias);
1277 
1278 	switch (m_textureSpec.type)
1279 	{
1280 		case TEXTURETYPE_2D:			samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW			: glu::getSampler2DType(texFmt);		break;
1281 		case TEXTURETYPE_CUBE_MAP:		samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW			: glu::getSamplerCubeType(texFmt);		break;
1282 		case TEXTURETYPE_2D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW		: glu::getSampler2DArrayType(texFmt);	break;
1283 		case TEXTURETYPE_3D:			DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);										break;
1284 		case TEXTURETYPE_1D:			samplerType = isShadow ? glu::TYPE_SAMPLER_1D_SHADOW			: glu::getSampler1DType(texFmt);		break;
1285 		case TEXTURETYPE_1D_ARRAY:		samplerType = isShadow ? glu::TYPE_SAMPLER_1D_ARRAY_SHADOW		: glu::getSampler1DArrayType(texFmt);	break;
1286 		case TEXTURETYPE_CUBE_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW	: glu::getSamplerCubeArrayType(texFmt);	break;
1287 		default:
1288 			DE_ASSERT(DE_FALSE);
1289 	}
1290 
1291 	switch (m_lookupSpec.function)
1292 	{
1293 		case FUNCTION_TEXTURE:			baseFuncName = "texture";			break;
1294 		case FUNCTION_TEXTUREPROJ:		baseFuncName = "textureProj";		break;
1295 		case FUNCTION_TEXTUREPROJ2:		baseFuncName = "textureProj";		break;
1296 		case FUNCTION_TEXTUREPROJ3:		baseFuncName = "textureProj";		break;
1297 		case FUNCTION_TEXTURELOD:		baseFuncName = "textureLod";		break;
1298 		case FUNCTION_TEXTUREPROJLOD:	baseFuncName = "textureProjLod";	break;
1299 		case FUNCTION_TEXTUREPROJLOD2:	baseFuncName = "textureProjLod";	break;
1300 		case FUNCTION_TEXTUREPROJLOD3:	baseFuncName = "textureProjLod";	break;
1301 		case FUNCTION_TEXTUREGRAD:		baseFuncName = "textureGrad";		break;
1302 		case FUNCTION_TEXTUREPROJGRAD:	baseFuncName = "textureProjGrad";	break;
1303 		case FUNCTION_TEXTUREPROJGRAD2:	baseFuncName = "textureProjGrad";	break;
1304 		case FUNCTION_TEXTUREPROJGRAD3:	baseFuncName = "textureProjGrad";	break;
1305 		case FUNCTION_TEXELFETCH:		baseFuncName = "texelFetch";		break;
1306 		default:
1307 			DE_ASSERT(DE_FALSE);
1308 	}
1309 
1310 	std::ostringstream	vert;
1311 	std::ostringstream	frag;
1312 	std::ostringstream&	op		= isVtxCase ? vert : frag;
1313 
1314 	vert << "#version 450 core\n"
1315 		 << "layout(location = 0) in highp vec4 a_position;\n"
1316 		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
1317 
1318 	if (isGrad)
1319 	{
1320 		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
1321 		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
1322 	}
1323 	else if (hasLodBias)
1324 		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
1325 
1326 	frag << "#version 450 core\n";
1327 
1328 	if (m_lookupSpec.useClamp)
1329 		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
1330 
1331 	frag  << "layout(location = 0) out mediump vec4 o_color;\n";
1332 
1333 	if (isVtxCase)
1334 	{
1335 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
1336 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
1337 	}
1338 	else
1339 	{
1340 		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1341 		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1342 
1343 		if (isGrad)
1344 		{
1345 			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1346 			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1347 			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1348 			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1349 		}
1350 		else if (hasLodBias)
1351 		{
1352 			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
1353 			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
1354 		}
1355 	}
1356 
1357 	// Uniforms
1358 	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
1359 	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
1360 	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
1361 
1362 	vert << "out gl_PerVertex {\n"
1363 		 << "\tvec4 gl_Position;\n"
1364 		 << "};\n";
1365 
1366 	vert << "\nvoid main()\n{\n"
1367 		 << "\tgl_Position = a_position;\n";
1368 	frag << "\nvoid main()\n{\n";
1369 
1370 	if (isVtxCase)
1371 		vert << "\tv_color = ";
1372 	else
1373 		frag << "\to_color = ";
1374 
1375 	// Op.
1376 	{
1377 		const char*	texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
1378 		const char* gradX		= isVtxCase ? "a_in1" : "v_gradX";
1379 		const char* gradY		= isVtxCase ? "a_in2" : "v_gradY";
1380 		const char*	lodBias		= isVtxCase ? "a_in1" : "v_lodBias";
1381 
1382 		op << "vec4(" << baseFuncName;
1383 		if (m_lookupSpec.useOffset)
1384 			op << "Offset";
1385 		if (m_lookupSpec.useClamp)
1386 			op << "ClampARB";
1387 		op << "(u_sampler, ";
1388 
1389 		if (isIntCoord)
1390 			op << glu::getDataTypeName(glu::getDataTypeIntVec(texCoordComps+extraCoordComps)) << "(";
1391 
1392 		op << texCoord;
1393 
1394 		if (isIntCoord)
1395 			op << ")";
1396 
1397 		if (isGrad)
1398 			op << ", " << gradX << ", " << gradY;
1399 
1400 		if (functionHasLod(function))
1401 		{
1402 			if (isIntCoord)
1403 				op << ", int(" << lodBias << ")";
1404 			else
1405 				op << ", " << lodBias;
1406 		}
1407 
1408 		if (m_lookupSpec.useOffset)
1409 		{
1410 			int offsetComps = m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? 1 :
1411 							  m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
1412 
1413 			op << ", " << glu::getDataTypeName(glu::getDataTypeIntVec(offsetComps)) << "(";
1414 			for (int ndx = 0; ndx < offsetComps; ndx++)
1415 			{
1416 				if (ndx != 0)
1417 					op << ", ";
1418 				op << m_lookupSpec.offset[ndx];
1419 			}
1420 			op << ")";
1421 		}
1422 
1423 		if (m_lookupSpec.useClamp)
1424 			op << ", float(" << m_lookupSpec.lodClamp << ")";
1425 
1426 		if (isCubeArrayShadow && m_lookupSpec.function == FUNCTION_TEXTURE)
1427 			op << ", " << texCoord << ".w";
1428 
1429 		if (m_lookupSpec.useBias)
1430 			op << ", " << lodBias;
1431 
1432 		op << ")";
1433 
1434 		if (isShadow)
1435 			op << ", 0.0, 0.0, 1.0)";
1436 		else
1437 			op << ")*u_scale + u_bias";
1438 
1439 		op << ";\n";
1440 	}
1441 
1442 	if (isVtxCase)
1443 		frag << "\to_color = v_color;\n";
1444 	else
1445 	{
1446 		vert << "\tv_texCoord = a_in0;\n";
1447 
1448 		if (isGrad)
1449 		{
1450 			vert << "\tv_gradX = a_in1;\n";
1451 			vert << "\tv_gradY = a_in2;\n";
1452 		}
1453 		else if (hasLodBias)
1454 			vert << "\tv_lodBias = a_in1;\n";
1455 	}
1456 
1457 	vert << "}\n";
1458 	frag << "}\n";
1459 
1460 	m_vertShaderSource = vert.str();
1461 	m_fragShaderSource = frag.str();
1462 }
1463 
1464 enum QueryFunction
1465 {
1466 	QUERYFUNCTION_TEXTURESIZE = 0,
1467 	QUERYFUNCTION_TEXTURESIZEMS,
1468 	QUERYFUNCTION_TEXTUREQUERYLOD,
1469 	QUERYFUNCTION_TEXTUREQUERYLEVELS,
1470 	QUERYFUNCTION_TEXTURESAMPLES,
1471 
1472 	QUERYFUNCTION_LAST
1473 };
1474 
1475 // test mode used to alter test behaviour
1476 using TestMode = deUint32;
1477 
1478 enum QueryLodTestModes
1479 {
1480 	QLODTM_DEFAULT			= 0,		// uv coords have different values
1481 	QLODTM_ZERO_UV_WIDTH				// all uv coords are 0; there were implementations that incorrectly returned 0 in that case instead of -22 or less
1482 };
1483 
1484 class TextureQueryInstance : public ShaderRenderCaseInstance
1485 {
1486 public:
1487 								TextureQueryInstance			(Context&					context,
1488 																 const bool					isVertexCase,
1489 																 const TextureSpec&			textureSpec);
1490 	virtual						~TextureQueryInstance			(void);
1491 
1492 protected:
1493 	virtual void				setupDefaultInputs				(void);
1494 	virtual void				setupUniforms					(const tcu::Vec4&);
1495 
1496 	void						render							(void);
1497 
1498 protected:
1499 	const TextureSpec&			m_textureSpec;
1500 };
1501 
TextureQueryInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)1502 TextureQueryInstance::TextureQueryInstance (Context&				context,
1503 											const bool				isVertexCase,
1504 											const TextureSpec&		textureSpec)
1505 	: ShaderRenderCaseInstance	(context, isVertexCase, DE_NULL, DE_NULL, DE_NULL)
1506 	, m_textureSpec				(textureSpec)
1507 {
1508 	m_colorFormat = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
1509 
1510 	checkDeviceFeatures(m_context, m_textureSpec.type);
1511 }
1512 
~TextureQueryInstance(void)1513 TextureQueryInstance::~TextureQueryInstance (void)
1514 {
1515 }
1516 
setupDefaultInputs(void)1517 void TextureQueryInstance::setupDefaultInputs (void)
1518 {
1519 	const deUint32		numVertices		= 4;
1520 	const float			positions[]		=
1521 	{
1522 		-1.0f, -1.0f, 0.0f, 1.0f,
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 	};
1527 
1528 	addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, positions);
1529 }
1530 
setupUniforms(const tcu::Vec4 &)1531 void TextureQueryInstance::setupUniforms (const tcu::Vec4&)
1532 {
1533 	useSampler(0u, 0u);
1534 }
1535 
render(void)1536 void TextureQueryInstance::render (void)
1537 {
1538 	const deUint32		numVertices		= 4;
1539 	const deUint32		numTriangles	= 2;
1540 	const deUint16		indices[6]		= { 0, 1, 2, 2, 1, 3 };
1541 
1542 	ShaderRenderCaseInstance::setup();
1543 
1544 	ShaderRenderCaseInstance::render(numVertices, numTriangles, indices);
1545 }
1546 
getMaxTextureSize(TextureType type,const tcu::IVec3 & textureSize)1547 static int getMaxTextureSize (TextureType type, const tcu::IVec3& textureSize)
1548 {
1549 	int		maxSize		= 0;
1550 
1551 	switch (type)
1552 	{
1553 		case TEXTURETYPE_1D:
1554 		case TEXTURETYPE_1D_ARRAY:
1555 			maxSize = textureSize.x();
1556 			break;
1557 
1558 		case TEXTURETYPE_2D:
1559 		case TEXTURETYPE_2D_ARRAY:
1560 		case TEXTURETYPE_CUBE_MAP:
1561 		case TEXTURETYPE_CUBE_ARRAY:
1562 			maxSize = de::max(textureSize.x(), textureSize.y());
1563 			break;
1564 
1565 		case TEXTURETYPE_3D:
1566 			maxSize = de::max(textureSize.x(), de::max(textureSize.y(), textureSize.z()));
1567 			break;
1568 
1569 		default:
1570 			DE_ASSERT(false);
1571 	}
1572 
1573 	return maxSize;
1574 }
1575 
getTextureSizeString(TextureType type,const tcu::IVec3 & textureSize)1576 static std::string getTextureSizeString (TextureType type, const tcu::IVec3& textureSize)
1577 {
1578 	std::ostringstream	str;
1579 
1580 	switch (type)
1581 	{
1582 		case TEXTURETYPE_1D:
1583 			str << textureSize.x() << "x1";
1584 			break;
1585 
1586 		case TEXTURETYPE_2D:
1587 		case TEXTURETYPE_CUBE_MAP:
1588 			str << textureSize.x() << "x" << textureSize.y();
1589 			break;
1590 
1591 		case TEXTURETYPE_3D:
1592 			str << textureSize.x() << "x" << textureSize.y() << "x" << textureSize.z();
1593 			break;
1594 
1595 		case TEXTURETYPE_1D_ARRAY:
1596 			str << textureSize.x() << "x1 with " << textureSize.z() << " layer(s)";
1597 			break;
1598 
1599 		case TEXTURETYPE_2D_ARRAY:
1600 		case TEXTURETYPE_CUBE_ARRAY:
1601 			str << textureSize.x() << "x" << textureSize.y() << " with " << textureSize.z() << " layers(s)";
1602 			break;
1603 
1604 		default:
1605 			DE_ASSERT(false);
1606 			break;
1607 	}
1608 
1609 	return str.str();
1610 }
1611 
isValidCase(TextureType type,const tcu::IVec3 & textureSize,int lodBase)1612 static bool isValidCase (TextureType type, const tcu::IVec3& textureSize, int lodBase)
1613 {
1614 	const bool	isSquare	= textureSize.x() == textureSize.y();
1615 	const bool	isCubeArray	= isSquare && (textureSize.z() % 6) == 0;
1616 	const int	maxSize		= getMaxTextureSize(type, textureSize);
1617 	const bool	isBaseValid	= (maxSize >> lodBase) != 0;
1618 
1619 	if (!isBaseValid)
1620 		return false;
1621 	if (type == TEXTURETYPE_CUBE_MAP && !isSquare)
1622 		return false;
1623 	if (type == TEXTURETYPE_CUBE_ARRAY && !isCubeArray)
1624 		return false;
1625 
1626 	return true;
1627 }
1628 
createEmptyTexture(deUint32 format,TextureType type,const tcu::IVec3 & textureSize,int numLevels,int lodBase,const tcu::Sampler & sampler)1629 static TextureBindingSp createEmptyTexture (deUint32				format,
1630 											TextureType				type,
1631 											const tcu::IVec3&		textureSize,
1632 											int						numLevels,
1633 											int						lodBase,
1634 											const tcu::Sampler&		sampler)
1635 {
1636 	const tcu::TextureFormat			texFmt				= glu::mapGLInternalFormat(format);
1637 	const TextureBinding::Parameters	params				(lodBase);
1638 	TextureBindingSp					textureBinding;
1639 
1640 	switch (type)
1641 	{
1642 
1643 		case TEXTURETYPE_1D:
1644 		{
1645 			de::MovePtr<tcu::Texture1D>			texture		(new tcu::Texture1D(texFmt, textureSize.x()));
1646 
1647 			for (int level = 0; level < numLevels; level++)
1648 				texture->allocLevel(level);
1649 
1650 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1651 			break;
1652 		}
1653 
1654 		case TEXTURETYPE_2D:
1655 		{
1656 			de::MovePtr<tcu::Texture2D>			texture		(new tcu::Texture2D(texFmt, textureSize.x(), textureSize.y()));
1657 
1658 			for (int level = 0; level < numLevels; level++)
1659 				texture->allocLevel(level);
1660 
1661 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1662 			break;
1663 		}
1664 
1665 		case TEXTURETYPE_3D:
1666 		{
1667 			de::MovePtr<tcu::Texture3D>			texture		(new tcu::Texture3D(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1668 
1669 			for (int level = 0; level < numLevels; level++)
1670 				texture->allocLevel(level);
1671 
1672 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1673 			break;
1674 		}
1675 
1676 		case TEXTURETYPE_CUBE_MAP:
1677 		{
1678 			de::MovePtr<tcu::TextureCube>		texture		(new tcu::TextureCube(texFmt, textureSize.x()));
1679 
1680 			for (int level = 0; level < numLevels; level++)
1681 				for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1682 					texture->allocLevel((tcu::CubeFace)face, level);
1683 
1684 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1685 			break;
1686 		}
1687 
1688 		case TEXTURETYPE_1D_ARRAY:
1689 		{
1690 			de::MovePtr<tcu::Texture1DArray>	texture		(new tcu::Texture1DArray(texFmt, textureSize.x(), textureSize.z()));
1691 
1692 			for (int level = 0; level < numLevels; level++)
1693 				texture->allocLevel(level);
1694 
1695 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1696 			break;
1697 		}
1698 
1699 		case TEXTURETYPE_2D_ARRAY:
1700 		{
1701 			de::MovePtr<tcu::Texture2DArray>	texture		(new tcu::Texture2DArray(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
1702 
1703 			for (int level = 0; level < numLevels; level++)
1704 				texture->allocLevel(level);
1705 
1706 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1707 			break;
1708 		}
1709 
1710 		case TEXTURETYPE_CUBE_ARRAY:
1711 		{
1712 			de::MovePtr<tcu::TextureCubeArray>	texture		(new tcu::TextureCubeArray(texFmt, textureSize.x(), textureSize.z()));
1713 
1714 			for (int level = 0; level < numLevels; level++)
1715 				texture->allocLevel(level);
1716 
1717 			textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
1718 			break;
1719 		}
1720 
1721 		default:
1722 			DE_ASSERT(false);
1723 			break;
1724 	}
1725 
1726 	textureBinding->setParameters(params);
1727 	return textureBinding;
1728 }
1729 
getTextureSizeFuncResultType(TextureType textureType)1730 static inline glu::DataType getTextureSizeFuncResultType (TextureType textureType)
1731 {
1732 	switch (textureType)
1733 	{
1734 		case TEXTURETYPE_1D:
1735 			return glu::TYPE_INT;
1736 
1737 		case TEXTURETYPE_2D:
1738 		case TEXTURETYPE_CUBE_MAP:
1739 		case TEXTURETYPE_1D_ARRAY:
1740 			return glu::TYPE_INT_VEC2;
1741 
1742 		case TEXTURETYPE_3D:
1743 		case TEXTURETYPE_2D_ARRAY:
1744 		case TEXTURETYPE_CUBE_ARRAY:
1745 			return glu::TYPE_INT_VEC3;
1746 
1747 		default:
1748 			DE_ASSERT(false);
1749 			return glu::TYPE_LAST;
1750 	}
1751 }
1752 
1753 class TextureSizeInstance : public TextureQueryInstance
1754 {
1755 public:
1756 								TextureSizeInstance				(Context&					context,
1757 																 const bool					isVertexCase,
1758 																 const TextureSpec&			textureSpec);
1759 	virtual						~TextureSizeInstance			(void);
1760 
1761 	virtual tcu::TestStatus		iterate							(void);
1762 
1763 protected:
1764 	virtual void				setupUniforms					(const tcu::Vec4& constCoords);
1765 
1766 private:
1767 	struct TestSize
1768 	{
1769 		tcu::IVec3	textureSize;
1770 		int			lod;
1771 		int			lodBase;
1772 		tcu::IVec3	expectedSize;
1773 	};
1774 
1775 	void						initTexture						(void);
1776 	bool						testTextureSize					(void);
1777 
1778 	TestSize					m_testSize;
1779 	tcu::IVec3					m_expectedSize;
1780 	int							m_iterationCounter;
1781 };
1782 
TextureSizeInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)1783 TextureSizeInstance::TextureSizeInstance (Context&					context,
1784 										  const bool				isVertexCase,
1785 										  const TextureSpec&		textureSpec)
1786 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
1787 	, m_testSize				()
1788 	, m_expectedSize			()
1789 	, m_iterationCounter		(0)
1790 {
1791 	deMemset(&m_testSize, 0, sizeof(TestSize));
1792 
1793 #ifdef CTS_USES_VULKANSC
1794 	const VkDevice			vkDevice			= getDevice();
1795 	const DeviceInterface&	vk					= getDeviceInterface();
1796 	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
1797 	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
1798 #endif // CTS_USES_VULKANSC
1799 
1800 	m_renderSize = tcu::UVec2(1, 1);
1801 }
1802 
~TextureSizeInstance(void)1803 TextureSizeInstance::~TextureSizeInstance (void)
1804 {
1805 }
1806 
setupUniforms(const tcu::Vec4 & constCoords)1807 void TextureSizeInstance::setupUniforms (const tcu::Vec4& constCoords)
1808 {
1809 	TextureQueryInstance::setupUniforms(constCoords);
1810 	addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(int), &m_testSize.lod);
1811 }
1812 
initTexture(void)1813 void TextureSizeInstance::initTexture (void)
1814 {
1815 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
1816 	const int				numLevels			= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
1817 	TextureBindingSp		textureBinding;
1818 
1819 	log << tcu::TestLog::Message << "Testing image size " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
1820 	log << tcu::TestLog::Message << "Lod: " << m_testSize.lod << ", base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
1821 
1822 	switch (m_textureSpec.type)
1823 	{
1824 		case TEXTURETYPE_3D:
1825 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << "x" << m_testSize.expectedSize.z() << tcu::TestLog::EndMessage;
1826 			break;
1827 
1828 		case TEXTURETYPE_2D:
1829 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1830 			break;
1831 
1832 		case TEXTURETYPE_CUBE_MAP:
1833 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
1834 			break;
1835 
1836 		case TEXTURETYPE_2D_ARRAY:
1837 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x" << m_testSize.expectedSize.y() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1838 			break;
1839 
1840 		case TEXTURETYPE_CUBE_ARRAY:
1841 			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;
1842 			break;
1843 
1844 		case TEXTURETYPE_1D:
1845 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << tcu::TestLog::EndMessage;
1846 			break;
1847 
1848 		case TEXTURETYPE_1D_ARRAY:
1849 			log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << " and " << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
1850 			break;
1851 
1852 		default:
1853 			DE_ASSERT(false);
1854 			break;
1855 	}
1856 
1857 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
1858 
1859 	m_textures.clear();
1860 	m_textures.push_back(textureBinding);
1861 }
1862 
iterate(void)1863 tcu::TestStatus TextureSizeInstance::iterate (void)
1864 {
1865 	const TestSize testSizes[] =
1866 	{
1867 		{ tcu::IVec3(1, 2, 1),			0,		0,	tcu::IVec3(1, 2, 1)			},
1868 		{ tcu::IVec3(1, 2, 1),			1,		0,	tcu::IVec3(1, 1, 1)			},
1869 
1870 		{ tcu::IVec3(1, 3, 2),			0,		0,	tcu::IVec3(1, 3, 2)			},
1871 		{ tcu::IVec3(1, 3, 2),			1,		0,	tcu::IVec3(1, 1, 1)			},
1872 
1873 		{ tcu::IVec3(100, 31, 18),		0,		0,	tcu::IVec3(100, 31, 18)		},
1874 		{ tcu::IVec3(100, 31, 18),		1,		0,	tcu::IVec3(50, 15, 9)		},
1875 		{ tcu::IVec3(100, 31, 18),		2,		0,	tcu::IVec3(25, 7, 4)		},
1876 		{ tcu::IVec3(100, 31, 18),		3,		0,	tcu::IVec3(12, 3, 2)		},
1877 		{ tcu::IVec3(100, 31, 18),		4,		0,	tcu::IVec3(6, 1, 1)			},
1878 		{ tcu::IVec3(100, 31, 18),		5,		0,	tcu::IVec3(3, 1, 1)			},
1879 		{ tcu::IVec3(100, 31, 18),		6,		0,	tcu::IVec3(1, 1, 1)			},
1880 
1881 		{ tcu::IVec3(100, 128, 32),		0,		0,	tcu::IVec3(100, 128, 32)	},
1882 		{ tcu::IVec3(100, 128, 32),		1,		0,	tcu::IVec3(50, 64, 16)		},
1883 		{ tcu::IVec3(100, 128, 32),		2,		0,	tcu::IVec3(25, 32, 8)		},
1884 		{ tcu::IVec3(100, 128, 32),		3,		0,	tcu::IVec3(12, 16, 4)		},
1885 		{ tcu::IVec3(100, 128, 32),		4,		0,	tcu::IVec3(6, 8, 2)			},
1886 		{ tcu::IVec3(100, 128, 32),		5,		0,	tcu::IVec3(3, 4, 1)			},
1887 		{ tcu::IVec3(100, 128, 32),		6,		0,	tcu::IVec3(1, 2, 1)			},
1888 		{ tcu::IVec3(100, 128, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1889 
1890 		// pow 2
1891 		{ tcu::IVec3(128, 64, 32),		0,		0,	tcu::IVec3(128, 64, 32)		},
1892 		{ tcu::IVec3(128, 64, 32),		1,		0,	tcu::IVec3(64, 32, 16)		},
1893 		{ tcu::IVec3(128, 64, 32),		2,		0,	tcu::IVec3(32, 16, 8)		},
1894 		{ tcu::IVec3(128, 64, 32),		3,		0,	tcu::IVec3(16, 8, 4)		},
1895 		{ tcu::IVec3(128, 64, 32),		4,		0,	tcu::IVec3(8, 4, 2)			},
1896 		{ tcu::IVec3(128, 64, 32),		5,		0,	tcu::IVec3(4, 2, 1)			},
1897 		{ tcu::IVec3(128, 64, 32),		6,		0,	tcu::IVec3(2, 1, 1)			},
1898 		{ tcu::IVec3(128, 64, 32),		7,		0,	tcu::IVec3(1, 1, 1)			},
1899 
1900 		// w == h
1901 		{ tcu::IVec3(1, 1, 1),			0,		0,	tcu::IVec3(1, 1, 1)			},
1902 		{ tcu::IVec3(64, 64, 64),		0,		0,	tcu::IVec3(64, 64, 64)		},
1903 		{ tcu::IVec3(64, 64, 64),		1,		0,	tcu::IVec3(32, 32, 32)		},
1904 		{ tcu::IVec3(64, 64, 64),		2,		0,	tcu::IVec3(16, 16, 16)		},
1905 		{ tcu::IVec3(64, 64, 64),		3,		0,	tcu::IVec3(8, 8, 8)			},
1906 		{ tcu::IVec3(64, 64, 64),		4,		0,	tcu::IVec3(4, 4, 4)			},
1907 
1908 		// with lod base
1909 		{ tcu::IVec3(100, 31, 18),		3,		1,	tcu::IVec3(6, 1, 1)			},
1910 		{ tcu::IVec3(128, 64, 32),		3,		1,	tcu::IVec3(8, 4, 2)			},
1911 		{ tcu::IVec3(64, 64, 64),		1,		1,	tcu::IVec3(16, 16, 16)		},
1912 
1913 		{ tcu::IVec3(100, 31, 18),		1,		2,	tcu::IVec3(12, 3, 2)		},
1914 		{ tcu::IVec3(100, 31, 18),		2,		2,	tcu::IVec3(6, 1, 1)			},
1915 		{ tcu::IVec3(100, 31, 18),		1,		4,	tcu::IVec3(3, 1, 1)			},
1916 
1917 		// out-of-range mip levels
1918 		{ tcu::IVec3(1, 3, 2),			-7,		0,	tcu::IVec3(0, 0, 0)			},
1919 		{ tcu::IVec3(1, 3, 2),			106,	0,	tcu::IVec3(0, 0, 0)			},
1920 		{ tcu::IVec3(100, 31, 18),		7,		0,	tcu::IVec3(0, 0, 0)			},
1921 		{ tcu::IVec3(32, 32, 12),		6,		0,	tcu::IVec3(0, 0, 0)			},
1922 		{ tcu::IVec3(32, 32, 12),		-9,		0,	tcu::IVec3(0, 0, 0)			},
1923 		{ tcu::IVec3(32, 32, 12),		4396,	0,	tcu::IVec3(0, 0, 0)			},
1924 
1925 		// w == h and d % 6 == 0 (for cube array)
1926 		{ tcu::IVec3(1, 1, 6),			0,		0,	tcu::IVec3(1, 1, 6)			},
1927 		{ tcu::IVec3(32, 32, 12),		0,		0,	tcu::IVec3(32, 32, 12)		},
1928 		{ tcu::IVec3(32, 32, 12),		0,		1,	tcu::IVec3(16, 16, 6)		},
1929 		{ tcu::IVec3(32, 32, 12),		1,		0,	tcu::IVec3(16, 16, 6)		},
1930 		{ tcu::IVec3(32, 32, 12),		2,		0,	tcu::IVec3(8, 8, 3)			},
1931 		{ tcu::IVec3(32, 32, 12),		3,		0,	tcu::IVec3(4, 4, 1)			},
1932 		{ tcu::IVec3(32, 32, 12),		4,		0,	tcu::IVec3(2, 2, 1)			},
1933 		{ tcu::IVec3(32, 32, 12),		5,		0,	tcu::IVec3(1, 1, 1)			},
1934 	};
1935 	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1936 
1937 	m_iterationCounter++;
1938 
1939 	if (m_iterationCounter == lastIterationIndex)
1940 		return tcu::TestStatus::pass("Pass");
1941 	else
1942 	{
1943 		// set current test size
1944 		m_testSize = testSizes[m_iterationCounter - 1];
1945 
1946 		bool result = testTextureSize();
1947 #ifdef CTS_USES_VULKANSC
1948 		if (m_context.getTestContext().getCommandLine().isSubProcess())
1949 #endif // CTS_USES_VULKANSC
1950 		{
1951 			if (!result)
1952 				return tcu::TestStatus::fail("Got unexpected result");
1953 		}
1954 		return tcu::TestStatus::incomplete();
1955 	}
1956 }
1957 
testTextureSize(void)1958 bool TextureSizeInstance::testTextureSize (void)
1959 {
1960 	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1961 	bool					success			= true;
1962 
1963 	// skip incompatible cases
1964 	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
1965 		return true;
1966 
1967 	// setup texture
1968 	initTexture();
1969 
1970 	// determine expected texture size
1971 	switch (m_textureSpec.type)
1972 	{
1973 		case TEXTURETYPE_1D:
1974 		case TEXTURETYPE_2D:
1975 		case TEXTURETYPE_3D:
1976 		case TEXTURETYPE_CUBE_MAP:
1977 			m_expectedSize = m_testSize.expectedSize;
1978 			break;
1979 
1980 		case TEXTURETYPE_1D_ARRAY:
1981 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.textureSize.z(), 0);
1982 			break;
1983 
1984 		case TEXTURETYPE_2D_ARRAY:
1985 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z());
1986 			break;
1987 
1988 		case TEXTURETYPE_CUBE_ARRAY:
1989 			m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z() / 6);
1990 			break;
1991 
1992 		default:
1993 			DE_ASSERT(false);
1994 			break;
1995 	}
1996 
1997 	// render
1998 	TextureQueryInstance::render();
1999 
2000 	// test
2001 	{
2002 		const tcu::TextureLevel&	result				= getResultImage();
2003 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2004 		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2005 
2006 		for (int ndx = 0; ndx < resultComponents; ndx++)
2007 		{
2008 			// We test all levels, but only compare results for valid LoDs. The others give
2009 			// undefined values.
2010 			const int	maxSize		= getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize);
2011 			const bool	isLodValid	= (maxSize >> (m_testSize.lod + m_testSize.lodBase)) != 0;
2012 			if (isLodValid && output[ndx] != m_expectedSize[ndx])
2013 			{
2014 				success = false;
2015 				break;
2016 			}
2017 		}
2018 
2019 		if (success)
2020 		{
2021 			// success
2022 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2023 		}
2024 		else
2025 		{
2026 			// failure
2027 			std::stringstream	resultSizeStr;
2028 			switch (resultComponents)
2029 			{
2030 				case 1:
2031 					resultSizeStr << output[0];
2032 					break;
2033 				case 2:
2034 					resultSizeStr << output.toWidth<2>();
2035 					break;
2036 				case 3:
2037 					resultSizeStr << output.toWidth<3>();
2038 					break;
2039 				default:
2040 					DE_ASSERT(false);
2041 					break;
2042 			}
2043 			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2044 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2045 		}
2046 	}
2047 
2048 	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2049 
2050 	return success;
2051 }
2052 
getVkImageType(TextureType type)2053 static vk::VkImageType getVkImageType (TextureType type)
2054 {
2055 	switch (type)
2056 	{
2057 		case TEXTURETYPE_1D:
2058 		case TEXTURETYPE_1D_ARRAY:
2059 			return vk::VK_IMAGE_TYPE_1D;
2060 
2061 		case TEXTURETYPE_2D:
2062 		case TEXTURETYPE_2D_ARRAY:
2063 		case TEXTURETYPE_CUBE_MAP:
2064 		case TEXTURETYPE_CUBE_ARRAY:
2065 			return vk::VK_IMAGE_TYPE_2D;
2066 
2067 		case TEXTURETYPE_3D:
2068 			return vk::VK_IMAGE_TYPE_3D;
2069 
2070 		default:
2071 			DE_ASSERT(false);
2072 			return (vk::VkImageType)0;
2073 	}
2074 }
2075 
2076 class TextureSizeMSInstance : public TextureQueryInstance
2077 {
2078 public:
2079 								TextureSizeMSInstance			(Context&					context,
2080 																 const bool					isVertexCase,
2081 																 const TextureSpec&			textureSpec);
2082 	virtual						~TextureSizeMSInstance			(void);
2083 
2084 	virtual tcu::TestStatus		iterate							(void);
2085 
2086 private:
2087 	void						initTexture						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2088 	bool						testSize						(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2089 
2090 	unsigned								m_iterationCounter;
2091 	vector<vk::VkSampleCountFlagBits>		m_iterations;
2092 };
2093 
TextureSizeMSInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2094 TextureSizeMSInstance::TextureSizeMSInstance	(Context&				context,
2095 												const bool				isVertexCase,
2096 												const TextureSpec&		textureSpec)
2097 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2098 	, m_iterationCounter		(0)
2099 {
2100 	m_renderSize = tcu::UVec2(1, 1);
2101 
2102 	// determine available sample counts
2103 	{
2104 		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2105 		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2106 		vk::VkImageFormatProperties				properties;
2107 
2108 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2109 																					format,
2110 																					imageType,
2111 																					vk::VK_IMAGE_TILING_OPTIMAL,
2112 																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2113 																					(vk::VkImageCreateFlags)0,
2114 																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2115 			TCU_THROW(NotSupportedError, "Format not supported");
2116 
2117 		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2118 		//       which invokes OpImageQuerySize against the image and checks the result.
2119 		//
2120 		//       Multisample images do not support a sample count of 1, so start from 2 samples.
2121 		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2122 		{
2123 			vk::VK_SAMPLE_COUNT_2_BIT,
2124 			vk::VK_SAMPLE_COUNT_4_BIT,
2125 			vk::VK_SAMPLE_COUNT_8_BIT,
2126 			vk::VK_SAMPLE_COUNT_16_BIT,
2127 			vk::VK_SAMPLE_COUNT_32_BIT,
2128 			vk::VK_SAMPLE_COUNT_64_BIT
2129 		};
2130 
2131 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2132 		{
2133 			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2134 
2135 			if ((properties.sampleCounts & flag) != 0)
2136 				m_iterations.push_back(flag);
2137 		}
2138 
2139 		if (m_iterations.empty())
2140 		{
2141 			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2142 			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2143 				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2144 			{
2145 				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2146 			}
2147 
2148 			DE_ASSERT(false);
2149 		}
2150 	}
2151 }
2152 
~TextureSizeMSInstance(void)2153 TextureSizeMSInstance::~TextureSizeMSInstance (void)
2154 {
2155 }
2156 
iterate(void)2157 tcu::TestStatus TextureSizeMSInstance::iterate (void)
2158 {
2159 	const tcu::IVec3 testSizes[] =
2160 	{
2161 		tcu::IVec3(1, 1, 1),
2162 		tcu::IVec3(1, 2, 1),
2163 		tcu::IVec3(1, 3, 2),
2164 		tcu::IVec3(1, 1, 6),
2165 		tcu::IVec3(32, 32, 12),
2166 		tcu::IVec3(64, 64, 64),
2167 		tcu::IVec3(100, 31, 18),
2168 		tcu::IVec3(100, 128, 32),
2169 		tcu::IVec3(128, 64, 32),
2170 	};
2171 
2172 	unsigned sampleIdx	= m_iterationCounter / DE_LENGTH_OF_ARRAY(testSizes);
2173 	unsigned dimIdx		= m_iterationCounter % DE_LENGTH_OF_ARRAY(testSizes);
2174 
2175 	if (m_iterationCounter++ <  m_iterations.size() * DE_LENGTH_OF_ARRAY(testSizes))
2176 	{
2177 		bool result = testSize(m_iterations[sampleIdx], testSizes[dimIdx]);
2178 #ifdef CTS_USES_VULKANSC
2179 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2180 #endif // CTS_USES_VULKANSC
2181 		{
2182 			if (!result)
2183 				return tcu::TestStatus::fail("Got unexpected result");
2184 		}
2185 		return tcu::TestStatus::incomplete();
2186 	}
2187 	else
2188 		return tcu::TestStatus::pass("Pass");
2189 }
2190 
testSize(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2191 bool TextureSizeMSInstance::testSize (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2192 {
2193 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2194 
2195 	// setup texture
2196 	initTexture(samples, dim);
2197 
2198 	// render
2199 	TextureQueryInstance::render();
2200 
2201 	// test
2202 	{
2203 		const tcu::TextureLevel&	result				= getResultImage();
2204 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2205 		const int					resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2206 
2207 		bool success = true;
2208 
2209 		for (int ndx = 0; ndx < resultComponents; ndx++)
2210 		{
2211 			if (output[ndx] != dim[ndx])
2212 			{
2213 				success = false;
2214 				break;
2215 			}
2216 		}
2217 
2218 		if (success)
2219 		{
2220 			// success
2221 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2222 			return true;
2223 		}
2224 		else
2225 		{
2226 			// failure
2227 			std::stringstream	resultSizeStr;
2228 			switch (resultComponents)
2229 			{
2230 				case 1:
2231 					resultSizeStr << output[0];
2232 					break;
2233 				case 2:
2234 					resultSizeStr << output.toWidth<2>();
2235 					break;
2236 				case 3:
2237 					resultSizeStr << output.toWidth<3>();
2238 					break;
2239 				default:
2240 					DE_ASSERT(false);
2241 					break;
2242 			}
2243 			log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2244 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2245 			return false;
2246 		}
2247 	}
2248 }
2249 
initTexture(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2250 void TextureSizeMSInstance::initTexture (vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2251 {
2252 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2253 	TextureBindingSp		textureBinding;
2254 
2255 	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2256 
2257 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, dim) << ", samples: " << samples << tcu::TestLog::EndMessage;
2258 
2259 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, dim, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2260 
2261 	m_textures.clear();
2262 	m_textures.push_back(textureBinding);
2263 
2264 	// update samples count
2265 	{
2266 		DE_ASSERT(m_textures.size() == 1);
2267 
2268 		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2269 
2270 		params.initialization	= TextureBinding::INIT_CLEAR;
2271 		params.samples			= samples;
2272 
2273 		m_textures[0]->setParameters(params);
2274 	}
2275 }
2276 
2277 class TextureSamplesInstance : public TextureQueryInstance
2278 {
2279 public:
2280 								TextureSamplesInstance			(Context&					context,
2281 																 const bool					isVertexCase,
2282 																 const TextureSpec&			textureSpec);
2283 	virtual						~TextureSamplesInstance			(void);
2284 
2285 	virtual tcu::TestStatus		iterate							(void);
2286 
2287 private:
2288 	void						initTexture						(void);
2289 
2290 	int										m_iterationCounter;
2291 	vector<vk::VkSampleCountFlagBits>		m_iterations;
2292 };
2293 
TextureSamplesInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2294 TextureSamplesInstance::TextureSamplesInstance (Context&				context,
2295 												const bool				isVertexCase,
2296 												const TextureSpec&		textureSpec)
2297 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2298 	, m_iterationCounter		(0)
2299 {
2300 	m_renderSize = tcu::UVec2(1, 1);
2301 
2302 	// determine available sample counts
2303 	{
2304 		const vk::VkFormat						format			= vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2305 		const vk::VkImageType					imageType		= getVkImageType(m_textureSpec.type);
2306 		vk::VkImageFormatProperties				properties;
2307 
2308 		if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
2309 																					format,
2310 																					imageType,
2311 																					vk::VK_IMAGE_TILING_OPTIMAL,
2312 																					vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2313 																					(vk::VkImageCreateFlags)0,
2314 																					&properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2315 			TCU_THROW(NotSupportedError, "Format not supported");
2316 
2317 		// NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2318 		//       which invokes OpImageQuerySamples against the image and checks the result.
2319 		//
2320 		//       Now, in the SPIR-V spec for the very operation we have the following language:
2321 		//
2322 		//       OpImageQuerySamples
2323 		//       Query the number of samples available per texel fetch in a multisample image.
2324 		//       Result Type must be a scalar integer type.
2325 		//       The result is the number of samples.
2326 		//       Image must be an object whose type is OpTypeImage.
2327 		//       Its Dim operand must be one of 2D and **MS of 1(multisampled).
2328 		//
2329 		//       "MS of 1" implies the image must not be single-sample, meaning we must exclude
2330 		//       VK_SAMPLE_COUNT_1_BIT in the sampleFlags array below, and may have to skip further testing.
2331 		static const vk::VkSampleCountFlagBits	sampleFlags[]	=
2332 		{
2333 			vk::VK_SAMPLE_COUNT_2_BIT,
2334 			vk::VK_SAMPLE_COUNT_4_BIT,
2335 			vk::VK_SAMPLE_COUNT_8_BIT,
2336 			vk::VK_SAMPLE_COUNT_16_BIT,
2337 			vk::VK_SAMPLE_COUNT_32_BIT,
2338 			vk::VK_SAMPLE_COUNT_64_BIT
2339 		};
2340 
2341 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2342 		{
2343 			const vk::VkSampleCountFlagBits&	flag			= sampleFlags[samplesNdx];
2344 
2345 			if ((properties.sampleCounts & flag) != 0)
2346 				m_iterations.push_back(flag);
2347 		}
2348 
2349 		if (m_iterations.empty())
2350 		{
2351 			// Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2352 			if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2353 				tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2354 			{
2355 				TCU_THROW(NotSupportedError, "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2356 			}
2357 
2358 			DE_ASSERT(false);
2359 		}
2360 	}
2361 
2362 	// setup texture
2363 	initTexture();
2364 }
2365 
~TextureSamplesInstance(void)2366 TextureSamplesInstance::~TextureSamplesInstance (void)
2367 {
2368 }
2369 
iterate(void)2370 tcu::TestStatus TextureSamplesInstance::iterate (void)
2371 {
2372 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2373 
2374 	// update samples count
2375 	{
2376 		DE_ASSERT(m_textures.size() == 1);
2377 
2378 		TextureBinding::Parameters	params	= m_textures[0]->getParameters();
2379 
2380 		params.initialization	= TextureBinding::INIT_CLEAR;
2381 		params.samples			= m_iterations[m_iterationCounter];
2382 		log << tcu::TestLog::Message << "Expected samples: " << m_iterations[m_iterationCounter] << tcu::TestLog::EndMessage;
2383 
2384 		m_textures[0]->setParameters(params);
2385 	}
2386 
2387 	// render
2388 	TextureQueryInstance::render();
2389 
2390 	// test
2391 	{
2392 		const tcu::TextureLevel&	result				= getResultImage();
2393 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2394 
2395 #ifdef CTS_USES_VULKANSC
2396 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2397 #endif // CTS_USES_VULKANSC
2398 		{
2399 			if (output.x() == (int)m_iterations[m_iterationCounter])
2400 			{
2401 				// success
2402 				log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2403 			}
2404 			else
2405 			{
2406 				// failure
2407 				log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2408 				log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2409 				return tcu::TestStatus::fail("Got unexpected result");
2410 			}
2411 		}
2412 
2413 		m_iterationCounter++;
2414 		if (m_iterationCounter == (int)m_iterations.size())
2415 			return tcu::TestStatus::pass("Pass");
2416 		else
2417 			return tcu::TestStatus::incomplete();
2418 	}
2419 }
2420 
initTexture(void)2421 void TextureSamplesInstance::initTexture (void)
2422 {
2423 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2424 	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2425 	TextureBindingSp		textureBinding;
2426 
2427 	DE_ASSERT(m_textures.empty());
2428 	DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
2429 
2430 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2431 
2432 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2433 
2434 	m_textures.push_back(textureBinding);
2435 }
2436 
2437 class TextureQueryLevelsInstance : public TextureQueryInstance
2438 {
2439 public:
2440 								TextureQueryLevelsInstance		(Context&					context,
2441 																 const bool					isVertexCase,
2442 																 const TextureSpec&			textureSpec);
2443 	virtual						~TextureQueryLevelsInstance		(void);
2444 
2445 	virtual tcu::TestStatus		iterate							(void);
2446 
2447 private:
2448 	struct TestSize
2449 	{
2450 		tcu::IVec3	textureSize;
2451 		int			lodBase;
2452 	};
2453 
2454 	void						initTexture						(void);
2455 	bool						testTextureLevels				(void);
2456 
2457 	TestSize					m_testSize;
2458 	int							m_levels;
2459 	int							m_iterationCounter;
2460 };
2461 
TextureQueryLevelsInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2462 TextureQueryLevelsInstance::TextureQueryLevelsInstance (Context&				context,
2463 														const bool				isVertexCase,
2464 														const TextureSpec&		textureSpec)
2465 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2466 	, m_testSize				()
2467 	, m_levels					(0)
2468 	, m_iterationCounter		(0)
2469 {
2470 	deMemset(&m_testSize, 0, sizeof(TestSize));
2471 
2472 	m_renderSize								= tcu::UVec2(1, 1);
2473 
2474 #ifdef CTS_USES_VULKANSC
2475 	const VkDevice			vkDevice			= getDevice();
2476 	const DeviceInterface&	vk					= getDeviceInterface();
2477 	const deUint32			queueFamilyIndex	= getUniversalQueueFamilyIndex();
2478 	m_externalCommandPool						= de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
2479 #endif // CTS_USES_VULKANSC
2480 }
2481 
~TextureQueryLevelsInstance(void)2482 TextureQueryLevelsInstance::~TextureQueryLevelsInstance (void)
2483 {
2484 }
2485 
iterate(void)2486 tcu::TestStatus TextureQueryLevelsInstance::iterate (void)
2487 {
2488 	const TestSize testSizes[] =
2489 	{
2490 		{ tcu::IVec3(1, 2, 1),			0	},
2491 		{ tcu::IVec3(1, 2, 1),			1	},
2492 
2493 		{ tcu::IVec3(1, 3, 2),			0	},
2494 		{ tcu::IVec3(1, 3, 2),			1	},
2495 
2496 		{ tcu::IVec3(100, 31, 18),		0	},
2497 		{ tcu::IVec3(100, 31, 18),		1	},
2498 		{ tcu::IVec3(100, 31, 18),		2	},
2499 		{ tcu::IVec3(100, 31, 18),		3	},
2500 		{ tcu::IVec3(100, 31, 18),		4	},
2501 		{ tcu::IVec3(100, 31, 18),		5	},
2502 		{ tcu::IVec3(100, 31, 18),		6	},
2503 
2504 		{ tcu::IVec3(100, 128, 32),		0	},
2505 		{ tcu::IVec3(100, 128, 32),		1	},
2506 		{ tcu::IVec3(100, 128, 32),		2	},
2507 		{ tcu::IVec3(100, 128, 32),		3	},
2508 		{ tcu::IVec3(100, 128, 32),		4	},
2509 		{ tcu::IVec3(100, 128, 32),		5	},
2510 		{ tcu::IVec3(100, 128, 32),		6	},
2511 		{ tcu::IVec3(100, 128, 32),		7	},
2512 
2513 		// pow 2
2514 		{ tcu::IVec3(128, 64, 32),		0	},
2515 		{ tcu::IVec3(128, 64, 32),		1	},
2516 		{ tcu::IVec3(128, 64, 32),		2	},
2517 		{ tcu::IVec3(128, 64, 32),		3	},
2518 		{ tcu::IVec3(128, 64, 32),		4	},
2519 		{ tcu::IVec3(128, 64, 32),		5	},
2520 		{ tcu::IVec3(128, 64, 32),		6	},
2521 		{ tcu::IVec3(128, 64, 32),		7	},
2522 
2523 		// w == h
2524 		{ tcu::IVec3(1, 1, 1),			0	},
2525 		{ tcu::IVec3(64, 64, 64),		0	},
2526 		{ tcu::IVec3(64, 64, 64),		1	},
2527 		{ tcu::IVec3(64, 64, 64),		2	},
2528 		{ tcu::IVec3(64, 64, 64),		3	},
2529 		{ tcu::IVec3(64, 64, 64),		4	},
2530 		{ tcu::IVec3(64, 64, 64),		5	},
2531 		{ tcu::IVec3(64, 64, 64),		6	},
2532 
2533 		// w == h and d % 6 == 0 (for cube array)
2534 		{ tcu::IVec3(1, 1, 6),			0	},
2535 		{ tcu::IVec3(32, 32, 12),		0	},
2536 		{ tcu::IVec3(32, 32, 12),		1	},
2537 		{ tcu::IVec3(32, 32, 12),		2	},
2538 		{ tcu::IVec3(32, 32, 12),		3	},
2539 		{ tcu::IVec3(32, 32, 12),		4	},
2540 		{ tcu::IVec3(32, 32, 12),		5	},
2541 	};
2542 	const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
2543 
2544 	m_iterationCounter++;
2545 
2546 	if (m_iterationCounter == lastIterationIndex)
2547 		return tcu::TestStatus::pass("Pass");
2548 	else
2549 	{
2550 		// set current test size
2551 		m_testSize = testSizes[m_iterationCounter - 1];
2552 
2553 		bool result = testTextureLevels();
2554 #ifdef CTS_USES_VULKANSC
2555 		if (m_context.getTestContext().getCommandLine().isSubProcess())
2556 #endif // CTS_USES_VULKANSC
2557 		{
2558 			if (!result)
2559 				return tcu::TestStatus::fail("Got unexpected result");
2560 		}
2561 		return tcu::TestStatus::incomplete();
2562 	}
2563 }
2564 
testTextureLevels(void)2565 bool TextureQueryLevelsInstance::testTextureLevels (void)
2566 {
2567 	tcu::TestLog&			log				= m_context.getTestContext().getLog();
2568 	bool					success			= true;
2569 
2570 	// skip incompatible cases
2571 	if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
2572 		return true;
2573 
2574 	// setup texture
2575 	initTexture();
2576 
2577 	// calculate accessible levels
2578 	{
2579 		const int	mipLevels	= deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
2580 
2581 		m_levels = mipLevels - m_testSize.lodBase;
2582 		DE_ASSERT(m_levels > 0);
2583 
2584 		log << tcu::TestLog::Message << "Expected levels: " << m_levels << tcu::TestLog::EndMessage;
2585 	}
2586 
2587 	// render
2588 	TextureQueryInstance::render();
2589 
2590 	// test
2591 	{
2592 		const tcu::TextureLevel&	result				= getResultImage();
2593 		tcu::IVec4					output				= result.getAccess().getPixelInt(0, 0);
2594 
2595 		if (output.x() == m_levels)
2596 		{
2597 			// success
2598 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2599 		}
2600 		else
2601 		{
2602 			// failure
2603 			log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
2604 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2605 			success = false;
2606 		}
2607 	}
2608 
2609 	log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2610 
2611 	return success;
2612 }
2613 
initTexture(void)2614 void TextureQueryLevelsInstance::initTexture (void)
2615 {
2616 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2617 	int						numLevels			= m_testSize.lodBase + 1;
2618 	TextureBindingSp		textureBinding;
2619 
2620 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
2621 	log << tcu::TestLog::Message << "Base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
2622 
2623 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels, m_testSize.lodBase, m_textureSpec.sampler);
2624 
2625 	m_textures.clear();
2626 	m_textures.push_back(textureBinding);
2627 }
2628 
getQueryLodFuncTextCoordComps(TextureType type)2629 static int getQueryLodFuncTextCoordComps (TextureType type)
2630 {
2631 	switch (type)
2632 	{
2633 		case TEXTURETYPE_1D:
2634 		case TEXTURETYPE_1D_ARRAY:
2635 			return 1;
2636 
2637 		case TEXTURETYPE_2D:
2638 		case TEXTURETYPE_2D_ARRAY:
2639 			return 2;
2640 
2641 		case TEXTURETYPE_3D:
2642 		case TEXTURETYPE_CUBE_MAP:
2643 		case TEXTURETYPE_CUBE_ARRAY:
2644 			return 3;
2645 
2646 		default:
2647 			DE_ASSERT(false);
2648 			return 0;
2649 	}
2650 }
2651 
2652 class TextureQueryLodInstance : public TextureQueryInstance
2653 {
2654 public:
2655 								TextureQueryLodInstance			(Context&					context,
2656 																 const bool					isVertexCase,
2657 																 const TextureSpec&			textureSpec,
2658 																 const TestMode				mode);
2659 	virtual						~TextureQueryLodInstance		(void);
2660 
2661 	virtual tcu::TestStatus		iterate							(void);
2662 
2663 protected:
2664 	virtual void				setupDefaultInputs				(void);
2665 
2666 private:
2667 	void						initTexture						(void);
2668 	float						computeLevelFromLod				(float computedLod) const;
2669 	vector<float>				computeQuadTexCoord				(void) const;
2670 
2671 	const TestMode				m_mode;
2672 	tcu::Vec4					m_minCoord;
2673 	tcu::Vec4					m_maxCoord;
2674 	tcu::Vec2					m_lodBounds;
2675 	tcu::Vec2					m_levelBounds;
2676 };
2677 
TextureQueryLodInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec,const TestMode mode)2678 TextureQueryLodInstance::TextureQueryLodInstance (Context&					context,
2679 												  const bool				isVertexCase,
2680 												  const TextureSpec&		textureSpec,
2681 												  const TestMode			mode)
2682 	: TextureQueryInstance		(context, isVertexCase, textureSpec)
2683 	, m_mode					(mode)
2684 	, m_minCoord				()
2685 	, m_maxCoord				()
2686 	, m_lodBounds				()
2687 	, m_levelBounds				()
2688 {
2689 	// setup texture
2690 	initTexture();
2691 
2692 	if (m_mode == QLODTM_DEFAULT)
2693 	{
2694 		const tcu::UVec2&	viewportSize	= getViewportSize();
2695 		const float			lodEps			= (1.0f / float(1u << m_context.getDeviceProperties().limits.mipmapPrecisionBits)) + 0.008f;
2696 
2697 		// init min/max coords and calculate lod and accessed level
2698 		switch (m_textureSpec.type)
2699 		{
2700 			case TEXTURETYPE_1D:
2701 			case TEXTURETYPE_1D_ARRAY:
2702 			{
2703 				m_minCoord = Vec4(-0.2f, 0.0f, 0.0f, 0.0f);
2704 				m_maxCoord = Vec4( 1.5f, 0.0f, 0.0f, 0.0f);
2705 
2706 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2707 
2708 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f)-lodEps;
2709 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f)+lodEps;
2710 				break;
2711 			}
2712 
2713 			case TEXTURETYPE_2D:
2714 			case TEXTURETYPE_2D_ARRAY:
2715 			{
2716 				m_minCoord = Vec4(-0.2f, -0.4f, 0.0f, 0.0f);
2717 				m_maxCoord = Vec4( 1.5f,  2.3f, 0.0f, 0.0f);
2718 
2719 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width	/ (float)viewportSize[0];
2720 				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height	/ (float)viewportSize[1];
2721 
2722 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2723 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2724 				break;
2725 			}
2726 
2727 			case TEXTURETYPE_CUBE_MAP:
2728 			case TEXTURETYPE_CUBE_ARRAY:
2729 			{
2730 				m_minCoord = Vec4(-1.0f, -1.0f, 1.01f, 0.0f);
2731 				m_maxCoord = Vec4( 1.0f,  1.0f, 1.01f, 0.0f);
2732 
2733 				// Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
2734 				DE_ASSERT(de::abs(m_minCoord[2] - m_maxCoord[2]) < 0.005);
2735 				DE_ASSERT(de::abs(m_minCoord[0]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[0]) < de::abs(m_minCoord[2]));
2736 				DE_ASSERT(de::abs(m_minCoord[1]) < de::abs(m_minCoord[2]) && de::abs(m_maxCoord[1]) < de::abs(m_minCoord[2]));
2737 
2738 				tcu::CubeFaceFloatCoords	c00		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_minCoord[1], m_minCoord[2]));
2739 				tcu::CubeFaceFloatCoords	c10		= tcu::getCubeFaceCoords(Vec3(m_maxCoord[0], m_minCoord[1], m_minCoord[2]));
2740 				tcu::CubeFaceFloatCoords	c01		= tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_maxCoord[1], m_minCoord[2]));
2741 				float						dudx	= (c10.s - c00.s)*(float)m_textureSpec.width	/ (float)viewportSize[0];
2742 				float						dvdy	= (c01.t - c00.t)*(float)m_textureSpec.height	/ (float)viewportSize[1];
2743 
2744 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy)-lodEps;
2745 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy)+lodEps;
2746 				break;
2747 			}
2748 
2749 			case TEXTURETYPE_3D:
2750 			{
2751 				m_minCoord = Vec4(-1.2f, -1.4f, 0.1f, 0.0f);
2752 				m_maxCoord = Vec4( 1.5f,  2.3f, 2.3f, 0.0f);
2753 
2754 				const float	dudx	= (m_maxCoord[0]-m_minCoord[0])*(float)m_textureSpec.width		/ (float)viewportSize[0];
2755 				const float	dvdy	= (m_maxCoord[1]-m_minCoord[1])*(float)m_textureSpec.height		/ (float)viewportSize[1];
2756 				const float	dwdx	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[0];
2757 				const float	dwdy	= (m_maxCoord[2]-m_minCoord[2])*0.5f*(float)m_textureSpec.depth	/ (float)viewportSize[1];
2758 
2759 				m_lodBounds[0]		= computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)-lodEps;
2760 				m_lodBounds[1]		= computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy)+lodEps;
2761 				break;
2762 			}
2763 
2764 			default:
2765 				DE_ASSERT(false);
2766 				break;
2767 		}
2768 
2769 		m_levelBounds[0] = computeLevelFromLod(m_lodBounds[0]);
2770 		m_levelBounds[1] = computeLevelFromLod(m_lodBounds[1]);
2771 
2772 		return;
2773 	}
2774 
2775 	if (m_mode == QLODTM_ZERO_UV_WIDTH)
2776 	{
2777 		// setup same texture coordinates that will result in pmax
2778 		// beeing 0 and as a result lambda being -inf; on most
2779 		// implementations lambda is computed as fixed-point, so
2780 		// infinities can't be returned, instead -22 or less
2781 		// should be returned
2782 
2783 		m_minCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2784 		m_maxCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
2785 
2786 		m_lodBounds[0]		= -std::numeric_limits<float>::infinity();
2787 		m_lodBounds[1]		= -22.0f;
2788 		m_levelBounds[0]	= 0.0f;
2789 		m_levelBounds[1]	= 0.0f;
2790 
2791 		return;
2792 	}
2793 
2794 	DE_ASSERT(false);
2795 }
2796 
~TextureQueryLodInstance(void)2797 TextureQueryLodInstance::~TextureQueryLodInstance (void)
2798 {
2799 }
2800 
iterate(void)2801 tcu::TestStatus TextureQueryLodInstance::iterate (void)
2802 {
2803 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
2804 
2805 	log << tcu::TestLog::Message << "Expected: level in range " << m_levelBounds << ", lod in range " << m_lodBounds << tcu::TestLog::EndMessage;
2806 
2807 	// render
2808 	TextureQueryInstance::render();
2809 
2810 	// test
2811 	{
2812 		const tcu::TextureLevel&	result		= getResultImage();
2813 		const tcu::Vec4				output		= result.getAccess().getPixel(0, 0);
2814 		const float					resLevel	= output.x();
2815 		const float					resLod		= output.y();
2816 
2817 		if (de::inRange(resLevel, m_levelBounds[0], m_levelBounds[1]) && de::inRange(resLod, m_lodBounds[0], m_lodBounds[1]))
2818 		{
2819 			// success
2820 			log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2821 			return tcu::TestStatus::pass("Pass");
2822 		}
2823 		else
2824 		{
2825 			// failure
2826 			log << tcu::TestLog::Message << "Result: level: " << resLevel << ", lod: " << resLod << tcu::TestLog::EndMessage;
2827 			log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2828 			return tcu::TestStatus::fail("Got unexpected result");
2829 		}
2830 	}
2831 }
2832 
setupDefaultInputs(void)2833 void TextureQueryLodInstance::setupDefaultInputs (void)
2834 {
2835 	TextureQueryInstance::setupDefaultInputs();
2836 
2837 	const deUint32			numVertices			= 4;
2838 	const vector<float>		texCoord			= computeQuadTexCoord();
2839 	const int				texCoordComps		= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2840 	const vk::VkFormat		coordFormats[]		=
2841 	{
2842 		vk::VK_FORMAT_R32_SFLOAT,
2843 		vk::VK_FORMAT_R32G32_SFLOAT,
2844 		vk::VK_FORMAT_R32G32B32_SFLOAT
2845 	};
2846 
2847 	DE_ASSERT(de::inRange(texCoordComps, 1, 3));
2848 	DE_ASSERT((int)texCoord.size() == texCoordComps * 4);
2849 
2850 	addAttribute(1u, coordFormats[texCoordComps - 1], (deUint32)(texCoordComps * sizeof(float)), numVertices, texCoord.data());
2851 }
2852 
initTexture(void)2853 void TextureQueryLodInstance::initTexture (void)
2854 {
2855 	tcu::TestLog&			log					= m_context.getTestContext().getLog();
2856 	tcu::IVec3				textureSize			(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
2857 	TextureBindingSp		textureBinding;
2858 
2859 	DE_ASSERT(m_textures.empty());
2860 
2861 	log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize) << tcu::TestLog::EndMessage;
2862 
2863 	textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels, 0 /* lodBase */, m_textureSpec.sampler);
2864 
2865 	m_textures.push_back(textureBinding);
2866 }
2867 
computeLevelFromLod(float computedLod) const2868 float TextureQueryLodInstance::computeLevelFromLod (float computedLod) const
2869 {
2870 	const int	maxAccessibleLevel	= m_textureSpec.numLevels - 1;
2871 
2872 	// Clamp the computed LOD to the range of accessible levels.
2873 	computedLod = deFloatClamp(computedLod, 0.0f, (float)maxAccessibleLevel);
2874 
2875 	// Return a value according to the min filter.
2876 	switch (m_textureSpec.sampler.minFilter)
2877 	{
2878 		case tcu::Sampler::LINEAR:
2879 		case tcu::Sampler::NEAREST:
2880 			return 0.0f;
2881 
2882 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
2883 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
2884 			return deFloatClamp(deFloatCeil(computedLod + 0.5f) - 1.0f, 0.0f, (float)maxAccessibleLevel);
2885 
2886 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
2887 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
2888 			return computedLod;
2889 
2890 		default:
2891 			DE_ASSERT(false);
2892 			return 0.0f;
2893 	}
2894 }
2895 
computeQuadTexCoord(void) const2896 vector<float> TextureQueryLodInstance::computeQuadTexCoord (void) const
2897 {
2898 	vector<float>	res;
2899 	tcu::Mat4		coordTransMat;
2900 
2901 	{
2902 		Vec4 s = m_maxCoord - m_minCoord;
2903 		Vec4 b = m_minCoord;
2904 
2905 		float baseCoordTrans[] =
2906 		{
2907 			s.x(),		0.0f,		0.f,	b.x(),
2908 			0.f,		s.y(),		0.f,	b.y(),
2909 			s.z()/2.f,	-s.z()/2.f,	0.f,	s.z()/2.f + b.z(),
2910 			-s.w()/2.f,	s.w()/2.f,	0.f,	s.w()/2.f + b.w()
2911 		};
2912 
2913 		coordTransMat = tcu::Mat4(baseCoordTrans);
2914 	}
2915 
2916 	const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
2917 	Vec4			coords[4]		=
2918 	{
2919 		coordTransMat * tcu::Vec4(0, 0, 0, 1),
2920 		coordTransMat * tcu::Vec4(0, 1, 0, 1),
2921 		coordTransMat * tcu::Vec4(1, 0, 0, 1),
2922 		coordTransMat * tcu::Vec4(1, 1, 0, 1)
2923 	};
2924 
2925 	res.resize(4 * texCoordComps);
2926 
2927 	for (int ndx = 0; ndx < 4; ndx++)
2928 		deMemcpy(&res[ndx * texCoordComps], coords[ndx].getPtr(), texCoordComps * sizeof(float));
2929 
2930 	return res;
2931 }
2932 
2933 class TextureQueryCase : public ShaderRenderCase
2934 {
2935 public:
2936 								TextureQueryCase				(tcu::TestContext&			testCtx,
2937 																 const std::string&			name,
2938 																 const std::string&			desc,
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 
2949 protected:
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 
TextureQueryCase(tcu::TestContext & testCtx,const std::string & name,const std::string & desc,const std::string & samplerType,const TextureSpec & texture,bool isVertexCase,QueryFunction function,TestMode mode)2958 TextureQueryCase::TextureQueryCase (tcu::TestContext&		testCtx,
2959 									const std::string&		name,
2960 									const std::string&		desc,
2961 									const std::string&		samplerType,
2962 									const TextureSpec&		texture,
2963 									bool					isVertexCase,
2964 									QueryFunction			function,
2965 									TestMode				mode)
2966 	: ShaderRenderCase	(testCtx, name, desc, isVertexCase, (ShaderEvaluator*)DE_NULL, DE_NULL, DE_NULL)
2967 	, m_samplerTypeStr	(samplerType)
2968 	, m_textureSpec		(texture)
2969 	, m_function		(function)
2970 	, m_mode			(mode)
2971 {
2972 	initShaderSources();
2973 }
2974 
~TextureQueryCase(void)2975 TextureQueryCase::~TextureQueryCase (void)
2976 {
2977 }
2978 
createInstance(Context & context) const2979 TestInstance* TextureQueryCase::createInstance (Context& context) const
2980 {
2981 	switch (m_function)
2982 	{
2983 		case QUERYFUNCTION_TEXTURESIZE:				return new TextureSizeInstance(context, m_isVertexCase, m_textureSpec);
2984 		case QUERYFUNCTION_TEXTURESIZEMS:			return new TextureSizeMSInstance(context, m_isVertexCase, m_textureSpec);
2985 		case QUERYFUNCTION_TEXTUREQUERYLOD:			return new TextureQueryLodInstance(context, m_isVertexCase, m_textureSpec, m_mode);
2986 		case QUERYFUNCTION_TEXTUREQUERYLEVELS:		return new TextureQueryLevelsInstance(context, m_isVertexCase, m_textureSpec);
2987 		case QUERYFUNCTION_TEXTURESAMPLES:			return new TextureSamplesInstance(context, m_isVertexCase, m_textureSpec);
2988 		default:
2989 			DE_ASSERT(false);
2990 			return DE_NULL;
2991 	}
2992 }
2993 
checkSupport(Context & context) const2994 void TextureQueryCase::checkSupport(Context& context) const
2995 {
2996 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
2997 }
2998 
initShaderSources(void)2999 void TextureQueryCase::initShaderSources (void)
3000 {
3001 	std::ostringstream		vert;
3002 	std::ostringstream		frag;
3003 	std::ostringstream&		op			= m_isVertexCase ? vert : frag;
3004 
3005 	DE_ASSERT(m_function != QUERYFUNCTION_TEXTUREQUERYLOD || !m_isVertexCase);
3006 
3007 	vert << "#version 450 core\n"
3008 		 << "layout(location = 0) in highp vec4 a_position;\n";
3009 
3010 	frag << "#version 450 core\n"
3011 		 << "layout(location = 0) out mediump vec4 o_color;\n";
3012 
3013 	if (m_isVertexCase)
3014 	{
3015 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3016 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3017 	}
3018 
3019 	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3020 	{
3021 		const int		texCoordComps	= getQueryLodFuncTextCoordComps(m_textureSpec.type);
3022 		const char*		coordTypeName	= glu::getDataTypeName(glu::getDataTypeFloatVec(texCoordComps));
3023 
3024 		vert << "layout (location = 1) in highp " << coordTypeName << " a_texCoord;\n";
3025 		vert << "layout (location = 0) out highp " << coordTypeName << " v_texCoord;\n";
3026 		frag << "layout (location = 0) in highp " << coordTypeName << " v_texCoord;\n";
3027 	}
3028 
3029 	// uniforms
3030 	op << "layout(set = 0, binding = 0) uniform highp " << m_samplerTypeStr << " u_sampler;\n";
3031 	if (m_function == QUERYFUNCTION_TEXTURESIZE)
3032 		op << "layout(set = 0, binding = 1) uniform buf0 { highp int u_lod; };\n";
3033 
3034 	vert << "out gl_PerVertex {\n"
3035 		 << "\tvec4 gl_Position;\n"
3036 		 << "};\n";
3037 
3038 	vert << "\nvoid main()\n{\n"
3039 		 << "\tgl_Position = a_position;\n";
3040 	frag << "\nvoid main()\n{\n";
3041 
3042 	if (m_isVertexCase)
3043 		vert << "\tv_color = ";
3044 	else
3045 		frag << "\to_color = ";
3046 
3047 	// op
3048 	{
3049 		op << "vec4(";
3050 
3051 		switch (m_function)
3052 		{
3053 			case QUERYFUNCTION_TEXTURESIZE:
3054 			{
3055 				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3056 
3057 				op << "textureSize(u_sampler, u_lod)";
3058 				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3059 					op << ", 0.0";
3060 				op << ", 1.0";
3061 
3062 				break;
3063 			}
3064 
3065 			case QUERYFUNCTION_TEXTURESIZEMS:
3066 			{
3067 				const int		resultComponents	= glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3068 
3069 				op << "textureSize(u_sampler)";
3070 				for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3071 					op << ", 0.0";
3072 				op << ", 1.0";
3073 
3074 				break;
3075 			}
3076 
3077 			case QUERYFUNCTION_TEXTUREQUERYLOD:
3078 				op << "textureQueryLod(u_sampler, v_texCoord), 0.0, 1.0";
3079 				break;
3080 
3081 			case QUERYFUNCTION_TEXTUREQUERYLEVELS:
3082 				op << "textureQueryLevels(u_sampler), 0.0, 0.0, 1.0";
3083 				break;
3084 
3085 			case QUERYFUNCTION_TEXTURESAMPLES:
3086 				op << "textureSamples(u_sampler), 0.0, 0.0, 1.0";
3087 				break;
3088 
3089 			default:
3090 				DE_ASSERT(false);
3091 				break;
3092 		}
3093 
3094 		op << ");\n";
3095 	}
3096 
3097 	if (m_isVertexCase)
3098 		frag << "\to_color = v_color;\n";
3099 
3100 	if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3101 		vert << "\tv_texCoord = a_texCoord;\n";
3102 
3103 	vert << "}\n";
3104 	frag << "}\n";
3105 
3106 	m_vertShaderSource = vert.str();
3107 	m_fragShaderSource = frag.str();
3108 }
3109 
3110 class ShaderTextureFunctionTests : public tcu::TestCaseGroup
3111 {
3112 public:
3113 									ShaderTextureFunctionTests		(tcu::TestContext& context);
3114 	virtual							~ShaderTextureFunctionTests		(void);
3115 	virtual void					init							(void);
3116 
3117 private:
3118 									ShaderTextureFunctionTests		(const ShaderTextureFunctionTests&);		// not allowed!
3119 	ShaderTextureFunctionTests&		operator=						(const ShaderTextureFunctionTests&);		// not allowed!
3120 };
3121 
ShaderTextureFunctionTests(tcu::TestContext & context)3122 ShaderTextureFunctionTests::ShaderTextureFunctionTests (tcu::TestContext& context)
3123 	: TestCaseGroup(context, "texture_functions", "Texture Access Function Tests")
3124 {
3125 }
3126 
~ShaderTextureFunctionTests(void)3127 ShaderTextureFunctionTests::~ShaderTextureFunctionTests (void)
3128 {
3129 }
3130 
3131 enum CaseFlags
3132 {
3133 	VERTEX		= (1<<0),
3134 	FRAGMENT	= (1<<1),
3135 	BOTH		= VERTEX|FRAGMENT
3136 };
3137 
3138 struct TexFuncCaseSpec
3139 {
3140 	const char*			name;
3141 	TextureLookupSpec	lookupSpec;
3142 	TextureSpec			texSpec;
3143 	TexEvalFunc			evalFunc;
3144 	deUint32			flags;
3145 };
3146 
3147 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3148 	{ #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 }
3149 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC, FLAGS) \
3150 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, false, 0.0f), TEXSPEC, EVALFUNC, FLAGS }
3151 #define CLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3152 	{ #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 }
3153 #define GRADCLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, EVALFUNC, FLAGS) \
3154 	{ #NAME, TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, true, LODCLAMP), TEXSPEC, EVALFUNC, FLAGS }
3155 
3156 #ifndef CTS_USES_VULKANSC
3157 
3158 class SparseShaderTextureFunctionInstance : public ShaderTextureFunctionInstance
3159 {
3160 public:
3161 				SparseShaderTextureFunctionInstance		(Context&					context,
3162 														const bool					isVertexCase,
3163 														const ShaderEvaluator&		evaluator,
3164 														const UniformSetup&			uniformSetup,
3165 														const TextureLookupSpec&	lookupSpec,
3166 														const TextureSpec&			textureSpec,
3167 														const TexLookupParams&		lookupParams,
3168 														const ImageBackingMode		imageBackingMode = IMAGE_BACKING_MODE_SPARSE);
3169 	virtual		~SparseShaderTextureFunctionInstance	(void);
3170 };
3171 
SparseShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)3172 SparseShaderTextureFunctionInstance::SparseShaderTextureFunctionInstance (Context&					context,
3173 																		 const bool					isVertexCase,
3174 																		 const ShaderEvaluator&		evaluator,
3175 																		 const UniformSetup&		uniformSetup,
3176 																		 const TextureLookupSpec&	lookupSpec,
3177 																		 const TextureSpec&			textureSpec,
3178 																		 const TexLookupParams&		lookupParams,
3179 																		 const ImageBackingMode		imageBackingMode)
3180 	: ShaderTextureFunctionInstance (context, isVertexCase, evaluator, uniformSetup, lookupSpec, textureSpec, lookupParams, imageBackingMode)
3181 {
3182 	if (lookupSpec.useClamp)
3183 	{
3184 		const vk::VkPhysicalDeviceFeatures&	deviceFeatures	= context.getDeviceFeatures();
3185 
3186 		if (!deviceFeatures.shaderResourceMinLod)
3187 			TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
3188 	}
3189 }
3190 
~SparseShaderTextureFunctionInstance(void)3191 SparseShaderTextureFunctionInstance::~SparseShaderTextureFunctionInstance (void)
3192 {
3193 }
3194 
3195 class SparseShaderTextureFunctionCase : public ShaderTextureFunctionCase
3196 {
3197 public:
3198 							SparseShaderTextureFunctionCase		(tcu::TestContext&			testCtx,
3199 																const std::string&			name,
3200 																const std::string&			desc,
3201 																const TextureLookupSpec&	lookup,
3202 																const TextureSpec&			texture,
3203 																TexEvalFunc					evalFunc,
3204 																bool						isVertexCase);
3205 
3206 	virtual					~SparseShaderTextureFunctionCase	(void);
3207 
3208 	virtual	TestInstance*	createInstance						(Context& context) const;
3209 	virtual	void			checkSupport						(Context& context) const;
3210 protected:
3211 	void					initShaderSources					(void);
3212 };
3213 
SparseShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const std::string & desc,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)3214 SparseShaderTextureFunctionCase::SparseShaderTextureFunctionCase (tcu::TestContext&				testCtx,
3215 																  const std::string&			name,
3216 																  const std::string&			desc,
3217 																  const TextureLookupSpec&		lookup,
3218 																  const TextureSpec&			texture,
3219 																  TexEvalFunc					evalFunc,
3220 																  bool							isVertexCase)
3221 	: ShaderTextureFunctionCase		(testCtx, name, desc, lookup, texture, evalFunc, isVertexCase)
3222 {
3223 	initShaderSources();
3224 }
3225 
initShaderSources(void)3226 void SparseShaderTextureFunctionCase::initShaderSources (void)
3227 {
3228 	const Function				function			= m_lookupSpec.function;
3229 	const bool					isVtxCase			= m_isVertexCase;
3230 	const bool					isProj				= functionHasProj(function);
3231 	const bool					isGrad				= functionHasGrad(function);
3232 	const bool					isShadow			= m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
3233 	const bool					is2DProj4			= !isShadow && m_textureSpec.type == TEXTURETYPE_2D && (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD);
3234 	const bool					isIntCoord			= function == FUNCTION_TEXELFETCH;
3235 	const bool					hasLodBias			= functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
3236 	const int					texCoordComps		= m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
3237 	const int					extraCoordComps		= (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
3238 	const glu::DataType			coordType			= glu::getDataTypeFloatVec(texCoordComps+extraCoordComps);
3239 	const glu::Precision		coordPrec			= glu::PRECISION_HIGHP;
3240 	const char*					coordTypeName		= glu::getDataTypeName(coordType);
3241 	const char*					coordPrecName		= glu::getPrecisionName(coordPrec);
3242 	const tcu::TextureFormat	texFmt				= glu::mapGLInternalFormat(m_textureSpec.format);
3243 	glu::DataType				samplerType			= glu::TYPE_LAST;
3244 	const glu::DataType			gradType			= (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 : glu::TYPE_FLOAT_VEC2;
3245 	const char*					gradTypeName		= glu::getDataTypeName(gradType);
3246 	const char*					baseFuncName		= DE_NULL;
3247 
3248 	DE_ASSERT(!isGrad || !hasLodBias);
3249 
3250 	switch (m_textureSpec.type)
3251 	{
3252 		case TEXTURETYPE_2D:		samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW		: glu::getSampler2DType(texFmt);		break;
3253 		case TEXTURETYPE_CUBE_MAP:	samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW		: glu::getSamplerCubeType(texFmt);		break;
3254 		case TEXTURETYPE_2D_ARRAY:	samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW	: glu::getSampler2DArrayType(texFmt);	break;
3255 		case TEXTURETYPE_3D:		DE_ASSERT(!isShadow); samplerType = glu::getSampler3DType(texFmt);									break;
3256 		default:
3257 			DE_ASSERT(DE_FALSE);
3258 	}
3259 
3260 	// Not supported cases
3261 	switch (m_lookupSpec.function)
3262 	{
3263 		case FUNCTION_TEXTURE:			baseFuncName = "sparseTexture";			break;
3264 		case FUNCTION_TEXTURELOD:		baseFuncName = "sparseTextureLod";		break;
3265 		case FUNCTION_TEXTUREGRAD:		baseFuncName = "sparseTextureGrad";		break;
3266 		case FUNCTION_TEXELFETCH:		baseFuncName = "sparseTexelFetch";		break;
3267 		default:
3268 			DE_ASSERT(DE_FALSE);
3269 	}
3270 
3271 	std::ostringstream	vert;
3272 	std::ostringstream	frag;
3273 	std::ostringstream&	op		= isVtxCase ? vert : frag;
3274 
3275 	vert << "#version 450\n"
3276 		 << "#extension GL_ARB_sparse_texture2 : require\n"
3277 		 << "layout(location = 0) in highp vec4 a_position;\n"
3278 		 << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
3279 
3280 	if (isGrad)
3281 	{
3282 		vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
3283 		vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
3284 	}
3285 	else if (hasLodBias)
3286 		vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
3287 
3288 	frag << "#version 450\n"
3289 		 << "#extension GL_ARB_sparse_texture2 : require\n";
3290 
3291 	if (m_lookupSpec.useClamp)
3292 		frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
3293 
3294 	frag << "layout(location = 0) out mediump vec4 o_color;\n";
3295 
3296 	if (isVtxCase)
3297 	{
3298 		vert << "layout(location = 0) out mediump vec4 v_color;\n";
3299 		frag << "layout(location = 0) in mediump vec4 v_color;\n";
3300 	}
3301 	else
3302 	{
3303 		vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3304 		frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
3305 
3306 		if (isGrad)
3307 		{
3308 			vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3309 			vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3310 			frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
3311 			frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
3312 		}
3313 		else if (hasLodBias)
3314 		{
3315 			vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
3316 			frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
3317 		}
3318 	}
3319 
3320 	// Uniforms
3321 	op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
3322 	   << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
3323 	   << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
3324 
3325 	vert << "out gl_PerVertex {\n"
3326 		 << "	vec4 gl_Position;\n"
3327 		 << "};\n";
3328 	vert << "\nvoid main()\n{\n"
3329 		 << "\tgl_Position = a_position;\n";
3330 	frag << "\nvoid main()\n{\n";
3331 
3332 	// Op.
3333 	{
3334 		// Texel declaration
3335 		if (isShadow)
3336 			op << "\tfloat texel;\n";
3337 		else
3338 			op << "\tvec4 texel;\n";
3339 
3340 		const char*	const texCoord	= isVtxCase ? "a_in0" : "v_texCoord";
3341 		const char* const gradX		= isVtxCase ? "a_in1" : "v_gradX";
3342 		const char* const gradY		= isVtxCase ? "a_in2" : "v_gradY";
3343 		const char*	const lodBias	= isVtxCase ? "a_in1" : "v_lodBias";
3344 
3345 		op << "\tint success = " << baseFuncName;
3346 
3347 		if (m_lookupSpec.useOffset)
3348 			op << "Offset";
3349 
3350 		if (m_lookupSpec.useClamp)
3351 			op << "Clamp";
3352 
3353 		op << "ARB(u_sampler, ";
3354 
3355 		if (isIntCoord)
3356 			op << "ivec" << (texCoordComps+extraCoordComps) << "(";
3357 
3358 		op << texCoord;
3359 
3360 		if (isIntCoord)
3361 			op << ")";
3362 
3363 		if (isGrad)
3364 			op << ", " << gradX << ", " << gradY;
3365 
3366 		if (functionHasLod(function))
3367 		{
3368 			if (isIntCoord)
3369 				op << ", int(" << lodBias << ")";
3370 			else
3371 				op << ", " << lodBias;
3372 		}
3373 
3374 		if (m_lookupSpec.useOffset)
3375 		{
3376 			int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
3377 
3378 			op << ", ivec" << offsetComps << "(";
3379 			for (int ndx = 0; ndx < offsetComps; ndx++)
3380 			{
3381 				if (ndx != 0)
3382 					op << ", ";
3383 				op << m_lookupSpec.offset[ndx];
3384 			}
3385 			op << ")";
3386 		}
3387 
3388 		if (m_lookupSpec.useClamp)
3389 			op << ", float(" << m_lookupSpec.lodClamp << ")";
3390 
3391 		op << ", texel";
3392 
3393 		if (m_lookupSpec.useBias)
3394 			op << ", " << lodBias;
3395 
3396 		op << ");\n";
3397 
3398 		// Check sparse validity, and handle each case
3399 		op << "\tif (sparseTexelsResidentARB(success))\n";
3400 
3401 		if (isVtxCase)
3402 			vert << "\t\tv_color = ";
3403 		else
3404 			frag << "\t\to_color = ";
3405 
3406 		if (isShadow)
3407 			op << "vec4(texel, 0.0, 0.0, 1.0);\n";
3408 		else
3409 			op << "vec4(texel * u_scale + u_bias);\n";
3410 
3411 		op << "\telse\n";
3412 
3413 		// This color differs from the used colors
3414 		if (isVtxCase)
3415 			vert << "\t\tv_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3416 		else
3417 			frag << "\t\to_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
3418 	}
3419 
3420 	if (isVtxCase)
3421 		frag << "\to_color = v_color;\n";
3422 	else
3423 	{
3424 		vert << "\tv_texCoord = a_in0;\n";
3425 
3426 		if (isGrad)
3427 		{
3428 			vert << "\tv_gradX = a_in1;\n";
3429 			vert << "\tv_gradY = a_in2;\n";
3430 		}
3431 		else if (hasLodBias)
3432 			vert << "\tv_lodBias = a_in1;\n";
3433 	}
3434 
3435 	vert << "}\n";
3436 	frag << "}\n";
3437 
3438 	m_vertShaderSource = vert.str();
3439 	m_fragShaderSource = frag.str();
3440 }
3441 
~SparseShaderTextureFunctionCase()3442 SparseShaderTextureFunctionCase::~SparseShaderTextureFunctionCase ()
3443 {
3444 }
3445 
createInstance(Context & context) const3446 TestInstance* SparseShaderTextureFunctionCase::createInstance (Context& context) const
3447 {
3448 	DE_ASSERT(m_evaluator != DE_NULL);
3449 	DE_ASSERT(m_uniformSetup != DE_NULL);
3450 	return new SparseShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec, m_textureSpec, m_lookupParams);
3451 }
3452 
checkSupport(Context & context) const3453 void SparseShaderTextureFunctionCase::checkSupport(Context& context) const
3454 {
3455 	checkMutableComparisonSamplersSupport(context, m_textureSpec);
3456 }
3457 
3458 #endif // CTS_USES_VULKANSC
3459 
createCaseGroup(tcu::TestCaseGroup * parent,const char * groupName,const char * groupDesc,const TexFuncCaseSpec * cases,int numCases)3460 static void createCaseGroup (tcu::TestCaseGroup* parent, const char* groupName, const char* groupDesc, const TexFuncCaseSpec* cases, int numCases)
3461 {
3462 	de::MovePtr<tcu::TestCaseGroup>	group	(new tcu::TestCaseGroup(parent->getTestContext(), groupName, groupDesc));
3463 
3464 	for (int ndx = 0; ndx < numCases; ndx++)
3465 	{
3466 		std::string	name			= cases[ndx].name;
3467 #ifndef CTS_USES_VULKANSC
3468 		bool		sparseSupported	= !functionHasProj(cases[ndx].lookupSpec.function)		&&
3469 									  TEXTURETYPE_1D			!= cases[ndx].texSpec.type	&&
3470 									  TEXTURETYPE_1D_ARRAY		!= cases[ndx].texSpec.type	&&
3471 									  TEXTURETYPE_CUBE_ARRAY	!= cases[ndx].texSpec.type;
3472 #endif // CTS_USES_VULKANSC
3473 
3474 		if (cases[ndx].flags & VERTEX)
3475 		{
3476 #ifndef CTS_USES_VULKANSC
3477 			if (sparseSupported)
3478 				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_vertex"),   "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3479 #endif // CTS_USES_VULKANSC
3480 
3481 			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_vertex"),   "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true ));
3482 		}
3483 
3484 		if (cases[ndx].flags & FRAGMENT)
3485 		{
3486 #ifndef CTS_USES_VULKANSC
3487 			if (sparseSupported)
3488 				group->addChild(new SparseShaderTextureFunctionCase(parent->getTestContext(), ("sparse_" + name + "_fragment"), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3489 #endif // CTS_USES_VULKANSC
3490 
3491 			group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_fragment"), "", cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
3492 		}
3493 	}
3494 
3495 	parent->addChild(group.release());
3496 }
3497 
init(void)3498 void ShaderTextureFunctionTests::init (void)
3499 {
3500 	// Samplers
3501 	static const tcu::Sampler	samplerNearestNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3502 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3503 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3504 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3505 	static const tcu::Sampler	samplerLinearNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3506 														 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
3507 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3508 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3509 	static const tcu::Sampler	samplerNearestMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3510 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3511 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3512 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3513 	static const tcu::Sampler	samplerLinearMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3514 														 tcu::Sampler::LINEAR_MIPMAP_NEAREST, tcu::Sampler::LINEAR,
3515 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3516 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3517 
3518 	static const tcu::Sampler	samplerShadowNoMipmap	(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3519 														 tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
3520 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3521 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3522 	static const tcu::Sampler	samplerShadowMipmap		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3523 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3524 														 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
3525 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3526 
3527 	static const tcu::Sampler	samplerTexelFetch		(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
3528 														 tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST,
3529 														 00.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
3530 														 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
3531 
3532 	// Default textures.
3533 	//												Type					Format					W		H		D	L	Sampler
3534 	static const TextureSpec tex2DFixed				(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	1,	samplerLinearNoMipmap);
3535 	static const TextureSpec tex2DFloat				(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	1,	samplerLinearNoMipmap);
3536 	static const TextureSpec tex2DInt				(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	1,	samplerNearestNoMipmap);
3537 	static const TextureSpec tex2DUint				(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	1,	samplerNearestNoMipmap);
3538 	static const TextureSpec tex2DMipmapFixed		(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerLinearMipmap);
3539 	static const TextureSpec tex2DMipmapFloat		(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerLinearMipmap);
3540 	static const TextureSpec tex2DMipmapInt			(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerNearestMipmap);
3541 	static const TextureSpec tex2DMipmapUint		(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerNearestMipmap);
3542 
3543 	static const TextureSpec tex2DShadow			(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3544 	static const TextureSpec tex2DMipmapShadow		(TEXTURETYPE_2D,		GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3545 
3546 	static const TextureSpec tex2DTexelFetchFixed	(TEXTURETYPE_2D,		GL_RGBA8,				256,	256,	1,	9,	samplerTexelFetch);
3547 	static const TextureSpec tex2DTexelFetchFloat	(TEXTURETYPE_2D,		GL_RGBA16F,				256,	256,	1,	9,	samplerTexelFetch);
3548 	static const TextureSpec tex2DTexelFetchInt		(TEXTURETYPE_2D,		GL_RGBA8I,				256,	256,	1,	9,	samplerTexelFetch);
3549 	static const TextureSpec tex2DTexelFetchUint	(TEXTURETYPE_2D,		GL_RGBA8UI,				256,	256,	1,	9,	samplerTexelFetch);
3550 
3551 	static const TextureSpec texCubeFixed			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	1,	samplerLinearNoMipmap);
3552 	static const TextureSpec texCubeFloat			(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	256,	256,	1,	1,	samplerLinearNoMipmap);
3553 	static const TextureSpec texCubeInt				(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	1,	samplerNearestNoMipmap);
3554 	static const TextureSpec texCubeUint			(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	1,	samplerNearestNoMipmap);
3555 	static const TextureSpec texCubeMipmapFixed		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8,	256,	256,	1,	9,	samplerLinearMipmap);
3556 	static const TextureSpec texCubeMipmapFloat		(TEXTURETYPE_CUBE_MAP,	GL_RGBA16F,	128,	128,	1,	8,	samplerLinearMipmap);
3557 	static const TextureSpec texCubeMipmapInt		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8I,	256,	256,	1,	9,	samplerNearestMipmap);
3558 	static const TextureSpec texCubeMipmapUint		(TEXTURETYPE_CUBE_MAP,	GL_RGBA8UI,	256,	256,	1,	9,	samplerNearestMipmap);
3559 
3560 	static const TextureSpec texCubeShadow			(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	1,	samplerShadowNoMipmap);
3561 	static const TextureSpec texCubeMipmapShadow	(TEXTURETYPE_CUBE_MAP,	GL_DEPTH_COMPONENT16,	256,	256,	1,	9,	samplerShadowMipmap);
3562 
3563 	static const TextureSpec tex2DArrayFixed		(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	1,	samplerLinearNoMipmap);
3564 	static const TextureSpec tex2DArrayFloat		(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	1,	samplerLinearNoMipmap);
3565 	static const TextureSpec tex2DArrayInt			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	1,	samplerNearestNoMipmap);
3566 	static const TextureSpec tex2DArrayUint			(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	1,	samplerNearestNoMipmap);
3567 	static const TextureSpec tex2DArrayMipmapFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerLinearMipmap);
3568 	static const TextureSpec tex2DArrayMipmapFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerLinearMipmap);
3569 	static const TextureSpec tex2DArrayMipmapInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerNearestMipmap);
3570 	static const TextureSpec tex2DArrayMipmapUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerNearestMipmap);
3571 
3572 	static const TextureSpec tex2DArrayShadow		(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	1,	samplerShadowNoMipmap);
3573 	static const TextureSpec tex2DArrayMipmapShadow	(TEXTURETYPE_2D_ARRAY,	GL_DEPTH_COMPONENT16,	128,	128,	4,	8,	samplerShadowMipmap);
3574 
3575 	static const TextureSpec tex2DArrayTexelFetchFixed	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8,	128,	128,	4,	8,	samplerTexelFetch);
3576 	static const TextureSpec tex2DArrayTexelFetchFloat	(TEXTURETYPE_2D_ARRAY,	GL_RGBA16F,	128,	128,	4,	8,	samplerTexelFetch);
3577 	static const TextureSpec tex2DArrayTexelFetchInt	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8I,	128,	128,	4,	8,	samplerTexelFetch);
3578 	static const TextureSpec tex2DArrayTexelFetchUint	(TEXTURETYPE_2D_ARRAY,	GL_RGBA8UI,	128,	128,	4,	8,	samplerTexelFetch);
3579 
3580 	static const TextureSpec tex3DFixed				(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	1,	samplerLinearNoMipmap);
3581 	static const TextureSpec tex3DFloat				(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	1,	samplerLinearNoMipmap);
3582 	static const TextureSpec tex3DInt				(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	1,	samplerNearestNoMipmap);
3583 	static const TextureSpec tex3DUint				(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	1,	samplerNearestNoMipmap);
3584 	static const TextureSpec tex3DMipmapFixed		(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerLinearMipmap);
3585 	static const TextureSpec tex3DMipmapFloat		(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerLinearMipmap);
3586 	static const TextureSpec tex3DMipmapInt			(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerNearestMipmap);
3587 	static const TextureSpec tex3DMipmapUint		(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerNearestMipmap);
3588 
3589 	static const TextureSpec tex3DTexelFetchFixed	(TEXTURETYPE_3D,		GL_RGBA8,	64,		32,		32,	7,	samplerTexelFetch);
3590 	static const TextureSpec tex3DTexelFetchFloat	(TEXTURETYPE_3D,		GL_RGBA16F,	64,		32,		32,	7,	samplerTexelFetch);
3591 	static const TextureSpec tex3DTexelFetchInt		(TEXTURETYPE_3D,		GL_RGBA8I,	64,		32,		32,	7,	samplerTexelFetch);
3592 	static const TextureSpec tex3DTexelFetchUint	(TEXTURETYPE_3D,		GL_RGBA8UI,	64,		32,		32,	7,	samplerTexelFetch);
3593 
3594 	static const TextureSpec tex1DFixed				(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	1,	samplerLinearNoMipmap);
3595 	static const TextureSpec tex1DFloat				(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	1,	samplerLinearNoMipmap);
3596 	static const TextureSpec tex1DInt				(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	1,	samplerNearestNoMipmap);
3597 	static const TextureSpec tex1DUint				(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	1,	samplerNearestNoMipmap);
3598 	static const TextureSpec tex1DMipmapFixed		(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerLinearMipmap);
3599 	static const TextureSpec tex1DMipmapFloat		(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerLinearMipmap);
3600 	static const TextureSpec tex1DMipmapInt			(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerNearestMipmap);
3601 	static const TextureSpec tex1DMipmapUint		(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerNearestMipmap);
3602 
3603 	static const TextureSpec tex1DShadow			(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	1,	samplerShadowNoMipmap);
3604 	static const TextureSpec tex1DMipmapShadow		(TEXTURETYPE_1D,		GL_DEPTH_COMPONENT16,	256,	1,	1,	9,	samplerShadowMipmap);
3605 
3606 	static const TextureSpec tex1DTexelFetchFixed	(TEXTURETYPE_1D,		GL_RGBA8,				256,	1,	1,	9,	samplerTexelFetch);
3607 	static const TextureSpec tex1DTexelFetchFloat	(TEXTURETYPE_1D,		GL_RGBA16F,				256,	1,	1,	9,	samplerTexelFetch);
3608 	static const TextureSpec tex1DTexelFetchInt		(TEXTURETYPE_1D,		GL_RGBA8I,				256,	1,	1,	9,	samplerTexelFetch);
3609 	static const TextureSpec tex1DTexelFetchUint	(TEXTURETYPE_1D,		GL_RGBA8UI,				256,	1,	1,	9,	samplerTexelFetch);
3610 
3611 	static const TextureSpec tex1DArrayFixed		(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	1,	samplerLinearNoMipmap);
3612 	static const TextureSpec tex1DArrayFloat		(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	1,	samplerLinearNoMipmap);
3613 	static const TextureSpec tex1DArrayInt			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	1,	samplerNearestNoMipmap);
3614 	static const TextureSpec tex1DArrayUint			(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	1,	samplerNearestNoMipmap);
3615 	static const TextureSpec tex1DArrayMipmapFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerLinearMipmap);
3616 	static const TextureSpec tex1DArrayMipmapFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerLinearMipmap);
3617 	static const TextureSpec tex1DArrayMipmapInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerNearestMipmap);
3618 	static const TextureSpec tex1DArrayMipmapUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerNearestMipmap);
3619 
3620 	static const TextureSpec tex1DArrayShadow		(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	1,	samplerShadowNoMipmap);
3621 	static const TextureSpec tex1DArrayMipmapShadow	(TEXTURETYPE_1D_ARRAY,	GL_DEPTH_COMPONENT16,	256,	1,	4,	9,	samplerShadowMipmap);
3622 
3623 	static const TextureSpec tex1DArrayTexelFetchFixed	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8,	256,	1,	4,	9,	samplerTexelFetch);
3624 	static const TextureSpec tex1DArrayTexelFetchFloat	(TEXTURETYPE_1D_ARRAY,	GL_RGBA16F,	256,	1,	4,	9,	samplerTexelFetch);
3625 	static const TextureSpec tex1DArrayTexelFetchInt	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8I,	256,	1,	4,	9,	samplerTexelFetch);
3626 	static const TextureSpec tex1DArrayTexelFetchUint	(TEXTURETYPE_1D_ARRAY,	GL_RGBA8UI,	256,	1,	4,	9,	samplerTexelFetch);
3627 
3628 	static const TextureSpec texCubeArrayFixed			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	1,	samplerLinearNoMipmap);
3629 	static const TextureSpec texCubeArrayFloat			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	1,	samplerLinearNoMipmap);
3630 	static const TextureSpec texCubeArrayInt			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	1,	samplerNearestNoMipmap);
3631 	static const TextureSpec texCubeArrayUint			(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	1,	samplerNearestNoMipmap);
3632 	static const TextureSpec texCubeArrayMipmapFixed	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8,	64,		64,		12,	7,	samplerLinearMipmap);
3633 	static const TextureSpec texCubeArrayMipmapFloat	(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA16F,	64,		64,		12,	7,	samplerLinearMipmap);
3634 	static const TextureSpec texCubeArrayMipmapInt		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8I,	64,		64,		12,	7,	samplerNearestMipmap);
3635 	static const TextureSpec texCubeArrayMipmapUint		(TEXTURETYPE_CUBE_ARRAY,	GL_RGBA8UI,	64,		64,		12,	7,	samplerNearestMipmap);
3636 
3637 	static const TextureSpec texCubeArrayShadow			(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	1,	samplerShadowNoMipmap);
3638 	static const TextureSpec texCubeArrayMipmapShadow	(TEXTURETYPE_CUBE_ARRAY,	GL_DEPTH_COMPONENT16,	64,		64,		12,	7,	samplerShadowMipmap);
3639 
3640 	// texture() cases
3641 	static const TexFuncCaseSpec textureCases[] =
3642 	{
3643 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
3644 		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),
3645 		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),
3646 		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),
3647 		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),
3648 		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),
3649 		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),
3650 		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),
3651 		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),
3652 
3653 		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),
3654 		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),
3655 		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),
3656 		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),
3657 
3658 		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),
3659 		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),
3660 		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),
3661 		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),
3662 		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),
3663 		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),
3664 		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),
3665 		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),
3666 
3667 		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),
3668 		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),
3669 		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),
3670 		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),
3671 
3672 		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),
3673 		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),
3674 		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),
3675 		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),
3676 		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),
3677 		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),
3678 		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),
3679 		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),
3680 
3681 		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),
3682 		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),
3683 		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),
3684 		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),
3685 
3686 		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),
3687 		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),
3688 		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),
3689 		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),
3690 		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),
3691 		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),
3692 		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),
3693 		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),
3694 
3695 		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),
3696 		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),
3697 		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),
3698 		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),
3699 
3700 		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),
3701 		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),
3702 		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),
3703 		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),
3704 		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),
3705 		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),
3706 		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),
3707 		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),
3708 
3709 		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),
3710 		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),
3711 		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),
3712 		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),
3713 
3714 		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),
3715 		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),
3716 		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),
3717 		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),
3718 		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),
3719 		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),
3720 		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),
3721 		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),
3722 
3723 		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),
3724 		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),
3725 		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),
3726 		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),
3727 
3728 		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),
3729 		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),
3730 		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),
3731 		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),
3732 		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),
3733 		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),
3734 		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),
3735 		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),
3736 
3737 		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),
3738 		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),
3739 		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),
3740 		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),
3741 
3742 		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),
3743 		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),
3744 		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),
3745 
3746 		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),
3747 		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),
3748 		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),
3749 
3750 		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),
3751 		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),
3752 
3753 		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),
3754 		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),
3755 		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),
3756 
3757 		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),
3758 		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),
3759 		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),
3760 
3761 		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),
3762 	};
3763 	createCaseGroup(this, "texture", "texture() Tests", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
3764 
3765 	// textureClampARB() cases
3766 	static const TexFuncCaseSpec textureClampARBCases[] =
3767 	{
3768 		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		LodClamp	Format					EvalFunc							Flags
3769 		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),
3770 		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),
3771 		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),
3772 		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),
3773 
3774 		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),
3775 		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),
3776 		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),
3777 		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),
3778 
3779 		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),
3780 		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),
3781 		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),
3782 		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),
3783 
3784 		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),
3785 		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),
3786 		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),
3787 		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),
3788 
3789 		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),
3790 		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),
3791 		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),
3792 		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),
3793 
3794 		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),
3795 		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),
3796 		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),
3797 		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),
3798 
3799 		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),
3800 		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),
3801 		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),
3802 		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),
3803 
3804 		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),
3805 		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),
3806 		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),
3807 		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),
3808 	};
3809 	createCaseGroup(this, "textureclamp", "textureClampARB() Tests", textureClampARBCases, DE_LENGTH_OF_ARRAY(textureClampARBCases));
3810 
3811 	// textureOffset() cases
3812 	// \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
3813 	static const TexFuncCaseSpec textureOffsetCases[] =
3814 	{
3815 		//		  Name							Function			MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
3816 		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),
3817 		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),
3818 		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),
3819 		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),
3820 		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),
3821 		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),
3822 		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),
3823 		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),
3824 
3825 		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),
3826 		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),
3827 		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),
3828 		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),
3829 
3830 		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),
3831 		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),
3832 		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),
3833 		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),
3834 		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),
3835 		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),
3836 		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),
3837 		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),
3838 
3839 		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),
3840 		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),
3841 		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),
3842 		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),
3843 
3844 		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),
3845 		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),
3846 		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),
3847 		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),
3848 		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),
3849 		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),
3850 		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),
3851 		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),
3852 
3853 		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),
3854 		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),
3855 		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),
3856 		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),
3857 
3858 		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),
3859 		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),
3860 		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),
3861 		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),
3862 		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),
3863 		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),
3864 		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),
3865 		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),
3866 
3867 		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),
3868 		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),
3869 		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),
3870 		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),
3871 
3872 		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),
3873 		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),
3874 		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),
3875 		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),
3876 		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),
3877 		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),
3878 		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),
3879 		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),
3880 
3881 		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),
3882 		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),
3883 		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),
3884 		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),
3885 
3886 		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),
3887 		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),
3888 		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),
3889 		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),
3890 		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),
3891 		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),
3892 		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),
3893 		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),
3894 		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),
3895 		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),
3896 		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),
3897 	};
3898 	createCaseGroup(this, "textureoffset", "textureOffset() Tests", textureOffsetCases, DE_LENGTH_OF_ARRAY(textureOffsetCases));
3899 
3900 	// textureOffsetClampARB() cases
3901 	static const TexFuncCaseSpec textureOffsetClampARBCases[] =
3902 	{
3903 		//			    Name							Function			MinCoord						MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				LodClamp	Format					EvalFunc									Flags
3904 		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),
3905 		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),
3906 		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),
3907 		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),
3908 
3909 		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),
3910 		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),
3911 		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),
3912 		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),
3913 
3914 		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),
3915 		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),
3916 		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),
3917 		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),
3918 
3919 		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),
3920 		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),
3921 		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),
3922 		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),
3923 
3924 		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),
3925 		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),
3926 		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),
3927 		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),
3928 
3929 		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),
3930 		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),
3931 		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),
3932 	};
3933 	createCaseGroup(this, "textureoffsetclamp", "textureOffsetClampARB() Tests", textureOffsetClampARBCases, DE_LENGTH_OF_ARRAY(textureOffsetClampARBCases));
3934 
3935 	// textureProj() cases
3936 	// \note Currently uses constant divider!
3937 	static const TexFuncCaseSpec textureProjCases[] =
3938 	{
3939 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
3940 		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),
3941 		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),
3942 		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),
3943 		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),
3944 		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),
3945 		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),
3946 		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),
3947 		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),
3948 
3949 		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),
3950 		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),
3951 		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),
3952 		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),
3953 
3954 		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),
3955 		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),
3956 		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),
3957 		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),
3958 		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),
3959 		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),
3960 		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),
3961 		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),
3962 
3963 		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),
3964 		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),
3965 		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),
3966 		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),
3967 
3968 		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),
3969 		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),
3970 		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),
3971 		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),
3972 		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),
3973 		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),
3974 		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),
3975 		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),
3976 
3977 		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),
3978 		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),
3979 		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),
3980 		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),
3981 
3982 		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),
3983 		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),
3984 		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),
3985 		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),
3986 		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),
3987 		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),
3988 		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),
3989 		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),
3990 
3991 		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),
3992 		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),
3993 		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),
3994 		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),
3995 
3996 		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),
3997 		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),
3998 		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),
3999 		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),
4000 		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),
4001 		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),
4002 		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),
4003 		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),
4004 
4005 		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),
4006 		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),
4007 		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),
4008 		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),
4009 
4010 		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),
4011 		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),
4012 		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),
4013 		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),
4014 		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),
4015 		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),
4016 	};
4017 	createCaseGroup(this, "textureproj", "textureProj() Tests", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
4018 
4019 	// textureProjOffset() cases
4020 	// \note Currently uses constant divider!
4021 	static const TexFuncCaseSpec textureProjOffsetCases[] =
4022 	{
4023 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4024 		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),
4025 		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),
4026 		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),
4027 		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),
4028 		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),
4029 		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),
4030 		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),
4031 		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),
4032 
4033 		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),
4034 		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),
4035 		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),
4036 		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),
4037 
4038 		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),
4039 		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),
4040 		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),
4041 		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),
4042 		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),
4043 		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),
4044 		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),
4045 		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),
4046 
4047 		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),
4048 		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),
4049 		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),
4050 		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),
4051 
4052 		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),
4053 		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),
4054 		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),
4055 		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),
4056 		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),
4057 		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),
4058 		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),
4059 		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),
4060 
4061 		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),
4062 		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),
4063 		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),
4064 		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),
4065 
4066 		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),
4067 		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),
4068 		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),
4069 		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),
4070 		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),
4071 		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),
4072 		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),
4073 		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),
4074 
4075 		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),
4076 		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),
4077 		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),
4078 		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),
4079 
4080 		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),
4081 		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),
4082 		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),
4083 		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),
4084 		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),
4085 		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),
4086 		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),
4087 		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),
4088 
4089 		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),
4090 		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),
4091 		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),
4092 		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),
4093 
4094 		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),
4095 		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),
4096 		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),
4097 		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),
4098 		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),
4099 		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),
4100 	};
4101 	createCaseGroup(this, "textureprojoffset", "textureOffsetProj() Tests", textureProjOffsetCases, DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
4102 
4103 	// textureLod() cases
4104 	static const TexFuncCaseSpec textureLodCases[] =
4105 	{
4106 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc				Flags
4107 		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),
4108 		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),
4109 		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),
4110 		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),
4111 
4112 		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),
4113 		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),
4114 		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),
4115 		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),
4116 
4117 		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),
4118 		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),
4119 		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),
4120 		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),
4121 
4122 		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),
4123 		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),
4124 		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),
4125 		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),
4126 
4127 		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),
4128 		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),
4129 		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),
4130 		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),
4131 
4132 		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),
4133 		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),
4134 		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),
4135 		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),
4136 
4137 		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),
4138 		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),
4139 		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),
4140 		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),
4141 
4142 		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),
4143 		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),
4144 		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),
4145 	};
4146 	createCaseGroup(this, "texturelod", "textureLod() Tests", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
4147 
4148 	// textureLodOffset() cases
4149 	static const TexFuncCaseSpec textureLodOffsetCases[] =
4150 	{
4151 		//		  Name							Function				MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc						Flags
4152 		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),
4153 		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),
4154 		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),
4155 		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),
4156 
4157 		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),
4158 		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),
4159 		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),
4160 		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),
4161 
4162 		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),
4163 		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),
4164 		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),
4165 		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),
4166 
4167 		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),
4168 		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),
4169 		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),
4170 		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),
4171 
4172 		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),
4173 		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),
4174 		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),
4175 		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),
4176 
4177 		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),
4178 		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),
4179 		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),
4180 	};
4181 	createCaseGroup(this, "texturelodoffset", "textureLodOffset() Tests", textureLodOffsetCases, DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
4182 
4183 	// textureProjLod() cases
4184 	static const TexFuncCaseSpec textureProjLodCases[] =
4185 	{
4186 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset		Format					EvalFunc					Flags
4187 		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),
4188 		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),
4189 		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),
4190 		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),
4191 
4192 		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),
4193 		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),
4194 		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),
4195 		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),
4196 
4197 		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),
4198 		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),
4199 		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),
4200 		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),
4201 
4202 		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),
4203 		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),
4204 		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),
4205 		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),
4206 
4207 		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),
4208 		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),
4209 		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),
4210 		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),
4211 
4212 		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),
4213 		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),
4214 	};
4215 	createCaseGroup(this, "textureprojlod", "textureProjLod() Tests", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
4216 
4217 	// textureProjLodOffset() cases
4218 	static const TexFuncCaseSpec textureProjLodOffsetCases[] =
4219 	{
4220 		//		  Name							Function					MinCoord							MaxCoord							Bias?	MinLod	MaxLod	Offset?	Offset				Format					EvalFunc								Flags
4221 		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),
4222 		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),
4223 		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),
4224 		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),
4225 
4226 		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),
4227 		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),
4228 		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),
4229 		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),
4230 
4231 		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),
4232 		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),
4233 		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),
4234 		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),
4235 
4236 		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),
4237 		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),
4238 		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),
4239 		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),
4240 
4241 		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),
4242 		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),
4243 		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),
4244 		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),
4245 
4246 		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),
4247 		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),
4248 	};
4249 	createCaseGroup(this, "textureprojlodoffset", "textureProjLodOffset() Tests", textureProjLodOffsetCases, DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
4250 
4251 	// textureGrad() cases
4252 	// \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
4253 	static const TexFuncCaseSpec textureGradCases[] =
4254 	{
4255 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc				Flags
4256 		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),
4257 		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),
4258 		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),
4259 		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),
4260 
4261 		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),
4262 		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),
4263 		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),
4264 		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),
4265 
4266 		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),
4267 		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),
4268 		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),
4269 		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),
4270 
4271 		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),
4272 		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),
4273 		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),
4274 		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),
4275 		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),
4276 		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),
4277 
4278 		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),
4279 		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),
4280 		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),
4281 		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),
4282 
4283 		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),
4284 		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),
4285 		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),
4286 		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),
4287 
4288 		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),
4289 		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),
4290 		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),
4291 		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),
4292 
4293 		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),
4294 		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),
4295 		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),
4296 		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),
4297 		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),
4298 		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),
4299 		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),
4300 	};
4301 	createCaseGroup(this, "texturegrad", "textureGrad() Tests", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
4302 
4303 	// textureGradClampARB() cases
4304 	static const TexFuncCaseSpec textureGradClampCases[] =
4305 	{
4306 		//		  Name									Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		LodClamp	Format					EvalFunc						Flags
4307 		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),
4308 		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),
4309 		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),
4310 		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),
4311 
4312 		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),
4313 		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),
4314 		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),
4315 		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),
4316 
4317 		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),
4318 		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),
4319 		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),
4320 		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),
4321 
4322 		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),
4323 		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),
4324 		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),
4325 		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),
4326 
4327 		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),
4328 		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),
4329 		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),
4330 		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),
4331 
4332 		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),
4333 		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),
4334 		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),
4335 		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),
4336 
4337 		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),
4338 		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),
4339 		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),
4340 		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),
4341 
4342 		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),
4343 		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),
4344 		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),
4345 		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),
4346 		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),
4347 	};
4348 	createCaseGroup(this, "texturegradclamp", "textureGradClampARB() Tests", textureGradClampCases, DE_LENGTH_OF_ARRAY(textureGradClampCases));
4349 
4350 	// textureGradOffset() cases
4351 	static const TexFuncCaseSpec textureGradOffsetCases[] =
4352 	{
4353 		//		  Name							Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4354 		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),
4355 		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),
4356 		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),
4357 		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),
4358 
4359 		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),
4360 		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),
4361 		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),
4362 		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),
4363 
4364 		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),
4365 		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),
4366 		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),
4367 		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),
4368 		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),
4369 		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),
4370 
4371 		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),
4372 		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),
4373 		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),
4374 		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),
4375 
4376 		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),
4377 		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),
4378 		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),
4379 		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),
4380 
4381 		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),
4382 		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),
4383 		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),
4384 		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),
4385 		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),
4386 		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),
4387 		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),
4388 		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),
4389 	};
4390 	createCaseGroup(this, "texturegradoffset", "textureGradOffset() Tests", textureGradOffsetCases, DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
4391 
4392 	// textureGradOffsetClampARB() cases
4393 	static const TexFuncCaseSpec textureGradOffsetClampCases[] =
4394 	{
4395 		//		  Name								Function				MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				LodClamp	Format				EvalFunc									Flags
4396 		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),
4397 		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),
4398 		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),
4399 		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),
4400 
4401 		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),
4402 		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),
4403 		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),
4404 		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),
4405 
4406 		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),
4407 		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),
4408 		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),
4409 		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),
4410 
4411 		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),
4412 		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),
4413 		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),
4414 		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),
4415 
4416 		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),
4417 		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),
4418 		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),
4419 		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),
4420 
4421 		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),
4422 		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),
4423 		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),
4424 		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),
4425 	};
4426 	createCaseGroup(this, "texturegradoffsetclamp", "textureGradOffsetClampARB() Tests", textureGradOffsetClampCases, DE_LENGTH_OF_ARRAY(textureGradOffsetClampCases));
4427 
4428 
4429 	// textureProjGrad() cases
4430 	static const TexFuncCaseSpec textureProjGradCases[] =
4431 	{
4432 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset		Format					EvalFunc					Flags
4433 		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),
4434 		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),
4435 		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),
4436 		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),
4437 
4438 		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),
4439 		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),
4440 		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),
4441 		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),
4442 
4443 		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),
4444 		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),
4445 		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),
4446 		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),
4447 		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),
4448 		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),
4449 
4450 		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),
4451 		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),
4452 		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),
4453 		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),
4454 
4455 		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),
4456 		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),
4457 		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),
4458 		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),
4459 
4460 		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),
4461 		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),
4462 		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),
4463 		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),
4464 	};
4465 	createCaseGroup(this, "textureprojgrad", "textureProjGrad() Tests", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
4466 
4467 	// textureProjGradOffset() cases
4468 	static const TexFuncCaseSpec textureProjGradOffsetCases[] =
4469 	{
4470 		//		  Name							Function					MinCoord							MaxCoord							MinDx						MaxDx						MinDy						MaxDy						Offset?	Offset				Format					EvalFunc							Flags
4471 		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),
4472 		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),
4473 		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),
4474 		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),
4475 
4476 		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),
4477 		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),
4478 		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),
4479 		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),
4480 
4481 		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),
4482 		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),
4483 		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),
4484 		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),
4485 		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),
4486 		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),
4487 
4488 		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),
4489 		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),
4490 		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),
4491 		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),
4492 
4493 		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),
4494 		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),
4495 		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),
4496 		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),
4497 
4498 		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),
4499 		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),
4500 		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),
4501 		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),
4502 	};
4503 	createCaseGroup(this, "textureprojgradoffset", "textureProjGradOffset() Tests", textureProjGradOffsetCases, DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
4504 
4505 	// texelFetch() cases
4506 	// \note Level is constant across quad
4507 	static const TexFuncCaseSpec texelFetchCases[] =
4508 	{
4509 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4510 		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),
4511 		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),
4512 		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),
4513 		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),
4514 
4515 		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),
4516 		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),
4517 		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),
4518 		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),
4519 
4520 		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),
4521 		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),
4522 		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),
4523 		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),
4524 
4525 		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),
4526 		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),
4527 		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),
4528 		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),
4529 
4530 		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),
4531 		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),
4532 		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),
4533 		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),
4534 	};
4535 	createCaseGroup(this, "texelfetch", "texelFetch() Tests", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
4536 
4537 	// texelFetchOffset() cases
4538 	static const TexFuncCaseSpec texelFetchOffsetCases[] =
4539 	{
4540 		//		  Name							Function				MinCoord							MaxCoord						Bias?	MinLod	MaxLod	Offset?	Offset		Format						EvalFunc				Flags
4541 		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),
4542 		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),
4543 		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),
4544 		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),
4545 
4546 		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),
4547 		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),
4548 		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),
4549 		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),
4550 
4551 		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),
4552 		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),
4553 		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),
4554 		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),
4555 
4556 		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),
4557 		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),
4558 		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),
4559 		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),
4560 
4561 		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),
4562 		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),
4563 		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),
4564 		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),
4565 	};
4566 	createCaseGroup(this, "texelfetchoffset", "texelFetchOffset() Tests", texelFetchOffsetCases, DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
4567 
4568 	// texture query functions
4569 	{
4570 		struct TexQueryFuncCaseSpec
4571 		{
4572 			const char*		name;
4573 			const char*		samplerName;
4574 			TextureSpec		textureSpec;
4575 		};
4576 
4577 		de::MovePtr<tcu::TestCaseGroup>			queryGroup	(new tcu::TestCaseGroup(m_testCtx, "query", "Texture query function tests"));
4578 
4579 		// textureSize() cases
4580 		{
4581 			const TexQueryFuncCaseSpec textureSizeCases[] =
4582 			{
4583 				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4584 				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4585 				{ "isampler2d",					"isampler2D",				tex2DInt			},
4586 				{ "usampler2d",					"usampler2D",				tex2DUint			},
4587 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4588 				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4589 				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4590 				{ "isampler3d",					"isampler3D",				tex3DInt			},
4591 				{ "usampler3d",					"usampler3D",				tex3DUint			},
4592 				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4593 				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4594 				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4595 				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4596 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4597 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4598 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4599 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4600 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4601 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4602 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4603 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4604 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4605 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4606 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4607 				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4608 				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4609 				{ "isampler1d",					"isampler1D",				tex1DInt			},
4610 				{ "usampler1d",					"usampler1D",				tex1DUint			},
4611 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4612 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4613 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4614 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4615 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4616 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4617 			};
4618 
4619 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesize", "textureSize() Tests"));
4620 
4621 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
4622 			{
4623 				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeCases[ndx];
4624 
4625 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZE));
4626 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZE));
4627 			}
4628 
4629 			queryGroup->addChild(group.release());
4630 		}
4631 
4632 		// textureSize() cases for multisample textures
4633 		{
4634 			const TexQueryFuncCaseSpec textureSizeMSCases[] =
4635 			{
4636 				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4637 				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4638 				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4639 				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4640 				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4641 				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4642 				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4643 				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4644 			};
4645 
4646 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesizems", "textureSize() Tests for Multisample Textures"));
4647 
4648 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeMSCases); ++ndx)
4649 			{
4650 				const TexQueryFuncCaseSpec&		caseSpec	= textureSizeMSCases[ndx];
4651 
4652 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESIZEMS));
4653 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESIZEMS));
4654 			}
4655 
4656 			queryGroup->addChild(group.release());
4657 		}
4658 
4659 		// textureSamples() cases
4660 		{
4661 			const TexQueryFuncCaseSpec textureSamplesCases[] =
4662 			{
4663 				{ "sampler2dms_fixed",			"sampler2DMS",				tex2DFixed			},
4664 				{ "sampler2dms_float",			"sampler2DMS",				tex2DFloat			},
4665 				{ "isampler2dms",				"isampler2DMS",				tex2DInt			},
4666 				{ "usampler2dms",				"usampler2DMS",				tex2DUint			},
4667 				{ "sampler2dmsarray_fixed",		"sampler2DMSArray",			tex2DArrayFixed		},
4668 				{ "sampler2dmsarray_float",		"sampler2DMSArray",			tex2DArrayFloat		},
4669 				{ "isampler2dmsarray",			"isampler2DMSArray",		tex2DArrayInt		},
4670 				{ "usampler2dmsarray",			"usampler2DMSArray",		tex2DArrayUint		},
4671 			};
4672 
4673 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturesamples", "textureSamples() Tests"));
4674 
4675 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSamplesCases); ++ndx)
4676 			{
4677 				const TexQueryFuncCaseSpec&		caseSpec	= textureSamplesCases[ndx];
4678 
4679 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTURESAMPLES));
4680 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTURESAMPLES));
4681 			}
4682 
4683 			queryGroup->addChild(group.release());
4684 		}
4685 
4686 		// textureQueryLevels() cases
4687 		{
4688 			const TexQueryFuncCaseSpec textureQueryLevelsCases[] =
4689 			{
4690 				{ "sampler2d_fixed",			"sampler2D",				tex2DFixed			},
4691 				{ "sampler2d_float",			"sampler2D",				tex2DFloat			},
4692 				{ "isampler2d",					"isampler2D",				tex2DInt			},
4693 				{ "usampler2d",					"usampler2D",				tex2DUint			},
4694 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DShadow			},
4695 				{ "sampler3d_fixed",			"sampler3D",				tex3DFixed			},
4696 				{ "sampler3d_float",			"sampler3D",				tex3DFloat			},
4697 				{ "isampler3d",					"isampler3D",				tex3DInt			},
4698 				{ "usampler3d",					"usampler3D",				tex3DUint			},
4699 				{ "samplercube_fixed",			"samplerCube",				texCubeFixed		},
4700 				{ "samplercube_float",			"samplerCube",				texCubeFloat		},
4701 				{ "isamplercube",				"isamplerCube",				texCubeInt			},
4702 				{ "usamplercube",				"usamplerCube",				texCubeUint			},
4703 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeShadow		},
4704 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayFixed		},
4705 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayFloat		},
4706 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayInt		},
4707 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayUint		},
4708 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayShadow	},
4709 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayFixed	},
4710 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayFloat	},
4711 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayInt		},
4712 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayUint	},
4713 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayShadow	},
4714 				{ "sampler1d_fixed",			"sampler1D",				tex1DFixed			},
4715 				{ "sampler1d_float",			"sampler1D",				tex1DFloat			},
4716 				{ "isampler1d",					"isampler1D",				tex1DInt			},
4717 				{ "usampler1d",					"usampler1D",				tex1DUint			},
4718 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DShadow			},
4719 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayFixed		},
4720 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayFloat		},
4721 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayInt		},
4722 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayUint		},
4723 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayShadow	},
4724 			};
4725 
4726 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylevels", "textureQueryLevels() Tests"));
4727 
4728 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLevelsCases); ++ndx)
4729 			{
4730 				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLevelsCases[ndx];
4731 
4732 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),   "", caseSpec.samplerName, caseSpec.textureSpec, true,  QUERYFUNCTION_TEXTUREQUERYLEVELS));
4733 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLEVELS));
4734 			}
4735 
4736 			queryGroup->addChild(group.release());
4737 		}
4738 
4739 		// textureQueryLod() cases
4740 		{
4741 			const TexQueryFuncCaseSpec textureQueryLodCases[] =
4742 			{
4743 				{ "sampler2d_fixed",			"sampler2D",				tex2DMipmapFixed			},
4744 				{ "sampler2d_float",			"sampler2D",				tex2DMipmapFloat			},
4745 				{ "isampler2d",					"isampler2D",				tex2DMipmapInt				},
4746 				{ "usampler2d",					"usampler2D",				tex2DMipmapUint				},
4747 				{ "sampler2dshadow",			"sampler2DShadow",			tex2DMipmapShadow			},
4748 				{ "sampler3d_fixed",			"sampler3D",				tex3DMipmapFixed			},
4749 				{ "sampler3d_float",			"sampler3D",				tex3DMipmapFloat			},
4750 				{ "isampler3d",					"isampler3D",				tex3DMipmapInt				},
4751 				{ "usampler3d",					"usampler3D",				tex3DMipmapUint				},
4752 				{ "samplercube_fixed",			"samplerCube",				texCubeMipmapFixed			},
4753 				{ "samplercube_float",			"samplerCube",				texCubeMipmapFloat			},
4754 				{ "isamplercube",				"isamplerCube",				texCubeMipmapInt			},
4755 				{ "usamplercube",				"usamplerCube",				texCubeMipmapUint			},
4756 				{ "samplercubeshadow",			"samplerCubeShadow",		texCubeMipmapShadow			},
4757 				{ "sampler2darray_fixed",		"sampler2DArray",			tex2DArrayMipmapFixed		},
4758 				{ "sampler2darray_float",		"sampler2DArray",			tex2DArrayMipmapFloat		},
4759 				{ "isampler2darray",			"isampler2DArray",			tex2DArrayMipmapInt			},
4760 				{ "usampler2darray",			"usampler2DArray",			tex2DArrayMipmapUint		},
4761 				{ "sampler2darrayshadow",		"sampler2DArrayShadow",		tex2DArrayMipmapShadow		},
4762 				{ "samplercubearray_fixed",		"samplerCubeArray",			texCubeArrayMipmapFixed		},
4763 				{ "samplercubearray_float",		"samplerCubeArray",			texCubeArrayMipmapFloat		},
4764 				{ "isamplercubearray",			"isamplerCubeArray",		texCubeArrayMipmapInt		},
4765 				{ "usamplercubearray",			"usamplerCubeArray",		texCubeArrayMipmapUint		},
4766 				{ "samplercubearrayshadow",		"samplerCubeArrayShadow",	texCubeArrayMipmapShadow	},
4767 				{ "sampler1d_fixed",			"sampler1D",				tex1DMipmapFixed			},
4768 				{ "sampler1d_float",			"sampler1D",				tex1DMipmapFloat			},
4769 				{ "isampler1d",					"isampler1D",				tex1DMipmapInt				},
4770 				{ "usampler1d",					"usampler1D",				tex1DMipmapUint				},
4771 				{ "sampler1dshadow",			"sampler1DShadow",			tex1DMipmapShadow			},
4772 				{ "sampler1darray_fixed",		"sampler1DArray",			tex1DArrayMipmapFixed		},
4773 				{ "sampler1darray_float",		"sampler1DArray",			tex1DArrayMipmapFloat		},
4774 				{ "isampler1darray",			"isampler1DArray",			tex1DArrayMipmapInt			},
4775 				{ "usampler1darray",			"usampler1DArray",			tex1DArrayMipmapUint		},
4776 				{ "sampler1darrayshadow",		"sampler1DArrayShadow",		tex1DArrayMipmapShadow		},
4777 			};
4778 
4779 			de::MovePtr<tcu::TestCaseGroup>		group		(new tcu::TestCaseGroup(m_testCtx, "texturequerylod", "textureQueryLod() Tests"));
4780 
4781 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLodCases); ++ndx)
4782 			{
4783 				const TexQueryFuncCaseSpec&		caseSpec	= textureQueryLodCases[ndx];
4784 
4785 				// available only in fragment shader
4786 				group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"), "", caseSpec.samplerName, caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD));
4787 				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));
4788 			}
4789 
4790 			queryGroup->addChild(group.release());
4791 		}
4792 
4793 		addChild(queryGroup.release());
4794 	}
4795 }
4796 
4797 } // anonymous
4798 
createTextureFunctionTests(tcu::TestContext & testCtx)4799 tcu::TestCaseGroup* createTextureFunctionTests (tcu::TestContext& testCtx)
4800 {
4801 	return new ShaderTextureFunctionTests(testCtx);
4802 }
4803 
4804 } // sr
4805 } // vkt
4806