1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Texture access and query function tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktShaderRenderTextureFunctionTests.hpp"
27 #include "vktShaderRender.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "tcuTexture.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuTestLog.hpp"
32 #include "tcuCommandLine.hpp"
33 #include "glwEnums.hpp"
34 #include "deMath.h"
35 #include "vkBarrierUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include <limits>
41 
42 namespace vkt
43 {
44 namespace sr
45 {
46 namespace
47 {
48 
49 using tcu::IVec2;
50 using tcu::IVec3;
51 using tcu::IVec4;
52 using tcu::Vec2;
53 using tcu::Vec3;
54 using tcu::Vec4;
55 
56 using std::vector;
57 
58 enum Function
59 {
60     FUNCTION_TEXTURE = 0,  //!< texture(), textureOffset(), textureClampARB, textureOffsetClampARB
61     FUNCTION_TEXTUREPROJ,  //!< textureProj(), textureProjOffset()
62     FUNCTION_TEXTUREPROJ2, //!< textureProj(sampler1D, vec2)
63     FUNCTION_TEXTUREPROJ3, //!< textureProj(sampler2D, vec3)
64     FUNCTION_TEXTURELOD,   // ...
65     FUNCTION_TEXTUREPROJLOD,
66     FUNCTION_TEXTUREPROJLOD2, //!< textureProjLod(sampler1D, vec2)
67     FUNCTION_TEXTUREPROJLOD3, //!< textureProjLod(sampler2D, vec3)
68     FUNCTION_TEXTUREGRAD,     //!< textureGrad, textureGradOffset, textureGradClampARB, textureGradOffsetClampARB
69     FUNCTION_TEXTUREPROJGRAD,
70     FUNCTION_TEXTUREPROJGRAD2, //!< textureProjGrad(sampler1D, vec2)
71     FUNCTION_TEXTUREPROJGRAD3, //!< textureProjGrad(sampler2D, vec3)
72     FUNCTION_TEXELFETCH,
73 
74     FUNCTION_LAST
75 };
76 
functionHasAutoLod(glu::ShaderType shaderType,Function function)77 inline bool functionHasAutoLod(glu::ShaderType shaderType, Function function)
78 {
79     return shaderType == glu::SHADERTYPE_FRAGMENT &&
80            (function == FUNCTION_TEXTURE || function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJ2 ||
81             function == FUNCTION_TEXTUREPROJ3);
82 }
83 
functionHasProj(Function function)84 inline bool functionHasProj(Function function)
85 {
86     return function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJ2 || function == FUNCTION_TEXTUREPROJ3 ||
87            function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJLOD2 ||
88            function == FUNCTION_TEXTUREPROJLOD3 || function == FUNCTION_TEXTUREPROJGRAD ||
89            function == FUNCTION_TEXTUREPROJGRAD2 || function == FUNCTION_TEXTUREPROJGRAD3;
90 }
91 
functionHasGrad(Function function)92 inline bool functionHasGrad(Function function)
93 {
94     return function == FUNCTION_TEXTUREGRAD || function == FUNCTION_TEXTUREPROJGRAD ||
95            function == FUNCTION_TEXTUREPROJGRAD2 || function == FUNCTION_TEXTUREPROJGRAD3;
96 }
97 
functionHasLod(Function function)98 inline bool functionHasLod(Function function)
99 {
100     return function == FUNCTION_TEXTURELOD || function == FUNCTION_TEXTUREPROJLOD ||
101            function == FUNCTION_TEXTUREPROJLOD2 || function == FUNCTION_TEXTUREPROJLOD3 ||
102            function == FUNCTION_TEXELFETCH;
103 }
104 
105 struct TextureLookupSpec
106 {
107     Function function;
108 
109     tcu::Vec4 minCoord;
110     tcu::Vec4 maxCoord;
111 
112     // Bias
113     bool useBias;
114 
115     // Bias or Lod for *Lod* functions
116     float minLodBias;
117     float maxLodBias;
118 
119     // For *Grad* functions
120     tcu::Vec3 minDX;
121     tcu::Vec3 maxDX;
122     tcu::Vec3 minDY;
123     tcu::Vec3 maxDY;
124 
125     bool useOffset;
126     tcu::IVec3 offset;
127 
128     // Lod clamp
129     bool useClamp;
130     float lodClamp;
131 
TextureLookupSpecvkt::sr::__anon6c3503510111::TextureLookupSpec132     TextureLookupSpec(void)
133         : function(FUNCTION_LAST)
134         , minCoord(0.0f)
135         , maxCoord(1.0f)
136         , useBias(false)
137         , minLodBias(0.0f)
138         , maxLodBias(0.0f)
139         , minDX(0.0f)
140         , maxDX(0.0f)
141         , minDY(0.0f)
142         , maxDY(0.0f)
143         , useOffset(false)
144         , offset(0)
145         , useClamp(false)
146         , lodClamp(0.0f)
147     {
148     }
149 
TextureLookupSpecvkt::sr::__anon6c3503510111::TextureLookupSpec150     TextureLookupSpec(Function function_, const tcu::Vec4 &minCoord_, const tcu::Vec4 &maxCoord_, bool useBias_,
151                       float minLodBias_, float maxLodBias_, const tcu::Vec3 &minDX_, const tcu::Vec3 &maxDX_,
152                       const tcu::Vec3 &minDY_, const tcu::Vec3 &maxDY_, bool useOffset_, const tcu::IVec3 &offset_,
153                       bool useClamp_, float lodClamp_)
154         : function(function_)
155         , minCoord(minCoord_)
156         , maxCoord(maxCoord_)
157         , useBias(useBias_)
158         , minLodBias(minLodBias_)
159         , maxLodBias(maxLodBias_)
160         , minDX(minDX_)
161         , maxDX(maxDX_)
162         , minDY(minDY_)
163         , maxDY(maxDY_)
164         , useOffset(useOffset_)
165         , offset(offset_)
166         , useClamp(useClamp_)
167         , lodClamp(lodClamp_)
168     {
169     }
170 };
171 
172 enum TextureType
173 {
174     TEXTURETYPE_1D = 0,
175     TEXTURETYPE_2D,
176     TEXTURETYPE_3D,
177     TEXTURETYPE_CUBE_MAP,
178     TEXTURETYPE_1D_ARRAY,
179     TEXTURETYPE_2D_ARRAY,
180     TEXTURETYPE_CUBE_ARRAY,
181 
182     TEXTURETYPE_LAST
183 };
184 
185 struct TextureSpec
186 {
187     TextureType type; //!< Texture type (2D, cubemap, ...)
188     uint32_t format;  //!< Internal format.
189     int width;
190     int height;
191     int depth;
192     int numLevels;
193     tcu::Sampler sampler;
194 
TextureSpecvkt::sr::__anon6c3503510111::TextureSpec195     TextureSpec(void) : type(TEXTURETYPE_LAST), format(GL_NONE), width(0), height(0), depth(0), numLevels(0)
196     {
197     }
198 
TextureSpecvkt::sr::__anon6c3503510111::TextureSpec199     TextureSpec(TextureType type_, uint32_t format_, int width_, int height_, int depth_, int numLevels_,
200                 const tcu::Sampler &sampler_)
201         : type(type_)
202         , format(format_)
203         , width(width_)
204         , height(height_)
205         , depth(depth_)
206         , numLevels(numLevels_)
207         , sampler(sampler_)
208     {
209     }
210 };
211 
212 struct TexLookupParams
213 {
214     float lod;
215     float lodClamp;
216     tcu::IVec3 offset;
217     tcu::Vec4 scale;
218     tcu::Vec4 bias;
219 
TexLookupParamsvkt::sr::__anon6c3503510111::TexLookupParams220     TexLookupParams(void) : lod(0.0f), lodClamp(0.0f), offset(0), scale(1.0f), bias(0.0f)
221     {
222     }
223 };
224 
225 // \note LodMode and computeLodFromDerivates functions are copied from glsTextureTestUtil
226 namespace TextureTestUtil
227 {
228 
229 enum LodMode
230 {
231     LODMODE_EXACT = 0, //!< Ideal lod computation.
232     LODMODE_MIN_BOUND, //!< Use estimation range minimum bound.
233     LODMODE_MAX_BOUND, //!< Use estimation range maximum bound.
234 
235     LODMODE_LAST
236 };
237 
238 // 1D lookup LOD computation.
239 
computeLodFromDerivates(LodMode mode,float dudx,float dudy)240 float computeLodFromDerivates(LodMode mode, float dudx, float dudy)
241 {
242     float p = 0.0f;
243     switch (mode)
244     {
245     // \note [mika] Min and max bounds equal to exact with 1D textures
246     case LODMODE_EXACT:
247     case LODMODE_MIN_BOUND:
248     case LODMODE_MAX_BOUND:
249         p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
250         break;
251 
252     default:
253         DE_ASSERT(false);
254     }
255 
256     return deFloatLog2(p);
257 }
258 
259 // 2D lookup LOD computation.
260 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dudy,float dvdy)261 float computeLodFromDerivates(LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
262 {
263     float p = 0.0f;
264     switch (mode)
265     {
266     case LODMODE_EXACT:
267         p = de::max(deFloatSqrt(dudx * dudx + dvdx * dvdx), deFloatSqrt(dudy * dudy + dvdy * dvdy));
268         break;
269 
270     case LODMODE_MIN_BOUND:
271     case LODMODE_MAX_BOUND:
272     {
273         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
274         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
275 
276         p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
277         break;
278     }
279 
280     default:
281         DE_ASSERT(false);
282     }
283 
284     return deFloatLog2(p);
285 }
286 
287 // 3D lookup LOD computation.
288 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dwdx,float dudy,float dvdy,float dwdy)289 float computeLodFromDerivates(LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
290 {
291     float p = 0.0f;
292     switch (mode)
293     {
294     case LODMODE_EXACT:
295         p = de::max(deFloatSqrt(dudx * dudx + dvdx * dvdx + dwdx * dwdx),
296                     deFloatSqrt(dudy * dudy + dvdy * dvdy + dwdy * dwdy));
297         break;
298 
299     case LODMODE_MIN_BOUND:
300     case LODMODE_MAX_BOUND:
301     {
302         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
303         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
304         float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
305 
306         p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
307         break;
308     }
309 
310     default:
311         DE_ASSERT(false);
312     }
313 
314     return deFloatLog2(p);
315 }
316 
317 } // namespace TextureTestUtil
318 
319 using namespace TextureTestUtil;
320 
321 static const LodMode DEFAULT_LOD_MODE = LODMODE_EXACT;
322 
computeLodFromGrad2D(const ShaderEvalContext & c)323 inline float computeLodFromGrad2D(const ShaderEvalContext &c)
324 {
325     float w = (float)c.textures[0].tex2D->getWidth();
326     float h = (float)c.textures[0].tex2D->getHeight();
327     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[1].y() * h, c.in[2].x() * w,
328                                    c.in[2].y() * h);
329 }
330 
computeLodFromGrad2DArray(const ShaderEvalContext & c)331 inline float computeLodFromGrad2DArray(const ShaderEvalContext &c)
332 {
333     float w = (float)c.textures[0].tex2DArray->getWidth();
334     float h = (float)c.textures[0].tex2DArray->getHeight();
335     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[1].y() * h, c.in[2].x() * w,
336                                    c.in[2].y() * h);
337 }
338 
computeLodFromGrad3D(const ShaderEvalContext & c)339 inline float computeLodFromGrad3D(const ShaderEvalContext &c)
340 {
341     float w = (float)c.textures[0].tex3D->getWidth();
342     float h = (float)c.textures[0].tex3D->getHeight();
343     float d = (float)c.textures[0].tex3D->getDepth();
344     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,
345                                    c.in[2].y() * h, c.in[2].z() * d);
346 }
347 
computeLodFromGradCube(const ShaderEvalContext & c)348 inline float computeLodFromGradCube(const ShaderEvalContext &c)
349 {
350     // \note Major axis is always -Z or +Z
351     float m = de::abs(c.in[0].z());
352     float d = (float)c.textures[0].texCube->getSize();
353     float s = d / (2.0f * m);
354     float t = d / (2.0f * m);
355     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * s, c.in[1].y() * t, c.in[2].x() * s,
356                                    c.in[2].y() * t);
357 }
358 
computeLodFromGrad1D(const ShaderEvalContext & c)359 inline float computeLodFromGrad1D(const ShaderEvalContext &c)
360 {
361     float w = (float)c.textures[0].tex1D->getWidth();
362     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[2].x() * w);
363 }
364 
computeLodFromGrad1DArray(const ShaderEvalContext & c)365 inline float computeLodFromGrad1DArray(const ShaderEvalContext &c)
366 {
367     float w = (float)c.textures[0].tex1DArray->getWidth();
368     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[2].x() * w);
369 }
370 
computeLodFromGradCubeArray(const ShaderEvalContext & c)371 inline float computeLodFromGradCubeArray(const ShaderEvalContext &c)
372 {
373     // \note Major axis is always -Z or +Z
374     float m = de::abs(c.in[0].z());
375     float d = (float)c.textures[0].texCubeArray->getSize();
376     float s = d / (2.0f * m);
377     float t = d / (2.0f * m);
378     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * s, c.in[1].y() * t, c.in[2].x() * s,
379                                    c.in[2].y() * t);
380 }
381 
382 typedef void (*TexEvalFunc)(ShaderEvalContext &c, const TexLookupParams &lookupParams);
383 
texture2D(const ShaderEvalContext & c,float s,float t,float lod)384 inline Vec4 texture2D(const ShaderEvalContext &c, float s, float t, float lod)
385 {
386     return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);
387 }
textureCube(const ShaderEvalContext & c,float s,float t,float r,float lod)388 inline Vec4 textureCube(const ShaderEvalContext &c, float s, float t, float r, float lod)
389 {
390     return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);
391 }
texture2DArray(const ShaderEvalContext & c,float s,float t,float r,float lod)392 inline Vec4 texture2DArray(const ShaderEvalContext &c, float s, float t, float r, float lod)
393 {
394     return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod);
395 }
texture3D(const ShaderEvalContext & c,float s,float t,float r,float lod)396 inline Vec4 texture3D(const ShaderEvalContext &c, float s, float t, float r, float lod)
397 {
398     return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);
399 }
texture1D(const ShaderEvalContext & c,float s,float lod)400 inline Vec4 texture1D(const ShaderEvalContext &c, float s, float lod)
401 {
402     return c.textures[0].tex1D->sample(c.textures[0].sampler, s, lod);
403 }
texture1DArray(const ShaderEvalContext & c,float s,float t,float lod)404 inline Vec4 texture1DArray(const ShaderEvalContext &c, float s, float t, float lod)
405 {
406     return c.textures[0].tex1DArray->sample(c.textures[0].sampler, s, t, lod);
407 }
textureCubeArray(const ShaderEvalContext & c,float s,float t,float r,float q,float lod)408 inline Vec4 textureCubeArray(const ShaderEvalContext &c, float s, float t, float r, float q, float lod)
409 {
410     return c.textures[0].texCubeArray->sample(c.textures[0].sampler, s, t, r, q, lod);
411 }
412 
texture2DShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)413 inline float texture2DShadow(const ShaderEvalContext &c, float ref, float s, float t, float lod)
414 {
415     return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod);
416 }
textureCubeShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)417 inline float textureCubeShadow(const ShaderEvalContext &c, float ref, float s, float t, float r, float lod)
418 {
419     return c.textures[0].texCube->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);
420 }
texture2DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod)421 inline float texture2DArrayShadow(const ShaderEvalContext &c, float ref, float s, float t, float r, float lod)
422 {
423     return c.textures[0].tex2DArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);
424 }
texture1DShadow(const ShaderEvalContext & c,float ref,float s,float lod)425 inline float texture1DShadow(const ShaderEvalContext &c, float ref, float s, float lod)
426 {
427     return c.textures[0].tex1D->sampleCompare(c.textures[0].sampler, ref, s, lod);
428 }
texture1DArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float lod)429 inline float texture1DArrayShadow(const ShaderEvalContext &c, float ref, float s, float t, float lod)
430 {
431     return c.textures[0].tex1DArray->sampleCompare(c.textures[0].sampler, ref, s, t, lod);
432 }
textureCubeArrayShadow(const ShaderEvalContext & c,float ref,float s,float t,float r,float q,float lod)433 inline float textureCubeArrayShadow(const ShaderEvalContext &c, float ref, float s, float t, float r, float q,
434                                     float lod)
435 {
436     return c.textures[0].texCubeArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, q, lod);
437 }
438 
texture2DOffset(const ShaderEvalContext & c,float s,float t,float lod,IVec2 offset)439 inline Vec4 texture2DOffset(const ShaderEvalContext &c, float s, float t, float lod, IVec2 offset)
440 {
441     return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);
442 }
texture2DArrayOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec2 offset)443 inline Vec4 texture2DArrayOffset(const ShaderEvalContext &c, float s, float t, float r, float lod, IVec2 offset)
444 {
445     return c.textures[0].tex2DArray->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);
446 }
texture3DOffset(const ShaderEvalContext & c,float s,float t,float r,float lod,IVec3 offset)447 inline Vec4 texture3DOffset(const ShaderEvalContext &c, float s, float t, float r, float lod, IVec3 offset)
448 {
449     return c.textures[0].tex3D->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);
450 }
texture1DOffset(const ShaderEvalContext & c,float s,float lod,int32_t offset)451 inline Vec4 texture1DOffset(const ShaderEvalContext &c, float s, float lod, int32_t offset)
452 {
453     return c.textures[0].tex1D->sampleOffset(c.textures[0].sampler, s, lod, offset);
454 }
texture1DArrayOffset(const ShaderEvalContext & c,float s,float t,float lod,int32_t offset)455 inline Vec4 texture1DArrayOffset(const ShaderEvalContext &c, float s, float t, float lod, int32_t offset)
456 {
457     return c.textures[0].tex1DArray->sampleOffset(c.textures[0].sampler, s, t, lod, offset);
458 }
459 
texture2DShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,IVec2 offset)460 inline float texture2DShadowOffset(const ShaderEvalContext &c, float ref, float s, float t, float lod, IVec2 offset)
461 {
462     return c.textures[0].tex2D->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);
463 }
texture2DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float r,float lod,IVec2 offset)464 inline float texture2DArrayShadowOffset(const ShaderEvalContext &c, float ref, float s, float t, float r, float lod,
465                                         IVec2 offset)
466 {
467     return c.textures[0].tex2DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, r, lod, offset);
468 }
texture1DShadowOffset(const ShaderEvalContext & c,float ref,float s,float lod,int32_t offset)469 inline float texture1DShadowOffset(const ShaderEvalContext &c, float ref, float s, float lod, int32_t offset)
470 {
471     return c.textures[0].tex1D->sampleCompareOffset(c.textures[0].sampler, ref, s, lod, offset);
472 }
texture1DArrayShadowOffset(const ShaderEvalContext & c,float ref,float s,float t,float lod,int32_t offset)473 inline float texture1DArrayShadowOffset(const ShaderEvalContext &c, float ref, float s, float t, float lod,
474                                         int32_t offset)
475 {
476     return c.textures[0].tex1DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);
477 }
478 
479 // Eval functions.
evalTexture2D(ShaderEvalContext & c,const TexLookupParams & p)480 static void evalTexture2D(ShaderEvalContext &c, const TexLookupParams &p)
481 {
482     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod) * p.scale + p.bias;
483 }
evalTextureCube(ShaderEvalContext & c,const TexLookupParams & p)484 static void evalTextureCube(ShaderEvalContext &c, const TexLookupParams &p)
485 {
486     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
487 }
evalTexture2DArray(ShaderEvalContext & c,const TexLookupParams & p)488 static void evalTexture2DArray(ShaderEvalContext &c, const TexLookupParams &p)
489 {
490     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
491 }
evalTexture3D(ShaderEvalContext & c,const TexLookupParams & p)492 static void evalTexture3D(ShaderEvalContext &c, const TexLookupParams &p)
493 {
494     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
495 }
evalTexture1D(ShaderEvalContext & c,const TexLookupParams & p)496 static void evalTexture1D(ShaderEvalContext &c, const TexLookupParams &p)
497 {
498     c.color = texture1D(c, c.in[0].x(), p.lod) * p.scale + p.bias;
499 }
evalTexture1DArray(ShaderEvalContext & c,const TexLookupParams & p)500 static void evalTexture1DArray(ShaderEvalContext &c, const TexLookupParams &p)
501 {
502     c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod) * p.scale + p.bias;
503 }
evalTextureCubeArray(ShaderEvalContext & c,const TexLookupParams & p)504 static void evalTextureCubeArray(ShaderEvalContext &c, const TexLookupParams &p)
505 {
506     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;
507 }
508 
evalTexture2DBias(ShaderEvalContext & c,const TexLookupParams & p)509 static void evalTexture2DBias(ShaderEvalContext &c, const TexLookupParams &p)
510 {
511     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x()) * p.scale + p.bias;
512 }
evalTextureCubeBias(ShaderEvalContext & c,const TexLookupParams & p)513 static void evalTextureCubeBias(ShaderEvalContext &c, const TexLookupParams &p)
514 {
515     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;
516 }
evalTexture2DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)517 static void evalTexture2DArrayBias(ShaderEvalContext &c, const TexLookupParams &p)
518 {
519     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;
520 }
evalTexture3DBias(ShaderEvalContext & c,const TexLookupParams & p)521 static void evalTexture3DBias(ShaderEvalContext &c, const TexLookupParams &p)
522 {
523     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;
524 }
evalTexture1DBias(ShaderEvalContext & c,const TexLookupParams & p)525 static void evalTexture1DBias(ShaderEvalContext &c, const TexLookupParams &p)
526 {
527     c.color = texture1D(c, c.in[0].x(), p.lod + c.in[1].x()) * p.scale + p.bias;
528 }
evalTexture1DArrayBias(ShaderEvalContext & c,const TexLookupParams & p)529 static void evalTexture1DArrayBias(ShaderEvalContext &c, const TexLookupParams &p)
530 {
531     c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x()) * p.scale + p.bias;
532 }
evalTextureCubeArrayBias(ShaderEvalContext & c,const TexLookupParams & p)533 static void evalTextureCubeArrayBias(ShaderEvalContext &c, const TexLookupParams &p)
534 {
535     c.color =
536         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;
537 }
538 
evalTexture2DProj3(ShaderEvalContext & c,const TexLookupParams & p)539 static void evalTexture2DProj3(ShaderEvalContext &c, const TexLookupParams &p)
540 {
541     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;
542 }
evalTexture2DProj3Bias(ShaderEvalContext & c,const TexLookupParams & p)543 static void evalTexture2DProj3Bias(ShaderEvalContext &c, const TexLookupParams &p)
544 {
545     c.color =
546         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;
547 }
evalTexture2DProj(ShaderEvalContext & c,const TexLookupParams & p)548 static void evalTexture2DProj(ShaderEvalContext &c, const TexLookupParams &p)
549 {
550     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;
551 }
evalTexture2DProjBias(ShaderEvalContext & c,const TexLookupParams & p)552 static void evalTexture2DProjBias(ShaderEvalContext &c, const TexLookupParams &p)
553 {
554     c.color =
555         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;
556 }
evalTexture3DProj(ShaderEvalContext & c,const TexLookupParams & p)557 static void evalTexture3DProj(ShaderEvalContext &c, const TexLookupParams &p)
558 {
559     c.color =
560         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 +
561         p.bias;
562 }
evalTexture3DProjBias(ShaderEvalContext & c,const TexLookupParams & p)563 static void evalTexture3DProjBias(ShaderEvalContext &c, const TexLookupParams &p)
564 {
565     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(),
566                         p.lod + c.in[1].x()) *
567                   p.scale +
568               p.bias;
569 }
evalTexture1DProj2(ShaderEvalContext & c,const TexLookupParams & p)570 static void evalTexture1DProj2(ShaderEvalContext &c, const TexLookupParams &p)
571 {
572     c.color = texture1D(c, c.in[0].x() / c.in[0].y(), p.lod) * p.scale + p.bias;
573 }
evalTexture1DProj2Bias(ShaderEvalContext & c,const TexLookupParams & p)574 static void evalTexture1DProj2Bias(ShaderEvalContext &c, const TexLookupParams &p)
575 {
576     c.color = texture1D(c, c.in[0].x() / c.in[0].y(), p.lod + c.in[1].x()) * p.scale + p.bias;
577 }
evalTexture1DProj(ShaderEvalContext & c,const TexLookupParams & p)578 static void evalTexture1DProj(ShaderEvalContext &c, const TexLookupParams &p)
579 {
580     c.color = texture1D(c, c.in[0].x() / c.in[0].w(), p.lod) * p.scale + p.bias;
581 }
evalTexture1DProjBias(ShaderEvalContext & c,const TexLookupParams & p)582 static void evalTexture1DProjBias(ShaderEvalContext &c, const TexLookupParams &p)
583 {
584     c.color = texture1D(c, c.in[0].x() / c.in[0].w(), p.lod + c.in[1].x()) * p.scale + p.bias;
585 }
586 
evalTexture2DLod(ShaderEvalContext & c,const TexLookupParams & p)587 static void evalTexture2DLod(ShaderEvalContext &c, const TexLookupParams &p)
588 {
589     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), c.in[1].x()) * p.scale + p.bias;
590 }
evalTextureCubeLod(ShaderEvalContext & c,const TexLookupParams & p)591 static void evalTextureCubeLod(ShaderEvalContext &c, const TexLookupParams &p)
592 {
593     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
594 }
evalTexture2DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)595 static void evalTexture2DArrayLod(ShaderEvalContext &c, const TexLookupParams &p)
596 {
597     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
598 }
evalTexture3DLod(ShaderEvalContext & c,const TexLookupParams & p)599 static void evalTexture3DLod(ShaderEvalContext &c, const TexLookupParams &p)
600 {
601     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
602 }
evalTexture1DLod(ShaderEvalContext & c,const TexLookupParams & p)603 static void evalTexture1DLod(ShaderEvalContext &c, const TexLookupParams &p)
604 {
605     c.color = texture1D(c, c.in[0].x(), c.in[1].x()) * p.scale + p.bias;
606 }
evalTexture1DArrayLod(ShaderEvalContext & c,const TexLookupParams & p)607 static void evalTexture1DArrayLod(ShaderEvalContext &c, const TexLookupParams &p)
608 {
609     c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), c.in[1].x()) * p.scale + p.bias;
610 }
evalTextureCubeArrayLod(ShaderEvalContext & c,const TexLookupParams & p)611 static void evalTextureCubeArrayLod(ShaderEvalContext &c, const TexLookupParams &p)
612 {
613     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;
614 }
615 
evalTexture2DProjLod3(ShaderEvalContext & c,const TexLookupParams & p)616 static void evalTexture2DProjLod3(ShaderEvalContext &c, const TexLookupParams &p)
617 {
618     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;
619 }
evalTexture2DProjLod(ShaderEvalContext & c,const TexLookupParams & p)620 static void evalTexture2DProjLod(ShaderEvalContext &c, const TexLookupParams &p)
621 {
622     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;
623 }
evalTexture3DProjLod(ShaderEvalContext & c,const TexLookupParams & p)624 static void evalTexture3DProjLod(ShaderEvalContext &c, const TexLookupParams &p)
625 {
626     c.color =
627         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()) *
628             p.scale +
629         p.bias;
630 }
evalTexture1DProjLod2(ShaderEvalContext & c,const TexLookupParams & p)631 static void evalTexture1DProjLod2(ShaderEvalContext &c, const TexLookupParams &p)
632 {
633     c.color = texture1D(c, c.in[0].x() / c.in[0].y(), c.in[1].x()) * p.scale + p.bias;
634 }
evalTexture1DProjLod(ShaderEvalContext & c,const TexLookupParams & p)635 static void evalTexture1DProjLod(ShaderEvalContext &c, const TexLookupParams &p)
636 {
637     c.color = texture1D(c, c.in[0].x() / c.in[0].w(), c.in[1].x()) * p.scale + p.bias;
638 }
639 
evalTexture2DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)640 static void evalTexture2DBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
641 {
642     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;
643 }
evalTextureCubeBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)644 static void evalTextureCubeBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
645 {
646     c.color =
647         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 +
648         p.bias;
649 }
evalTexture2DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)650 static void evalTexture2DArrayBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
651 {
652     c.color =
653         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 +
654         p.bias;
655 }
evalTexture3DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)656 static void evalTexture3DBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
657 {
658     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 +
659               p.bias;
660 }
evalTexture1DBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)661 static void evalTexture1DBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
662 {
663     c.color = texture1D(c, c.in[0].x(), de::max(p.lod + c.in[1].x(), p.lodClamp)) * p.scale + p.bias;
664 }
evalTexture1DArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)665 static void evalTexture1DArrayBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
666 {
667     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;
668 }
evalTextureCubeArrayBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)669 static void evalTextureCubeArrayBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
670 {
671     c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(),
672                                de::max(p.lod + c.in[1].x(), p.lodClamp)) *
673                   p.scale +
674               p.bias;
675 }
676 
677 // Offset variants
678 
evalTexture2DOffset(ShaderEvalContext & c,const TexLookupParams & p)679 static void evalTexture2DOffset(ShaderEvalContext &c, const TexLookupParams &p)
680 {
681     c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0, 1)) * p.scale + p.bias;
682 }
evalTexture2DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)683 static void evalTexture2DArrayOffset(ShaderEvalContext &c, const TexLookupParams &p)
684 {
685     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 +
686               p.bias;
687 }
evalTexture3DOffset(ShaderEvalContext & c,const TexLookupParams & p)688 static void evalTexture3DOffset(ShaderEvalContext &c, const TexLookupParams &p)
689 {
690     c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset) * p.scale + p.bias;
691 }
evalTexture1DOffset(ShaderEvalContext & c,const TexLookupParams & p)692 static void evalTexture1DOffset(ShaderEvalContext &c, const TexLookupParams &p)
693 {
694     c.color = texture1DOffset(c, c.in[0].x(), p.lod, p.offset.x()) * p.scale + p.bias;
695 }
evalTexture1DArrayOffset(ShaderEvalContext & c,const TexLookupParams & p)696 static void evalTexture1DArrayOffset(ShaderEvalContext &c, const TexLookupParams &p)
697 {
698     c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.x()) * p.scale + p.bias;
699 }
700 
evalTexture2DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)701 static void evalTexture2DOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
702 {
703     c.color =
704         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;
705 }
evalTexture2DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)706 static void evalTexture2DArrayOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
707 {
708     c.color =
709         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)) *
710             p.scale +
711         p.bias;
712 }
evalTexture3DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)713 static void evalTexture3DOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
714 {
715     c.color =
716         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;
717 }
evalTexture1DOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)718 static void evalTexture1DOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
719 {
720     c.color = texture1DOffset(c, c.in[0].x(), p.lod + c.in[1].x(), p.offset.x()) * p.scale + p.bias;
721 }
evalTexture1DArrayOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)722 static void evalTexture1DArrayOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
723 {
724     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;
725 }
726 
evalTexture2DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)727 static void evalTexture2DLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
728 {
729     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;
730 }
evalTexture2DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)731 static void evalTexture2DArrayLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
732 {
733     c.color =
734         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 +
735         p.bias;
736 }
evalTexture3DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)737 static void evalTexture3DLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
738 {
739     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;
740 }
evalTexture1DLodOffset(ShaderEvalContext & c,const TexLookupParams & p)741 static void evalTexture1DLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
742 {
743     c.color = texture1DOffset(c, c.in[0].x(), c.in[1].x(), p.offset.x()) * p.scale + p.bias;
744 }
evalTexture1DArrayLodOffset(ShaderEvalContext & c,const TexLookupParams & p)745 static void evalTexture1DArrayLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
746 {
747     c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x()) * p.scale + p.bias;
748 }
749 
evalTexture2DProj3Offset(ShaderEvalContext & c,const TexLookupParams & p)750 static void evalTexture2DProj3Offset(ShaderEvalContext &c, const TexLookupParams &p)
751 {
752     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)) *
753                   p.scale +
754               p.bias;
755 }
evalTexture2DProj3OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)756 static void evalTexture2DProj3OffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
757 {
758     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(),
759                               p.offset.swizzle(0, 1)) *
760                   p.scale +
761               p.bias;
762 }
evalTexture2DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)763 static void evalTexture2DProjOffset(ShaderEvalContext &c, const TexLookupParams &p)
764 {
765     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)) *
766                   p.scale +
767               p.bias;
768 }
evalTexture2DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)769 static void evalTexture2DProjOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
770 {
771     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(),
772                               p.offset.swizzle(0, 1)) *
773                   p.scale +
774               p.bias;
775 }
evalTexture3DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)776 static void evalTexture3DProjOffset(ShaderEvalContext &c, const TexLookupParams &p)
777 {
778     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,
779                               p.offset) *
780                   p.scale +
781               p.bias;
782 }
evalTexture3DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)783 static void evalTexture3DProjOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
784 {
785     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(),
786                               p.lod + c.in[1].x(), p.offset) *
787                   p.scale +
788               p.bias;
789 }
evalTexture1DProj2Offset(ShaderEvalContext & c,const TexLookupParams & p)790 static void evalTexture1DProj2Offset(ShaderEvalContext &c, const TexLookupParams &p)
791 {
792     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].y(), p.lod, p.offset.x()) * p.scale + p.bias;
793 }
evalTexture1DProj2OffsetBias(ShaderEvalContext & c,const TexLookupParams & p)794 static void evalTexture1DProj2OffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
795 {
796     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;
797 }
evalTexture1DProjOffset(ShaderEvalContext & c,const TexLookupParams & p)798 static void evalTexture1DProjOffset(ShaderEvalContext &c, const TexLookupParams &p)
799 {
800     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].w(), p.lod, p.offset.x()) * p.scale + p.bias;
801 }
evalTexture1DProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)802 static void evalTexture1DProjOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
803 {
804     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;
805 }
806 
evalTexture2DProjLod3Offset(ShaderEvalContext & c,const TexLookupParams & p)807 static void evalTexture2DProjLod3Offset(ShaderEvalContext &c, const TexLookupParams &p)
808 {
809     c.color =
810         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)) *
811             p.scale +
812         p.bias;
813 }
evalTexture2DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)814 static void evalTexture2DProjLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
815 {
816     c.color =
817         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)) *
818             p.scale +
819         p.bias;
820 }
evalTexture3DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)821 static void evalTexture3DProjLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
822 {
823     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(),
824                               c.in[1].x(), p.offset) *
825                   p.scale +
826               p.bias;
827 }
evalTexture1DProjLod2Offset(ShaderEvalContext & c,const TexLookupParams & p)828 static void evalTexture1DProjLod2Offset(ShaderEvalContext &c, const TexLookupParams &p)
829 {
830     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].y(), c.in[1].x(), p.offset.x()) * p.scale + p.bias;
831 }
evalTexture1DProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)832 static void evalTexture1DProjLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
833 {
834     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].w(), c.in[1].x(), p.offset.x()) * p.scale + p.bias;
835 }
836 
evalTexture2DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)837 static void evalTexture2DOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
838 {
839     c.color =
840         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)) *
841             p.scale +
842         p.bias;
843 }
evalTexture2DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)844 static void evalTexture2DArrayOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
845 {
846     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),
847                                    p.offset.swizzle(0, 1)) *
848                   p.scale +
849               p.bias;
850 }
evalTexture3DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)851 static void evalTexture3DOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
852 {
853     c.color =
854         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) *
855             p.scale +
856         p.bias;
857 }
evalTexture1DOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)858 static void evalTexture1DOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
859 {
860     c.color =
861         texture1DOffset(c, c.in[0].x(), de::max(p.lod + c.in[1].x(), p.lodClamp), p.offset.x()) * p.scale + p.bias;
862 }
evalTexture1DArrayOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)863 static void evalTexture1DArrayOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
864 {
865     c.color =
866         texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(p.lod + c.in[1].x(), p.lodClamp), p.offset.x()) *
867             p.scale +
868         p.bias;
869 }
870 
871 // Shadow variants
872 
evalTexture2DShadow(ShaderEvalContext & c,const TexLookupParams & p)873 static void evalTexture2DShadow(ShaderEvalContext &c, const TexLookupParams &p)
874 {
875     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod);
876 }
evalTexture2DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)877 static void evalTexture2DShadowBias(ShaderEvalContext &c, const TexLookupParams &p)
878 {
879     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x());
880 }
881 
evalTextureCubeShadow(ShaderEvalContext & c,const TexLookupParams & p)882 static void evalTextureCubeShadow(ShaderEvalContext &c, const TexLookupParams &p)
883 {
884     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod);
885 }
evalTextureCubeShadowBias(ShaderEvalContext & c,const TexLookupParams & p)886 static void evalTextureCubeShadowBias(ShaderEvalContext &c, const TexLookupParams &p)
887 {
888     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());
889 }
890 
evalTexture2DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)891 static void evalTexture2DArrayShadow(ShaderEvalContext &c, const TexLookupParams &p)
892 {
893     c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod);
894 }
evalTexture1DShadow(ShaderEvalContext & c,const TexLookupParams & p)895 static void evalTexture1DShadow(ShaderEvalContext &c, const TexLookupParams &p)
896 {
897     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod);
898 }
evalTexture1DShadowBias(ShaderEvalContext & c,const TexLookupParams & p)899 static void evalTexture1DShadowBias(ShaderEvalContext &c, const TexLookupParams &p)
900 {
901     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), p.lod + c.in[1].x());
902 }
evalTexture1DArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)903 static void evalTexture1DArrayShadow(ShaderEvalContext &c, const TexLookupParams &p)
904 {
905     c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod);
906 }
evalTexture1DArrayShadowBias(ShaderEvalContext & c,const TexLookupParams & p)907 static void evalTexture1DArrayShadowBias(ShaderEvalContext &c, const TexLookupParams &p)
908 {
909     c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x());
910 }
evalTextureCubeArrayShadow(ShaderEvalContext & c,const TexLookupParams & p)911 static void evalTextureCubeArrayShadow(ShaderEvalContext &c, const TexLookupParams &p)
912 {
913     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);
914 }
915 
evalTexture2DShadowLod(ShaderEvalContext & c,const TexLookupParams &)916 static void evalTexture2DShadowLod(ShaderEvalContext &c, const TexLookupParams &)
917 {
918     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x());
919 }
evalTexture2DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)920 static void evalTexture2DShadowLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
921 {
922     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));
923 }
evalTexture1DShadowLod(ShaderEvalContext & c,const TexLookupParams &)924 static void evalTexture1DShadowLod(ShaderEvalContext &c, const TexLookupParams &)
925 {
926     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), c.in[1].x());
927 }
evalTexture1DShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)928 static void evalTexture1DShadowLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
929 {
930     c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[1].x(), p.offset.x());
931 }
evalTexture1DArrayShadowLod(ShaderEvalContext & c,const TexLookupParams &)932 static void evalTexture1DArrayShadowLod(ShaderEvalContext &c, const TexLookupParams &)
933 {
934     c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x());
935 }
evalTexture1DArrayShadowLodOffset(ShaderEvalContext & c,const TexLookupParams & p)936 static void evalTexture1DArrayShadowLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
937 {
938     c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x(), p.offset.x());
939 }
940 
evalTexture2DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)941 static void evalTexture2DShadowProj(ShaderEvalContext &c, const TexLookupParams &p)
942 {
943     c.color.x() =
944         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);
945 }
evalTexture2DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)946 static void evalTexture2DShadowProjBias(ShaderEvalContext &c, const TexLookupParams &p)
947 {
948     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(),
949                                   p.lod + c.in[1].x());
950 }
evalTexture1DShadowProj(ShaderEvalContext & c,const TexLookupParams & p)951 static void evalTexture1DShadowProj(ShaderEvalContext &c, const TexLookupParams &p)
952 {
953     c.color.x() = texture1DShadow(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(), p.lod);
954 }
evalTexture1DShadowProjBias(ShaderEvalContext & c,const TexLookupParams & p)955 static void evalTexture1DShadowProjBias(ShaderEvalContext &c, const TexLookupParams &p)
956 {
957     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());
958 }
959 
evalTexture2DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)960 static void evalTexture2DShadowProjLod(ShaderEvalContext &c, const TexLookupParams &)
961 {
962     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(),
963                                   c.in[1].x());
964 }
evalTexture2DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)965 static void evalTexture2DShadowProjLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
966 {
967     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
968                                         c.in[0].y() / c.in[0].w(), c.in[1].x(), p.offset.swizzle(0, 1));
969 }
evalTexture1DShadowProjLod(ShaderEvalContext & c,const TexLookupParams &)970 static void evalTexture1DShadowProjLod(ShaderEvalContext &c, const TexLookupParams &)
971 {
972     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());
973 }
evalTexture1DShadowProjLodOffset(ShaderEvalContext & c,const TexLookupParams & p)974 static void evalTexture1DShadowProjLodOffset(ShaderEvalContext &c, const TexLookupParams &p)
975 {
976     c.color.x() =
977         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());
978 }
979 
evalTexture2DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)980 static void evalTexture2DShadowOffset(ShaderEvalContext &c, const TexLookupParams &p)
981 {
982     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0, 1));
983 }
evalTexture2DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)984 static void evalTexture2DShadowOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
985 {
986     c.color.x() =
987         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));
988 }
evalTexture2DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)989 static void evalTexture2DArrayShadowOffset(ShaderEvalContext &c, const TexLookupParams &p)
990 {
991     c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod,
992                                              p.offset.swizzle(0, 1));
993 }
evalTexture1DShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)994 static void evalTexture1DShadowOffset(ShaderEvalContext &c, const TexLookupParams &p)
995 {
996     c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod, p.offset.x());
997 }
evalTexture1DShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)998 static void evalTexture1DShadowOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
999 {
1000     c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), p.lod + c.in[1].x(), p.offset.x());
1001 }
evalTexture1DArrayShadowOffset(ShaderEvalContext & c,const TexLookupParams & p)1002 static void evalTexture1DArrayShadowOffset(ShaderEvalContext &c, const TexLookupParams &p)
1003 {
1004     c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.x());
1005 }
evalTexture1DArrayShadowOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)1006 static void evalTexture1DArrayShadowOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
1007 {
1008     c.color.x() =
1009         texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x(), p.offset.x());
1010 }
1011 
evalTexture2DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)1012 static void evalTexture2DShadowProjOffset(ShaderEvalContext &c, const TexLookupParams &p)
1013 {
1014     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
1015                                         c.in[0].y() / c.in[0].w(), p.lod, p.offset.swizzle(0, 1));
1016 }
evalTexture2DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)1017 static void evalTexture2DShadowProjOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
1018 {
1019     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
1020                                         c.in[0].y() / c.in[0].w(), p.lod + c.in[1].x(), p.offset.swizzle(0, 1));
1021 }
evalTexture1DShadowProjOffset(ShaderEvalContext & c,const TexLookupParams & p)1022 static void evalTexture1DShadowProjOffset(ShaderEvalContext &c, const TexLookupParams &p)
1023 {
1024     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());
1025 }
evalTexture1DShadowProjOffsetBias(ShaderEvalContext & c,const TexLookupParams & p)1026 static void evalTexture1DShadowProjOffsetBias(ShaderEvalContext &c, const TexLookupParams &p)
1027 {
1028     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(),
1029                                         p.offset.x());
1030 }
1031 
evalTexture2DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1032 static void evalTexture2DShadowBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1033 {
1034     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));
1035 }
evalTextureCubeShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1036 static void evalTextureCubeShadowBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1037 {
1038     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
1039                                     de::max(p.lod + c.in[1].x(), p.lodClamp));
1040 }
evalTexture1DShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1041 static void evalTexture1DShadowBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1042 {
1043     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(p.lod + c.in[1].x(), p.lodClamp));
1044 }
evalTexture1DArrayShadowBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1045 static void evalTexture1DArrayShadowBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1046 {
1047     c.color.x() =
1048         texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(p.lod + c.in[1].x(), p.lodClamp));
1049 }
evalTexture2DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1050 static void evalTexture2DShadowOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1051 {
1052     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(),
1053                                         de::max(p.lod + c.in[1].x(), p.lodClamp), p.offset.swizzle(0, 1));
1054 }
evalTexture1DShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1055 static void evalTexture1DShadowOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1056 {
1057     c.color.x() =
1058         texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(p.lod + c.in[1].x(), p.lodClamp), p.offset.x());
1059 }
evalTexture1DArrayShadowOffsetBiasClamp(ShaderEvalContext & c,const TexLookupParams & p)1060 static void evalTexture1DArrayShadowOffsetBiasClamp(ShaderEvalContext &c, const TexLookupParams &p)
1061 {
1062     c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(),
1063                                              de::max(p.lod + c.in[1].x(), p.lodClamp), p.offset.x());
1064 }
1065 
1066 // Gradient variarts
1067 
evalTexture2DGrad(ShaderEvalContext & c,const TexLookupParams & p)1068 static void evalTexture2DGrad(ShaderEvalContext &c, const TexLookupParams &p)
1069 {
1070     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)) * p.scale + p.bias;
1071 }
evalTextureCubeGrad(ShaderEvalContext & c,const TexLookupParams & p)1072 static void evalTextureCubeGrad(ShaderEvalContext &c, const TexLookupParams &p)
1073 {
1074     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c)) * p.scale + p.bias;
1075 }
evalTexture2DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)1076 static void evalTexture2DArrayGrad(ShaderEvalContext &c, const TexLookupParams &p)
1077 {
1078     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c)) * p.scale + p.bias;
1079 }
evalTexture3DGrad(ShaderEvalContext & c,const TexLookupParams & p)1080 static void evalTexture3DGrad(ShaderEvalContext &c, const TexLookupParams &p)
1081 {
1082     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c)) * p.scale + p.bias;
1083 }
evalTexture1DGrad(ShaderEvalContext & c,const TexLookupParams & p)1084 static void evalTexture1DGrad(ShaderEvalContext &c, const TexLookupParams &p)
1085 {
1086     c.color = texture1D(c, c.in[0].x(), computeLodFromGrad1D(c)) * p.scale + p.bias;
1087 }
evalTexture1DArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)1088 static void evalTexture1DArrayGrad(ShaderEvalContext &c, const TexLookupParams &p)
1089 {
1090     c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c)) * p.scale + p.bias;
1091 }
evalTextureCubeArrayGrad(ShaderEvalContext & c,const TexLookupParams & p)1092 static void evalTextureCubeArrayGrad(ShaderEvalContext &c, const TexLookupParams &p)
1093 {
1094     c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(), computeLodFromGradCubeArray(c)) *
1095                   p.scale +
1096               p.bias;
1097 }
1098 
evalTexture2DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)1099 static void evalTexture2DShadowGrad(ShaderEvalContext &c, const TexLookupParams &)
1100 {
1101     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c));
1102 }
evalTextureCubeShadowGrad(ShaderEvalContext & c,const TexLookupParams &)1103 static void evalTextureCubeShadowGrad(ShaderEvalContext &c, const TexLookupParams &)
1104 {
1105     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c));
1106 }
evalTexture2DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)1107 static void evalTexture2DArrayShadowGrad(ShaderEvalContext &c, const TexLookupParams &)
1108 {
1109     c.color.x() =
1110         texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c));
1111 }
evalTexture1DShadowGrad(ShaderEvalContext & c,const TexLookupParams &)1112 static void evalTexture1DShadowGrad(ShaderEvalContext &c, const TexLookupParams &)
1113 {
1114     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c));
1115 }
evalTexture1DArrayShadowGrad(ShaderEvalContext & c,const TexLookupParams &)1116 static void evalTexture1DArrayShadowGrad(ShaderEvalContext &c, const TexLookupParams &)
1117 {
1118     c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c));
1119 }
1120 
evalTexture2DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1121 static void evalTexture2DGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1122 {
1123     c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0, 1)) * p.scale +
1124               p.bias;
1125 }
evalTexture2DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1126 static void evalTexture2DArrayGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1127 {
1128     c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c),
1129                                    p.offset.swizzle(0, 1)) *
1130                   p.scale +
1131               p.bias;
1132 }
evalTexture3DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1133 static void evalTexture3DGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1134 {
1135     c.color =
1136         texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c), p.offset) * p.scale + p.bias;
1137 }
evalTexture1DGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1138 static void evalTexture1DGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1139 {
1140     c.color = texture1DOffset(c, c.in[0].x(), computeLodFromGrad1D(c), p.offset.x()) * p.scale + p.bias;
1141 }
evalTexture1DArrayGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1142 static void evalTexture1DArrayGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1143 {
1144     c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c), p.offset.x()) * p.scale +
1145               p.bias;
1146 }
1147 
evalTexture2DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1148 static void evalTexture2DShadowGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1149 {
1150     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c),
1151                                         p.offset.swizzle(0, 1));
1152 }
evalTexture2DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1153 static void evalTexture2DArrayShadowGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1154 {
1155     c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
1156                                              computeLodFromGrad2DArray(c), p.offset.swizzle(0, 1));
1157 }
evalTexture1DShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1158 static void evalTexture1DShadowGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1159 {
1160     c.color.x() = texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), computeLodFromGrad1D(c), p.offset.x());
1161 }
evalTexture1DArrayShadowGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1162 static void evalTexture1DArrayShadowGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1163 {
1164     c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad1DArray(c),
1165                                              p.offset.x());
1166 }
1167 
evalTexture2DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)1168 static void evalTexture2DShadowProjGrad(ShaderEvalContext &c, const TexLookupParams &)
1169 {
1170     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(),
1171                                   computeLodFromGrad2D(c));
1172 }
evalTexture2DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1173 static void evalTexture2DShadowProjGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1174 {
1175     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
1176                                         c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0, 1));
1177 }
evalTexture1DShadowProjGrad(ShaderEvalContext & c,const TexLookupParams &)1178 static void evalTexture1DShadowProjGrad(ShaderEvalContext &c, const TexLookupParams &)
1179 {
1180     c.color.x() = texture1DShadow(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(), computeLodFromGrad1D(c));
1181 }
evalTexture1DShadowProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1182 static void evalTexture1DShadowProjGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1183 {
1184     c.color.x() = texture1DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
1185                                         computeLodFromGrad1D(c), p.offset.x());
1186 }
1187 
evalTexture2DProjGrad3(ShaderEvalContext & c,const TexLookupParams & p)1188 static void evalTexture2DProjGrad3(ShaderEvalContext &c, const TexLookupParams &p)
1189 {
1190     c.color =
1191         texture2D(c, c.in[0].x() / c.in[0].z(), c.in[0].y() / c.in[0].z(), computeLodFromGrad2D(c)) * p.scale + p.bias;
1192 }
evalTexture2DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)1193 static void evalTexture2DProjGrad(ShaderEvalContext &c, const TexLookupParams &p)
1194 {
1195     c.color =
1196         texture2D(c, c.in[0].x() / c.in[0].w(), c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c)) * p.scale + p.bias;
1197 }
evalTexture3DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)1198 static void evalTexture3DProjGrad(ShaderEvalContext &c, const TexLookupParams &p)
1199 {
1200     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(),
1201                         computeLodFromGrad3D(c)) *
1202                   p.scale +
1203               p.bias;
1204 }
evalTexture1DProjGrad2(ShaderEvalContext & c,const TexLookupParams & p)1205 static void evalTexture1DProjGrad2(ShaderEvalContext &c, const TexLookupParams &p)
1206 {
1207     c.color = texture1D(c, c.in[0].x() / c.in[0].y(), computeLodFromGrad1D(c)) * p.scale + p.bias;
1208 }
evalTexture1DProjGrad(ShaderEvalContext & c,const TexLookupParams & p)1209 static void evalTexture1DProjGrad(ShaderEvalContext &c, const TexLookupParams &p)
1210 {
1211     c.color = texture1D(c, c.in[0].x() / c.in[0].w(), computeLodFromGrad1D(c)) * p.scale + p.bias;
1212 }
1213 
evalTexture2DProjGrad3Offset(ShaderEvalContext & c,const TexLookupParams & p)1214 static void evalTexture2DProjGrad3Offset(ShaderEvalContext &c, const TexLookupParams &p)
1215 {
1216     c.color = texture2DOffset(c, c.in[0].x() / c.in[0].z(), c.in[0].y() / c.in[0].z(), computeLodFromGrad2D(c),
1217                               p.offset.swizzle(0, 1)) *
1218                   p.scale +
1219               p.bias;
1220 }
evalTexture2DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1221 static void evalTexture2DProjGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1222 {
1223     c.color = texture2DOffset(c, c.in[0].x() / c.in[0].w(), c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c),
1224                               p.offset.swizzle(0, 1)) *
1225                   p.scale +
1226               p.bias;
1227 }
evalTexture3DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1228 static void evalTexture3DProjGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1229 {
1230     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(),
1231                               computeLodFromGrad3D(c), p.offset) *
1232                   p.scale +
1233               p.bias;
1234 }
evalTexture1DProjGrad2Offset(ShaderEvalContext & c,const TexLookupParams & p)1235 static void evalTexture1DProjGrad2Offset(ShaderEvalContext &c, const TexLookupParams &p)
1236 {
1237     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].y(), computeLodFromGrad1D(c), p.offset.x()) * p.scale + p.bias;
1238 }
evalTexture1DProjGradOffset(ShaderEvalContext & c,const TexLookupParams & p)1239 static void evalTexture1DProjGradOffset(ShaderEvalContext &c, const TexLookupParams &p)
1240 {
1241     c.color = texture1DOffset(c, c.in[0].x() / c.in[0].w(), computeLodFromGrad1D(c), p.offset.x()) * p.scale + p.bias;
1242 }
1243 
evalTexture2DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1244 static void evalTexture2DGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1245 {
1246     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp)) * p.scale + p.bias;
1247 }
evalTextureCubeGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1248 static void evalTextureCubeGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1249 {
1250     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGradCube(c), p.lodClamp)) *
1251                   p.scale +
1252               p.bias;
1253 }
evalTexture2DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1254 static void evalTexture2DArrayGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1255 {
1256     c.color =
1257         texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad2DArray(c), p.lodClamp)) *
1258             p.scale +
1259         p.bias;
1260 }
evalTexture3DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1261 static void evalTexture3DGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1262 {
1263     c.color =
1264         texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp)) * p.scale +
1265         p.bias;
1266 }
evalTexture1DGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1267 static void evalTexture1DGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1268 {
1269     c.color = texture1D(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp)) * p.scale + p.bias;
1270 }
evalTexture1DArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1271 static void evalTexture1DArrayGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1272 {
1273     c.color = texture1DArray(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp)) * p.scale +
1274               p.bias;
1275 }
evalTextureCubeArrayGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1276 static void evalTextureCubeArrayGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1277 {
1278     c.color = textureCubeArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[0].w(),
1279                                de::max(computeLodFromGradCubeArray(c), p.lodClamp)) *
1280                   p.scale +
1281               p.bias;
1282 }
1283 
evalTexture2DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1284 static void evalTexture2DShadowGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1285 {
1286     c.color.x() =
1287         texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp));
1288 }
evalTextureCubeShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1289 static void evalTextureCubeShadowGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1290 {
1291     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
1292                                     de::max(computeLodFromGradCube(c), p.lodClamp));
1293 }
evalTexture2DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1294 static void evalTexture2DArrayShadowGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1295 {
1296     c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
1297                                        de::max(computeLodFromGrad2DArray(c), p.lodClamp));
1298 }
evalTexture1DShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1299 static void evalTexture1DShadowGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1300 {
1301     c.color.x() = texture1DShadow(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp));
1302 }
evalTexture1DArrayShadowGradClamp(ShaderEvalContext & c,const TexLookupParams & p)1303 static void evalTexture1DArrayShadowGradClamp(ShaderEvalContext &c, const TexLookupParams &p)
1304 {
1305     c.color.x() = texture1DArrayShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(),
1306                                        de::max(computeLodFromGrad1DArray(c), p.lodClamp));
1307 }
1308 
evalTexture2DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1309 static void evalTexture2DGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1310 {
1311     c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad2D(c), p.lodClamp),
1312                               p.offset.swizzle(0, 1)) *
1313                   p.scale +
1314               p.bias;
1315 }
evalTexture2DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1316 static void evalTexture2DArrayGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1317 {
1318     c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(),
1319                                    de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0, 1)) *
1320                   p.scale +
1321               p.bias;
1322 }
evalTexture3DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1323 static void evalTexture3DGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1324 {
1325     c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), de::max(computeLodFromGrad3D(c), p.lodClamp),
1326                               p.offset) *
1327                   p.scale +
1328               p.bias;
1329 }
evalTexture1DGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1330 static void evalTexture1DGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1331 {
1332     c.color =
1333         texture1DOffset(c, c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x()) * p.scale + p.bias;
1334 }
evalTexture1DArrayGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1335 static void evalTexture1DArrayGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1336 {
1337     c.color = texture1DArrayOffset(c, c.in[0].x(), c.in[0].y(), de::max(computeLodFromGrad1DArray(c), p.lodClamp),
1338                                    p.offset.x()) *
1339                   p.scale +
1340               p.bias;
1341 }
1342 
evalTexture2DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1343 static void evalTexture2DShadowGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1344 {
1345     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(),
1346                                         de::max(computeLodFromGrad2D(c), p.lodClamp), p.offset.swizzle(0, 1));
1347 }
evalTexture2DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1348 static void evalTexture2DArrayShadowGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1349 {
1350     c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
1351                                              de::max(computeLodFromGrad2DArray(c), p.lodClamp), p.offset.swizzle(0, 1));
1352 }
evalTexture1DShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1353 static void evalTexture1DShadowGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1354 {
1355     c.color.x() =
1356         texture1DShadowOffset(c, c.in[0].z(), c.in[0].x(), de::max(computeLodFromGrad1D(c), p.lodClamp), p.offset.x());
1357 }
evalTexture1DArrayShadowGradOffsetClamp(ShaderEvalContext & c,const TexLookupParams & p)1358 static void evalTexture1DArrayShadowGradOffsetClamp(ShaderEvalContext &c, const TexLookupParams &p)
1359 {
1360     c.color.x() = texture1DArrayShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(),
1361                                              de::max(computeLodFromGrad1DArray(c), p.lodClamp), p.offset.x());
1362 }
1363 
1364 // Texel fetch variants
1365 
evalTexelFetch2D(ShaderEvalContext & c,const TexLookupParams & p)1366 static void evalTexelFetch2D(ShaderEvalContext &c, const TexLookupParams &p)
1367 {
1368     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
1369     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
1370     int lod = deChopFloatToInt32(c.in[1].x());
1371     c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y) * p.scale + p.bias;
1372 }
1373 
evalTexelFetch2DArray(ShaderEvalContext & c,const TexLookupParams & p)1374 static void evalTexelFetch2DArray(ShaderEvalContext &c, const TexLookupParams &p)
1375 {
1376     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
1377     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
1378     int l   = deChopFloatToInt32(c.in[0].z());
1379     int lod = deChopFloatToInt32(c.in[1].x());
1380     c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l) * p.scale + p.bias;
1381 }
1382 
evalTexelFetch3D(ShaderEvalContext & c,const TexLookupParams & p)1383 static void evalTexelFetch3D(ShaderEvalContext &c, const TexLookupParams &p)
1384 {
1385     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
1386     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
1387     int z   = deChopFloatToInt32(c.in[0].z()) + p.offset.z();
1388     int lod = deChopFloatToInt32(c.in[1].x());
1389     c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z) * p.scale + p.bias;
1390 }
1391 
evalTexelFetch1D(ShaderEvalContext & c,const TexLookupParams & p)1392 static void evalTexelFetch1D(ShaderEvalContext &c, const TexLookupParams &p)
1393 {
1394     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
1395     int lod = deChopFloatToInt32(c.in[1].x());
1396     c.color = c.textures[0].tex1D->getLevel(lod).getPixel(x, 0) * p.scale + p.bias;
1397 }
1398 
evalTexelFetch1DArray(ShaderEvalContext & c,const TexLookupParams & p)1399 static void evalTexelFetch1DArray(ShaderEvalContext &c, const TexLookupParams &p)
1400 {
1401     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
1402     int l   = deChopFloatToInt32(c.in[0].y());
1403     int lod = deChopFloatToInt32(c.in[1].x());
1404     c.color = c.textures[0].tex1DArray->getLevel(lod).getPixel(x, l) * p.scale + p.bias;
1405 }
1406 
1407 class TexLookupEvaluator : public ShaderEvaluator
1408 {
1409 public:
TexLookupEvaluator(TexEvalFunc evalFunc,const TexLookupParams & lookupParams)1410     TexLookupEvaluator(TexEvalFunc evalFunc, const TexLookupParams &lookupParams)
1411         : m_evalFunc(evalFunc)
1412         , m_lookupParams(lookupParams)
1413     {
1414     }
~TexLookupEvaluator(void)1415     virtual ~TexLookupEvaluator(void)
1416     {
1417     }
1418 
evaluate(ShaderEvalContext & ctx) const1419     virtual void evaluate(ShaderEvalContext &ctx) const
1420     {
1421         m_evalFunc(ctx, m_lookupParams);
1422     }
1423 
1424 private:
1425     TexEvalFunc m_evalFunc;
1426     const TexLookupParams &m_lookupParams;
1427 };
1428 
checkDeviceFeatures(Context & context,TextureType textureType)1429 static void checkDeviceFeatures(Context &context, TextureType textureType)
1430 {
1431     if (textureType == TEXTURETYPE_CUBE_ARRAY)
1432     {
1433         const vk::VkPhysicalDeviceFeatures &deviceFeatures = context.getDeviceFeatures();
1434 
1435         if (!deviceFeatures.imageCubeArray)
1436             TCU_THROW(NotSupportedError, "Cube array is not supported");
1437     }
1438 }
1439 
checkMutableComparisonSamplersSupport(Context & context,const TextureSpec & textureSpec)1440 static void checkMutableComparisonSamplersSupport(Context &context, const TextureSpec &textureSpec)
1441 {
1442     // when compare mode is not none then ShaderRenderCaseInstance::createSamplerUniform
1443     // uses mapSampler utill from vkImageUtil that sets compareEnable to true
1444     // for portability this needs to be under feature flag
1445 #ifndef CTS_USES_VULKANSC
1446     if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1447         !context.getPortabilitySubsetFeatures().mutableComparisonSamplers &&
1448         (textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE))
1449     {
1450         TCU_THROW(NotSupportedError,
1451                   "VK_KHR_portability_subset: mutableComparisonSamplers are not supported by this implementation");
1452     }
1453 #else
1454     DE_UNREF(context);
1455     DE_UNREF(textureSpec);
1456 #endif // CTS_USES_VULKANSC
1457 }
1458 
1459 class ShaderTextureFunctionInstance : public ShaderRenderCaseInstance
1460 {
1461 public:
1462     ShaderTextureFunctionInstance(Context &context, const bool isVertexCase, const ShaderEvaluator &evaluator,
1463                                   const UniformSetup &uniformSetup, const TextureLookupSpec &lookupSpec,
1464                                   const TextureSpec &textureSpec, const TexLookupParams &lookupParams,
1465                                   const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_REGULAR);
1466     virtual ~ShaderTextureFunctionInstance(void);
1467 
1468 protected:
1469     virtual void setupUniforms(const tcu::Vec4 &);
1470     void initTexture(void);
1471 
1472 private:
1473     const TextureLookupSpec &m_lookupSpec;
1474     const TextureSpec &m_textureSpec;
1475     const TexLookupParams &m_lookupParams;
1476 };
1477 
ShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)1478 ShaderTextureFunctionInstance::ShaderTextureFunctionInstance(
1479     Context &context, const bool isVertexCase, const ShaderEvaluator &evaluator, const UniformSetup &uniformSetup,
1480     const TextureLookupSpec &lookupSpec, const TextureSpec &textureSpec, const TexLookupParams &lookupParams,
1481     const ImageBackingMode imageBackingMode)
1482     : ShaderRenderCaseInstance(context, isVertexCase, evaluator, uniformSetup, DE_NULL, imageBackingMode,
1483                                (isVertexCase ? 92 : GRID_SIZE_DEFAULT_FRAGMENT))
1484     , m_lookupSpec(lookupSpec)
1485     , m_textureSpec(textureSpec)
1486     , m_lookupParams(lookupParams)
1487 {
1488     checkDeviceFeatures(m_context, m_textureSpec.type);
1489 
1490     if (lookupSpec.useClamp)
1491     {
1492         const vk::VkPhysicalDeviceFeatures &deviceFeatures = context.getDeviceFeatures();
1493 
1494         if (!deviceFeatures.shaderResourceMinLod)
1495             TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
1496     }
1497 
1498     {
1499         // Base coord scale & bias
1500         Vec4 s = m_lookupSpec.maxCoord - m_lookupSpec.minCoord;
1501         Vec4 b = m_lookupSpec.minCoord;
1502 
1503         float baseCoordTrans[] = {s.x(),        0.0f,         0.f, b.x(),
1504                                   0.f,          s.y(),        0.f, b.y(),
1505                                   s.z() / 2.f,  -s.z() / 2.f, 0.f, s.z() / 2.f + b.z(),
1506                                   -s.w() / 2.f, s.w() / 2.f,  0.f, s.w() / 2.f + b.w()};
1507 
1508         m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
1509 
1510         useAttribute(4u, A_IN0);
1511     }
1512 
1513     bool hasLodBias = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1514     bool isGrad     = functionHasGrad(m_lookupSpec.function);
1515     DE_ASSERT(!isGrad || !hasLodBias);
1516 
1517     if (hasLodBias)
1518     {
1519         float s               = m_lookupSpec.maxLodBias - m_lookupSpec.minLodBias;
1520         float b               = m_lookupSpec.minLodBias;
1521         float lodCoordTrans[] = {s / 2.0f, s / 2.0f, 0.f,  b,    0.0f, 0.0f, 0.0f, 0.0f,
1522                                  0.0f,     0.0f,     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
1523 
1524         m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
1525 
1526         useAttribute(5u, A_IN1);
1527     }
1528     else if (isGrad)
1529     {
1530         Vec3 sx             = m_lookupSpec.maxDX - m_lookupSpec.minDX;
1531         Vec3 sy             = m_lookupSpec.maxDY - m_lookupSpec.minDY;
1532         float gradDxTrans[] = {sx.x() / 2.0f, sx.x() / 2.0f, 0.f,  m_lookupSpec.minDX.x(),
1533                                sx.y() / 2.0f, sx.y() / 2.0f, 0.0f, m_lookupSpec.minDX.y(),
1534                                sx.z() / 2.0f, sx.z() / 2.0f, 0.0f, m_lookupSpec.minDX.z(),
1535                                0.0f,          0.0f,          0.0f, 0.0f};
1536         float gradDyTrans[] = {-sy.x() / 2.0f, -sy.x() / 2.0f, 0.f,  m_lookupSpec.maxDY.x(),
1537                                -sy.y() / 2.0f, -sy.y() / 2.0f, 0.0f, m_lookupSpec.maxDY.y(),
1538                                -sy.z() / 2.0f, -sy.z() / 2.0f, 0.0f, m_lookupSpec.maxDY.z(),
1539                                0.0f,           0.0f,           0.0f, 0.0f};
1540 
1541         m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
1542         m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
1543 
1544         useAttribute(5u, A_IN1);
1545         useAttribute(6u, A_IN2);
1546     }
1547 
1548     initTexture();
1549 }
1550 
~ShaderTextureFunctionInstance(void)1551 ShaderTextureFunctionInstance::~ShaderTextureFunctionInstance(void)
1552 {
1553 }
1554 
setupUniforms(const tcu::Vec4 &)1555 void ShaderTextureFunctionInstance::setupUniforms(const tcu::Vec4 &)
1556 {
1557     useSampler(0u, 0u);
1558     addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.scale.getPtr());
1559     addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(tcu::Vec4), m_lookupParams.bias.getPtr());
1560 }
1561 
initTexture(void)1562 void ShaderTextureFunctionInstance::initTexture(void)
1563 {
1564     static const IVec4 texCubeSwz[] = {IVec4(0, 0, 1, 1), IVec4(1, 1, 0, 0), IVec4(0, 1, 0, 1),
1565                                        IVec4(1, 0, 1, 0), IVec4(0, 1, 1, 0), IVec4(1, 0, 0, 1)};
1566     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
1567 
1568     tcu::TextureFormat texFmt      = glu::mapGLInternalFormat(m_textureSpec.format);
1569     tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1570     tcu::UVec2 viewportSize        = getViewportSize();
1571     bool isProj                    = functionHasProj(m_lookupSpec.function);
1572     bool isAutoLod = functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
1573                                         m_lookupSpec.function); // LOD can vary significantly
1574     float proj = isProj ? 1.0f / m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ2 ? 1 :
1575                                                        m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 :
1576                                                                                                         3] :
1577                           1.0f;
1578     TexLookupParams lookupParams;
1579 
1580     switch (m_textureSpec.type)
1581     {
1582     case TEXTURETYPE_2D:
1583     {
1584         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
1585         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1586         Vec4 cBias       = fmtInfo.valueMin;
1587         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
1588         de::MovePtr<tcu::Texture2D> texture2D;
1589 
1590         texture2D = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(texFmt, m_textureSpec.width, m_textureSpec.height));
1591 
1592         for (int level = 0; level < m_textureSpec.numLevels; level++)
1593         {
1594             float fA    = float(level) * levelStep;
1595             float fB    = 1.0f - fA;
1596             Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1597             Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1598 
1599             texture2D->allocLevel(level);
1600             tcu::fillWithGrid(texture2D->getLevel(level), de::max(1, baseCellSize >> level), colorA, colorB);
1601         }
1602 
1603         // Compute LOD.
1604         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1605                      (float)viewportSize[0];
1606         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
1607                      (float)viewportSize[1];
1608         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1609 
1610         // Append to texture list.
1611         m_textures.push_back(TextureBindingSp(new TextureBinding(texture2D.release(), m_textureSpec.sampler)));
1612         break;
1613     }
1614 
1615     case TEXTURETYPE_CUBE_MAP:
1616     {
1617         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
1618         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1619         Vec4 cBias       = fmtInfo.valueMin;
1620         Vec4 cCorner     = cBias + cScale * 0.5f;
1621         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
1622         de::MovePtr<tcu::TextureCube> textureCube;
1623 
1624         DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
1625         textureCube = de::MovePtr<tcu::TextureCube>(new tcu::TextureCube(texFmt, m_textureSpec.width));
1626 
1627         for (int level = 0; level < m_textureSpec.numLevels; level++)
1628         {
1629             float fA = float(level) * levelStep;
1630             float fB = 1.0f - fA;
1631             Vec2 f(fA, fB);
1632 
1633             for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1634             {
1635                 const IVec4 &swzA = texCubeSwz[face];
1636                 IVec4 swzB        = 1 - swzA;
1637                 Vec4 colorA       = cBias + cScale * f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
1638                 Vec4 colorB       = cBias + cScale * f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
1639 
1640                 textureCube->allocLevel((tcu::CubeFace)face, level);
1641 
1642                 {
1643                     const tcu::PixelBufferAccess access = textureCube->getLevelFace(level, (tcu::CubeFace)face);
1644                     const int lastPix                   = access.getWidth() - 1;
1645 
1646                     tcu::fillWithGrid(access, de::max(1, baseCellSize >> level), colorA, colorB);
1647 
1648                     // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
1649                     access.setPixel(cCorner, 0, 0);
1650                     access.setPixel(cCorner, 0, lastPix);
1651                     access.setPixel(cCorner, lastPix, 0);
1652                     access.setPixel(cCorner, lastPix, lastPix);
1653                 }
1654             }
1655         }
1656 
1657         // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
1658         DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
1659         DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) &&
1660                   de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
1661         DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) &&
1662                   de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
1663 
1664         tcu::CubeFaceFloatCoords c00 = tcu::getCubeFaceCoords(
1665             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1666         tcu::CubeFaceFloatCoords c10 = tcu::getCubeFaceCoords(
1667             Vec3(m_lookupSpec.maxCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1668         tcu::CubeFaceFloatCoords c01 = tcu::getCubeFaceCoords(
1669             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.maxCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1670         float dudx       = (c10.s - c00.s) * (float)m_textureSpec.width / (float)viewportSize[0];
1671         float dvdy       = (c01.t - c00.t) * (float)m_textureSpec.height / (float)viewportSize[1];
1672         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1673 
1674         // Append to texture list.
1675         m_textures.push_back(TextureBindingSp(new TextureBinding(textureCube.release(), m_textureSpec.sampler)));
1676         break;
1677     }
1678 
1679     case TEXTURETYPE_2D_ARRAY:
1680     {
1681         float layerStep = 1.0f / (float)m_textureSpec.depth;
1682         float levelStep =
1683             isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels - 1) * m_textureSpec.depth);
1684         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1685         Vec4 cBias       = fmtInfo.valueMin;
1686         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
1687         de::MovePtr<tcu::Texture2DArray> texture2DArray;
1688 
1689         texture2DArray = de::MovePtr<tcu::Texture2DArray>(
1690             new tcu::Texture2DArray(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
1691 
1692         for (int level = 0; level < m_textureSpec.numLevels; level++)
1693         {
1694             texture2DArray->allocLevel(level);
1695             tcu::PixelBufferAccess levelAccess = texture2DArray->getLevel(level);
1696 
1697             for (int layer = 0; layer < levelAccess.getDepth(); layer++)
1698             {
1699                 float fA    = (float)layer * layerStep + (float)level * levelStep;
1700                 float fB    = 1.0f - fA;
1701                 Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1702                 Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1703 
1704                 tcu::fillWithGrid(
1705                     tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1),
1706                     de::max(1, baseCellSize >> level), colorA, colorB);
1707             }
1708         }
1709 
1710         // Compute LOD.
1711         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1712                      (float)viewportSize[0];
1713         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
1714                      (float)viewportSize[1];
1715         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1716 
1717         // Append to texture list.
1718         m_textures.push_back(TextureBindingSp(new TextureBinding(texture2DArray.release(), m_textureSpec.sampler)));
1719         break;
1720     }
1721 
1722     case TEXTURETYPE_3D:
1723     {
1724         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
1725         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1726         Vec4 cBias       = fmtInfo.valueMin;
1727         int baseCellSize = de::min(de::min(m_textureSpec.width / 2, m_textureSpec.height / 2), m_textureSpec.depth / 2);
1728         de::MovePtr<tcu::Texture3D> texture3D;
1729 
1730         texture3D = de::MovePtr<tcu::Texture3D>(
1731             new tcu::Texture3D(texFmt, m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth));
1732 
1733         for (int level = 0; level < m_textureSpec.numLevels; level++)
1734         {
1735             float fA    = (float)level * levelStep;
1736             float fB    = 1.0f - fA;
1737             Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1738             Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1739 
1740             texture3D->allocLevel(level);
1741             tcu::fillWithGrid(texture3D->getLevel(level), de::max(1, baseCellSize >> level), colorA, colorB);
1742         }
1743 
1744         // Compute LOD.
1745         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1746                      (float)viewportSize[0];
1747         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
1748                      (float)viewportSize[1];
1749         float dwdx = (m_lookupSpec.maxCoord[2] - m_lookupSpec.minCoord[2]) * 0.5f * proj * (float)m_textureSpec.depth /
1750                      (float)viewportSize[0];
1751         float dwdy = (m_lookupSpec.maxCoord[2] - m_lookupSpec.minCoord[2]) * 0.5f * proj * (float)m_textureSpec.depth /
1752                      (float)viewportSize[1];
1753         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
1754 
1755         // Append to texture list.
1756         m_textures.push_back(TextureBindingSp(new TextureBinding(texture3D.release(), m_textureSpec.sampler)));
1757         break;
1758     }
1759 
1760     case TEXTURETYPE_1D:
1761     {
1762         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
1763         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1764         Vec4 cBias       = fmtInfo.valueMin;
1765         int baseCellSize = m_textureSpec.width / 4;
1766         de::MovePtr<tcu::Texture1D> texture1D;
1767 
1768         texture1D = de::MovePtr<tcu::Texture1D>(new tcu::Texture1D(texFmt, m_textureSpec.width));
1769 
1770         for (int level = 0; level < m_textureSpec.numLevels; level++)
1771         {
1772             float fA    = float(level) * levelStep;
1773             float fB    = 1.0f - fA;
1774             Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1775             Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1776 
1777             texture1D->allocLevel(level);
1778             tcu::fillWithGrid(texture1D->getLevel(level), de::max(1, baseCellSize >> level), colorA, colorB);
1779         }
1780 
1781         // Compute LOD.
1782         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1783                      (float)viewportSize[0];
1784         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1785 
1786         // Append to texture list.
1787         m_textures.push_back(TextureBindingSp(new TextureBinding(texture1D.release(), m_textureSpec.sampler)));
1788         break;
1789     }
1790 
1791     case TEXTURETYPE_1D_ARRAY:
1792     {
1793         float layerStep = 1.0f / (float)m_textureSpec.depth;
1794         float levelStep =
1795             isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels - 1) * m_textureSpec.depth);
1796         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1797         Vec4 cBias       = fmtInfo.valueMin;
1798         int baseCellSize = m_textureSpec.width / 4;
1799         de::MovePtr<tcu::Texture1DArray> texture1DArray;
1800 
1801         texture1DArray =
1802             de::MovePtr<tcu::Texture1DArray>(new tcu::Texture1DArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1803 
1804         for (int level = 0; level < m_textureSpec.numLevels; level++)
1805         {
1806             texture1DArray->allocLevel(level);
1807             tcu::PixelBufferAccess levelAccess = texture1DArray->getLevel(level);
1808 
1809             for (int layer = 0; layer < levelAccess.getHeight(); layer++)
1810             {
1811                 float fA    = (float)layer * layerStep + (float)level * levelStep;
1812                 float fB    = 1.0f - fA;
1813                 Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1814                 Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1815 
1816                 tcu::fillWithGrid(tcu::getSubregion(levelAccess, 0, layer, 0, levelAccess.getWidth(), 1, 1),
1817                                   de::max(1, baseCellSize >> level), colorA, colorB);
1818             }
1819         }
1820 
1821         // Compute LOD.
1822         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1823                      (float)viewportSize[0];
1824         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f);
1825 
1826         // Append to texture list.
1827         m_textures.push_back(TextureBindingSp(new TextureBinding(texture1DArray.release(), m_textureSpec.sampler)));
1828         break;
1829     }
1830 
1831     case TEXTURETYPE_CUBE_ARRAY:
1832     {
1833         float layerStep = 1.0f / (float)(m_textureSpec.depth / 6);
1834         float levelStep =
1835             isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels - 1) * (m_textureSpec.depth / 6));
1836         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1837         Vec4 cBias       = fmtInfo.valueMin;
1838         Vec4 cCorner     = cBias + cScale * 0.5f;
1839         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
1840         de::MovePtr<tcu::TextureCubeArray> textureCubeArray;
1841 
1842         DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
1843         DE_ASSERT(m_textureSpec.depth % 6 == 0);
1844 
1845         textureCubeArray = de::MovePtr<tcu::TextureCubeArray>(
1846             new tcu::TextureCubeArray(texFmt, m_textureSpec.width, m_textureSpec.depth));
1847 
1848         for (int level = 0; level < m_textureSpec.numLevels; level++)
1849         {
1850             float fA = float(level) * levelStep;
1851             float fB = 1.0f - fA;
1852             Vec2 f(fA, fB);
1853 
1854             textureCubeArray->allocLevel(level);
1855             tcu::PixelBufferAccess levelAccess = textureCubeArray->getLevel(level);
1856 
1857             for (int layer = 0; layer < m_textureSpec.depth / 6; layer++)
1858             {
1859                 float layerCorr = 1.0f - (float)layer * layerStep;
1860 
1861                 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1862                 {
1863                     const IVec4 &swzA = texCubeSwz[face];
1864                     IVec4 swzB        = 1 - swzA;
1865                     Vec4 colorA       = cBias + cScale * f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]) * layerCorr;
1866                     Vec4 colorB       = cBias + cScale * f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]) * layerCorr;
1867 
1868                     {
1869                         const tcu::PixelBufferAccess access = tcu::getSubregion(
1870                             levelAccess, 0, 0, (layer * 6) + face, levelAccess.getWidth(), levelAccess.getHeight(), 1);
1871                         const int lastPix = access.getWidth() - 1;
1872 
1873                         tcu::fillWithGrid(access, de::max(1, baseCellSize >> level), colorA, colorB);
1874 
1875                         // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
1876                         access.setPixel(cCorner, 0, 0);
1877                         access.setPixel(cCorner, 0, lastPix);
1878                         access.setPixel(cCorner, lastPix, 0);
1879                         access.setPixel(cCorner, lastPix, lastPix);
1880                     }
1881                 }
1882             }
1883         }
1884 
1885         // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
1886         DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
1887         DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) &&
1888                   de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
1889         DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) &&
1890                   de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
1891 
1892         tcu::CubeFaceFloatCoords c00 = tcu::getCubeFaceCoords(
1893             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1894         tcu::CubeFaceFloatCoords c10 = tcu::getCubeFaceCoords(
1895             Vec3(m_lookupSpec.maxCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1896         tcu::CubeFaceFloatCoords c01 = tcu::getCubeFaceCoords(
1897             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.maxCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
1898         float dudx       = (c10.s - c00.s) * (float)m_textureSpec.width / (float)viewportSize[0];
1899         float dvdy       = (c01.t - c00.t) * (float)m_textureSpec.height / (float)viewportSize[1];
1900         lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1901 
1902         // Append to texture list.
1903         m_textures.push_back(TextureBindingSp(new TextureBinding(textureCubeArray.release(), m_textureSpec.sampler)));
1904         break;
1905     }
1906 
1907     default:
1908         DE_ASSERT(false);
1909     }
1910 
1911     // Set lookup scale & bias
1912     lookupParams.scale    = fmtInfo.lookupScale;
1913     lookupParams.bias     = fmtInfo.lookupBias;
1914     lookupParams.offset   = m_lookupSpec.offset;
1915     lookupParams.lodClamp = m_lookupSpec.lodClamp;
1916 
1917     // \todo [dirnerakos] Avoid const cast somehow
1918     const_cast<TexLookupParams &>(m_lookupParams) = lookupParams;
1919 }
1920 
1921 class ShaderTextureFunctionCase : public ShaderRenderCase
1922 {
1923 public:
1924     ShaderTextureFunctionCase(tcu::TestContext &testCtx, const std::string &name, const TextureLookupSpec &lookup,
1925                               const TextureSpec &texture, TexEvalFunc evalFunc, bool isVertexCase);
1926     virtual ~ShaderTextureFunctionCase(void);
1927 
1928     virtual TestInstance *createInstance(Context &context) const;
1929     virtual void checkSupport(Context &context) const;
1930 
1931 protected:
1932     const TextureLookupSpec m_lookupSpec;
1933     const TextureSpec m_textureSpec;
1934     const TexLookupParams m_lookupParams;
1935 
1936     void initShaderSources(void);
1937 };
1938 
ShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)1939 ShaderTextureFunctionCase::ShaderTextureFunctionCase(tcu::TestContext &testCtx, const std::string &name,
1940                                                      const TextureLookupSpec &lookup, const TextureSpec &texture,
1941                                                      TexEvalFunc evalFunc, bool isVertexCase)
1942     : ShaderRenderCase(testCtx, name, isVertexCase, new TexLookupEvaluator(evalFunc, m_lookupParams), NULL, NULL)
1943     , m_lookupSpec(lookup)
1944     , m_textureSpec(texture)
1945 {
1946     initShaderSources();
1947 }
1948 
~ShaderTextureFunctionCase(void)1949 ShaderTextureFunctionCase::~ShaderTextureFunctionCase(void)
1950 {
1951 }
1952 
createInstance(Context & context) const1953 TestInstance *ShaderTextureFunctionCase::createInstance(Context &context) const
1954 {
1955     DE_ASSERT(m_evaluator != DE_NULL);
1956     DE_ASSERT(m_uniformSetup != DE_NULL);
1957     return new ShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec,
1958                                              m_textureSpec, m_lookupParams);
1959 }
1960 
checkSupport(Context & context) const1961 void ShaderTextureFunctionCase::checkSupport(Context &context) const
1962 {
1963     checkMutableComparisonSamplersSupport(context, m_textureSpec);
1964 }
1965 
initShaderSources(void)1966 void ShaderTextureFunctionCase::initShaderSources(void)
1967 {
1968     Function function = m_lookupSpec.function;
1969     bool isVtxCase    = m_isVertexCase;
1970     bool isProj       = functionHasProj(function);
1971     bool isGrad       = functionHasGrad(function);
1972     bool isShadow     = m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1973     bool is2DProj4    = !isShadow && m_textureSpec.type == TEXTURETYPE_2D &&
1974                      (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD ||
1975                       function == FUNCTION_TEXTUREPROJGRAD);
1976     bool is1DProj4 = !isShadow && m_textureSpec.type == TEXTURETYPE_1D &&
1977                      (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD ||
1978                       function == FUNCTION_TEXTUREPROJGRAD);
1979     bool isIntCoord     = function == FUNCTION_TEXELFETCH;
1980     bool hasLodBias     = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1981     int texCoordComps   = m_textureSpec.type == TEXTURETYPE_1D                                               ? 1 :
1982                           m_textureSpec.type == TEXTURETYPE_1D_ARRAY || m_textureSpec.type == TEXTURETYPE_2D ? 2 :
1983                           m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY                                       ? 4 :
1984                                                                                                                3;
1985     int extraCoordComps = (isProj ? (is2DProj4 ? 2 : (is1DProj4 ? 3 : 1)) : 0) +
1986                           (isShadow ? (m_textureSpec.type == TEXTURETYPE_1D ? 2 : 1) : 0);
1987     const bool isCubeArrayShadow = isShadow && m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY;
1988     glu::DataType coordType      = glu::getDataTypeFloatVec(isCubeArrayShadow ? 4 : texCoordComps + extraCoordComps);
1989     glu::Precision coordPrec     = glu::PRECISION_HIGHP;
1990     const char *coordTypeName    = glu::getDataTypeName(coordType);
1991     const char *coordPrecName    = glu::getPrecisionName(coordPrec);
1992     tcu::TextureFormat texFmt    = glu::mapGLInternalFormat(m_textureSpec.format);
1993     glu::DataType samplerType    = glu::TYPE_LAST;
1994     glu::DataType gradType       = m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ?
1995                                        glu::TYPE_FLOAT :
1996                                    m_textureSpec.type == TEXTURETYPE_3D || m_textureSpec.type == TEXTURETYPE_CUBE_MAP ||
1997                                      m_textureSpec.type == TEXTURETYPE_CUBE_ARRAY ?
1998                                        glu::TYPE_FLOAT_VEC3 :
1999                                        glu::TYPE_FLOAT_VEC2;
2000     const char *gradTypeName     = glu::getDataTypeName(gradType);
2001     const char *baseFuncName     = DE_NULL;
2002 
2003     DE_ASSERT(!isGrad || !hasLodBias);
2004 
2005     switch (m_textureSpec.type)
2006     {
2007     case TEXTURETYPE_2D:
2008         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW : glu::getSampler2DType(texFmt);
2009         break;
2010     case TEXTURETYPE_CUBE_MAP:
2011         samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW : glu::getSamplerCubeType(texFmt);
2012         break;
2013     case TEXTURETYPE_2D_ARRAY:
2014         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW : glu::getSampler2DArrayType(texFmt);
2015         break;
2016     case TEXTURETYPE_3D:
2017         DE_ASSERT(!isShadow);
2018         samplerType = glu::getSampler3DType(texFmt);
2019         break;
2020     case TEXTURETYPE_1D:
2021         samplerType = isShadow ? glu::TYPE_SAMPLER_1D_SHADOW : glu::getSampler1DType(texFmt);
2022         break;
2023     case TEXTURETYPE_1D_ARRAY:
2024         samplerType = isShadow ? glu::TYPE_SAMPLER_1D_ARRAY_SHADOW : glu::getSampler1DArrayType(texFmt);
2025         break;
2026     case TEXTURETYPE_CUBE_ARRAY:
2027         samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW : glu::getSamplerCubeArrayType(texFmt);
2028         break;
2029     default:
2030         DE_ASSERT(false);
2031     }
2032 
2033     switch (m_lookupSpec.function)
2034     {
2035     case FUNCTION_TEXTURE:
2036         baseFuncName = "texture";
2037         break;
2038     case FUNCTION_TEXTUREPROJ:
2039         baseFuncName = "textureProj";
2040         break;
2041     case FUNCTION_TEXTUREPROJ2:
2042         baseFuncName = "textureProj";
2043         break;
2044     case FUNCTION_TEXTUREPROJ3:
2045         baseFuncName = "textureProj";
2046         break;
2047     case FUNCTION_TEXTURELOD:
2048         baseFuncName = "textureLod";
2049         break;
2050     case FUNCTION_TEXTUREPROJLOD:
2051         baseFuncName = "textureProjLod";
2052         break;
2053     case FUNCTION_TEXTUREPROJLOD2:
2054         baseFuncName = "textureProjLod";
2055         break;
2056     case FUNCTION_TEXTUREPROJLOD3:
2057         baseFuncName = "textureProjLod";
2058         break;
2059     case FUNCTION_TEXTUREGRAD:
2060         baseFuncName = "textureGrad";
2061         break;
2062     case FUNCTION_TEXTUREPROJGRAD:
2063         baseFuncName = "textureProjGrad";
2064         break;
2065     case FUNCTION_TEXTUREPROJGRAD2:
2066         baseFuncName = "textureProjGrad";
2067         break;
2068     case FUNCTION_TEXTUREPROJGRAD3:
2069         baseFuncName = "textureProjGrad";
2070         break;
2071     case FUNCTION_TEXELFETCH:
2072         baseFuncName = "texelFetch";
2073         break;
2074     default:
2075         DE_ASSERT(false);
2076     }
2077 
2078     std::ostringstream vert;
2079     std::ostringstream frag;
2080     std::ostringstream &op = isVtxCase ? vert : frag;
2081 
2082     vert << "#version 450 core\n"
2083          << "layout(location = 0) in highp vec4 a_position;\n"
2084          << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
2085 
2086     if (isGrad)
2087     {
2088         vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
2089         vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
2090     }
2091     else if (hasLodBias)
2092         vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
2093 
2094     frag << "#version 450 core\n";
2095 
2096     if (m_lookupSpec.useClamp)
2097         frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
2098 
2099     frag << "layout(location = 0) out mediump vec4 o_color;\n";
2100 
2101     if (isVtxCase)
2102     {
2103         vert << "layout(location = 0) out mediump vec4 v_color;\n";
2104         frag << "layout(location = 0) in mediump vec4 v_color;\n";
2105     }
2106     else
2107     {
2108         vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
2109         frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
2110 
2111         if (isGrad)
2112         {
2113             vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
2114             vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
2115             frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
2116             frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
2117         }
2118         else if (hasLodBias)
2119         {
2120             vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
2121             frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
2122         }
2123     }
2124 
2125     // Uniforms
2126     op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
2127        << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
2128        << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
2129 
2130     vert << "out gl_PerVertex {\n"
2131          << "\tvec4 gl_Position;\n"
2132          << "};\n";
2133 
2134     vert << "\nvoid main()\n{\n"
2135          << "\tgl_Position = a_position;\n";
2136     frag << "\nvoid main()\n{\n";
2137 
2138     if (isVtxCase)
2139         vert << "\tv_color = ";
2140     else
2141         frag << "\to_color = ";
2142 
2143     // Op.
2144     {
2145         const char *texCoord = isVtxCase ? "a_in0" : "v_texCoord";
2146         const char *gradX    = isVtxCase ? "a_in1" : "v_gradX";
2147         const char *gradY    = isVtxCase ? "a_in2" : "v_gradY";
2148         const char *lodBias  = isVtxCase ? "a_in1" : "v_lodBias";
2149 
2150         op << "vec4(" << baseFuncName;
2151         if (m_lookupSpec.useOffset)
2152             op << "Offset";
2153         if (m_lookupSpec.useClamp)
2154             op << "ClampARB";
2155         op << "(u_sampler, ";
2156 
2157         if (isIntCoord)
2158             op << glu::getDataTypeName(glu::getDataTypeIntVec(texCoordComps + extraCoordComps)) << "(";
2159 
2160         op << texCoord;
2161 
2162         if (isIntCoord)
2163             op << ")";
2164 
2165         if (isGrad)
2166             op << ", " << gradX << ", " << gradY;
2167 
2168         if (functionHasLod(function))
2169         {
2170             if (isIntCoord)
2171                 op << ", int(" << lodBias << ")";
2172             else
2173                 op << ", " << lodBias;
2174         }
2175 
2176         if (m_lookupSpec.useOffset)
2177         {
2178             int offsetComps = m_textureSpec.type == TEXTURETYPE_1D || m_textureSpec.type == TEXTURETYPE_1D_ARRAY ? 1 :
2179                               m_textureSpec.type == TEXTURETYPE_3D                                               ? 3 :
2180                                                                                                                    2;
2181 
2182             op << ", " << glu::getDataTypeName(glu::getDataTypeIntVec(offsetComps)) << "(";
2183             for (int ndx = 0; ndx < offsetComps; ndx++)
2184             {
2185                 if (ndx != 0)
2186                     op << ", ";
2187                 op << m_lookupSpec.offset[ndx];
2188             }
2189             op << ")";
2190         }
2191 
2192         if (m_lookupSpec.useClamp)
2193             op << ", float(" << m_lookupSpec.lodClamp << ")";
2194 
2195         if (isCubeArrayShadow && m_lookupSpec.function == FUNCTION_TEXTURE)
2196             op << ", " << texCoord << ".w";
2197 
2198         if (m_lookupSpec.useBias)
2199             op << ", " << lodBias;
2200 
2201         op << ")";
2202 
2203         if (isShadow)
2204             op << ", 0.0, 0.0, 1.0)";
2205         else
2206             op << ")*u_scale + u_bias";
2207 
2208         op << ";\n";
2209     }
2210 
2211     if (isVtxCase)
2212         frag << "\to_color = v_color;\n";
2213     else
2214     {
2215         vert << "\tv_texCoord = a_in0;\n";
2216 
2217         if (isGrad)
2218         {
2219             vert << "\tv_gradX = a_in1;\n";
2220             vert << "\tv_gradY = a_in2;\n";
2221         }
2222         else if (hasLodBias)
2223             vert << "\tv_lodBias = a_in1;\n";
2224     }
2225 
2226     vert << "}\n";
2227     frag << "}\n";
2228 
2229     m_vertShaderSource = vert.str();
2230     m_fragShaderSource = frag.str();
2231 }
2232 
2233 enum QueryFunction
2234 {
2235     QUERYFUNCTION_TEXTURESIZE = 0,
2236     QUERYFUNCTION_TEXTURESIZEMS,
2237     QUERYFUNCTION_TEXTUREQUERYLOD,
2238     QUERYFUNCTION_TEXTUREQUERYLEVELS,
2239     QUERYFUNCTION_TEXTURESAMPLES,
2240 
2241     QUERYFUNCTION_LAST
2242 };
2243 
2244 // test mode used to alter test behaviour
2245 using TestMode = uint32_t;
2246 
2247 enum QueryLodTestModes
2248 {
2249     QLODTM_DEFAULT = 0,  // uv coords have different values
2250     QLODTM_ZERO_UV_WIDTH // all uv coords are 0; there were implementations that incorrectly returned 0 in that case instead of -maxSamplerLodBias or less
2251 };
2252 
2253 class TextureQueryInstance : public ShaderRenderCaseInstance
2254 {
2255 public:
2256     TextureQueryInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec);
2257     virtual ~TextureQueryInstance(void);
2258 
2259 protected:
2260     virtual void setupDefaultInputs(void);
2261     virtual void setupUniforms(const tcu::Vec4 &);
2262 
2263     void render(void);
2264 
2265 protected:
2266     const TextureSpec &m_textureSpec;
2267 };
2268 
TextureQueryInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2269 TextureQueryInstance::TextureQueryInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec)
2270     : ShaderRenderCaseInstance(context, isVertexCase, DE_NULL, DE_NULL, DE_NULL)
2271     , m_textureSpec(textureSpec)
2272 {
2273     m_colorFormat = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
2274 
2275     checkDeviceFeatures(m_context, m_textureSpec.type);
2276 }
2277 
~TextureQueryInstance(void)2278 TextureQueryInstance::~TextureQueryInstance(void)
2279 {
2280 }
2281 
setupDefaultInputs(void)2282 void TextureQueryInstance::setupDefaultInputs(void)
2283 {
2284     const uint32_t numVertices = 4;
2285     const float positions[]    = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
2286                                   1.0f,  -1.0f, 0.0f, 1.0f, 1.0f,  1.0f, 0.0f, 1.0f};
2287 
2288     addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (uint32_t)sizeof(float), numVertices, positions);
2289 }
2290 
setupUniforms(const tcu::Vec4 &)2291 void TextureQueryInstance::setupUniforms(const tcu::Vec4 &)
2292 {
2293     useSampler(0u, 0u);
2294 }
2295 
render(void)2296 void TextureQueryInstance::render(void)
2297 {
2298     const uint32_t numVertices  = 4;
2299     const uint32_t numTriangles = 2;
2300     const uint16_t indices[6]   = {0, 1, 2, 2, 1, 3};
2301 
2302     ShaderRenderCaseInstance::setup();
2303 
2304     ShaderRenderCaseInstance::render(numVertices, numTriangles, indices);
2305 }
2306 
getMaxTextureSize(TextureType type,const tcu::IVec3 & textureSize)2307 static int getMaxTextureSize(TextureType type, const tcu::IVec3 &textureSize)
2308 {
2309     int maxSize = 0;
2310 
2311     switch (type)
2312     {
2313     case TEXTURETYPE_1D:
2314     case TEXTURETYPE_1D_ARRAY:
2315         maxSize = textureSize.x();
2316         break;
2317 
2318     case TEXTURETYPE_2D:
2319     case TEXTURETYPE_2D_ARRAY:
2320     case TEXTURETYPE_CUBE_MAP:
2321     case TEXTURETYPE_CUBE_ARRAY:
2322         maxSize = de::max(textureSize.x(), textureSize.y());
2323         break;
2324 
2325     case TEXTURETYPE_3D:
2326         maxSize = de::max(textureSize.x(), de::max(textureSize.y(), textureSize.z()));
2327         break;
2328 
2329     default:
2330         DE_ASSERT(false);
2331     }
2332 
2333     return maxSize;
2334 }
2335 
getTextureSizeString(TextureType type,const tcu::IVec3 & textureSize)2336 static std::string getTextureSizeString(TextureType type, const tcu::IVec3 &textureSize)
2337 {
2338     std::ostringstream str;
2339 
2340     switch (type)
2341     {
2342     case TEXTURETYPE_1D:
2343         str << textureSize.x() << "x1";
2344         break;
2345 
2346     case TEXTURETYPE_2D:
2347     case TEXTURETYPE_CUBE_MAP:
2348         str << textureSize.x() << "x" << textureSize.y();
2349         break;
2350 
2351     case TEXTURETYPE_3D:
2352         str << textureSize.x() << "x" << textureSize.y() << "x" << textureSize.z();
2353         break;
2354 
2355     case TEXTURETYPE_1D_ARRAY:
2356         str << textureSize.x() << "x1 with " << textureSize.z() << " layer(s)";
2357         break;
2358 
2359     case TEXTURETYPE_2D_ARRAY:
2360     case TEXTURETYPE_CUBE_ARRAY:
2361         str << textureSize.x() << "x" << textureSize.y() << " with " << textureSize.z() << " layers(s)";
2362         break;
2363 
2364     default:
2365         DE_ASSERT(false);
2366         break;
2367     }
2368 
2369     return str.str();
2370 }
2371 
isValidCase(TextureType type,const tcu::IVec3 & textureSize,int lodBase)2372 static bool isValidCase(TextureType type, const tcu::IVec3 &textureSize, int lodBase)
2373 {
2374     const bool isSquare    = textureSize.x() == textureSize.y();
2375     const bool isCubeArray = isSquare && (textureSize.z() % 6) == 0;
2376     const int maxSize      = getMaxTextureSize(type, textureSize);
2377     const bool isBaseValid = (maxSize >> lodBase) != 0;
2378 
2379     if (!isBaseValid)
2380         return false;
2381     if (type == TEXTURETYPE_CUBE_MAP && !isSquare)
2382         return false;
2383     if (type == TEXTURETYPE_CUBE_ARRAY && !isCubeArray)
2384         return false;
2385 
2386     return true;
2387 }
2388 
createEmptyTexture(uint32_t format,TextureType type,const tcu::IVec3 & textureSize,int numLevels,int lodBase,const tcu::Sampler & sampler)2389 static TextureBindingSp createEmptyTexture(uint32_t format, TextureType type, const tcu::IVec3 &textureSize,
2390                                            int numLevels, int lodBase, const tcu::Sampler &sampler)
2391 {
2392     const tcu::TextureFormat texFmt = glu::mapGLInternalFormat(format);
2393     const TextureBinding::Parameters params(lodBase);
2394     TextureBindingSp textureBinding;
2395 
2396     switch (type)
2397     {
2398 
2399     case TEXTURETYPE_1D:
2400     {
2401         de::MovePtr<tcu::Texture1D> texture(new tcu::Texture1D(texFmt, textureSize.x()));
2402 
2403         for (int level = 0; level < numLevels; level++)
2404             texture->allocLevel(level);
2405 
2406         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2407         break;
2408     }
2409 
2410     case TEXTURETYPE_2D:
2411     {
2412         de::MovePtr<tcu::Texture2D> texture(new tcu::Texture2D(texFmt, textureSize.x(), textureSize.y()));
2413 
2414         for (int level = 0; level < numLevels; level++)
2415             texture->allocLevel(level);
2416 
2417         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2418         break;
2419     }
2420 
2421     case TEXTURETYPE_3D:
2422     {
2423         de::MovePtr<tcu::Texture3D> texture(
2424             new tcu::Texture3D(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
2425 
2426         for (int level = 0; level < numLevels; level++)
2427             texture->allocLevel(level);
2428 
2429         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2430         break;
2431     }
2432 
2433     case TEXTURETYPE_CUBE_MAP:
2434     {
2435         de::MovePtr<tcu::TextureCube> texture(new tcu::TextureCube(texFmt, textureSize.x()));
2436 
2437         for (int level = 0; level < numLevels; level++)
2438             for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
2439                 texture->allocLevel((tcu::CubeFace)face, level);
2440 
2441         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2442         break;
2443     }
2444 
2445     case TEXTURETYPE_1D_ARRAY:
2446     {
2447         de::MovePtr<tcu::Texture1DArray> texture(new tcu::Texture1DArray(texFmt, textureSize.x(), textureSize.z()));
2448 
2449         for (int level = 0; level < numLevels; level++)
2450             texture->allocLevel(level);
2451 
2452         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2453         break;
2454     }
2455 
2456     case TEXTURETYPE_2D_ARRAY:
2457     {
2458         de::MovePtr<tcu::Texture2DArray> texture(
2459             new tcu::Texture2DArray(texFmt, textureSize.x(), textureSize.y(), textureSize.z()));
2460 
2461         for (int level = 0; level < numLevels; level++)
2462             texture->allocLevel(level);
2463 
2464         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2465         break;
2466     }
2467 
2468     case TEXTURETYPE_CUBE_ARRAY:
2469     {
2470         de::MovePtr<tcu::TextureCubeArray> texture(new tcu::TextureCubeArray(texFmt, textureSize.x(), textureSize.z()));
2471 
2472         for (int level = 0; level < numLevels; level++)
2473             texture->allocLevel(level);
2474 
2475         textureBinding = TextureBindingSp(new TextureBinding(texture.release(), sampler));
2476         break;
2477     }
2478 
2479     default:
2480         DE_ASSERT(false);
2481         break;
2482     }
2483 
2484     textureBinding->setParameters(params);
2485     return textureBinding;
2486 }
2487 
getTextureSizeFuncResultType(TextureType textureType)2488 static inline glu::DataType getTextureSizeFuncResultType(TextureType textureType)
2489 {
2490     switch (textureType)
2491     {
2492     case TEXTURETYPE_1D:
2493         return glu::TYPE_INT;
2494 
2495     case TEXTURETYPE_2D:
2496     case TEXTURETYPE_CUBE_MAP:
2497     case TEXTURETYPE_1D_ARRAY:
2498         return glu::TYPE_INT_VEC2;
2499 
2500     case TEXTURETYPE_3D:
2501     case TEXTURETYPE_2D_ARRAY:
2502     case TEXTURETYPE_CUBE_ARRAY:
2503         return glu::TYPE_INT_VEC3;
2504 
2505     default:
2506         DE_ASSERT(false);
2507         return glu::TYPE_LAST;
2508     }
2509 }
2510 
2511 class TextureSizeInstance : public TextureQueryInstance
2512 {
2513 public:
2514     TextureSizeInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec);
2515     virtual ~TextureSizeInstance(void);
2516 
2517     virtual tcu::TestStatus iterate(void);
2518 
2519 protected:
2520     virtual void setupUniforms(const tcu::Vec4 &constCoords);
2521 
2522 private:
2523     struct TestSize
2524     {
2525         tcu::IVec3 textureSize;
2526         int lod;
2527         int lodBase;
2528         tcu::IVec3 expectedSize;
2529     };
2530 
2531     void initTexture(void);
2532     bool testTextureSize(void);
2533 
2534     TestSize m_testSize;
2535     tcu::IVec3 m_expectedSize;
2536     int m_iterationCounter;
2537 };
2538 
TextureSizeInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2539 TextureSizeInstance::TextureSizeInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec)
2540     : TextureQueryInstance(context, isVertexCase, textureSpec)
2541     , m_testSize()
2542     , m_expectedSize()
2543     , m_iterationCounter(0)
2544 {
2545     deMemset(&m_testSize, 0, sizeof(TestSize));
2546 
2547 #ifdef CTS_USES_VULKANSC
2548     const VkDevice vkDevice         = getDevice();
2549     const DeviceInterface &vk       = getDeviceInterface();
2550     const uint32_t queueFamilyIndex = getUniversalQueueFamilyIndex();
2551     m_externalCommandPool           = de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(
2552         createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
2553 #endif // CTS_USES_VULKANSC
2554 
2555     m_renderSize = tcu::UVec2(1, 1);
2556 }
2557 
~TextureSizeInstance(void)2558 TextureSizeInstance::~TextureSizeInstance(void)
2559 {
2560 }
2561 
setupUniforms(const tcu::Vec4 & constCoords)2562 void TextureSizeInstance::setupUniforms(const tcu::Vec4 &constCoords)
2563 {
2564     TextureQueryInstance::setupUniforms(constCoords);
2565     addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(int), &m_testSize.lod);
2566 }
2567 
initTexture(void)2568 void TextureSizeInstance::initTexture(void)
2569 {
2570     tcu::TestLog &log   = m_context.getTestContext().getLog();
2571     const int numLevels = deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
2572     TextureBindingSp textureBinding;
2573 
2574     log << tcu::TestLog::Message << "Testing image size "
2575         << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize) << tcu::TestLog::EndMessage;
2576     log << tcu::TestLog::Message << "Lod: " << m_testSize.lod << ", base level: " << m_testSize.lodBase
2577         << tcu::TestLog::EndMessage;
2578 
2579     switch (m_textureSpec.type)
2580     {
2581     case TEXTURETYPE_3D:
2582         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x"
2583             << m_testSize.expectedSize.y() << "x" << m_testSize.expectedSize.z() << tcu::TestLog::EndMessage;
2584         break;
2585 
2586     case TEXTURETYPE_2D:
2587         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x"
2588             << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
2589         break;
2590 
2591     case TEXTURETYPE_CUBE_MAP:
2592         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x"
2593             << m_testSize.expectedSize.y() << tcu::TestLog::EndMessage;
2594         break;
2595 
2596     case TEXTURETYPE_2D_ARRAY:
2597         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x"
2598             << m_testSize.expectedSize.y() << " and " << m_testSize.textureSize.z() << " layer(s)"
2599             << tcu::TestLog::EndMessage;
2600         break;
2601 
2602     case TEXTURETYPE_CUBE_ARRAY:
2603         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << "x"
2604             << m_testSize.expectedSize.y() << " and " << (m_testSize.textureSize.z() / 6) << " cube(s)"
2605             << tcu::TestLog::EndMessage;
2606         break;
2607 
2608     case TEXTURETYPE_1D:
2609         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << tcu::TestLog::EndMessage;
2610         break;
2611 
2612     case TEXTURETYPE_1D_ARRAY:
2613         log << tcu::TestLog::Message << "Expecting: " << m_testSize.expectedSize.x() << " and "
2614             << m_testSize.textureSize.z() << " layer(s)" << tcu::TestLog::EndMessage;
2615         break;
2616 
2617     default:
2618         DE_ASSERT(false);
2619         break;
2620     }
2621 
2622     textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels,
2623                                         m_testSize.lodBase, m_textureSpec.sampler);
2624 
2625     m_textures.clear();
2626     m_textures.push_back(textureBinding);
2627 }
2628 
iterate(void)2629 tcu::TestStatus TextureSizeInstance::iterate(void)
2630 {
2631     const TestSize testSizes[] = {
2632         {tcu::IVec3(1, 2, 1), 0, 0, tcu::IVec3(1, 2, 1)},
2633         {tcu::IVec3(1, 2, 1), 1, 0, tcu::IVec3(1, 1, 1)},
2634 
2635         {tcu::IVec3(1, 3, 2), 0, 0, tcu::IVec3(1, 3, 2)},
2636         {tcu::IVec3(1, 3, 2), 1, 0, tcu::IVec3(1, 1, 1)},
2637 
2638         {tcu::IVec3(100, 31, 18), 0, 0, tcu::IVec3(100, 31, 18)},
2639         {tcu::IVec3(100, 31, 18), 1, 0, tcu::IVec3(50, 15, 9)},
2640         {tcu::IVec3(100, 31, 18), 2, 0, tcu::IVec3(25, 7, 4)},
2641         {tcu::IVec3(100, 31, 18), 3, 0, tcu::IVec3(12, 3, 2)},
2642         {tcu::IVec3(100, 31, 18), 4, 0, tcu::IVec3(6, 1, 1)},
2643         {tcu::IVec3(100, 31, 18), 5, 0, tcu::IVec3(3, 1, 1)},
2644         {tcu::IVec3(100, 31, 18), 6, 0, tcu::IVec3(1, 1, 1)},
2645 
2646         {tcu::IVec3(100, 128, 32), 0, 0, tcu::IVec3(100, 128, 32)},
2647         {tcu::IVec3(100, 128, 32), 1, 0, tcu::IVec3(50, 64, 16)},
2648         {tcu::IVec3(100, 128, 32), 2, 0, tcu::IVec3(25, 32, 8)},
2649         {tcu::IVec3(100, 128, 32), 3, 0, tcu::IVec3(12, 16, 4)},
2650         {tcu::IVec3(100, 128, 32), 4, 0, tcu::IVec3(6, 8, 2)},
2651         {tcu::IVec3(100, 128, 32), 5, 0, tcu::IVec3(3, 4, 1)},
2652         {tcu::IVec3(100, 128, 32), 6, 0, tcu::IVec3(1, 2, 1)},
2653         {tcu::IVec3(100, 128, 32), 7, 0, tcu::IVec3(1, 1, 1)},
2654 
2655         // pow 2
2656         {tcu::IVec3(128, 64, 32), 0, 0, tcu::IVec3(128, 64, 32)},
2657         {tcu::IVec3(128, 64, 32), 1, 0, tcu::IVec3(64, 32, 16)},
2658         {tcu::IVec3(128, 64, 32), 2, 0, tcu::IVec3(32, 16, 8)},
2659         {tcu::IVec3(128, 64, 32), 3, 0, tcu::IVec3(16, 8, 4)},
2660         {tcu::IVec3(128, 64, 32), 4, 0, tcu::IVec3(8, 4, 2)},
2661         {tcu::IVec3(128, 64, 32), 5, 0, tcu::IVec3(4, 2, 1)},
2662         {tcu::IVec3(128, 64, 32), 6, 0, tcu::IVec3(2, 1, 1)},
2663         {tcu::IVec3(128, 64, 32), 7, 0, tcu::IVec3(1, 1, 1)},
2664 
2665         // w == h
2666         {tcu::IVec3(1, 1, 1), 0, 0, tcu::IVec3(1, 1, 1)},
2667         {tcu::IVec3(64, 64, 64), 0, 0, tcu::IVec3(64, 64, 64)},
2668         {tcu::IVec3(64, 64, 64), 1, 0, tcu::IVec3(32, 32, 32)},
2669         {tcu::IVec3(64, 64, 64), 2, 0, tcu::IVec3(16, 16, 16)},
2670         {tcu::IVec3(64, 64, 64), 3, 0, tcu::IVec3(8, 8, 8)},
2671         {tcu::IVec3(64, 64, 64), 4, 0, tcu::IVec3(4, 4, 4)},
2672 
2673         // with lod base
2674         {tcu::IVec3(100, 31, 18), 3, 1, tcu::IVec3(6, 1, 1)},
2675         {tcu::IVec3(128, 64, 32), 3, 1, tcu::IVec3(8, 4, 2)},
2676         {tcu::IVec3(64, 64, 64), 1, 1, tcu::IVec3(16, 16, 16)},
2677 
2678         {tcu::IVec3(100, 31, 18), 1, 2, tcu::IVec3(12, 3, 2)},
2679         {tcu::IVec3(100, 31, 18), 2, 2, tcu::IVec3(6, 1, 1)},
2680         {tcu::IVec3(100, 31, 18), 1, 4, tcu::IVec3(3, 1, 1)},
2681 
2682         // out-of-range mip levels
2683         {tcu::IVec3(1, 3, 2), -7, 0, tcu::IVec3(0, 0, 0)},
2684         {tcu::IVec3(1, 3, 2), 106, 0, tcu::IVec3(0, 0, 0)},
2685         {tcu::IVec3(100, 31, 18), 7, 0, tcu::IVec3(0, 0, 0)},
2686         {tcu::IVec3(32, 32, 12), 6, 0, tcu::IVec3(0, 0, 0)},
2687         {tcu::IVec3(32, 32, 12), -9, 0, tcu::IVec3(0, 0, 0)},
2688         {tcu::IVec3(32, 32, 12), 4396, 0, tcu::IVec3(0, 0, 0)},
2689 
2690         // w == h and d % 6 == 0 (for cube array)
2691         {tcu::IVec3(1, 1, 6), 0, 0, tcu::IVec3(1, 1, 6)},
2692         {tcu::IVec3(32, 32, 12), 0, 0, tcu::IVec3(32, 32, 12)},
2693         {tcu::IVec3(32, 32, 12), 0, 1, tcu::IVec3(16, 16, 6)},
2694         {tcu::IVec3(32, 32, 12), 1, 0, tcu::IVec3(16, 16, 6)},
2695         {tcu::IVec3(32, 32, 12), 2, 0, tcu::IVec3(8, 8, 3)},
2696         {tcu::IVec3(32, 32, 12), 3, 0, tcu::IVec3(4, 4, 1)},
2697         {tcu::IVec3(32, 32, 12), 4, 0, tcu::IVec3(2, 2, 1)},
2698         {tcu::IVec3(32, 32, 12), 5, 0, tcu::IVec3(1, 1, 1)},
2699     };
2700     const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
2701 
2702     m_iterationCounter++;
2703 
2704     if (m_iterationCounter == lastIterationIndex)
2705         return tcu::TestStatus::pass("Pass");
2706     else
2707     {
2708         // set current test size
2709         m_testSize = testSizes[m_iterationCounter - 1];
2710 
2711         bool result = testTextureSize();
2712 #ifdef CTS_USES_VULKANSC
2713         if (m_context.getTestContext().getCommandLine().isSubProcess())
2714 #endif // CTS_USES_VULKANSC
2715         {
2716             if (!result)
2717                 return tcu::TestStatus::fail("Got unexpected result");
2718         }
2719         return tcu::TestStatus::incomplete();
2720     }
2721 }
2722 
testTextureSize(void)2723 bool TextureSizeInstance::testTextureSize(void)
2724 {
2725     tcu::TestLog &log = m_context.getTestContext().getLog();
2726     bool success      = true;
2727 
2728     // skip incompatible cases
2729     if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
2730         return true;
2731 
2732     // setup texture
2733     initTexture();
2734 
2735     // determine expected texture size
2736     switch (m_textureSpec.type)
2737     {
2738     case TEXTURETYPE_1D:
2739     case TEXTURETYPE_2D:
2740     case TEXTURETYPE_3D:
2741     case TEXTURETYPE_CUBE_MAP:
2742         m_expectedSize = m_testSize.expectedSize;
2743         break;
2744 
2745     case TEXTURETYPE_1D_ARRAY:
2746         m_expectedSize = tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.textureSize.z(), 0);
2747         break;
2748 
2749     case TEXTURETYPE_2D_ARRAY:
2750         m_expectedSize =
2751             tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z());
2752         break;
2753 
2754     case TEXTURETYPE_CUBE_ARRAY:
2755         m_expectedSize =
2756             tcu::IVec3(m_testSize.expectedSize.x(), m_testSize.expectedSize.y(), m_testSize.textureSize.z() / 6);
2757         break;
2758 
2759     default:
2760         DE_ASSERT(false);
2761         break;
2762     }
2763 
2764     // render
2765     TextureQueryInstance::render();
2766 
2767     // test
2768     {
2769         const tcu::TextureLevel &result = getResultImage();
2770         tcu::IVec4 output               = result.getAccess().getPixelInt(0, 0);
2771         const int resultComponents      = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2772 
2773         for (int ndx = 0; ndx < resultComponents; ndx++)
2774         {
2775             // We test all levels, but only compare results for valid LoDs. The others give
2776             // undefined values.
2777             const int maxSize     = getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize);
2778             const bool isLodValid = (maxSize >> (m_testSize.lod + m_testSize.lodBase)) != 0;
2779             if (isLodValid && output[ndx] != m_expectedSize[ndx])
2780             {
2781                 success = false;
2782                 break;
2783             }
2784         }
2785 
2786         if (success)
2787         {
2788             // success
2789             log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2790         }
2791         else
2792         {
2793             // failure
2794             std::stringstream resultSizeStr;
2795             switch (resultComponents)
2796             {
2797             case 1:
2798                 resultSizeStr << output[0];
2799                 break;
2800             case 2:
2801                 resultSizeStr << output.toWidth<2>();
2802                 break;
2803             case 3:
2804                 resultSizeStr << output.toWidth<3>();
2805                 break;
2806             default:
2807                 DE_ASSERT(false);
2808                 break;
2809             }
2810             log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2811             log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2812         }
2813     }
2814 
2815     log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
2816 
2817     return success;
2818 }
2819 
getVkImageType(TextureType type)2820 static vk::VkImageType getVkImageType(TextureType type)
2821 {
2822     switch (type)
2823     {
2824     case TEXTURETYPE_1D:
2825     case TEXTURETYPE_1D_ARRAY:
2826         return vk::VK_IMAGE_TYPE_1D;
2827 
2828     case TEXTURETYPE_2D:
2829     case TEXTURETYPE_2D_ARRAY:
2830     case TEXTURETYPE_CUBE_MAP:
2831     case TEXTURETYPE_CUBE_ARRAY:
2832         return vk::VK_IMAGE_TYPE_2D;
2833 
2834     case TEXTURETYPE_3D:
2835         return vk::VK_IMAGE_TYPE_3D;
2836 
2837     default:
2838         DE_ASSERT(false);
2839         return (vk::VkImageType)0;
2840     }
2841 }
2842 
2843 class TextureSizeMSInstance : public TextureQueryInstance
2844 {
2845 public:
2846     TextureSizeMSInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec);
2847     virtual ~TextureSizeMSInstance(void);
2848 
2849     virtual tcu::TestStatus iterate(void);
2850 
2851 private:
2852     void initTexture(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2853     bool testSize(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim);
2854 
2855     unsigned m_iterationCounter;
2856     vector<vk::VkSampleCountFlagBits> m_iterations;
2857 };
2858 
TextureSizeMSInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)2859 TextureSizeMSInstance::TextureSizeMSInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec)
2860     : TextureQueryInstance(context, isVertexCase, textureSpec)
2861     , m_iterationCounter(0)
2862 {
2863     m_renderSize = tcu::UVec2(1, 1);
2864 
2865     // determine available sample counts
2866     {
2867         const vk::VkFormat format       = vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
2868         const vk::VkImageType imageType = getVkImageType(m_textureSpec.type);
2869         vk::VkImageFormatProperties properties;
2870 
2871         if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
2872                 m_context.getPhysicalDevice(), format, imageType, vk::VK_IMAGE_TILING_OPTIMAL,
2873                 vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, (vk::VkImageCreateFlags)0,
2874                 &properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2875             TCU_THROW(NotSupportedError, "Format not supported");
2876 
2877         // NOTE: The test case initializes MS images (for all supported N of samples), runs a program
2878         //       which invokes OpImageQuerySize against the image and checks the result.
2879         //
2880         //       Multisample images do not support a sample count of 1, so start from 2 samples.
2881         static const vk::VkSampleCountFlagBits sampleFlags[] = {vk::VK_SAMPLE_COUNT_2_BIT,  vk::VK_SAMPLE_COUNT_4_BIT,
2882                                                                 vk::VK_SAMPLE_COUNT_8_BIT,  vk::VK_SAMPLE_COUNT_16_BIT,
2883                                                                 vk::VK_SAMPLE_COUNT_32_BIT, vk::VK_SAMPLE_COUNT_64_BIT};
2884 
2885         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
2886         {
2887             const vk::VkSampleCountFlagBits &flag = sampleFlags[samplesNdx];
2888 
2889             if ((properties.sampleCounts & flag) != 0)
2890                 m_iterations.push_back(flag);
2891         }
2892 
2893         if (m_iterations.empty())
2894         {
2895             // Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
2896             if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2897                 tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2898             {
2899                 TCU_THROW(NotSupportedError,
2900                           "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
2901             }
2902 
2903             DE_ASSERT(false);
2904         }
2905     }
2906 }
2907 
~TextureSizeMSInstance(void)2908 TextureSizeMSInstance::~TextureSizeMSInstance(void)
2909 {
2910 }
2911 
iterate(void)2912 tcu::TestStatus TextureSizeMSInstance::iterate(void)
2913 {
2914     const tcu::IVec3 testSizes[] = {
2915         tcu::IVec3(1, 1, 1),     tcu::IVec3(1, 2, 1),      tcu::IVec3(1, 3, 2),
2916         tcu::IVec3(1, 1, 6),     tcu::IVec3(32, 32, 12),   tcu::IVec3(64, 64, 64),
2917         tcu::IVec3(100, 31, 18), tcu::IVec3(100, 128, 32), tcu::IVec3(128, 64, 32),
2918     };
2919 
2920     unsigned sampleIdx = m_iterationCounter / DE_LENGTH_OF_ARRAY(testSizes);
2921     unsigned dimIdx    = m_iterationCounter % DE_LENGTH_OF_ARRAY(testSizes);
2922 
2923     if (m_iterationCounter++ < m_iterations.size() * DE_LENGTH_OF_ARRAY(testSizes))
2924     {
2925         bool result = testSize(m_iterations[sampleIdx], testSizes[dimIdx]);
2926 #ifdef CTS_USES_VULKANSC
2927         if (m_context.getTestContext().getCommandLine().isSubProcess())
2928 #endif // CTS_USES_VULKANSC
2929         {
2930             if (!result)
2931                 return tcu::TestStatus::fail("Got unexpected result");
2932         }
2933         return tcu::TestStatus::incomplete();
2934     }
2935     else
2936         return tcu::TestStatus::pass("Pass");
2937 }
2938 
testSize(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2939 bool TextureSizeMSInstance::testSize(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2940 {
2941     tcu::TestLog &log = m_context.getTestContext().getLog();
2942 
2943     // setup texture
2944     initTexture(samples, dim);
2945 
2946     // render
2947     TextureQueryInstance::render();
2948 
2949     // test
2950     {
2951         const tcu::TextureLevel &result = getResultImage();
2952         tcu::IVec4 output               = result.getAccess().getPixelInt(0, 0);
2953         const int resultComponents      = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
2954 
2955         bool success = true;
2956 
2957         for (int ndx = 0; ndx < resultComponents; ndx++)
2958         {
2959             if (output[ndx] != dim[ndx])
2960             {
2961                 success = false;
2962                 break;
2963             }
2964         }
2965 
2966         if (success)
2967         {
2968             // success
2969             log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
2970             return true;
2971         }
2972         else
2973         {
2974             // failure
2975             std::stringstream resultSizeStr;
2976             switch (resultComponents)
2977             {
2978             case 1:
2979                 resultSizeStr << output[0];
2980                 break;
2981             case 2:
2982                 resultSizeStr << output.toWidth<2>();
2983                 break;
2984             case 3:
2985                 resultSizeStr << output.toWidth<3>();
2986                 break;
2987             default:
2988                 DE_ASSERT(false);
2989                 break;
2990             }
2991             log << tcu::TestLog::Message << "Result: " << resultSizeStr.str() << tcu::TestLog::EndMessage;
2992             log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
2993             return false;
2994         }
2995     }
2996 }
2997 
initTexture(vk::VkSampleCountFlagBits samples,const tcu::IVec3 & dim)2998 void TextureSizeMSInstance::initTexture(vk::VkSampleCountFlagBits samples, const tcu::IVec3 &dim)
2999 {
3000     tcu::TestLog &log = m_context.getTestContext().getLog();
3001     TextureBindingSp textureBinding;
3002 
3003     DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
3004 
3005     log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, dim)
3006         << ", samples: " << samples << tcu::TestLog::EndMessage;
3007 
3008     textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, dim, m_textureSpec.numLevels,
3009                                         0 /* lodBase */, m_textureSpec.sampler);
3010 
3011     m_textures.clear();
3012     m_textures.push_back(textureBinding);
3013 
3014     // update samples count
3015     {
3016         DE_ASSERT(m_textures.size() == 1);
3017 
3018         TextureBinding::Parameters params = m_textures[0]->getParameters();
3019 
3020         params.initialization = TextureBinding::INIT_CLEAR;
3021         params.samples        = samples;
3022 
3023         m_textures[0]->setParameters(params);
3024     }
3025 }
3026 
3027 class TextureSamplesInstance : public TextureQueryInstance
3028 {
3029 public:
3030     TextureSamplesInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec);
3031     virtual ~TextureSamplesInstance(void);
3032 
3033     virtual tcu::TestStatus iterate(void);
3034 
3035 private:
3036     void initTexture(void);
3037 
3038     int m_iterationCounter;
3039     vector<vk::VkSampleCountFlagBits> m_iterations;
3040 };
3041 
TextureSamplesInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)3042 TextureSamplesInstance::TextureSamplesInstance(Context &context, const bool isVertexCase,
3043                                                const TextureSpec &textureSpec)
3044     : TextureQueryInstance(context, isVertexCase, textureSpec)
3045     , m_iterationCounter(0)
3046 {
3047     m_renderSize = tcu::UVec2(1, 1);
3048 
3049     // determine available sample counts
3050     {
3051         const vk::VkFormat format       = vk::mapTextureFormat(glu::mapGLInternalFormat(m_textureSpec.format));
3052         const vk::VkImageType imageType = getVkImageType(m_textureSpec.type);
3053         vk::VkImageFormatProperties properties;
3054 
3055         if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
3056                 m_context.getPhysicalDevice(), format, imageType, vk::VK_IMAGE_TILING_OPTIMAL,
3057                 vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, (vk::VkImageCreateFlags)0,
3058                 &properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3059             TCU_THROW(NotSupportedError, "Format not supported");
3060 
3061         // NOTE: The test case initializes MS images (for all supported N of samples), runs a program
3062         //       which invokes OpImageQuerySamples against the image and checks the result.
3063         //
3064         //       Now, in the SPIR-V spec for the very operation we have the following language:
3065         //
3066         //       OpImageQuerySamples
3067         //       Query the number of samples available per texel fetch in a multisample image.
3068         //       Result Type must be a scalar integer type.
3069         //       The result is the number of samples.
3070         //       Image must be an object whose type is OpTypeImage.
3071         //       Its Dim operand must be one of 2D and **MS of 1(multisampled).
3072         //
3073         //       "MS of 1" implies the image must not be single-sample, meaning we must exclude
3074         //       VK_SAMPLE_COUNT_1_BIT in the sampleFlags array below, and may have to skip further testing.
3075         static const vk::VkSampleCountFlagBits sampleFlags[] = {vk::VK_SAMPLE_COUNT_2_BIT,  vk::VK_SAMPLE_COUNT_4_BIT,
3076                                                                 vk::VK_SAMPLE_COUNT_8_BIT,  vk::VK_SAMPLE_COUNT_16_BIT,
3077                                                                 vk::VK_SAMPLE_COUNT_32_BIT, vk::VK_SAMPLE_COUNT_64_BIT};
3078 
3079         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(sampleFlags); samplesNdx++)
3080         {
3081             const vk::VkSampleCountFlagBits &flag = sampleFlags[samplesNdx];
3082 
3083             if ((properties.sampleCounts & flag) != 0)
3084                 m_iterations.push_back(flag);
3085         }
3086 
3087         if (m_iterations.empty())
3088         {
3089             // Sampled images of integer formats may support only 1 sample. Exit the test with "Not supported" in these cases.
3090             if (tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
3091                 tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
3092             {
3093                 TCU_THROW(NotSupportedError,
3094                           "Skipping validation of integer formats as only VK_SAMPLE_COUNT_1_BIT is supported.");
3095             }
3096 
3097             DE_ASSERT(false);
3098         }
3099     }
3100 
3101     // setup texture
3102     initTexture();
3103 }
3104 
~TextureSamplesInstance(void)3105 TextureSamplesInstance::~TextureSamplesInstance(void)
3106 {
3107 }
3108 
iterate(void)3109 tcu::TestStatus TextureSamplesInstance::iterate(void)
3110 {
3111     tcu::TestLog &log = m_context.getTestContext().getLog();
3112 
3113     // update samples count
3114     {
3115         DE_ASSERT(m_textures.size() == 1);
3116 
3117         TextureBinding::Parameters params = m_textures[0]->getParameters();
3118 
3119         params.initialization = TextureBinding::INIT_CLEAR;
3120         params.samples        = m_iterations[m_iterationCounter];
3121         log << tcu::TestLog::Message << "Expected samples: " << m_iterations[m_iterationCounter]
3122             << tcu::TestLog::EndMessage;
3123 
3124         m_textures[0]->setParameters(params);
3125     }
3126 
3127     // render
3128     TextureQueryInstance::render();
3129 
3130     // test
3131     {
3132         const tcu::TextureLevel &result = getResultImage();
3133         tcu::IVec4 output               = result.getAccess().getPixelInt(0, 0);
3134 
3135 #ifdef CTS_USES_VULKANSC
3136         if (m_context.getTestContext().getCommandLine().isSubProcess())
3137 #endif // CTS_USES_VULKANSC
3138         {
3139             if (output.x() == (int)m_iterations[m_iterationCounter])
3140             {
3141                 // success
3142                 log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
3143             }
3144             else
3145             {
3146                 // failure
3147                 log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
3148                 log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
3149                 return tcu::TestStatus::fail("Got unexpected result");
3150             }
3151         }
3152 
3153         m_iterationCounter++;
3154         if (m_iterationCounter == (int)m_iterations.size())
3155             return tcu::TestStatus::pass("Pass");
3156         else
3157             return tcu::TestStatus::incomplete();
3158     }
3159 }
3160 
initTexture(void)3161 void TextureSamplesInstance::initTexture(void)
3162 {
3163     tcu::TestLog &log = m_context.getTestContext().getLog();
3164     tcu::IVec3 textureSize(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
3165     TextureBindingSp textureBinding;
3166 
3167     DE_ASSERT(m_textures.empty());
3168     DE_ASSERT(m_textureSpec.type == TEXTURETYPE_2D || m_textureSpec.type == TEXTURETYPE_2D_ARRAY);
3169 
3170     log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize)
3171         << tcu::TestLog::EndMessage;
3172 
3173     textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels,
3174                                         0 /* lodBase */, m_textureSpec.sampler);
3175 
3176     m_textures.push_back(textureBinding);
3177 }
3178 
3179 class TextureQueryLevelsInstance : public TextureQueryInstance
3180 {
3181 public:
3182     TextureQueryLevelsInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec);
3183     virtual ~TextureQueryLevelsInstance(void);
3184 
3185     virtual tcu::TestStatus iterate(void);
3186 
3187 private:
3188     struct TestSize
3189     {
3190         tcu::IVec3 textureSize;
3191         int lodBase;
3192     };
3193 
3194     void initTexture(void);
3195     bool testTextureLevels(void);
3196 
3197     TestSize m_testSize;
3198     int m_levels;
3199     int m_iterationCounter;
3200 };
3201 
TextureQueryLevelsInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec)3202 TextureQueryLevelsInstance::TextureQueryLevelsInstance(Context &context, const bool isVertexCase,
3203                                                        const TextureSpec &textureSpec)
3204     : TextureQueryInstance(context, isVertexCase, textureSpec)
3205     , m_testSize()
3206     , m_levels(0)
3207     , m_iterationCounter(0)
3208 {
3209     deMemset(&m_testSize, 0, sizeof(TestSize));
3210 
3211     m_renderSize = tcu::UVec2(1, 1);
3212 
3213 #ifdef CTS_USES_VULKANSC
3214     const VkDevice vkDevice         = getDevice();
3215     const DeviceInterface &vk       = getDeviceInterface();
3216     const uint32_t queueFamilyIndex = getUniversalQueueFamilyIndex();
3217     m_externalCommandPool           = de::SharedPtr<Unique<VkCommandPool>>(new vk::Unique<VkCommandPool>(
3218         createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)));
3219 #endif // CTS_USES_VULKANSC
3220 }
3221 
~TextureQueryLevelsInstance(void)3222 TextureQueryLevelsInstance::~TextureQueryLevelsInstance(void)
3223 {
3224 }
3225 
iterate(void)3226 tcu::TestStatus TextureQueryLevelsInstance::iterate(void)
3227 {
3228     const TestSize testSizes[] = {
3229         {tcu::IVec3(1, 2, 1), 0},
3230         {tcu::IVec3(1, 2, 1), 1},
3231 
3232         {tcu::IVec3(1, 3, 2), 0},
3233         {tcu::IVec3(1, 3, 2), 1},
3234 
3235         {tcu::IVec3(100, 31, 18), 0},
3236         {tcu::IVec3(100, 31, 18), 1},
3237         {tcu::IVec3(100, 31, 18), 2},
3238         {tcu::IVec3(100, 31, 18), 3},
3239         {tcu::IVec3(100, 31, 18), 4},
3240         {tcu::IVec3(100, 31, 18), 5},
3241         {tcu::IVec3(100, 31, 18), 6},
3242 
3243         {tcu::IVec3(100, 128, 32), 0},
3244         {tcu::IVec3(100, 128, 32), 1},
3245         {tcu::IVec3(100, 128, 32), 2},
3246         {tcu::IVec3(100, 128, 32), 3},
3247         {tcu::IVec3(100, 128, 32), 4},
3248         {tcu::IVec3(100, 128, 32), 5},
3249         {tcu::IVec3(100, 128, 32), 6},
3250         {tcu::IVec3(100, 128, 32), 7},
3251 
3252         // pow 2
3253         {tcu::IVec3(128, 64, 32), 0},
3254         {tcu::IVec3(128, 64, 32), 1},
3255         {tcu::IVec3(128, 64, 32), 2},
3256         {tcu::IVec3(128, 64, 32), 3},
3257         {tcu::IVec3(128, 64, 32), 4},
3258         {tcu::IVec3(128, 64, 32), 5},
3259         {tcu::IVec3(128, 64, 32), 6},
3260         {tcu::IVec3(128, 64, 32), 7},
3261 
3262         // w == h
3263         {tcu::IVec3(1, 1, 1), 0},
3264         {tcu::IVec3(64, 64, 64), 0},
3265         {tcu::IVec3(64, 64, 64), 1},
3266         {tcu::IVec3(64, 64, 64), 2},
3267         {tcu::IVec3(64, 64, 64), 3},
3268         {tcu::IVec3(64, 64, 64), 4},
3269         {tcu::IVec3(64, 64, 64), 5},
3270         {tcu::IVec3(64, 64, 64), 6},
3271 
3272         // w == h and d % 6 == 0 (for cube array)
3273         {tcu::IVec3(1, 1, 6), 0},
3274         {tcu::IVec3(32, 32, 12), 0},
3275         {tcu::IVec3(32, 32, 12), 1},
3276         {tcu::IVec3(32, 32, 12), 2},
3277         {tcu::IVec3(32, 32, 12), 3},
3278         {tcu::IVec3(32, 32, 12), 4},
3279         {tcu::IVec3(32, 32, 12), 5},
3280     };
3281     const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
3282 
3283     m_iterationCounter++;
3284 
3285     if (m_iterationCounter == lastIterationIndex)
3286         return tcu::TestStatus::pass("Pass");
3287     else
3288     {
3289         // set current test size
3290         m_testSize = testSizes[m_iterationCounter - 1];
3291 
3292         bool result = testTextureLevels();
3293 #ifdef CTS_USES_VULKANSC
3294         if (m_context.getTestContext().getCommandLine().isSubProcess())
3295 #endif // CTS_USES_VULKANSC
3296         {
3297             if (!result)
3298                 return tcu::TestStatus::fail("Got unexpected result");
3299         }
3300         return tcu::TestStatus::incomplete();
3301     }
3302 }
3303 
testTextureLevels(void)3304 bool TextureQueryLevelsInstance::testTextureLevels(void)
3305 {
3306     tcu::TestLog &log = m_context.getTestContext().getLog();
3307     bool success      = true;
3308 
3309     // skip incompatible cases
3310     if (!isValidCase(m_textureSpec.type, m_testSize.textureSize, m_testSize.lodBase))
3311         return true;
3312 
3313     // setup texture
3314     initTexture();
3315 
3316     // calculate accessible levels
3317     {
3318         const int mipLevels = deLog2Floor32(getMaxTextureSize(m_textureSpec.type, m_testSize.textureSize)) + 1;
3319 
3320         m_levels = mipLevels - m_testSize.lodBase;
3321         DE_ASSERT(m_levels > 0);
3322 
3323         log << tcu::TestLog::Message << "Expected levels: " << m_levels << tcu::TestLog::EndMessage;
3324     }
3325 
3326     // render
3327     TextureQueryInstance::render();
3328 
3329     // test
3330     {
3331         const tcu::TextureLevel &result = getResultImage();
3332         tcu::IVec4 output               = result.getAccess().getPixelInt(0, 0);
3333 
3334         if (output.x() == m_levels)
3335         {
3336             // success
3337             log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
3338         }
3339         else
3340         {
3341             // failure
3342             log << tcu::TestLog::Message << "Result: " << output.x() << tcu::TestLog::EndMessage;
3343             log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
3344             success = false;
3345         }
3346     }
3347 
3348     log << tcu::TestLog::Message << tcu::TestLog::EndMessage;
3349 
3350     return success;
3351 }
3352 
initTexture(void)3353 void TextureQueryLevelsInstance::initTexture(void)
3354 {
3355     tcu::TestLog &log = m_context.getTestContext().getLog();
3356     int numLevels     = m_testSize.lodBase + 1;
3357     TextureBindingSp textureBinding;
3358 
3359     log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, m_testSize.textureSize)
3360         << tcu::TestLog::EndMessage;
3361     log << tcu::TestLog::Message << "Base level: " << m_testSize.lodBase << tcu::TestLog::EndMessage;
3362 
3363     textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, m_testSize.textureSize, numLevels,
3364                                         m_testSize.lodBase, m_textureSpec.sampler);
3365 
3366     m_textures.clear();
3367     m_textures.push_back(textureBinding);
3368 }
3369 
getQueryLodFuncTextCoordComps(TextureType type)3370 static int getQueryLodFuncTextCoordComps(TextureType type)
3371 {
3372     switch (type)
3373     {
3374     case TEXTURETYPE_1D:
3375     case TEXTURETYPE_1D_ARRAY:
3376         return 1;
3377 
3378     case TEXTURETYPE_2D:
3379     case TEXTURETYPE_2D_ARRAY:
3380         return 2;
3381 
3382     case TEXTURETYPE_3D:
3383     case TEXTURETYPE_CUBE_MAP:
3384     case TEXTURETYPE_CUBE_ARRAY:
3385         return 3;
3386 
3387     default:
3388         DE_ASSERT(false);
3389         return 0;
3390     }
3391 }
3392 
3393 class TextureQueryLodInstance : public TextureQueryInstance
3394 {
3395 public:
3396     TextureQueryLodInstance(Context &context, const bool isVertexCase, const TextureSpec &textureSpec,
3397                             const TestMode mode);
3398     virtual ~TextureQueryLodInstance(void);
3399 
3400     virtual tcu::TestStatus iterate(void);
3401 
3402 protected:
3403     virtual void setupDefaultInputs(void);
3404 
3405 private:
3406     void initTexture(void);
3407     float computeLevelFromLod(float computedLod) const;
3408     vector<float> computeQuadTexCoord(void) const;
3409 
3410     const TestMode m_mode;
3411     tcu::Vec4 m_minCoord;
3412     tcu::Vec4 m_maxCoord;
3413     tcu::Vec2 m_lodBounds;
3414     tcu::Vec2 m_levelBounds;
3415 };
3416 
TextureQueryLodInstance(Context & context,const bool isVertexCase,const TextureSpec & textureSpec,const TestMode mode)3417 TextureQueryLodInstance::TextureQueryLodInstance(Context &context, const bool isVertexCase,
3418                                                  const TextureSpec &textureSpec, const TestMode mode)
3419     : TextureQueryInstance(context, isVertexCase, textureSpec)
3420     , m_mode(mode)
3421     , m_minCoord()
3422     , m_maxCoord()
3423     , m_lodBounds()
3424     , m_levelBounds()
3425 {
3426     // setup texture
3427     initTexture();
3428 
3429     if (m_mode == QLODTM_DEFAULT)
3430     {
3431         const tcu::UVec2 &viewportSize = getViewportSize();
3432         const float lodEps = (1.0f / float(1u << m_context.getDeviceProperties().limits.mipmapPrecisionBits)) + 0.008f;
3433 
3434         // init min/max coords and calculate lod and accessed level
3435         switch (m_textureSpec.type)
3436         {
3437         case TEXTURETYPE_1D:
3438         case TEXTURETYPE_1D_ARRAY:
3439         {
3440             m_minCoord = Vec4(-0.2f, 0.0f, 0.0f, 0.0f);
3441             m_maxCoord = Vec4(1.5f, 0.0f, 0.0f, 0.0f);
3442 
3443             const float dudx = (m_maxCoord[0] - m_minCoord[0]) * (float)m_textureSpec.width / (float)viewportSize[0];
3444 
3445             m_lodBounds[0] = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f) - lodEps;
3446             m_lodBounds[1] = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f) + lodEps;
3447             break;
3448         }
3449 
3450         case TEXTURETYPE_2D:
3451         case TEXTURETYPE_2D_ARRAY:
3452         {
3453             m_minCoord = Vec4(-0.2f, -0.4f, 0.0f, 0.0f);
3454             m_maxCoord = Vec4(1.5f, 2.3f, 0.0f, 0.0f);
3455 
3456             const float dudx = (m_maxCoord[0] - m_minCoord[0]) * (float)m_textureSpec.width / (float)viewportSize[0];
3457             const float dvdy = (m_maxCoord[1] - m_minCoord[1]) * (float)m_textureSpec.height / (float)viewportSize[1];
3458 
3459             m_lodBounds[0] = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy) - lodEps;
3460             m_lodBounds[1] = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy) + lodEps;
3461             break;
3462         }
3463 
3464         case TEXTURETYPE_CUBE_MAP:
3465         case TEXTURETYPE_CUBE_ARRAY:
3466         {
3467             m_minCoord = Vec4(-1.0f, -1.0f, 1.01f, 0.0f);
3468             m_maxCoord = Vec4(1.0f, 1.0f, 1.01f, 0.0f);
3469 
3470             // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
3471             DE_ASSERT(de::abs(m_minCoord[2] - m_maxCoord[2]) < 0.005);
3472             DE_ASSERT(de::abs(m_minCoord[0]) < de::abs(m_minCoord[2]) &&
3473                       de::abs(m_maxCoord[0]) < de::abs(m_minCoord[2]));
3474             DE_ASSERT(de::abs(m_minCoord[1]) < de::abs(m_minCoord[2]) &&
3475                       de::abs(m_maxCoord[1]) < de::abs(m_minCoord[2]));
3476 
3477             tcu::CubeFaceFloatCoords c00 = tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_minCoord[1], m_minCoord[2]));
3478             tcu::CubeFaceFloatCoords c10 = tcu::getCubeFaceCoords(Vec3(m_maxCoord[0], m_minCoord[1], m_minCoord[2]));
3479             tcu::CubeFaceFloatCoords c01 = tcu::getCubeFaceCoords(Vec3(m_minCoord[0], m_maxCoord[1], m_minCoord[2]));
3480             float dudx                   = (c10.s - c00.s) * (float)m_textureSpec.width / (float)viewportSize[0];
3481             float dvdy                   = (c01.t - c00.t) * (float)m_textureSpec.height / (float)viewportSize[1];
3482 
3483             m_lodBounds[0] = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, 0.0f, dvdy) - lodEps;
3484             m_lodBounds[1] = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, 0.0f, dvdy) + lodEps;
3485             break;
3486         }
3487 
3488         case TEXTURETYPE_3D:
3489         {
3490             m_minCoord = Vec4(-1.2f, -1.4f, 0.1f, 0.0f);
3491             m_maxCoord = Vec4(1.5f, 2.3f, 2.3f, 0.0f);
3492 
3493             const float dudx = (m_maxCoord[0] - m_minCoord[0]) * (float)m_textureSpec.width / (float)viewportSize[0];
3494             const float dvdy = (m_maxCoord[1] - m_minCoord[1]) * (float)m_textureSpec.height / (float)viewportSize[1];
3495             const float dwdx =
3496                 (m_maxCoord[2] - m_minCoord[2]) * 0.5f * (float)m_textureSpec.depth / (float)viewportSize[0];
3497             const float dwdy =
3498                 (m_maxCoord[2] - m_minCoord[2]) * 0.5f * (float)m_textureSpec.depth / (float)viewportSize[1];
3499 
3500             m_lodBounds[0] = computeLodFromDerivates(LODMODE_MIN_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy) - lodEps;
3501             m_lodBounds[1] = computeLodFromDerivates(LODMODE_MAX_BOUND, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy) + lodEps;
3502             break;
3503         }
3504 
3505         default:
3506             DE_ASSERT(false);
3507             break;
3508         }
3509 
3510         m_levelBounds[0] = computeLevelFromLod(m_lodBounds[0]);
3511         m_levelBounds[1] = computeLevelFromLod(m_lodBounds[1]);
3512 
3513         return;
3514     }
3515 
3516     if (m_mode == QLODTM_ZERO_UV_WIDTH)
3517     {
3518         // setup same texture coordinates that will result in pmax
3519         // beeing 0 and as a result lambda being -inf; on most
3520         // implementations lambda is computed as fixed-point, so
3521         // infinities can't be returned, instead -maxSamplerLodBias or less
3522         // should be returned
3523 
3524         m_minCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
3525         m_maxCoord = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
3526 
3527         m_lodBounds[0]   = -std::numeric_limits<float>::infinity();
3528         m_lodBounds[1]   = -context.getDeviceProperties().limits.maxSamplerLodBias;
3529         m_levelBounds[0] = 0.0f;
3530         m_levelBounds[1] = 0.0f;
3531 
3532         return;
3533     }
3534 
3535     DE_ASSERT(false);
3536 }
3537 
~TextureQueryLodInstance(void)3538 TextureQueryLodInstance::~TextureQueryLodInstance(void)
3539 {
3540 }
3541 
iterate(void)3542 tcu::TestStatus TextureQueryLodInstance::iterate(void)
3543 {
3544     tcu::TestLog &log = m_context.getTestContext().getLog();
3545 
3546     log << tcu::TestLog::Message << "Expected: level in range " << m_levelBounds << ", lod in range " << m_lodBounds
3547         << tcu::TestLog::EndMessage;
3548 
3549     // render
3550     TextureQueryInstance::render();
3551 
3552     // test
3553     {
3554         const tcu::TextureLevel &result = getResultImage();
3555         const tcu::Vec4 output          = result.getAccess().getPixel(0, 0);
3556         const float resLevel            = output.x();
3557         const float resLod              = output.y();
3558 
3559         if (de::inRange(resLevel, m_levelBounds[0], m_levelBounds[1]) &&
3560             de::inRange(resLod, m_lodBounds[0], m_lodBounds[1]))
3561         {
3562             // success
3563             log << tcu::TestLog::Message << "Passed" << tcu::TestLog::EndMessage;
3564             return tcu::TestStatus::pass("Pass");
3565         }
3566         else
3567         {
3568             // failure
3569             log << tcu::TestLog::Message << "Result: level: " << resLevel << ", lod: " << resLod
3570                 << tcu::TestLog::EndMessage;
3571             log << tcu::TestLog::Message << "Failed" << tcu::TestLog::EndMessage;
3572             return tcu::TestStatus::fail("Got unexpected result");
3573         }
3574     }
3575 }
3576 
setupDefaultInputs(void)3577 void TextureQueryLodInstance::setupDefaultInputs(void)
3578 {
3579     TextureQueryInstance::setupDefaultInputs();
3580 
3581     const uint32_t numVertices        = 4;
3582     const vector<float> texCoord      = computeQuadTexCoord();
3583     const int texCoordComps           = getQueryLodFuncTextCoordComps(m_textureSpec.type);
3584     const vk::VkFormat coordFormats[] = {vk::VK_FORMAT_R32_SFLOAT, vk::VK_FORMAT_R32G32_SFLOAT,
3585                                          vk::VK_FORMAT_R32G32B32_SFLOAT};
3586 
3587     DE_ASSERT(de::inRange(texCoordComps, 1, 3));
3588     DE_ASSERT((int)texCoord.size() == texCoordComps * 4);
3589 
3590     addAttribute(1u, coordFormats[texCoordComps - 1], (uint32_t)(texCoordComps * sizeof(float)), numVertices,
3591                  texCoord.data());
3592 }
3593 
initTexture(void)3594 void TextureQueryLodInstance::initTexture(void)
3595 {
3596     tcu::TestLog &log = m_context.getTestContext().getLog();
3597     tcu::IVec3 textureSize(m_textureSpec.width, m_textureSpec.height, m_textureSpec.depth);
3598     TextureBindingSp textureBinding;
3599 
3600     DE_ASSERT(m_textures.empty());
3601 
3602     log << tcu::TestLog::Message << "Image size: " << getTextureSizeString(m_textureSpec.type, textureSize)
3603         << tcu::TestLog::EndMessage;
3604 
3605     textureBinding = createEmptyTexture(m_textureSpec.format, m_textureSpec.type, textureSize, m_textureSpec.numLevels,
3606                                         0 /* lodBase */, m_textureSpec.sampler);
3607 
3608     m_textures.push_back(textureBinding);
3609 }
3610 
computeLevelFromLod(float computedLod) const3611 float TextureQueryLodInstance::computeLevelFromLod(float computedLod) const
3612 {
3613     const int maxAccessibleLevel = m_textureSpec.numLevels - 1;
3614 
3615     // Clamp the computed LOD to the range of accessible levels.
3616     computedLod = deFloatClamp(computedLod, 0.0f, (float)maxAccessibleLevel);
3617 
3618     // Return a value according to the min filter.
3619     switch (m_textureSpec.sampler.minFilter)
3620     {
3621     case tcu::Sampler::LINEAR:
3622     case tcu::Sampler::NEAREST:
3623         return 0.0f;
3624 
3625     case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
3626     case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
3627         return deFloatClamp(deFloatCeil(computedLod + 0.5f) - 1.0f, 0.0f, (float)maxAccessibleLevel);
3628 
3629     case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
3630     case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
3631         return computedLod;
3632 
3633     default:
3634         DE_ASSERT(false);
3635         return 0.0f;
3636     }
3637 }
3638 
computeQuadTexCoord(void) const3639 vector<float> TextureQueryLodInstance::computeQuadTexCoord(void) const
3640 {
3641     vector<float> res;
3642     tcu::Mat4 coordTransMat;
3643 
3644     {
3645         Vec4 s = m_maxCoord - m_minCoord;
3646         Vec4 b = m_minCoord;
3647 
3648         float baseCoordTrans[] = {s.x(),        0.0f,         0.f, b.x(),
3649                                   0.f,          s.y(),        0.f, b.y(),
3650                                   s.z() / 2.f,  -s.z() / 2.f, 0.f, s.z() / 2.f + b.z(),
3651                                   -s.w() / 2.f, s.w() / 2.f,  0.f, s.w() / 2.f + b.w()};
3652 
3653         coordTransMat = tcu::Mat4(baseCoordTrans);
3654     }
3655 
3656     const int texCoordComps = getQueryLodFuncTextCoordComps(m_textureSpec.type);
3657     Vec4 coords[4]          = {coordTransMat * tcu::Vec4(0, 0, 0, 1), coordTransMat * tcu::Vec4(0, 1, 0, 1),
3658                                coordTransMat * tcu::Vec4(1, 0, 0, 1), coordTransMat * tcu::Vec4(1, 1, 0, 1)};
3659 
3660     res.resize(4 * texCoordComps);
3661 
3662     for (int ndx = 0; ndx < 4; ndx++)
3663         deMemcpy(&res[ndx * texCoordComps], coords[ndx].getPtr(), texCoordComps * sizeof(float));
3664 
3665     return res;
3666 }
3667 
3668 class TextureQueryCase : public ShaderRenderCase
3669 {
3670 public:
3671     TextureQueryCase(tcu::TestContext &testCtx, const std::string &name, const std::string &samplerType,
3672                      const TextureSpec &texture, bool isVertexCase, QueryFunction function, TestMode mode = 0);
3673     virtual ~TextureQueryCase(void);
3674 
3675     virtual TestInstance *createInstance(Context &context) const;
3676     virtual void checkSupport(Context &context) const;
3677 
3678 protected:
3679     void initShaderSources(void);
3680 
3681     const std::string m_samplerTypeStr;
3682     const TextureSpec m_textureSpec;
3683     const QueryFunction m_function;
3684     const TestMode m_mode;
3685 };
3686 
TextureQueryCase(tcu::TestContext & testCtx,const std::string & name,const std::string & samplerType,const TextureSpec & texture,bool isVertexCase,QueryFunction function,TestMode mode)3687 TextureQueryCase::TextureQueryCase(tcu::TestContext &testCtx, const std::string &name, const std::string &samplerType,
3688                                    const TextureSpec &texture, bool isVertexCase, QueryFunction function, TestMode mode)
3689     : ShaderRenderCase(testCtx, name, isVertexCase, (ShaderEvaluator *)DE_NULL, DE_NULL, DE_NULL)
3690     , m_samplerTypeStr(samplerType)
3691     , m_textureSpec(texture)
3692     , m_function(function)
3693     , m_mode(mode)
3694 {
3695     initShaderSources();
3696 }
3697 
~TextureQueryCase(void)3698 TextureQueryCase::~TextureQueryCase(void)
3699 {
3700 }
3701 
createInstance(Context & context) const3702 TestInstance *TextureQueryCase::createInstance(Context &context) const
3703 {
3704     switch (m_function)
3705     {
3706     case QUERYFUNCTION_TEXTURESIZE:
3707         return new TextureSizeInstance(context, m_isVertexCase, m_textureSpec);
3708     case QUERYFUNCTION_TEXTURESIZEMS:
3709         return new TextureSizeMSInstance(context, m_isVertexCase, m_textureSpec);
3710     case QUERYFUNCTION_TEXTUREQUERYLOD:
3711         return new TextureQueryLodInstance(context, m_isVertexCase, m_textureSpec, m_mode);
3712     case QUERYFUNCTION_TEXTUREQUERYLEVELS:
3713         return new TextureQueryLevelsInstance(context, m_isVertexCase, m_textureSpec);
3714     case QUERYFUNCTION_TEXTURESAMPLES:
3715         return new TextureSamplesInstance(context, m_isVertexCase, m_textureSpec);
3716     default:
3717         DE_ASSERT(false);
3718         return DE_NULL;
3719     }
3720 }
3721 
checkSupport(Context & context) const3722 void TextureQueryCase::checkSupport(Context &context) const
3723 {
3724     checkMutableComparisonSamplersSupport(context, m_textureSpec);
3725 }
3726 
initShaderSources(void)3727 void TextureQueryCase::initShaderSources(void)
3728 {
3729     std::ostringstream vert;
3730     std::ostringstream frag;
3731     std::ostringstream &op = m_isVertexCase ? vert : frag;
3732 
3733     DE_ASSERT(m_function != QUERYFUNCTION_TEXTUREQUERYLOD || !m_isVertexCase);
3734 
3735     vert << "#version 450 core\n"
3736          << "layout(location = 0) in highp vec4 a_position;\n";
3737 
3738     frag << "#version 450 core\n"
3739          << "layout(location = 0) out mediump vec4 o_color;\n";
3740 
3741     if (m_isVertexCase)
3742     {
3743         vert << "layout(location = 0) out mediump vec4 v_color;\n";
3744         frag << "layout(location = 0) in mediump vec4 v_color;\n";
3745     }
3746 
3747     if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3748     {
3749         const int texCoordComps   = getQueryLodFuncTextCoordComps(m_textureSpec.type);
3750         const char *coordTypeName = glu::getDataTypeName(glu::getDataTypeFloatVec(texCoordComps));
3751 
3752         vert << "layout (location = 1) in highp " << coordTypeName << " a_texCoord;\n";
3753         vert << "layout (location = 0) out highp " << coordTypeName << " v_texCoord;\n";
3754         frag << "layout (location = 0) in highp " << coordTypeName << " v_texCoord;\n";
3755     }
3756 
3757     // uniforms
3758     op << "layout(set = 0, binding = 0) uniform highp " << m_samplerTypeStr << " u_sampler;\n";
3759     if (m_function == QUERYFUNCTION_TEXTURESIZE)
3760         op << "layout(set = 0, binding = 1) uniform buf0 { highp int u_lod; };\n";
3761 
3762     vert << "out gl_PerVertex {\n"
3763          << "\tvec4 gl_Position;\n"
3764          << "};\n";
3765 
3766     vert << "\nvoid main()\n{\n"
3767          << "\tgl_Position = a_position;\n";
3768     frag << "\nvoid main()\n{\n";
3769 
3770     if (m_isVertexCase)
3771         vert << "\tv_color = ";
3772     else
3773         frag << "\to_color = ";
3774 
3775     // op
3776     {
3777         op << "vec4(";
3778 
3779         switch (m_function)
3780         {
3781         case QUERYFUNCTION_TEXTURESIZE:
3782         {
3783             const int resultComponents = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3784 
3785             op << "textureSize(u_sampler, u_lod)";
3786             for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3787                 op << ", 0.0";
3788             op << ", 1.0";
3789 
3790             break;
3791         }
3792 
3793         case QUERYFUNCTION_TEXTURESIZEMS:
3794         {
3795             const int resultComponents = glu::getDataTypeScalarSize(getTextureSizeFuncResultType(m_textureSpec.type));
3796 
3797             op << "textureSize(u_sampler)";
3798             for (int ndx = 0; ndx < 3 - resultComponents; ndx++)
3799                 op << ", 0.0";
3800             op << ", 1.0";
3801 
3802             break;
3803         }
3804 
3805         case QUERYFUNCTION_TEXTUREQUERYLOD:
3806             op << "textureQueryLod(u_sampler, v_texCoord), 0.0, 1.0";
3807             break;
3808 
3809         case QUERYFUNCTION_TEXTUREQUERYLEVELS:
3810             op << "textureQueryLevels(u_sampler), 0.0, 0.0, 1.0";
3811             break;
3812 
3813         case QUERYFUNCTION_TEXTURESAMPLES:
3814             op << "textureSamples(u_sampler), 0.0, 0.0, 1.0";
3815             break;
3816 
3817         default:
3818             DE_ASSERT(false);
3819             break;
3820         }
3821 
3822         op << ");\n";
3823     }
3824 
3825     if (m_isVertexCase)
3826         frag << "\to_color = v_color;\n";
3827 
3828     if (m_function == QUERYFUNCTION_TEXTUREQUERYLOD)
3829         vert << "\tv_texCoord = a_texCoord;\n";
3830 
3831     vert << "}\n";
3832     frag << "}\n";
3833 
3834     m_vertShaderSource = vert.str();
3835     m_fragShaderSource = frag.str();
3836 }
3837 
3838 namespace SpecialCases
3839 {
3840 using namespace vk;
3841 
textureSizeOOBPrograms(vk::SourceCollections & programCollection)3842 void textureSizeOOBPrograms(vk::SourceCollections &programCollection)
3843 {
3844     programCollection.glslSources.add("comp")
3845         << glu::ComputeSource("#version 450\n"
3846                               "layout(local_size_x = 1) in;\n"
3847                               "layout(binding = 0) buffer InBuffer\n"
3848                               "{\n"
3849                               "  highp int lods[];\n"
3850                               "};\n"
3851                               "layout(binding = 1) buffer OutBuffer\n"
3852                               "{\n"
3853                               "  highp ivec2 results[];\n"
3854                               "};\n"
3855                               "layout(binding = 2) uniform sampler2D u_image;\n"
3856                               "void main(void)\n"
3857                               "{\n"
3858                               "  uint invocationNdx = gl_WorkGroupID.x;\n"
3859                               "  int lod = lods[invocationNdx];\n"
3860                               "  results[invocationNdx] = textureSize(u_image, lod);\n"
3861                               "}\n");
3862 }
3863 
textureSizeOOBTest(Context & context)3864 tcu::TestStatus textureSizeOOBTest(Context &context)
3865 {
3866     // run few shader invocations, some invocations have in-bounds lod values, some out of bounds
3867 
3868     const int testedLods[] = {0, 10, 0, 1, 50, 0, 1, 2, -1, 0};
3869     const IVec2 imageSize  = {16, 8};
3870 
3871     const DeviceInterface &vk       = context.getDeviceInterface();
3872     const VkDevice device           = context.getDevice();
3873     const VkQueue queue             = context.getUniversalQueue();
3874     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3875     Allocator &allocator            = context.getDefaultAllocator();
3876 
3877     // create input and output buffers
3878     const VkDeviceSize bufferSizeBytes  = sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods) * 2;
3879     VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3880     BufferWithMemory inBuffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3881     BufferWithMemory outBuffer(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);
3882 
3883     // write data to input buffer
3884     auto &inAlloc = inBuffer.getAllocation();
3885     deMemcpy(inAlloc.getHostPtr(), testedLods, sizeof(int) * DE_LENGTH_OF_ARRAY(testedLods));
3886     flushAlloc(vk, device, inAlloc);
3887 
3888     // create image, we do not need to fill it with data for this test
3889     const VkImageCreateInfo imageCreateInfo{
3890         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                          // VkStructureType sType;
3891         DE_NULL,                                                      // const void* pNext;
3892         0u,                                                           // VkImageCreateFlags flags;
3893         VK_IMAGE_TYPE_2D,                                             // VkImageType imageType;
3894         VK_FORMAT_R8G8B8A8_UNORM,                                     // VkFormat format;
3895         vk::makeExtent3D(imageSize.x(), imageSize.y(), 1),            // VkExtent3D extent;
3896         3u,                                                           // uint32_t mipLevels;
3897         1u,                                                           // uint32_t arrayLayers;
3898         VK_SAMPLE_COUNT_1_BIT,                                        // VkSampleCountFlagBits samples;
3899         VK_IMAGE_TILING_OPTIMAL,                                      // VkImageTiling tiling;
3900         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
3901         VK_SHARING_MODE_EXCLUSIVE,                                    // VkSharingMode sharingMode;
3902         0u,                                                           // uint32_t queueFamilyIndexCount;
3903         DE_NULL,                                                      // const uint32_t* pQueueFamilyIndices;
3904         VK_IMAGE_LAYOUT_UNDEFINED,                                    // VkImageLayout initialLayout;
3905     };
3906     const ImageWithMemory image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any);
3907     const VkImageSubresourceRange subresourceRange(
3908         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 3u, 0u, 1u));
3909     const Unique<VkImageView> imageView(
3910         makeImageView(vk, device, *image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, subresourceRange));
3911 
3912     // create sampler with everything set to 0 as we wont use it in test
3913     const VkSamplerCreateInfo samplerCreateInfo = initVulkanStructure();
3914     const Unique<VkSampler> sampler(createSampler(vk, device, &samplerCreateInfo));
3915 
3916     // create descriptors
3917     const Unique<VkDescriptorPool> descriptorPool(
3918         DescriptorPoolBuilder()
3919             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
3920             .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
3921             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
3922 
3923     const Unique<VkDescriptorSetLayout> descriptorSetLayout(
3924         DescriptorSetLayoutBuilder()
3925             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3926             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
3927             .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
3928             .build(vk, device));
3929 
3930     const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
3931     const VkDescriptorBufferInfo inDescriptorInfo  = makeDescriptorBufferInfo(*inBuffer, 0ull, bufferSizeBytes);
3932     const VkDescriptorBufferInfo outDescriptorInfo = makeDescriptorBufferInfo(*outBuffer, 0ull, bufferSizeBytes);
3933     const VkDescriptorImageInfo imageDescriptorInfo =
3934         makeDescriptorImageInfo(*sampler, *imageView, VK_IMAGE_LAYOUT_GENERAL);
3935     DescriptorSetUpdateBuilder()
3936         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
3937                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inDescriptorInfo)
3938         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
3939                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outDescriptorInfo)
3940         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
3941                      VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageDescriptorInfo)
3942         .update(vk, device);
3943 
3944     // perform the computation
3945     const Unique<VkShaderModule> shaderModule(
3946         createShaderModule(vk, device, context.getBinaryCollection().get("comp"), 0u));
3947     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
3948     const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
3949     const VkImageMemoryBarrier layoutBarrier(makeImageMemoryBarrier(
3950         0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, *image, subresourceRange));
3951     const VkBufferMemoryBarrier outBarrier(makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
3952                                                                    *outBuffer, 0ull, bufferSizeBytes));
3953     const Unique<VkCommandPool> cmdPool(makeCommandPool(vk, device, queueFamilyIndex));
3954     const Unique<VkCommandBuffer> cmdBuffer(
3955         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3956 
3957     // start recording commands
3958     beginCommandBuffer(vk, *cmdBuffer);
3959 
3960     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
3961                           (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &layoutBarrier);
3962     vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3963     vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(),
3964                              0u, DE_NULL);
3965     vk.cmdDispatch(*cmdBuffer, DE_LENGTH_OF_ARRAY(testedLods), 1, 1);
3966     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3967                           (VkDependencyFlags)0, 0, DE_NULL, 1, &outBarrier, 0, DE_NULL);
3968 
3969     endCommandBuffer(vk, *cmdBuffer);
3970     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
3971 
3972     // validate the results
3973     const Allocation &bufferAllocation = outBuffer.getAllocation();
3974     invalidateAlloc(vk, device, bufferAllocation);
3975 
3976     std::map<int, IVec2> expectedLodSize{
3977         {0, {16, 8}},
3978         {1, {8, 4}},
3979         {2, {4, 2}},
3980     };
3981     bool testFailed      = false;
3982     tcu::TestLog &log    = context.getTestContext().getLog();
3983     const int *bufferPtr = static_cast<int *>(bufferAllocation.getHostPtr());
3984 
3985     for (uint32_t lodNdx = 0; lodNdx < DE_LENGTH_OF_ARRAY(testedLods); ++lodNdx)
3986     {
3987         const int returnedWidth  = bufferPtr[2 * lodNdx + 0];
3988         const int returnedHeight = bufferPtr[2 * lodNdx + 1];
3989         const int usedLod        = testedLods[lodNdx];
3990 
3991         if ((usedLod >= 0) && (usedLod < 3))
3992         {
3993             const auto &expectedSize = expectedLodSize[usedLod];
3994             if ((returnedWidth != expectedSize.x()) || (returnedHeight != expectedSize.y()))
3995             {
3996                 log << tcu::TestLog::Message << "Wrong size for invocation " << lodNdx << ", expected " << expectedSize
3997                     << " got (" << returnedWidth << ", " << returnedHeight << ")" << tcu::TestLog::EndMessage;
3998                 testFailed = true;
3999             }
4000         }
4001     }
4002 
4003     if (testFailed)
4004         return tcu::TestStatus::fail("Fail");
4005     return tcu::TestStatus::pass("Pass");
4006 }
4007 
4008 } // namespace SpecialCases
4009 
4010 class ShaderTextureFunctionTests : public tcu::TestCaseGroup
4011 {
4012 public:
4013     ShaderTextureFunctionTests(tcu::TestContext &context);
4014     virtual ~ShaderTextureFunctionTests(void);
4015     virtual void init(void);
4016 
4017 private:
4018     ShaderTextureFunctionTests(const ShaderTextureFunctionTests &);            // not allowed!
4019     ShaderTextureFunctionTests &operator=(const ShaderTextureFunctionTests &); // not allowed!
4020 };
4021 
ShaderTextureFunctionTests(tcu::TestContext & context)4022 ShaderTextureFunctionTests::ShaderTextureFunctionTests(tcu::TestContext &context)
4023     : TestCaseGroup(context, "texture_functions")
4024 {
4025 }
4026 
~ShaderTextureFunctionTests(void)4027 ShaderTextureFunctionTests::~ShaderTextureFunctionTests(void)
4028 {
4029 }
4030 
4031 enum CaseFlags
4032 {
4033     VERTEX   = (1 << 0),
4034     FRAGMENT = (1 << 1),
4035     BOTH     = VERTEX | FRAGMENT
4036 };
4037 
4038 struct TexFuncCaseSpec
4039 {
4040     const char *name;
4041     TextureLookupSpec lookupSpec;
4042     TextureSpec texSpec;
4043     TexEvalFunc evalFunc;
4044     uint32_t flags;
4045 };
4046 
4047 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC,   \
4048                   FLAGS)                                                                                           \
4049     {                                                                                                              \
4050         #NAME,                                                                                                     \
4051             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), \
4052                               tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, false, 0.0f),                   \
4053             TEXSPEC, EVALFUNC, FLAGS                                                                               \
4054     }
4055 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC,    \
4056                        EVALFUNC, FLAGS)                                                                           \
4057     {                                                                                                             \
4058         #NAME,                                                                                                    \
4059             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, \
4060                               OFFSET, false, 0.0f),                                                               \
4061             TEXSPEC, EVALFUNC, FLAGS                                                                              \
4062     }
4063 #define CLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, LODCLAMP, TEXSPEC, \
4064                         EVALFUNC, FLAGS)                                                                               \
4065     {                                                                                                                  \
4066         #NAME,                                                                                                         \
4067             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f),     \
4068                               tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET, true, LODCLAMP),                    \
4069             TEXSPEC, EVALFUNC, FLAGS                                                                                   \
4070     }
4071 #define GRADCLAMP_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, LODCLAMP, \
4072                             TEXSPEC, EVALFUNC, FLAGS)                                                                \
4073     {                                                                                                                \
4074         #NAME,                                                                                                       \
4075             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET,    \
4076                               OFFSET, true, LODCLAMP),                                                               \
4077             TEXSPEC, EVALFUNC, FLAGS                                                                                 \
4078     }
4079 
4080 #ifndef CTS_USES_VULKANSC
4081 
4082 class SparseShaderTextureFunctionInstance : public ShaderTextureFunctionInstance
4083 {
4084 public:
4085     SparseShaderTextureFunctionInstance(Context &context, const bool isVertexCase, const ShaderEvaluator &evaluator,
4086                                         const UniformSetup &uniformSetup, const TextureLookupSpec &lookupSpec,
4087                                         const TextureSpec &textureSpec, const TexLookupParams &lookupParams,
4088                                         const ImageBackingMode imageBackingMode = IMAGE_BACKING_MODE_SPARSE);
4089     virtual ~SparseShaderTextureFunctionInstance(void);
4090 };
4091 
SparseShaderTextureFunctionInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const TextureLookupSpec & lookupSpec,const TextureSpec & textureSpec,const TexLookupParams & lookupParams,const ImageBackingMode imageBackingMode)4092 SparseShaderTextureFunctionInstance::SparseShaderTextureFunctionInstance(
4093     Context &context, const bool isVertexCase, const ShaderEvaluator &evaluator, const UniformSetup &uniformSetup,
4094     const TextureLookupSpec &lookupSpec, const TextureSpec &textureSpec, const TexLookupParams &lookupParams,
4095     const ImageBackingMode imageBackingMode)
4096     : ShaderTextureFunctionInstance(context, isVertexCase, evaluator, uniformSetup, lookupSpec, textureSpec,
4097                                     lookupParams, imageBackingMode)
4098 {
4099     if (lookupSpec.useClamp)
4100     {
4101         const vk::VkPhysicalDeviceFeatures &deviceFeatures = context.getDeviceFeatures();
4102 
4103         if (!deviceFeatures.shaderResourceMinLod)
4104             TCU_THROW(NotSupportedError, "ShaderResourceMinLod feature not supported.");
4105     }
4106 }
4107 
~SparseShaderTextureFunctionInstance(void)4108 SparseShaderTextureFunctionInstance::~SparseShaderTextureFunctionInstance(void)
4109 {
4110 }
4111 
4112 class SparseShaderTextureFunctionCase : public ShaderTextureFunctionCase
4113 {
4114 public:
4115     SparseShaderTextureFunctionCase(tcu::TestContext &testCtx, const std::string &name, const TextureLookupSpec &lookup,
4116                                     const TextureSpec &texture, TexEvalFunc evalFunc, bool isVertexCase);
4117 
4118     virtual ~SparseShaderTextureFunctionCase(void);
4119 
4120     virtual TestInstance *createInstance(Context &context) const;
4121     virtual void checkSupport(Context &context) const;
4122 
4123 protected:
4124     void initShaderSources(void);
4125 };
4126 
SparseShaderTextureFunctionCase(tcu::TestContext & testCtx,const std::string & name,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)4127 SparseShaderTextureFunctionCase::SparseShaderTextureFunctionCase(tcu::TestContext &testCtx, const std::string &name,
4128                                                                  const TextureLookupSpec &lookup,
4129                                                                  const TextureSpec &texture, TexEvalFunc evalFunc,
4130                                                                  bool isVertexCase)
4131     : ShaderTextureFunctionCase(testCtx, name, lookup, texture, evalFunc, isVertexCase)
4132 {
4133     initShaderSources();
4134 }
4135 
initShaderSources(void)4136 void SparseShaderTextureFunctionCase::initShaderSources(void)
4137 {
4138     const Function function = m_lookupSpec.function;
4139     const bool isVtxCase    = m_isVertexCase;
4140     const bool isProj       = functionHasProj(function);
4141     const bool isGrad       = functionHasGrad(function);
4142     const bool isShadow     = m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
4143     const bool is2DProj4    = !isShadow && m_textureSpec.type == TEXTURETYPE_2D &&
4144                            (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD ||
4145                             function == FUNCTION_TEXTUREPROJGRAD);
4146     const bool isIntCoord           = function == FUNCTION_TEXELFETCH;
4147     const bool hasLodBias           = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
4148     const int texCoordComps         = m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
4149     const int extraCoordComps       = (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
4150     const glu::DataType coordType   = glu::getDataTypeFloatVec(texCoordComps + extraCoordComps);
4151     const glu::Precision coordPrec  = glu::PRECISION_HIGHP;
4152     const char *coordTypeName       = glu::getDataTypeName(coordType);
4153     const char *coordPrecName       = glu::getPrecisionName(coordPrec);
4154     const tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_textureSpec.format);
4155     glu::DataType samplerType       = glu::TYPE_LAST;
4156     const glu::DataType gradType =
4157         (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ? glu::TYPE_FLOAT_VEC3 :
4158                                                                                                glu::TYPE_FLOAT_VEC2;
4159     const char *gradTypeName = glu::getDataTypeName(gradType);
4160     const char *baseFuncName = DE_NULL;
4161 
4162     DE_ASSERT(!isGrad || !hasLodBias);
4163 
4164     switch (m_textureSpec.type)
4165     {
4166     case TEXTURETYPE_2D:
4167         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW : glu::getSampler2DType(texFmt);
4168         break;
4169     case TEXTURETYPE_CUBE_MAP:
4170         samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW : glu::getSamplerCubeType(texFmt);
4171         break;
4172     case TEXTURETYPE_2D_ARRAY:
4173         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW : glu::getSampler2DArrayType(texFmt);
4174         break;
4175     case TEXTURETYPE_3D:
4176         DE_ASSERT(!isShadow);
4177         samplerType = glu::getSampler3DType(texFmt);
4178         break;
4179     default:
4180         DE_ASSERT(false);
4181     }
4182 
4183     // Not supported cases
4184     switch (m_lookupSpec.function)
4185     {
4186     case FUNCTION_TEXTURE:
4187         baseFuncName = "sparseTexture";
4188         break;
4189     case FUNCTION_TEXTURELOD:
4190         baseFuncName = "sparseTextureLod";
4191         break;
4192     case FUNCTION_TEXTUREGRAD:
4193         baseFuncName = "sparseTextureGrad";
4194         break;
4195     case FUNCTION_TEXELFETCH:
4196         baseFuncName = "sparseTexelFetch";
4197         break;
4198     default:
4199         DE_ASSERT(false);
4200     }
4201 
4202     std::ostringstream vert;
4203     std::ostringstream frag;
4204     std::ostringstream &op = isVtxCase ? vert : frag;
4205 
4206     vert << "#version 450\n"
4207          << "#extension GL_ARB_sparse_texture2 : require\n"
4208          << "layout(location = 0) in highp vec4 a_position;\n"
4209          << "layout(location = 4) in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
4210 
4211     if (isGrad)
4212     {
4213         vert << "layout(location = 5) in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
4214         vert << "layout(location = 6) in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
4215     }
4216     else if (hasLodBias)
4217         vert << "layout(location = 5) in " << coordPrecName << " float a_in1;\n";
4218 
4219     frag << "#version 450\n"
4220          << "#extension GL_ARB_sparse_texture2 : require\n";
4221 
4222     if (m_lookupSpec.useClamp)
4223         frag << "#extension GL_ARB_sparse_texture_clamp : require\n";
4224 
4225     frag << "layout(location = 0) out mediump vec4 o_color;\n";
4226 
4227     if (isVtxCase)
4228     {
4229         vert << "layout(location = 0) out mediump vec4 v_color;\n";
4230         frag << "layout(location = 0) in mediump vec4 v_color;\n";
4231     }
4232     else
4233     {
4234         vert << "layout(location = 0) out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
4235         frag << "layout(location = 0) in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
4236 
4237         if (isGrad)
4238         {
4239             vert << "layout(location = 1) out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
4240             vert << "layout(location = 2) out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
4241             frag << "layout(location = 1) in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
4242             frag << "layout(location = 2) in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
4243         }
4244         else if (hasLodBias)
4245         {
4246             vert << "layout(location = 1) out " << coordPrecName << " float v_lodBias;\n";
4247             frag << "layout(location = 1) in " << coordPrecName << " float v_lodBias;\n";
4248         }
4249     }
4250 
4251     // Uniforms
4252     op << "layout(set = 0, binding = 0) uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
4253        << "layout(set = 0, binding = 1) uniform buf0 { highp vec4 u_scale; };\n"
4254        << "layout(set = 0, binding = 2) uniform buf1 { highp vec4 u_bias; };\n";
4255 
4256     vert << "out gl_PerVertex {\n"
4257          << "    vec4 gl_Position;\n"
4258          << "};\n";
4259     vert << "\nvoid main()\n{\n"
4260          << "\tgl_Position = a_position;\n";
4261     frag << "\nvoid main()\n{\n";
4262 
4263     // Op.
4264     {
4265         // Texel declaration
4266         if (isShadow)
4267             op << "\tfloat texel;\n";
4268         else
4269             op << "\tvec4 texel;\n";
4270 
4271         const char *const texCoord = isVtxCase ? "a_in0" : "v_texCoord";
4272         const char *const gradX    = isVtxCase ? "a_in1" : "v_gradX";
4273         const char *const gradY    = isVtxCase ? "a_in2" : "v_gradY";
4274         const char *const lodBias  = isVtxCase ? "a_in1" : "v_lodBias";
4275 
4276         op << "\tint success = " << baseFuncName;
4277 
4278         if (m_lookupSpec.useOffset)
4279             op << "Offset";
4280 
4281         if (m_lookupSpec.useClamp)
4282             op << "Clamp";
4283 
4284         op << "ARB(u_sampler, ";
4285 
4286         if (isIntCoord)
4287             op << "ivec" << (texCoordComps + extraCoordComps) << "(";
4288 
4289         op << texCoord;
4290 
4291         if (isIntCoord)
4292             op << ")";
4293 
4294         if (isGrad)
4295             op << ", " << gradX << ", " << gradY;
4296 
4297         if (functionHasLod(function))
4298         {
4299             if (isIntCoord)
4300                 op << ", int(" << lodBias << ")";
4301             else
4302                 op << ", " << lodBias;
4303         }
4304 
4305         if (m_lookupSpec.useOffset)
4306         {
4307             int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
4308 
4309             op << ", ivec" << offsetComps << "(";
4310             for (int ndx = 0; ndx < offsetComps; ndx++)
4311             {
4312                 if (ndx != 0)
4313                     op << ", ";
4314                 op << m_lookupSpec.offset[ndx];
4315             }
4316             op << ")";
4317         }
4318 
4319         if (m_lookupSpec.useClamp)
4320             op << ", float(" << m_lookupSpec.lodClamp << ")";
4321 
4322         op << ", texel";
4323 
4324         if (m_lookupSpec.useBias)
4325             op << ", " << lodBias;
4326 
4327         op << ");\n";
4328 
4329         // Check sparse validity, and handle each case
4330         op << "\tif (sparseTexelsResidentARB(success))\n";
4331 
4332         if (isVtxCase)
4333             vert << "\t\tv_color = ";
4334         else
4335             frag << "\t\to_color = ";
4336 
4337         if (isShadow)
4338             op << "vec4(texel, 0.0, 0.0, 1.0);\n";
4339         else
4340             op << "vec4(texel * u_scale + u_bias);\n";
4341 
4342         op << "\telse\n";
4343 
4344         // This color differs from the used colors
4345         if (isVtxCase)
4346             vert << "\t\tv_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
4347         else
4348             frag << "\t\to_color = vec4(0.54117647058, 0.16862745098, 0.8862745098, 1.0);\n";
4349     }
4350 
4351     if (isVtxCase)
4352         frag << "\to_color = v_color;\n";
4353     else
4354     {
4355         vert << "\tv_texCoord = a_in0;\n";
4356 
4357         if (isGrad)
4358         {
4359             vert << "\tv_gradX = a_in1;\n";
4360             vert << "\tv_gradY = a_in2;\n";
4361         }
4362         else if (hasLodBias)
4363             vert << "\tv_lodBias = a_in1;\n";
4364     }
4365 
4366     vert << "}\n";
4367     frag << "}\n";
4368 
4369     m_vertShaderSource = vert.str();
4370     m_fragShaderSource = frag.str();
4371 }
4372 
~SparseShaderTextureFunctionCase()4373 SparseShaderTextureFunctionCase::~SparseShaderTextureFunctionCase()
4374 {
4375 }
4376 
createInstance(Context & context) const4377 TestInstance *SparseShaderTextureFunctionCase::createInstance(Context &context) const
4378 {
4379     DE_ASSERT(m_evaluator != DE_NULL);
4380     DE_ASSERT(m_uniformSetup != DE_NULL);
4381     return new SparseShaderTextureFunctionInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_lookupSpec,
4382                                                    m_textureSpec, m_lookupParams);
4383 }
4384 
checkSupport(Context & context) const4385 void SparseShaderTextureFunctionCase::checkSupport(Context &context) const
4386 {
4387     checkMutableComparisonSamplersSupport(context, m_textureSpec);
4388 }
4389 
4390 #endif // CTS_USES_VULKANSC
4391 
createCaseGroup(tcu::TestCaseGroup * parent,const char * groupName,const TexFuncCaseSpec * cases,int numCases)4392 static void createCaseGroup(tcu::TestCaseGroup *parent, const char *groupName, const TexFuncCaseSpec *cases,
4393                             int numCases)
4394 {
4395     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(parent->getTestContext(), groupName));
4396 
4397     for (int ndx = 0; ndx < numCases; ndx++)
4398     {
4399         std::string name = cases[ndx].name;
4400 #ifndef CTS_USES_VULKANSC
4401         bool sparseSupported =
4402             !functionHasProj(cases[ndx].lookupSpec.function) && TEXTURETYPE_1D != cases[ndx].texSpec.type &&
4403             TEXTURETYPE_1D_ARRAY != cases[ndx].texSpec.type && TEXTURETYPE_CUBE_ARRAY != cases[ndx].texSpec.type;
4404 #endif // CTS_USES_VULKANSC
4405 
4406         if (cases[ndx].flags & VERTEX)
4407         {
4408 #ifndef CTS_USES_VULKANSC
4409             if (sparseSupported)
4410                 group->addChild(new SparseShaderTextureFunctionCase(
4411                     parent->getTestContext(), ("sparse_" + name + "_vertex"), cases[ndx].lookupSpec, cases[ndx].texSpec,
4412                     cases[ndx].evalFunc, true));
4413 #endif // CTS_USES_VULKANSC
4414 
4415             group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_vertex"),
4416                                                           cases[ndx].lookupSpec, cases[ndx].texSpec,
4417                                                           cases[ndx].evalFunc, true));
4418         }
4419 
4420         if (cases[ndx].flags & FRAGMENT)
4421         {
4422 #ifndef CTS_USES_VULKANSC
4423             if (sparseSupported)
4424                 group->addChild(new SparseShaderTextureFunctionCase(
4425                     parent->getTestContext(), ("sparse_" + name + "_fragment"), cases[ndx].lookupSpec,
4426                     cases[ndx].texSpec, cases[ndx].evalFunc, false));
4427 #endif // CTS_USES_VULKANSC
4428 
4429             group->addChild(new ShaderTextureFunctionCase(parent->getTestContext(), (name + "_fragment"),
4430                                                           cases[ndx].lookupSpec, cases[ndx].texSpec,
4431                                                           cases[ndx].evalFunc, false));
4432         }
4433     }
4434 
4435     parent->addChild(group.release());
4436 }
4437 
init(void)4438 void ShaderTextureFunctionTests::init(void)
4439 {
4440     struct WrappingModeWithName
4441     {
4442         tcu::Sampler::WrapMode mode;
4443         const char *name;
4444     };
4445     static const WrappingModeWithName wrappingModesForOffset[] = {
4446         {tcu::Sampler::CLAMP_TO_EDGE, "clamp_to_edge"},
4447         {tcu::Sampler::CLAMP_TO_BORDER, "clamp_to_border"},
4448         {tcu::Sampler::REPEAT_GL, "repeat"},
4449         {tcu::Sampler::MIRRORED_REPEAT_GL, "mirrored_repeat"},
4450         {tcu::Sampler::MIRRORED_ONCE, "mirrored"},
4451     };
4452     // Samplers
4453     static const tcu::Sampler samplerNearestNoMipmap(
4454         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST,
4455         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
4456         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4457     static const tcu::Sampler samplerLinearNoMipmap(
4458         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR,
4459         tcu::Sampler::LINEAR, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
4460         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4461     static const tcu::Sampler samplerNearestMipmap(
4462         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
4463         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
4464         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4465     static const tcu::Sampler samplerLinearMipmap(
4466         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR_MIPMAP_NEAREST,
4467         tcu::Sampler::LINEAR, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
4468         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4469 
4470     static const tcu::Sampler samplerShadowNoMipmap(
4471         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST,
4472         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
4473         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4474     static const tcu::Sampler samplerShadowMipmap(
4475         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
4476         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
4477         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4478 
4479     static const tcu::Sampler samplerTexelFetch(
4480         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
4481         tcu::Sampler::NEAREST, 00.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
4482         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
4483 
4484     // Default textures.
4485     //                                                Type                    Format                    W        H        D    L    Sampler
4486     static const TextureSpec tex2DFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
4487     static const TextureSpec tex2DFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
4488     static const TextureSpec tex2DInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
4489     static const TextureSpec tex2DUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
4490     static const TextureSpec tex2DMipmapFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
4491     static const TextureSpec tex2DMipmapFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 9, samplerLinearMipmap);
4492     static const TextureSpec tex2DMipmapInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
4493     static const TextureSpec tex2DMipmapUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
4494 
4495     static const TextureSpec tex2DShadow(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 256, 256, 1, 1, samplerShadowNoMipmap);
4496     static const TextureSpec tex2DMipmapShadow(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 256, 256, 1, 9,
4497                                                samplerShadowMipmap);
4498 
4499     static const TextureSpec tex2DTexelFetchFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 9, samplerTexelFetch);
4500     static const TextureSpec tex2DTexelFetchFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 9, samplerTexelFetch);
4501     static const TextureSpec tex2DTexelFetchInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 9, samplerTexelFetch);
4502     static const TextureSpec tex2DTexelFetchUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 9, samplerTexelFetch);
4503 
4504     static const TextureSpec texCubeFixed(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
4505     static const TextureSpec texCubeFloat(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
4506     static const TextureSpec texCubeInt(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
4507     static const TextureSpec texCubeUint(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
4508     static const TextureSpec texCubeMipmapFixed(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
4509     static const TextureSpec texCubeMipmapFloat(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 128, 128, 1, 8, samplerLinearMipmap);
4510     static const TextureSpec texCubeMipmapInt(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
4511     static const TextureSpec texCubeMipmapUint(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
4512 
4513     static const TextureSpec texCubeShadow(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 256, 256, 1, 1,
4514                                            samplerShadowNoMipmap);
4515     static const TextureSpec texCubeMipmapShadow(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 256, 256, 1, 9,
4516                                                  samplerShadowMipmap);
4517 
4518     static const TextureSpec tex2DArrayFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 1, samplerLinearNoMipmap);
4519     static const TextureSpec tex2DArrayFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 1, samplerLinearNoMipmap);
4520     static const TextureSpec tex2DArrayInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 1, samplerNearestNoMipmap);
4521     static const TextureSpec tex2DArrayUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 1, samplerNearestNoMipmap);
4522     static const TextureSpec tex2DArrayMipmapFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 8, samplerLinearMipmap);
4523     static const TextureSpec tex2DArrayMipmapFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 8,
4524                                                    samplerLinearMipmap);
4525     static const TextureSpec tex2DArrayMipmapInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 8, samplerNearestMipmap);
4526     static const TextureSpec tex2DArrayMipmapUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 8,
4527                                                   samplerNearestMipmap);
4528 
4529     static const TextureSpec tex2DArrayShadow(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 128, 128, 4, 1,
4530                                               samplerShadowNoMipmap);
4531     static const TextureSpec tex2DArrayMipmapShadow(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 128, 128, 4, 8,
4532                                                     samplerShadowMipmap);
4533 
4534     static const TextureSpec tex2DArrayTexelFetchFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 8,
4535                                                        samplerTexelFetch);
4536     static const TextureSpec tex2DArrayTexelFetchFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 8,
4537                                                        samplerTexelFetch);
4538     static const TextureSpec tex2DArrayTexelFetchInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 8,
4539                                                      samplerTexelFetch);
4540     static const TextureSpec tex2DArrayTexelFetchUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 8,
4541                                                       samplerTexelFetch);
4542 
4543     static const TextureSpec tex3DFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 1, samplerLinearNoMipmap);
4544     static const TextureSpec tex3DFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 1, samplerLinearNoMipmap);
4545     static const TextureSpec tex3DInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 1, samplerNearestNoMipmap);
4546     static const TextureSpec tex3DUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 1, samplerNearestNoMipmap);
4547     static const TextureSpec tex3DMipmapFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 7, samplerLinearMipmap);
4548     static const TextureSpec tex3DMipmapFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 7, samplerLinearMipmap);
4549     static const TextureSpec tex3DMipmapInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 7, samplerNearestMipmap);
4550     static const TextureSpec tex3DMipmapUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 7, samplerNearestMipmap);
4551 
4552     static const TextureSpec tex3DTexelFetchFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 7, samplerTexelFetch);
4553     static const TextureSpec tex3DTexelFetchFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 7, samplerTexelFetch);
4554     static const TextureSpec tex3DTexelFetchInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 7, samplerTexelFetch);
4555     static const TextureSpec tex3DTexelFetchUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 7, samplerTexelFetch);
4556 
4557     static const TextureSpec tex1DFixed(TEXTURETYPE_1D, GL_RGBA8, 256, 1, 1, 1, samplerLinearNoMipmap);
4558     static const TextureSpec tex1DFloat(TEXTURETYPE_1D, GL_RGBA16F, 256, 1, 1, 1, samplerLinearNoMipmap);
4559     static const TextureSpec tex1DInt(TEXTURETYPE_1D, GL_RGBA8I, 256, 1, 1, 1, samplerNearestNoMipmap);
4560     static const TextureSpec tex1DUint(TEXTURETYPE_1D, GL_RGBA8UI, 256, 1, 1, 1, samplerNearestNoMipmap);
4561     static const TextureSpec tex1DMipmapFixed(TEXTURETYPE_1D, GL_RGBA8, 256, 1, 1, 9, samplerLinearMipmap);
4562     static const TextureSpec tex1DMipmapFloat(TEXTURETYPE_1D, GL_RGBA16F, 256, 1, 1, 9, samplerLinearMipmap);
4563     static const TextureSpec tex1DMipmapInt(TEXTURETYPE_1D, GL_RGBA8I, 256, 1, 1, 9, samplerNearestMipmap);
4564     static const TextureSpec tex1DMipmapUint(TEXTURETYPE_1D, GL_RGBA8UI, 256, 1, 1, 9, samplerNearestMipmap);
4565 
4566     static const TextureSpec tex1DShadow(TEXTURETYPE_1D, GL_DEPTH_COMPONENT16, 256, 1, 1, 1, samplerShadowNoMipmap);
4567     static const TextureSpec tex1DMipmapShadow(TEXTURETYPE_1D, GL_DEPTH_COMPONENT16, 256, 1, 1, 9, samplerShadowMipmap);
4568 
4569     static const TextureSpec tex1DTexelFetchFixed(TEXTURETYPE_1D, GL_RGBA8, 256, 1, 1, 9, samplerTexelFetch);
4570     static const TextureSpec tex1DTexelFetchFloat(TEXTURETYPE_1D, GL_RGBA16F, 256, 1, 1, 9, samplerTexelFetch);
4571     static const TextureSpec tex1DTexelFetchInt(TEXTURETYPE_1D, GL_RGBA8I, 256, 1, 1, 9, samplerTexelFetch);
4572     static const TextureSpec tex1DTexelFetchUint(TEXTURETYPE_1D, GL_RGBA8UI, 256, 1, 1, 9, samplerTexelFetch);
4573 
4574     static const TextureSpec tex1DArrayFixed(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 256, 1, 4, 1, samplerLinearNoMipmap);
4575     static const TextureSpec tex1DArrayFloat(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 256, 1, 4, 1, samplerLinearNoMipmap);
4576     static const TextureSpec tex1DArrayInt(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 256, 1, 4, 1, samplerNearestNoMipmap);
4577     static const TextureSpec tex1DArrayUint(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 256, 1, 4, 1, samplerNearestNoMipmap);
4578     static const TextureSpec tex1DArrayMipmapFixed(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 256, 1, 4, 9, samplerLinearMipmap);
4579     static const TextureSpec tex1DArrayMipmapFloat(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 256, 1, 4, 9, samplerLinearMipmap);
4580     static const TextureSpec tex1DArrayMipmapInt(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 256, 1, 4, 9, samplerNearestMipmap);
4581     static const TextureSpec tex1DArrayMipmapUint(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 256, 1, 4, 9, samplerNearestMipmap);
4582 
4583     static const TextureSpec tex1DArrayShadow(TEXTURETYPE_1D_ARRAY, GL_DEPTH_COMPONENT16, 256, 1, 4, 1,
4584                                               samplerShadowNoMipmap);
4585     static const TextureSpec tex1DArrayMipmapShadow(TEXTURETYPE_1D_ARRAY, GL_DEPTH_COMPONENT16, 256, 1, 4, 9,
4586                                                     samplerShadowMipmap);
4587 
4588     static const TextureSpec tex1DArrayTexelFetchFixed(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 256, 1, 4, 9, samplerTexelFetch);
4589     static const TextureSpec tex1DArrayTexelFetchFloat(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 256, 1, 4, 9,
4590                                                        samplerTexelFetch);
4591     static const TextureSpec tex1DArrayTexelFetchInt(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 256, 1, 4, 9, samplerTexelFetch);
4592     static const TextureSpec tex1DArrayTexelFetchUint(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 256, 1, 4, 9,
4593                                                       samplerTexelFetch);
4594 
4595     static const TextureSpec texCubeArrayFixed(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8, 64, 64, 12, 1, samplerLinearNoMipmap);
4596     static const TextureSpec texCubeArrayFloat(TEXTURETYPE_CUBE_ARRAY, GL_RGBA16F, 64, 64, 12, 1,
4597                                                samplerLinearNoMipmap);
4598     static const TextureSpec texCubeArrayInt(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8I, 64, 64, 12, 1, samplerNearestNoMipmap);
4599     static const TextureSpec texCubeArrayUint(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8UI, 64, 64, 12, 1,
4600                                               samplerNearestNoMipmap);
4601     static const TextureSpec texCubeArrayMipmapFixed(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8, 64, 64, 12, 7,
4602                                                      samplerLinearMipmap);
4603     static const TextureSpec texCubeArrayMipmapFloat(TEXTURETYPE_CUBE_ARRAY, GL_RGBA16F, 64, 64, 12, 7,
4604                                                      samplerLinearMipmap);
4605     static const TextureSpec texCubeArrayMipmapInt(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8I, 64, 64, 12, 7,
4606                                                    samplerNearestMipmap);
4607     static const TextureSpec texCubeArrayMipmapUint(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8UI, 64, 64, 12, 7,
4608                                                     samplerNearestMipmap);
4609 
4610     static const TextureSpec texCubeArrayShadow(TEXTURETYPE_CUBE_ARRAY, GL_DEPTH_COMPONENT16, 64, 64, 12, 1,
4611                                                 samplerShadowNoMipmap);
4612     static const TextureSpec texCubeArrayMipmapShadow(TEXTURETYPE_CUBE_ARRAY, GL_DEPTH_COMPONENT16, 64, 64, 12, 7,
4613                                                       samplerShadowMipmap);
4614 
4615     // Default textures for offset tests. Textures will be smaller than min/max allowed offsets (usually -8 and 7)
4616     //                                                        Type                    Format                        W    H    D    L    Sampler
4617     static const TextureSpec tex2DFixedOffset(TEXTURETYPE_2D, GL_RGBA8, 4, 4, 1, 1, samplerLinearNoMipmap);
4618     static const TextureSpec tex2DFloatOffset(TEXTURETYPE_2D, GL_RGBA16F, 4, 4, 1, 1, samplerLinearNoMipmap);
4619     static const TextureSpec tex2DIntOffset(TEXTURETYPE_2D, GL_RGBA8I, 4, 4, 1, 1, samplerNearestNoMipmap);
4620     static const TextureSpec tex2DUintOffset(TEXTURETYPE_2D, GL_RGBA8UI, 4, 4, 1, 1, samplerNearestNoMipmap);
4621     static const TextureSpec tex2DMipmapFixedOffset(TEXTURETYPE_2D, GL_RGBA8, 4, 4, 1, 3, samplerLinearMipmap);
4622     static const TextureSpec tex2DMipmapFloatOffset(TEXTURETYPE_2D, GL_RGBA16F, 4, 4, 1, 3, samplerLinearMipmap);
4623     static const TextureSpec tex2DMipmapIntOffset(TEXTURETYPE_2D, GL_RGBA8I, 4, 4, 1, 3, samplerNearestMipmap);
4624     static const TextureSpec tex2DMipmapUintOffset(TEXTURETYPE_2D, GL_RGBA8UI, 4, 4, 1, 3, samplerNearestMipmap);
4625 
4626     static const TextureSpec tex2DShadowOffset(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 4, 4, 1, 1, samplerShadowNoMipmap);
4627     static const TextureSpec tex2DMipmapShadowOffset(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 4, 4, 1, 3,
4628                                                      samplerShadowMipmap);
4629 
4630     static const TextureSpec tex2DTexelFetchFixedOffset(TEXTURETYPE_2D, GL_RGBA8, 4, 4, 1, 3, samplerTexelFetch);
4631     static const TextureSpec tex2DTexelFetchFloatOffset(TEXTURETYPE_2D, GL_RGBA16F, 4, 4, 1, 3, samplerTexelFetch);
4632     static const TextureSpec tex2DTexelFetchIntOffset(TEXTURETYPE_2D, GL_RGBA8I, 4, 4, 1, 3, samplerTexelFetch);
4633     static const TextureSpec tex2DTexelFetchUintOffset(TEXTURETYPE_2D, GL_RGBA8UI, 4, 4, 1, 3, samplerTexelFetch);
4634 
4635     static const TextureSpec texCubeFixedOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 4, 4, 1, 1, samplerLinearNoMipmap);
4636     static const TextureSpec texCubeFloatOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 4, 4, 1, 1, samplerLinearNoMipmap);
4637     static const TextureSpec texCubeIntOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 4, 4, 1, 1, samplerNearestNoMipmap);
4638     static const TextureSpec texCubeUintOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 4, 4, 1, 1, samplerNearestNoMipmap);
4639     static const TextureSpec texCubeMipmapFixedOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 4, 4, 1, 3, samplerLinearMipmap);
4640     static const TextureSpec texCubeMipmapFloatOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 4, 4, 1, 3,
4641                                                       samplerLinearMipmap);
4642     static const TextureSpec texCubeMipmapIntOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 4, 4, 1, 3, samplerNearestMipmap);
4643     static const TextureSpec texCubeMipmapUintOffset(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 4, 4, 1, 3,
4644                                                      samplerNearestMipmap);
4645 
4646     static const TextureSpec texCubeShadowOffset(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 4, 4, 1, 1,
4647                                                  samplerShadowNoMipmap);
4648     static const TextureSpec texCubeMipmapShadowOffset(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 4, 4, 1, 3,
4649                                                        samplerShadowMipmap);
4650 
4651     static const TextureSpec tex2DArrayFixedOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 4, 4, 4, 1, samplerLinearNoMipmap);
4652     static const TextureSpec tex2DArrayFloatOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 4, 4, 4, 1, samplerLinearNoMipmap);
4653     static const TextureSpec tex2DArrayIntOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 4, 4, 4, 1, samplerNearestNoMipmap);
4654     static const TextureSpec tex2DArrayUintOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 4, 4, 4, 1, samplerNearestNoMipmap);
4655     static const TextureSpec tex2DArrayMipmapFixedOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 4, 4, 4, 3,
4656                                                          samplerLinearMipmap);
4657     static const TextureSpec tex2DArrayMipmapFloatOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 4, 4, 4, 3,
4658                                                          samplerLinearMipmap);
4659     static const TextureSpec tex2DArrayMipmapIntOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 4, 4, 4, 3,
4660                                                        samplerNearestMipmap);
4661     static const TextureSpec tex2DArrayMipmapUintOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 4, 4, 4, 3,
4662                                                         samplerNearestMipmap);
4663 
4664     static const TextureSpec tex2DArrayShadowOffset(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 4, 4, 4, 1,
4665                                                     samplerShadowNoMipmap);
4666     static const TextureSpec tex2DArrayMipmapShadowOffset(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 4, 4, 4, 3,
4667                                                           samplerShadowMipmap);
4668 
4669     static const TextureSpec tex2DArrayTexelFetchFixedOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 4, 4, 4, 3,
4670                                                              samplerTexelFetch);
4671     static const TextureSpec tex2DArrayTexelFetchFloatOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 4, 4, 4, 3,
4672                                                              samplerTexelFetch);
4673     static const TextureSpec tex2DArrayTexelFetchIntOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 4, 4, 4, 3,
4674                                                            samplerTexelFetch);
4675     static const TextureSpec tex2DArrayTexelFetchUintOffset(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 4, 4, 4, 3,
4676                                                             samplerTexelFetch);
4677 
4678     static const TextureSpec tex3DFixedOffset(TEXTURETYPE_3D, GL_RGBA8, 4, 4, 4, 1, samplerLinearNoMipmap);
4679     static const TextureSpec tex3DFloatOffset(TEXTURETYPE_3D, GL_RGBA16F, 4, 4, 4, 1, samplerLinearNoMipmap);
4680     static const TextureSpec tex3DIntOffset(TEXTURETYPE_3D, GL_RGBA8I, 4, 4, 4, 1, samplerNearestNoMipmap);
4681     static const TextureSpec tex3DUintOffset(TEXTURETYPE_3D, GL_RGBA8UI, 4, 4, 4, 1, samplerNearestNoMipmap);
4682     static const TextureSpec tex3DMipmapFixedOffset(TEXTURETYPE_3D, GL_RGBA8, 4, 4, 4, 3, samplerLinearMipmap);
4683     static const TextureSpec tex3DMipmapFloatOffset(TEXTURETYPE_3D, GL_RGBA16F, 4, 4, 4, 3, samplerLinearMipmap);
4684     static const TextureSpec tex3DMipmapIntOffset(TEXTURETYPE_3D, GL_RGBA8I, 4, 4, 4, 3, samplerNearestMipmap);
4685     static const TextureSpec tex3DMipmapUintOffset(TEXTURETYPE_3D, GL_RGBA8UI, 4, 4, 4, 3, samplerNearestMipmap);
4686 
4687     static const TextureSpec tex3DTexelFetchFixedOffset(TEXTURETYPE_3D, GL_RGBA8, 4, 4, 4, 3, samplerTexelFetch);
4688     static const TextureSpec tex3DTexelFetchFloatOffset(TEXTURETYPE_3D, GL_RGBA16F, 4, 4, 4, 3, samplerTexelFetch);
4689     static const TextureSpec tex3DTexelFetchIntOffset(TEXTURETYPE_3D, GL_RGBA8I, 4, 4, 4, 3, samplerTexelFetch);
4690     static const TextureSpec tex3DTexelFetchUintOffset(TEXTURETYPE_3D, GL_RGBA8UI, 4, 4, 4, 3, samplerTexelFetch);
4691 
4692     static const TextureSpec tex1DFixedOffset(TEXTURETYPE_1D, GL_RGBA8, 4, 1, 1, 1, samplerLinearNoMipmap);
4693     static const TextureSpec tex1DFloatOffset(TEXTURETYPE_1D, GL_RGBA16F, 4, 1, 1, 1, samplerLinearNoMipmap);
4694     static const TextureSpec tex1DIntOffset(TEXTURETYPE_1D, GL_RGBA8I, 4, 1, 1, 1, samplerNearestNoMipmap);
4695     static const TextureSpec tex1DUintOffset(TEXTURETYPE_1D, GL_RGBA8UI, 4, 1, 1, 1, samplerNearestNoMipmap);
4696     static const TextureSpec tex1DMipmapFixedOffset(TEXTURETYPE_1D, GL_RGBA8, 4, 1, 1, 3, samplerLinearMipmap);
4697     static const TextureSpec tex1DMipmapFloatOffset(TEXTURETYPE_1D, GL_RGBA16F, 4, 1, 1, 3, samplerLinearMipmap);
4698     static const TextureSpec tex1DMipmapIntOffset(TEXTURETYPE_1D, GL_RGBA8I, 4, 1, 1, 3, samplerNearestMipmap);
4699     static const TextureSpec tex1DMipmapUintOffset(TEXTURETYPE_1D, GL_RGBA8UI, 4, 1, 1, 3, samplerNearestMipmap);
4700 
4701     static const TextureSpec tex1DShadowOffset(TEXTURETYPE_1D, GL_DEPTH_COMPONENT16, 4, 1, 1, 1, samplerShadowNoMipmap);
4702     static const TextureSpec tex1DMipmapShadowOffset(TEXTURETYPE_1D, GL_DEPTH_COMPONENT16, 4, 1, 1, 3,
4703                                                      samplerShadowMipmap);
4704 
4705     static const TextureSpec tex1DTexelFetchFixedOffset(TEXTURETYPE_1D, GL_RGBA8, 4, 1, 1, 3, samplerTexelFetch);
4706     static const TextureSpec tex1DTexelFetchFloatOffset(TEXTURETYPE_1D, GL_RGBA16F, 4, 1, 1, 3, samplerTexelFetch);
4707     static const TextureSpec tex1DTexelFetchIntOffset(TEXTURETYPE_1D, GL_RGBA8I, 4, 1, 1, 3, samplerTexelFetch);
4708     static const TextureSpec tex1DTexelFetchUintOffset(TEXTURETYPE_1D, GL_RGBA8UI, 4, 1, 1, 3, samplerTexelFetch);
4709 
4710     static const TextureSpec tex1DArrayFixedOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 4, 1, 4, 1, samplerLinearNoMipmap);
4711     static const TextureSpec tex1DArrayFloatOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 4, 1, 4, 1, samplerLinearNoMipmap);
4712     static const TextureSpec tex1DArrayIntOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 4, 1, 4, 1, samplerNearestNoMipmap);
4713     static const TextureSpec tex1DArrayUintOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 4, 1, 4, 1, samplerNearestNoMipmap);
4714     static const TextureSpec tex1DArrayMipmapFixedOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 4, 1, 4, 3,
4715                                                          samplerLinearMipmap);
4716     static const TextureSpec tex1DArrayMipmapFloatOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 4, 1, 4, 3,
4717                                                          samplerLinearMipmap);
4718     static const TextureSpec tex1DArrayMipmapIntOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 4, 1, 4, 3,
4719                                                        samplerNearestMipmap);
4720     static const TextureSpec tex1DArrayMipmapUintOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 4, 1, 4, 3,
4721                                                         samplerNearestMipmap);
4722 
4723     static const TextureSpec tex1DArrayShadowOffset(TEXTURETYPE_1D_ARRAY, GL_DEPTH_COMPONENT16, 4, 1, 4, 1,
4724                                                     samplerShadowNoMipmap);
4725     static const TextureSpec tex1DArrayMipmapShadowOffset(TEXTURETYPE_1D_ARRAY, GL_DEPTH_COMPONENT16, 4, 1, 4, 3,
4726                                                           samplerShadowMipmap);
4727 
4728     static const TextureSpec tex1DArrayTexelFetchFixedOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8, 4, 1, 4, 3,
4729                                                              samplerTexelFetch);
4730     static const TextureSpec tex1DArrayTexelFetchFloatOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA16F, 4, 1, 4, 3,
4731                                                              samplerTexelFetch);
4732     static const TextureSpec tex1DArrayTexelFetchIntOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8I, 4, 1, 4, 3,
4733                                                            samplerTexelFetch);
4734     static const TextureSpec tex1DArrayTexelFetchUintOffset(TEXTURETYPE_1D_ARRAY, GL_RGBA8UI, 4, 1, 4, 3,
4735                                                             samplerTexelFetch);
4736 
4737     static const TextureSpec texCubeArrayFixedOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8, 4, 4, 4, 1,
4738                                                      samplerLinearNoMipmap);
4739     static const TextureSpec texCubeArrayFloatOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA16F, 4, 4, 4, 1,
4740                                                      samplerLinearNoMipmap);
4741     static const TextureSpec texCubeArrayIntOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8I, 4, 4, 4, 1,
4742                                                    samplerNearestNoMipmap);
4743     static const TextureSpec texCubeArrayUintOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8UI, 4, 4, 4, 1,
4744                                                     samplerNearestNoMipmap);
4745     static const TextureSpec texCubeArrayMipmapFixedOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8, 4, 4, 4, 3,
4746                                                            samplerLinearMipmap);
4747     static const TextureSpec texCubeArrayMipmapFloatOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA16F, 4, 4, 4, 3,
4748                                                            samplerLinearMipmap);
4749     static const TextureSpec texCubeArrayMipmapIntOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8I, 4, 4, 4, 3,
4750                                                          samplerNearestMipmap);
4751     static const TextureSpec texCubeArrayMipmapUintOffset(TEXTURETYPE_CUBE_ARRAY, GL_RGBA8UI, 4, 4, 4, 3,
4752                                                           samplerNearestMipmap);
4753 
4754     static const TextureSpec texCubeArrayShadowOffset(TEXTURETYPE_CUBE_ARRAY, GL_DEPTH_COMPONENT16, 4, 4, 4, 1,
4755                                                       samplerShadowNoMipmap);
4756     static const TextureSpec texCubeArrayMipmapShadowOffset(TEXTURETYPE_CUBE_ARRAY, GL_DEPTH_COMPONENT16, 4, 4, 4, 3,
4757                                                             samplerShadowMipmap);
4758 
4759     // texture() cases
4760     static const TexFuncCaseSpec textureCases[] = {
4761         //          Name                            Function            MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
4762         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
4763                   false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2D, VERTEX),
4764         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
4765                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2D, FRAGMENT),
4766         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
4767                   false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2D, VERTEX),
4768         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
4769                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2D, FRAGMENT),
4770         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
4771                   0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2D, VERTEX),
4772         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
4773                   0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2D, FRAGMENT),
4774         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
4775                   0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2D, VERTEX),
4776         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
4777                   0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2D, FRAGMENT),
4778 
4779         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),
4780                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2DBias, FRAGMENT),
4781         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),
4782                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2DBias, FRAGMENT),
4783         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,
4784                   -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DBias, FRAGMENT),
4785         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,
4786                   -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DBias, FRAGMENT),
4787 
4788         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
4789                   false, 0.0f, 0.0f, false, IVec3(0), texCubeFixed, evalTextureCube, VERTEX),
4790         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
4791                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapFixed, evalTextureCube, FRAGMENT),
4792         CASE_SPEC(samplercube_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
4793                   false, 0.0f, 0.0f, false, IVec3(0), texCubeFloat, evalTextureCube, VERTEX),
4794         CASE_SPEC(samplercube_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
4795                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapFloat, evalTextureCube, FRAGMENT),
4796         CASE_SPEC(isamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f), false,
4797                   0.0f, 0.0f, false, IVec3(0), texCubeInt, evalTextureCube, VERTEX),
4798         CASE_SPEC(isamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f), false,
4799                   0.0f, 0.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCube, FRAGMENT),
4800         CASE_SPEC(usamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
4801                   false, 0.0f, 0.0f, false, IVec3(0), texCubeUint, evalTextureCube, VERTEX),
4802         CASE_SPEC(usamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
4803                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCube, FRAGMENT),
4804 
4805         CASE_SPEC(samplercube_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
4806                   Vec4(1.0f, 1.0f, 1.01f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapFixed,
4807                   evalTextureCubeBias, FRAGMENT),
4808         CASE_SPEC(samplercube_bias_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
4809                   Vec4(1.0f, 1.0f, -1.01f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapFloat,
4810                   evalTextureCubeBias, FRAGMENT),
4811         CASE_SPEC(isamplercube_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
4812                   true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCubeBias, FRAGMENT),
4813         CASE_SPEC(usamplercube_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
4814                   true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCubeBias, FRAGMENT),
4815 
4816         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4817                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayFixed, evalTexture2DArray, VERTEX),
4818         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4819                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapFixed, evalTexture2DArray, FRAGMENT),
4820         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4821                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayFloat, evalTexture2DArray, VERTEX),
4822         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4823                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapFloat, evalTexture2DArray, FRAGMENT),
4824         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4825                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayInt, evalTexture2DArray, VERTEX),
4826         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4827                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArray, FRAGMENT),
4828         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4829                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayUint, evalTexture2DArray, VERTEX),
4830         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4831                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArray, FRAGMENT),
4832 
4833         CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
4834                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapFixed,
4835                   evalTexture2DArrayBias, FRAGMENT),
4836         CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
4837                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapFloat,
4838                   evalTexture2DArrayBias, FRAGMENT),
4839         CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4840                   true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArrayBias, FRAGMENT),
4841         CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
4842                   true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArrayBias, FRAGMENT),
4843 
4844         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
4845                   false, 0.0f, 0.0f, false, IVec3(0), tex3DFixed, evalTexture3D, VERTEX),
4846         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
4847                   false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3D, FRAGMENT),
4848         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
4849                   false, 0.0f, 0.0f, false, IVec3(0), tex3DFloat, evalTexture3D, VERTEX),
4850         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
4851                   false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3D, FRAGMENT),
4852         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
4853                   0.0f, 0.0f, false, IVec3(0), tex3DInt, evalTexture3D, VERTEX),
4854         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
4855                   0.0f, 0.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3D, FRAGMENT),
4856         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
4857                   0.0f, 0.0f, false, IVec3(0), tex3DUint, evalTexture3D, VERTEX),
4858         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
4859                   0.0f, 0.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3D, FRAGMENT),
4860 
4861         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),
4862                   true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3DBias, FRAGMENT),
4863         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),
4864                   true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3DBias, FRAGMENT),
4865         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,
4866                   -2.0f, 2.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3DBias, FRAGMENT),
4867         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,
4868                   -2.0f, 2.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3DBias, FRAGMENT),
4869 
4870         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,
4871                   0.0f, 0.0f, false, IVec3(0), tex1DFixed, evalTexture1D, VERTEX),
4872         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,
4873                   0.0f, 0.0f, false, IVec3(0), tex1DMipmapFixed, evalTexture1D, FRAGMENT),
4874         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,
4875                   0.0f, 0.0f, false, IVec3(0), tex1DFloat, evalTexture1D, VERTEX),
4876         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,
4877                   0.0f, 0.0f, false, IVec3(0), tex1DMipmapFloat, evalTexture1D, FRAGMENT),
4878         CASE_SPEC(isampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
4879                   0.0f, 0.0f, false, IVec3(0), tex1DInt, evalTexture1D, VERTEX),
4880         CASE_SPEC(isampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
4881                   0.0f, 0.0f, false, IVec3(0), tex1DMipmapInt, evalTexture1D, FRAGMENT),
4882         CASE_SPEC(usampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
4883                   0.0f, 0.0f, false, IVec3(0), tex1DUint, evalTexture1D, VERTEX),
4884         CASE_SPEC(usampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
4885                   0.0f, 0.0f, false, IVec3(0), tex1DMipmapUint, evalTexture1D, FRAGMENT),
4886 
4887         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),
4888                   true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFixed, evalTexture1DBias, FRAGMENT),
4889         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),
4890                   true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFloat, evalTexture1DBias, FRAGMENT),
4891         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,
4892                   -2.0f, 2.0f, false, IVec3(0), tex1DMipmapInt, evalTexture1DBias, FRAGMENT),
4893         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,
4894                   -2.0f, 2.0f, false, IVec3(0), tex1DMipmapUint, evalTexture1DBias, FRAGMENT),
4895 
4896         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4897                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayFixed, evalTexture1DArray, VERTEX),
4898         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4899                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayMipmapFixed, evalTexture1DArray, FRAGMENT),
4900         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4901                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayFloat, evalTexture1DArray, VERTEX),
4902         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4903                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayMipmapFloat, evalTexture1DArray, FRAGMENT),
4904         CASE_SPEC(isampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4905                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayInt, evalTexture1DArray, VERTEX),
4906         CASE_SPEC(isampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4907                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayMipmapInt, evalTexture1DArray, FRAGMENT),
4908         CASE_SPEC(usampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4909                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayUint, evalTexture1DArray, VERTEX),
4910         CASE_SPEC(usampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4911                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayMipmapUint, evalTexture1DArray, FRAGMENT),
4912 
4913         CASE_SPEC(sampler1darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
4914                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DArrayMipmapFixed,
4915                   evalTexture1DArrayBias, FRAGMENT),
4916         CASE_SPEC(sampler1darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
4917                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DArrayMipmapFloat,
4918                   evalTexture1DArrayBias, FRAGMENT),
4919         CASE_SPEC(isampler1darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4920                   true, -2.0f, 2.0f, false, IVec3(0), tex1DArrayMipmapInt, evalTexture1DArrayBias, FRAGMENT),
4921         CASE_SPEC(usampler1darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
4922                   true, -2.0f, 2.0f, false, IVec3(0), tex1DArrayMipmapUint, evalTexture1DArrayBias, FRAGMENT),
4923 
4924         CASE_SPEC(samplercubearray_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
4925                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayFixed,
4926                   evalTextureCubeArray, VERTEX),
4927         CASE_SPEC(samplercubearray_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
4928                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayMipmapFixed,
4929                   evalTextureCubeArray, FRAGMENT),
4930         CASE_SPEC(samplercubearray_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4931                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayFloat,
4932                   evalTextureCubeArray, VERTEX),
4933         CASE_SPEC(samplercubearray_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4934                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayMipmapFloat,
4935                   evalTextureCubeArray, FRAGMENT),
4936         CASE_SPEC(isamplercubearray, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f), Vec4(1.0f, 1.0f, 1.01f, 1.5f),
4937                   false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayInt, evalTextureCubeArray, VERTEX),
4938         CASE_SPEC(isamplercubearray, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f), Vec4(1.0f, 1.0f, 1.01f, 1.5f),
4939                   false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayMipmapInt, evalTextureCubeArray, FRAGMENT),
4940         CASE_SPEC(usamplercubearray, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4941                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayUint,
4942                   evalTextureCubeArray, VERTEX),
4943         CASE_SPEC(usamplercubearray, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4944                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayMipmapUint,
4945                   evalTextureCubeArray, FRAGMENT),
4946 
4947         CASE_SPEC(samplercubearray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
4948                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), texCubeArrayMipmapFixed,
4949                   evalTextureCubeArrayBias, FRAGMENT),
4950         CASE_SPEC(samplercubearray_bias_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4951                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), texCubeArrayMipmapFloat,
4952                   evalTextureCubeArrayBias, FRAGMENT),
4953         CASE_SPEC(isamplercubearray_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
4954                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), texCubeArrayMipmapInt,
4955                   evalTextureCubeArrayBias, FRAGMENT),
4956         CASE_SPEC(usamplercubearray_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
4957                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), texCubeArrayMipmapUint,
4958                   evalTextureCubeArrayBias, FRAGMENT),
4959 
4960         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
4961                   false, 0.0f, 0.0f, false, IVec3(0), tex2DShadow, evalTexture2DShadow, VERTEX),
4962         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
4963                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadow, FRAGMENT),
4964         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
4965                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowBias, FRAGMENT),
4966 
4967         CASE_SPEC(samplercubeshadow, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 1.0f),
4968                   false, 0.0f, 0.0f, false, IVec3(0), texCubeShadow, evalTextureCubeShadow, VERTEX),
4969         CASE_SPEC(samplercubeshadow, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 1.0f),
4970                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapShadow, evalTextureCubeShadow, FRAGMENT),
4971         CASE_SPEC(samplercubeshadow_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
4972                   Vec4(1.0f, 1.0f, 1.01f, 1.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapShadow,
4973                   evalTextureCubeShadowBias, FRAGMENT),
4974 
4975         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
4976                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayShadow, evalTexture2DArrayShadow, VERTEX),
4977         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
4978                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapShadow, evalTexture2DArrayShadow, FRAGMENT),
4979 
4980         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f), false,
4981                   0.0f, 0.0f, false, IVec3(0), tex1DShadow, evalTexture1DShadow, VERTEX),
4982         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f), false,
4983                   0.0f, 0.0f, false, IVec3(0), tex1DMipmapShadow, evalTexture1DShadow, FRAGMENT),
4984         CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f),
4985                   true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapShadow, evalTexture1DShadowBias, FRAGMENT),
4986 
4987         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 1.0f, 0.0f),
4988                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayShadow, evalTexture1DArrayShadow, VERTEX),
4989         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 1.0f, 0.0f),
4990                   false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayMipmapShadow, evalTexture1DArrayShadow, FRAGMENT),
4991         CASE_SPEC(sampler1darrayshadow_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
4992                   Vec4(1.5f, 3.5f, 1.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DArrayMipmapShadow,
4993                   evalTexture1DArrayShadowBias, FRAGMENT),
4994 
4995         CASE_SPEC(samplercubearrayshadow, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
4996                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), texCubeArrayMipmapShadow,
4997                   evalTextureCubeArrayShadow, FRAGMENT),
4998     };
4999     createCaseGroup(this, "texture", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
5000 
5001     // textureClampARB() cases
5002     static const TexFuncCaseSpec textureClampARBCases[] = {
5003         //                Name                            Function            MinCoord                        MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        LodClamp    Format                    EvalFunc                            Flags
5004         CLAMP_CASE_SPEC(sampler2d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5005                         Vec4(1.0f, 1.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex2DMipmapFixed,
5006                         evalTexture2DBiasClamp, FRAGMENT),
5007         CLAMP_CASE_SPEC(sampler2d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5008                         Vec4(1.0f, 1.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex2DMipmapFloat,
5009                         evalTexture2DBiasClamp, FRAGMENT),
5010         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),
5011                         true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex2DMipmapInt, evalTexture2DBiasClamp, FRAGMENT),
5012         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),
5013                         true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex2DMipmapUint, evalTexture2DBiasClamp, FRAGMENT),
5014 
5015         CLAMP_CASE_SPEC(samplercube_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 1.01f, 0.0f),
5016                         Vec4(1.0f, 1.0f, 1.01f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 4.0f, texCubeMipmapFixed,
5017                         evalTextureCubeBiasClamp, FRAGMENT),
5018         CLAMP_CASE_SPEC(samplercube_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 1.01f, 0.0f),
5019                         Vec4(1.0f, 1.0f, 1.01f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 4.0f, texCubeMipmapFloat,
5020                         evalTextureCubeBiasClamp, FRAGMENT),
5021         CLAMP_CASE_SPEC(isamplercube_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 6.01f, 0.0f),
5022                         Vec4(6.0f, 6.0f, 6.01f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 6.0f, texCubeMipmapInt,
5023                         evalTextureCubeBiasClamp, FRAGMENT),
5024         CLAMP_CASE_SPEC(usamplercube_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 6.01f, 0.0f),
5025                         Vec4(6.0f, 6.0f, 6.01f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 6.0f, texCubeMipmapUint,
5026                         evalTextureCubeBiasClamp, FRAGMENT),
5027 
5028         CLAMP_CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5029                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex2DArrayMipmapFixed,
5030                         evalTexture2DArrayBiasClamp, FRAGMENT),
5031         CLAMP_CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5032                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex2DArrayMipmapFloat,
5033                         evalTexture2DArrayBiasClamp, FRAGMENT),
5034         CLAMP_CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5035                         Vec4(6.0f, 6.0f, 4.0f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex2DArrayMipmapInt,
5036                         evalTexture2DArrayBiasClamp, FRAGMENT),
5037         CLAMP_CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5038                         Vec4(6.0f, 6.0f, 4.0f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex2DArrayMipmapUint,
5039                         evalTexture2DArrayBiasClamp, FRAGMENT),
5040 
5041         CLAMP_CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5042                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, -10.0f, 10.0f, false, IVec3(0), 0.0f, tex3DMipmapFixed,
5043                         evalTexture3DBiasClamp, FRAGMENT),
5044         CLAMP_CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5045                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, -10.0f, 10.0f, false, IVec3(0), 0.0f, tex3DMipmapFloat,
5046                         evalTexture3DBiasClamp, FRAGMENT),
5047         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),
5048                         true, 0.0f, 8.0f, false, IVec3(0), 5.0f, tex3DMipmapInt, evalTexture3DBiasClamp, FRAGMENT),
5049         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),
5050                         true, 0.0f, 8.0f, false, IVec3(0), 5.0f, tex3DMipmapUint, evalTexture3DBiasClamp, FRAGMENT),
5051 
5052         CLAMP_CASE_SPEC(sampler1d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5053                         Vec4(1.0f, 0.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 4.0f, tex1DMipmapFixed,
5054                         evalTexture1DBiasClamp, FRAGMENT),
5055         CLAMP_CASE_SPEC(sampler1d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5056                         Vec4(1.0f, 0.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 4.0f, tex1DMipmapFloat,
5057                         evalTexture1DBiasClamp, FRAGMENT),
5058         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),
5059                         true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex1DMipmapInt, evalTexture1DBiasClamp, FRAGMENT),
5060         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),
5061                         true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex1DMipmapUint, evalTexture1DBiasClamp, FRAGMENT),
5062 
5063         CLAMP_CASE_SPEC(sampler1darray_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5064                         Vec4(1.0f, 4.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex1DArrayMipmapFixed,
5065                         evalTexture1DArrayBiasClamp, FRAGMENT),
5066         CLAMP_CASE_SPEC(sampler1darray_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5067                         Vec4(1.0f, 4.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 5.0f, tex1DArrayMipmapFloat,
5068                         evalTexture1DArrayBiasClamp, FRAGMENT),
5069         CLAMP_CASE_SPEC(isampler1darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5070                         Vec4(6.0f, 4.0f, 0.0f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex1DArrayMipmapInt,
5071                         evalTexture1DArrayBiasClamp, FRAGMENT),
5072         CLAMP_CASE_SPEC(usampler1darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5073                         Vec4(6.0f, 4.0f, 0.0f, 0.0f), true, 2.0f, 5.0f, false, IVec3(0), 7.0f, tex1DArrayMipmapUint,
5074                         evalTexture1DArrayBiasClamp, FRAGMENT),
5075 
5076         CLAMP_CASE_SPEC(samplercubearray_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 1.01f, 0.0f),
5077                         Vec4(1.0f, 1.0f, 1.01f, 2.0f), true, 0.0f, 5.0f, false, IVec3(0), 3.0f, texCubeArrayMipmapFixed,
5078                         evalTextureCubeArrayBiasClamp, FRAGMENT),
5079         CLAMP_CASE_SPEC(samplercubearray_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 1.01f, 0.0f),
5080                         Vec4(1.0f, 1.0f, 1.01f, 2.0f), true, 0.0f, 5.0f, false, IVec3(0), 3.0f, texCubeArrayMipmapFloat,
5081                         evalTextureCubeArrayBiasClamp, FRAGMENT),
5082         CLAMP_CASE_SPEC(isamplercubearray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 6.01f, 0.0f),
5083                         Vec4(6.0f, 6.0f, 6.01f, 2.0f), true, 2.0f, 5.0f, false, IVec3(0), 4.0f, texCubeArrayMipmapInt,
5084                         evalTextureCubeArrayBiasClamp, FRAGMENT),
5085         CLAMP_CASE_SPEC(usamplercubearray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 6.01f, 0.0f),
5086                         Vec4(6.0f, 6.0f, 6.01f, 2.0f), true, 2.0f, 5.0f, false, IVec3(0), 4.0f, texCubeArrayMipmapUint,
5087                         evalTextureCubeArrayBiasClamp, FRAGMENT),
5088 
5089         CLAMP_CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5090                         Vec4(1.0f, 1.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 7.0f, tex2DMipmapShadow,
5091                         evalTexture2DShadowBiasClamp, FRAGMENT),
5092         CLAMP_CASE_SPEC(samplercubeshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 1.01f, 0.0f),
5093                         Vec4(1.0f, 1.0f, 1.01f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 7.0f, texCubeMipmapShadow,
5094                         evalTextureCubeShadowBiasClamp, FRAGMENT),
5095         CLAMP_CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5096                         Vec4(1.0f, 0.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 7.0f, tex1DMipmapShadow,
5097                         evalTexture1DShadowBiasClamp, FRAGMENT),
5098         CLAMP_CASE_SPEC(sampler1darrayshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5099                         Vec4(1.0f, 4.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, false, IVec3(0), 7.0f, tex1DArrayMipmapShadow,
5100                         evalTexture1DArrayShadowBiasClamp, FRAGMENT),
5101     };
5102     createCaseGroup(this, "textureclamp", textureClampARBCases, DE_LENGTH_OF_ARRAY(textureClampARBCases));
5103 
5104     // textureOffset() cases
5105     // \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
5106     static TexFuncCaseSpec textureOffsetCases[] = {
5107         //          Name                            Function            MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                            EvalFunc                        Flags
5108         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5109                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset, evalTexture2DOffset, VERTEX),
5110         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5111                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixedOffset, evalTexture2DOffset, FRAGMENT),
5112         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5113                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloatOffset, evalTexture2DOffset, VERTEX),
5114         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5115                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset, evalTexture2DOffset, FRAGMENT),
5116         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5117                   0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DIntOffset, evalTexture2DOffset, VERTEX),
5118         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5119                   0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapIntOffset, evalTexture2DOffset, FRAGMENT),
5120         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5121                   0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUintOffset, evalTexture2DOffset, VERTEX),
5122         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5123                   0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset, evalTexture2DOffset, FRAGMENT),
5124 
5125         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),
5126                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset, evalTexture2DOffsetBias, FRAGMENT),
5127         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),
5128                   true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloatOffset, evalTexture2DOffsetBias, FRAGMENT),
5129         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,
5130                   -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DIntOffset, evalTexture2DOffsetBias, FRAGMENT),
5131         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,
5132                   -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUintOffset, evalTexture2DOffsetBias, FRAGMENT),
5133 
5134         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5135                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayFixedOffset, evalTexture2DArrayOffset, VERTEX),
5136         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5137                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFixedOffset, evalTexture2DArrayOffset,
5138                   FRAGMENT),
5139         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5140                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayFloatOffset, evalTexture2DArrayOffset, VERTEX),
5141         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5142                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFloatOffset, evalTexture2DArrayOffset,
5143                   FRAGMENT),
5144         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5145                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayIntOffset, evalTexture2DArrayOffset, VERTEX),
5146         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5147                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapIntOffset, evalTexture2DArrayOffset,
5148                   FRAGMENT),
5149         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5150                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayUintOffset, evalTexture2DArrayOffset, VERTEX),
5151         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5152                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapUintOffset, evalTexture2DArrayOffset,
5153                   FRAGMENT),
5154 
5155         CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5156                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DArrayFixedOffset,
5157                   evalTexture2DArrayOffsetBias, FRAGMENT),
5158         CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5159                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DArrayFloatOffset,
5160                   evalTexture2DArrayOffsetBias, FRAGMENT),
5161         CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5162                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DArrayIntOffset, evalTexture2DArrayOffsetBias,
5163                   FRAGMENT),
5164         CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5165                   true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DArrayUintOffset, evalTexture2DArrayOffsetBias,
5166                   FRAGMENT),
5167 
5168         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5169                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DFixedOffset, evalTexture3DOffset, VERTEX),
5170         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5171                   false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapFixedOffset, evalTexture3DOffset, FRAGMENT),
5172         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5173                   false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DFloatOffset, evalTexture3DOffset, VERTEX),
5174         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5175                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DMipmapFloatOffset, evalTexture3DOffset, FRAGMENT),
5176         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5177                   0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DIntOffset, evalTexture3DOffset, VERTEX),
5178         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5179                   0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DMipmapIntOffset, evalTexture3DOffset, FRAGMENT),
5180         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5181                   0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DUintOffset, evalTexture3DOffset, VERTEX),
5182         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5183                   0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapUintOffset, evalTexture3DOffset, FRAGMENT),
5184 
5185         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),
5186                   true, -2.0f, 1.0f, true, IVec3(-8, 7, 3), tex3DFixedOffset, evalTexture3DOffsetBias, FRAGMENT),
5187         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),
5188                   true, -2.0f, 1.0f, true, IVec3(7, 3, -8), tex3DFloatOffset, evalTexture3DOffsetBias, FRAGMENT),
5189         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,
5190                   -2.0f, 2.0f, true, IVec3(3, -8, 7), tex3DIntOffset, evalTexture3DOffsetBias, FRAGMENT),
5191         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,
5192                   -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DUintOffset, evalTexture3DOffsetBias, FRAGMENT),
5193 
5194         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,
5195                   0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset, evalTexture1DOffset, VERTEX),
5196         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,
5197                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFixedOffset, evalTexture1DOffset, FRAGMENT),
5198         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,
5199                   0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFloatOffset, evalTexture1DOffset, VERTEX),
5200         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,
5201                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset, evalTexture1DOffset, FRAGMENT),
5202         CASE_SPEC(isampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5203                   0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DIntOffset, evalTexture1DOffset, VERTEX),
5204         CASE_SPEC(isampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5205                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapIntOffset, evalTexture1DOffset, FRAGMENT),
5206         CASE_SPEC(usampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5207                   0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DUintOffset, evalTexture1DOffset, VERTEX),
5208         CASE_SPEC(usampler1d, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5209                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset, evalTexture1DOffset, FRAGMENT),
5210 
5211         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),
5212                   true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset, evalTexture1DOffsetBias, FRAGMENT),
5213         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),
5214                   true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DFloatOffset, evalTexture1DOffsetBias, FRAGMENT),
5215         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,
5216                   -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DIntOffset, evalTexture1DOffsetBias, FRAGMENT),
5217         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,
5218                   -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DUintOffset, evalTexture1DOffsetBias, FRAGMENT),
5219 
5220         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5221                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DArrayFixedOffset, evalTexture1DArrayOffset, VERTEX),
5222         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5223                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapFixedOffset, evalTexture1DArrayOffset,
5224                   FRAGMENT),
5225         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5226                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DArrayFloatOffset, evalTexture1DArrayOffset, VERTEX),
5227         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5228                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapFloatOffset, evalTexture1DArrayOffset,
5229                   FRAGMENT),
5230         CASE_SPEC(isampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5231                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DArrayIntOffset, evalTexture1DArrayOffset, VERTEX),
5232         CASE_SPEC(isampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5233                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapIntOffset, evalTexture1DArrayOffset,
5234                   FRAGMENT),
5235         CASE_SPEC(usampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5236                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DArrayUintOffset, evalTexture1DArrayOffset, VERTEX),
5237         CASE_SPEC(usampler1darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5238                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapUintOffset, evalTexture1DArrayOffset,
5239                   FRAGMENT),
5240 
5241         CASE_SPEC(sampler1darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5242                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DArrayFixedOffset,
5243                   evalTexture1DArrayOffsetBias, FRAGMENT),
5244         CASE_SPEC(sampler1darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5245                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DArrayFloatOffset,
5246                   evalTexture1DArrayOffsetBias, FRAGMENT),
5247         CASE_SPEC(isampler1darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5248                   true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DArrayIntOffset, evalTexture1DArrayOffsetBias,
5249                   FRAGMENT),
5250         CASE_SPEC(usampler1darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5251                   true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DArrayUintOffset, evalTexture1DArrayOffsetBias,
5252                   FRAGMENT),
5253 
5254         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
5255                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DShadowOffset, evalTexture2DShadowOffset, VERTEX),
5256         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
5257                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapShadowOffset, evalTexture2DShadowOffset,
5258                   FRAGMENT),
5259         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
5260                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DShadowOffset, evalTexture2DShadowOffsetBias, FRAGMENT),
5261         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
5262                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayShadowOffset, evalTexture2DArrayShadowOffset,
5263                   VERTEX),
5264         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
5265                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapShadowOffset,
5266                   evalTexture2DArrayShadowOffset, FRAGMENT),
5267         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f), false,
5268                   0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DShadowOffset, evalTexture1DShadowOffset, VERTEX),
5269         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f), false,
5270                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapShadowOffset, evalTexture1DShadowOffset, FRAGMENT),
5271         CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f),
5272                   true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DShadowOffset, evalTexture1DShadowOffsetBias, FRAGMENT),
5273         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 1.0f, 0.0f),
5274                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DArrayShadowOffset, evalTexture1DArrayShadowOffset,
5275                   VERTEX),
5276         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 1.0f, 0.0f),
5277                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapShadowOffset, evalTexture1DArrayShadowOffset,
5278                   FRAGMENT),
5279         CASE_SPEC(sampler1darrayshadow_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5280                   Vec4(1.5f, 3.5f, 1.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DArrayShadowOffset,
5281                   evalTexture1DArrayShadowOffsetBias, FRAGMENT),
5282     };
5283 
5284     {
5285         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "textureoffset");
5286         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
5287         {
5288             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureOffsetCases); ++j)
5289             {
5290                 textureOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
5291                 textureOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
5292                 textureOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
5293             }
5294             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureOffsetCases,
5295                             DE_LENGTH_OF_ARRAY(textureOffsetCases));
5296         }
5297         addChild(offsetGroup);
5298     }
5299 
5300     // textureOffsetClampARB() cases
5301     static TexFuncCaseSpec textureOffsetClampARBCases[] = {
5302         //                Name                            Function            MinCoord                        MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                LodClamp    Format                            EvalFunc                                    Flags
5303         CLAMP_CASE_SPEC(sampler2d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5304                         Vec4(1.0f, 1.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, -8, 0), 5.0f,
5305                         tex2DMipmapFixedOffset, evalTexture2DOffsetBiasClamp, FRAGMENT),
5306         CLAMP_CASE_SPEC(sampler2d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5307                         Vec4(1.0f, 1.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, -8, 0), 5.0f,
5308                         tex2DMipmapFloatOffset, evalTexture2DOffsetBiasClamp, FRAGMENT),
5309         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),
5310                         true, 2.0f, 5.0f, true, IVec3(7, -8, 0), 7.0f, tex2DMipmapIntOffset,
5311                         evalTexture2DOffsetBiasClamp, FRAGMENT),
5312         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),
5313                         true, 2.0f, 5.0f, true, IVec3(7, -8, 0), 7.0f, tex2DMipmapUintOffset,
5314                         evalTexture2DOffsetBiasClamp, FRAGMENT),
5315 
5316         CLAMP_CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5317                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, -8, 0), 5.0f,
5318                         tex2DArrayMipmapFixedOffset, evalTexture2DArrayOffsetBiasClamp, FRAGMENT),
5319         CLAMP_CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5320                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, -8, 0), 5.0f,
5321                         tex2DArrayMipmapFloatOffset, evalTexture2DArrayOffsetBiasClamp, FRAGMENT),
5322         CLAMP_CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5323                         Vec4(6.0f, 6.0f, 4.0f, 0.0f), true, 2.0f, 5.0f, true, IVec3(7, -8, 0), 7.0f,
5324                         tex2DArrayMipmapIntOffset, evalTexture2DArrayOffsetBiasClamp, FRAGMENT),
5325         CLAMP_CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5326                         Vec4(6.0f, 6.0f, 4.0f, 0.0f), true, 2.0f, 5.0f, true, IVec3(7, -8, 0), 7.0f,
5327                         tex2DArrayMipmapUintOffset, evalTexture2DArrayOffsetBiasClamp, FRAGMENT),
5328 
5329         CLAMP_CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5330                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, -12.0f, 12.0f, true, IVec3(-8, 7, 3), 2.0f,
5331                         tex3DMipmapFixedOffset, evalTexture3DOffsetBiasClamp, FRAGMENT),
5332         CLAMP_CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5333                         Vec4(1.0f, 1.0f, 4.0f, 0.0f), true, -12.0f, 12.0f, true, IVec3(-8, 7, 3), 2.0f,
5334                         tex3DMipmapFloatOffset, evalTexture3DOffsetBiasClamp, FRAGMENT),
5335         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),
5336                         true, -5.0f, 5.0f, true, IVec3(-8, 7, 3), 1.0f, tex3DMipmapIntOffset,
5337                         evalTexture3DOffsetBiasClamp, FRAGMENT),
5338         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),
5339                         true, -5.0f, 5.0f, true, IVec3(-8, 7, 3), 1.0f, tex3DMipmapUintOffset,
5340                         evalTexture3DOffsetBiasClamp, FRAGMENT),
5341 
5342         CLAMP_CASE_SPEC(sampler1d_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5343                         Vec4(1.0f, 0.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(-8, 0, 0), 4.0f,
5344                         tex1DMipmapFixedOffset, evalTexture1DOffsetBiasClamp, FRAGMENT),
5345         CLAMP_CASE_SPEC(sampler1d_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5346                         Vec4(1.0f, 0.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, 0, 0), 4.0f,
5347                         tex1DMipmapFloatOffset, evalTexture1DOffsetBiasClamp, FRAGMENT),
5348         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),
5349                         true, 2.0f, 5.0f, true, IVec3(-8, 0, 0), 7.0f, tex1DMipmapIntOffset,
5350                         evalTexture1DOffsetBiasClamp, FRAGMENT),
5351         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),
5352                         true, 2.0f, 5.0f, true, IVec3(7, 0, 0), 7.0f, tex1DMipmapUintOffset,
5353                         evalTexture1DOffsetBiasClamp, FRAGMENT),
5354 
5355         CLAMP_CASE_SPEC(sampler1darray_bias_fixed, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5356                         Vec4(1.0f, 4.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(-8, 0, 0), 5.0f,
5357                         tex1DArrayMipmapFixedOffset, evalTexture1DArrayOffsetBiasClamp, FRAGMENT),
5358         CLAMP_CASE_SPEC(sampler1darray_bias_float, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5359                         Vec4(1.0f, 4.0f, 0.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(7, 0, 0), 5.0f,
5360                         tex1DArrayMipmapFloatOffset, evalTexture1DArrayOffsetBiasClamp, FRAGMENT),
5361         CLAMP_CASE_SPEC(isampler1darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5362                         Vec4(6.0f, 4.0f, 0.0f, 0.0f), true, 2.0f, 5.0f, true, IVec3(-8, 0, 0), 7.0f,
5363                         tex1DArrayMipmapIntOffset, evalTexture1DArrayOffsetBiasClamp, FRAGMENT),
5364         CLAMP_CASE_SPEC(usampler1darray_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5365                         Vec4(6.0f, 4.0f, 0.0f, 0.0f), true, 2.0f, 5.0f, true, IVec3(7, 0, 0), 7.0f,
5366                         tex1DArrayMipmapUintOffset, evalTexture1DArrayOffsetBiasClamp, FRAGMENT),
5367 
5368         CLAMP_CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5369                         Vec4(1.0f, 1.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(-8, 7, 0), 7.0f,
5370                         tex2DMipmapShadowOffset, evalTexture2DShadowOffsetBiasClamp, FRAGMENT),
5371         CLAMP_CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5372                         Vec4(1.0f, 0.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(-8, 0, 0), 7.0f,
5373                         tex1DMipmapShadowOffset, evalTexture1DShadowOffsetBiasClamp, FRAGMENT),
5374         CLAMP_CASE_SPEC(sampler1darrayshadow_bias, FUNCTION_TEXTURE, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
5375                         Vec4(1.0f, 4.0f, 1.0f, 0.0f), true, 0.0f, 5.0f, true, IVec3(-8, 0, 0), 7.0f,
5376                         tex1DArrayMipmapShadowOffset, evalTexture1DArrayShadowOffsetBiasClamp, FRAGMENT),
5377     };
5378 
5379     {
5380         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "textureoffsetclamp");
5381         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
5382         {
5383             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureOffsetClampARBCases); ++j)
5384             {
5385                 textureOffsetClampARBCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
5386                 textureOffsetClampARBCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
5387                 textureOffsetClampARBCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
5388             }
5389             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureOffsetClampARBCases,
5390                             DE_LENGTH_OF_ARRAY(textureOffsetClampARBCases));
5391         }
5392         addChild(offsetGroup);
5393     }
5394 
5395     // textureProj() cases
5396     // \note Currently uses constant divider!
5397     static const TexFuncCaseSpec textureProjCases[] = {
5398         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
5399         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5400                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2DProj3,
5401                   VERTEX),
5402         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5403                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed,
5404                   evalTexture2DProj3, FRAGMENT),
5405         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5406                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2DProj3,
5407                   VERTEX),
5408         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5409                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat,
5410                   evalTexture2DProj3, FRAGMENT),
5411         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5412                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2DProj3,
5413                   VERTEX),
5414         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5415                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt,
5416                   evalTexture2DProj3, FRAGMENT),
5417         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5418                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2DProj3,
5419                   VERTEX),
5420         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5421                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint,
5422                   evalTexture2DProj3, FRAGMENT),
5423 
5424         CASE_SPEC(sampler2d_vec3_bias_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5425                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed,
5426                   evalTexture2DProj3Bias, FRAGMENT),
5427         CASE_SPEC(sampler2d_vec3_bias_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5428                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat,
5429                   evalTexture2DProj3Bias, FRAGMENT),
5430         CASE_SPEC(isampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5431                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt,
5432                   evalTexture2DProj3Bias, FRAGMENT),
5433         CASE_SPEC(usampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5434                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint,
5435                   evalTexture2DProj3Bias, FRAGMENT),
5436 
5437         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5438                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2DProj,
5439                   VERTEX),
5440         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5441                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed,
5442                   evalTexture2DProj, FRAGMENT),
5443         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5444                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2DProj,
5445                   VERTEX),
5446         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5447                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat,
5448                   evalTexture2DProj, FRAGMENT),
5449         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5450                   false, 0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2DProj, VERTEX),
5451         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5452                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DProj, FRAGMENT),
5453         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5454                   false, 0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2DProj, VERTEX),
5455         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5456                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DProj, FRAGMENT),
5457 
5458         CASE_SPEC(sampler2d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5459                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed,
5460                   evalTexture2DProjBias, FRAGMENT),
5461         CASE_SPEC(sampler2d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5462                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat,
5463                   evalTexture2DProjBias, FRAGMENT),
5464         CASE_SPEC(isampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5465                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt,
5466                   evalTexture2DProjBias, FRAGMENT),
5467         CASE_SPEC(usampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5468                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint,
5469                   evalTexture2DProjBias, FRAGMENT),
5470 
5471         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5472                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DFixed, evalTexture3DProj,
5473                   VERTEX),
5474         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5475                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFixed,
5476                   evalTexture3DProj, FRAGMENT),
5477         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5478                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DFloat, evalTexture3DProj,
5479                   VERTEX),
5480         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5481                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFloat,
5482                   evalTexture3DProj, FRAGMENT),
5483         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5484                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DInt, evalTexture3DProj,
5485                   VERTEX),
5486         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5487                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapInt,
5488                   evalTexture3DProj, FRAGMENT),
5489         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5490                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DUint, evalTexture3DProj,
5491                   VERTEX),
5492         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5493                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapUint,
5494                   evalTexture3DProj, FRAGMENT),
5495 
5496         CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5497                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFixed,
5498                   evalTexture3DProjBias, FRAGMENT),
5499         CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5500                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFloat,
5501                   evalTexture3DProjBias, FRAGMENT),
5502         CASE_SPEC(isampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5503                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, false, IVec3(0), tex3DMipmapInt,
5504                   evalTexture3DProjBias, FRAGMENT),
5505         CASE_SPEC(usampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5506                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, false, IVec3(0), tex3DMipmapUint,
5507                   evalTexture3DProjBias, FRAGMENT),
5508 
5509         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5510                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex1DFixed, evalTexture1DProj2,
5511                   VERTEX),
5512         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5513                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapFixed,
5514                   evalTexture1DProj2, FRAGMENT),
5515         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5516                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex1DFloat, evalTexture1DProj2,
5517                   VERTEX),
5518         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5519                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapFloat,
5520                   evalTexture1DProj2, FRAGMENT),
5521         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5522                   false, 0.0f, 0.0f, false, IVec3(0), tex1DInt, evalTexture1DProj2, VERTEX),
5523         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5524                   false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapInt, evalTexture1DProj2, FRAGMENT),
5525         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5526                   false, 0.0f, 0.0f, false, IVec3(0), tex1DUint, evalTexture1DProj2, VERTEX),
5527         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5528                   false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapUint, evalTexture1DProj2, FRAGMENT),
5529 
5530         CASE_SPEC(sampler1d_vec2_bias_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5531                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFixed,
5532                   evalTexture1DProj2Bias, FRAGMENT),
5533         CASE_SPEC(sampler1d_vec2_bias_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5534                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFloat,
5535                   evalTexture1DProj2Bias, FRAGMENT),
5536         CASE_SPEC(isampler1d_vec2_bias, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5537                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapInt,
5538                   evalTexture1DProj2Bias, FRAGMENT),
5539         CASE_SPEC(usampler1d_vec2_bias, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5540                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapUint,
5541                   evalTexture1DProj2Bias, FRAGMENT),
5542 
5543         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5544                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex1DFixed, evalTexture1DProj,
5545                   VERTEX),
5546         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5547                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapFixed,
5548                   evalTexture1DProj, FRAGMENT),
5549         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5550                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex1DFloat, evalTexture1DProj,
5551                   VERTEX),
5552         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5553                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapFloat,
5554                   evalTexture1DProj, FRAGMENT),
5555         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5556                   false, 0.0f, 0.0f, false, IVec3(0), tex1DInt, evalTexture1DProj, VERTEX),
5557         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5558                   false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapInt, evalTexture1DProj, FRAGMENT),
5559         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5560                   false, 0.0f, 0.0f, false, IVec3(0), tex1DUint, evalTexture1DProj, VERTEX),
5561         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5562                   false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapUint, evalTexture1DProj, FRAGMENT),
5563 
5564         CASE_SPEC(sampler1d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5565                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFixed,
5566                   evalTexture1DProjBias, FRAGMENT),
5567         CASE_SPEC(sampler1d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5568                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapFloat,
5569                   evalTexture1DProjBias, FRAGMENT),
5570         CASE_SPEC(isampler1d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5571                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapInt,
5572                   evalTexture1DProjBias, FRAGMENT),
5573         CASE_SPEC(usampler1d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5574                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapUint,
5575                   evalTexture1DProjBias, FRAGMENT),
5576 
5577         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
5578                   false, 0.0f, 0.0f, false, IVec3(0), tex2DShadow, evalTexture2DShadowProj, VERTEX),
5579         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
5580                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowProj, FRAGMENT),
5581         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
5582                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapShadow,
5583                   evalTexture2DShadowProjBias, FRAGMENT),
5584         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f), Vec4(-2.25f, 0.0f, 1.5f, 1.5f),
5585                   false, 0.0f, 0.0f, false, IVec3(0), tex1DShadow, evalTexture1DShadowProj, VERTEX),
5586         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f), Vec4(-2.25f, 0.0f, 1.5f, 1.5f),
5587                   false, 0.0f, 0.0f, false, IVec3(0), tex1DMipmapShadow, evalTexture1DShadowProj, FRAGMENT),
5588         CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f),
5589                   Vec4(-2.25f, 0.0f, 1.5f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex1DMipmapShadow,
5590                   evalTexture1DShadowProjBias, FRAGMENT),
5591     };
5592     createCaseGroup(this, "textureproj", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
5593 
5594     // textureProjOffset() cases
5595     // \note Currently uses constant divider!
5596     static TexFuncCaseSpec textureProjOffsetCases[] = {
5597         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                        EvalFunc                        Flags
5598         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5599                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset,
5600                   evalTexture2DProj3Offset, VERTEX),
5601         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5602                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixedOffset,
5603                   evalTexture2DProj3Offset, FRAGMENT),
5604         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5605                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloatOffset,
5606                   evalTexture2DProj3Offset, VERTEX),
5607         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5608                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
5609                   evalTexture2DProj3Offset, FRAGMENT),
5610         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5611                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DIntOffset,
5612                   evalTexture2DProj3Offset, VERTEX),
5613         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5614                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapIntOffset,
5615                   evalTexture2DProj3Offset, FRAGMENT),
5616         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5617                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUintOffset,
5618                   evalTexture2DProj3Offset, VERTEX),
5619         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5620                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset,
5621                   evalTexture2DProj3Offset, FRAGMENT),
5622 
5623         CASE_SPEC(sampler2d_vec3_bias_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5624                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset,
5625                   evalTexture2DProj3OffsetBias, FRAGMENT),
5626         CASE_SPEC(sampler2d_vec3_bias_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5627                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloatOffset,
5628                   evalTexture2DProj3OffsetBias, FRAGMENT),
5629         CASE_SPEC(isampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5630                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DIntOffset,
5631                   evalTexture2DProj3OffsetBias, FRAGMENT),
5632         CASE_SPEC(usampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5633                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUintOffset,
5634                   evalTexture2DProj3OffsetBias, FRAGMENT),
5635 
5636         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5637                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset,
5638                   evalTexture2DProjOffset, VERTEX),
5639         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5640                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixedOffset,
5641                   evalTexture2DProjOffset, FRAGMENT),
5642         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5643                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloatOffset,
5644                   evalTexture2DProjOffset, VERTEX),
5645         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5646                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
5647                   evalTexture2DProjOffset, FRAGMENT),
5648         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5649                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DIntOffset, evalTexture2DProjOffset, VERTEX),
5650         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5651                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapIntOffset, evalTexture2DProjOffset, FRAGMENT),
5652         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5653                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUintOffset, evalTexture2DProjOffset, VERTEX),
5654         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
5655                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset, evalTexture2DProjOffset, FRAGMENT),
5656 
5657         CASE_SPEC(sampler2d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5658                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixedOffset,
5659                   evalTexture2DProjOffsetBias, FRAGMENT),
5660         CASE_SPEC(sampler2d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5661                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloatOffset,
5662                   evalTexture2DProjOffsetBias, FRAGMENT),
5663         CASE_SPEC(isampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5664                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DIntOffset,
5665                   evalTexture2DProjOffsetBias, FRAGMENT),
5666         CASE_SPEC(usampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5667                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUintOffset,
5668                   evalTexture2DProjOffsetBias, FRAGMENT),
5669 
5670         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5671                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DFixedOffset, evalTexture3DProjOffset, VERTEX),
5672         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5673                   false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapFixedOffset, evalTexture3DProjOffset, FRAGMENT),
5674         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5675                   false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DFloatOffset, evalTexture3DProjOffset, VERTEX),
5676         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5677                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DMipmapFloatOffset, evalTexture3DProjOffset, FRAGMENT),
5678         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5679                   false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DIntOffset, evalTexture3DProjOffset, VERTEX),
5680         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5681                   false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DMipmapIntOffset, evalTexture3DProjOffset, FRAGMENT),
5682         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5683                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DUintOffset, evalTexture3DProjOffset, VERTEX),
5684         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 2.0f, 1.5f),
5685                   false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapUintOffset, evalTexture3DProjOffset, FRAGMENT),
5686 
5687         CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5688                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DFixedOffset,
5689                   evalTexture3DProjOffsetBias, FRAGMENT),
5690         CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5691                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(7, 3, -8), tex3DFloatOffset,
5692                   evalTexture3DProjOffsetBias, FRAGMENT),
5693         CASE_SPEC(isampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5694                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(3, -8, 7), tex3DIntOffset,
5695                   evalTexture3DProjOffsetBias, FRAGMENT),
5696         CASE_SPEC(usampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
5697                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DUintOffset,
5698                   evalTexture3DProjOffsetBias, FRAGMENT),
5699 
5700         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5701                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset,
5702                   evalTexture1DProj2Offset, VERTEX),
5703         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5704                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFixedOffset,
5705                   evalTexture1DProj2Offset, FRAGMENT),
5706         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5707                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFloatOffset,
5708                   evalTexture1DProj2Offset, VERTEX),
5709         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5710                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset,
5711                   evalTexture1DProj2Offset, FRAGMENT),
5712         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5713                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DIntOffset, evalTexture1DProj2Offset, VERTEX),
5714         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5715                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapIntOffset, evalTexture1DProj2Offset, FRAGMENT),
5716         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5717                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DUintOffset, evalTexture1DProj2Offset, VERTEX),
5718         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f), Vec4(2.25f, 1.5f, 0.0f, 0.0f),
5719                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset, evalTexture1DProj2Offset, FRAGMENT),
5720 
5721         CASE_SPEC(sampler1d_vec2_bias_fixed, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5722                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset,
5723                   evalTexture1DProj2OffsetBias, FRAGMENT),
5724         CASE_SPEC(sampler1d_vec2_bias_float, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5725                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DFloatOffset,
5726                   evalTexture1DProj2OffsetBias, FRAGMENT),
5727         CASE_SPEC(isampler1d_vec2_bias, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5728                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DIntOffset,
5729                   evalTexture1DProj2OffsetBias, FRAGMENT),
5730         CASE_SPEC(usampler1d_vec2_bias, FUNCTION_TEXTUREPROJ2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
5731                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DUintOffset,
5732                   evalTexture1DProj2OffsetBias, FRAGMENT),
5733 
5734         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5735                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset,
5736                   evalTexture1DProjOffset, VERTEX),
5737         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5738                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFixedOffset,
5739                   evalTexture1DProjOffset, FRAGMENT),
5740         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5741                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DFloatOffset,
5742                   evalTexture1DProjOffset, VERTEX),
5743         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5744                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset,
5745                   evalTexture1DProjOffset, FRAGMENT),
5746         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5747                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DIntOffset, evalTexture1DProjOffset, VERTEX),
5748         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5749                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapIntOffset, evalTexture1DProjOffset, FRAGMENT),
5750         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5751                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DUintOffset, evalTexture1DProjOffset, VERTEX),
5752         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f), Vec4(2.25f, 0.0f, 0.0f, 1.5f),
5753                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset, evalTexture1DProjOffset, FRAGMENT),
5754 
5755         CASE_SPEC(sampler1d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5756                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DFixedOffset,
5757                   evalTexture1DProjOffsetBias, FRAGMENT),
5758         CASE_SPEC(sampler1d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5759                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DFloatOffset,
5760                   evalTexture1DProjOffsetBias, FRAGMENT),
5761         CASE_SPEC(isampler1d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5762                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DIntOffset,
5763                   evalTexture1DProjOffsetBias, FRAGMENT),
5764         CASE_SPEC(usampler1d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
5765                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, 0, 0), tex1DUintOffset,
5766                   evalTexture1DProjOffsetBias, FRAGMENT),
5767 
5768         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
5769                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DShadowOffset, evalTexture2DShadowProjOffset, VERTEX),
5770         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
5771                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapShadowOffset, evalTexture2DShadowProjOffset,
5772                   FRAGMENT),
5773         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
5774                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DShadowOffset,
5775                   evalTexture2DShadowProjOffsetBias, FRAGMENT),
5776         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f), Vec4(-2.25f, 0.0f, 1.5f, 1.5f),
5777                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DShadowOffset, evalTexture1DShadowProjOffset, VERTEX),
5778         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f), Vec4(-2.25f, 0.0f, 1.5f, 1.5f),
5779                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DMipmapShadowOffset, evalTexture1DShadowProjOffset,
5780                   FRAGMENT),
5781         CASE_SPEC(sampler1dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.0f, 0.0f, 1.5f),
5782                   Vec4(-2.25f, 0.0f, 1.5f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 0, 0), tex1DShadowOffset,
5783                   evalTexture1DShadowProjOffsetBias, FRAGMENT),
5784     };
5785 
5786     {
5787         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "textureprojoffset");
5788         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
5789         {
5790             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureProjOffsetCases); ++j)
5791             {
5792                 textureProjOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
5793                 textureProjOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
5794                 textureProjOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
5795             }
5796             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureProjOffsetCases,
5797                             DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
5798         }
5799         addChild(offsetGroup);
5800     }
5801 
5802     // textureLod() cases
5803     static const TexFuncCaseSpec textureLodCases[] = {
5804         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
5805         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5806                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2DLod, BOTH),
5807         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5808                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2DLod, BOTH),
5809         CASE_SPEC(isampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5810                   -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DLod, BOTH),
5811         CASE_SPEC(usampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5812                   -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DLod, BOTH),
5813 
5814         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
5815                   Vec4(1.0f, 1.0f, 1.01f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapFixed,
5816                   evalTextureCubeLod, BOTH),
5817         CASE_SPEC(samplercube_float, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
5818                   Vec4(1.0f, 1.0f, -1.01f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapFloat,
5819                   evalTextureCubeLod, BOTH),
5820         CASE_SPEC(isamplercube, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
5821                   false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCubeLod, BOTH),
5822         CASE_SPEC(usamplercube, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
5823                   false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCubeLod, BOTH),
5824 
5825         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5826                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapFixed,
5827                   evalTexture2DArrayLod, BOTH),
5828         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5829                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapFloat,
5830                   evalTexture2DArrayLod, BOTH),
5831         CASE_SPEC(isampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5832                   false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArrayLod, BOTH),
5833         CASE_SPEC(usampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5834                   false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArrayLod, BOTH),
5835 
5836         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5837                   false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3DLod, BOTH),
5838         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5839                   false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3DLod, BOTH),
5840         CASE_SPEC(isampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5841                   -1.0f, 7.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3DLod, BOTH),
5842         CASE_SPEC(usampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5843                   -1.0f, 7.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3DLod, BOTH),
5844 
5845         CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
5846                   false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFixed, evalTexture1DLod, BOTH),
5847         CASE_SPEC(sampler1d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
5848                   false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFloat, evalTexture1DLod, BOTH),
5849         CASE_SPEC(isampler1d, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5850                   -1.0f, 9.0f, false, IVec3(0), tex1DMipmapInt, evalTexture1DLod, BOTH),
5851         CASE_SPEC(usampler1d, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5852                   -1.0f, 9.0f, false, IVec3(0), tex1DMipmapUint, evalTexture1DLod, BOTH),
5853 
5854         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5855                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DArrayMipmapFixed,
5856                   evalTexture1DArrayLod, BOTH),
5857         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5858                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DArrayMipmapFloat,
5859                   evalTexture1DArrayLod, BOTH),
5860         CASE_SPEC(isampler1darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5861                   false, -1.0f, 9.0f, false, IVec3(0), tex1DArrayMipmapInt, evalTexture1DArrayLod, BOTH),
5862         CASE_SPEC(usampler1darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5863                   false, -1.0f, 9.0f, false, IVec3(0), tex1DArrayMipmapUint, evalTexture1DArrayLod, BOTH),
5864 
5865         CASE_SPEC(samplercubearray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
5866                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), false, -1.0f, 7.0f, false, IVec3(0), texCubeArrayMipmapFixed,
5867                   evalTextureCubeArrayLod, BOTH),
5868         CASE_SPEC(samplercubearray_float, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
5869                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, -1.0f, 7.0f, false, IVec3(0), texCubeArrayMipmapFloat,
5870                   evalTextureCubeArrayLod, BOTH),
5871         CASE_SPEC(isamplercubearray, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
5872                   Vec4(1.0f, 1.0f, 1.01f, 1.5f), false, -1.0f, 7.0f, false, IVec3(0), texCubeArrayMipmapInt,
5873                   evalTextureCubeArrayLod, BOTH),
5874         CASE_SPEC(usamplercubearray, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
5875                   Vec4(1.0f, 1.0f, -1.01f, 1.5f), false, -1.0f, 7.0f, false, IVec3(0), texCubeArrayMipmapUint,
5876                   evalTextureCubeArrayLod, BOTH),
5877 
5878         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
5879                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowLod, BOTH),
5880         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f),
5881                   false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapShadow, evalTexture1DShadowLod, BOTH),
5882         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5883                   Vec4(1.5f, 3.5f, 1.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DArrayMipmapShadow,
5884                   evalTexture1DArrayShadowLod, BOTH),
5885     };
5886     createCaseGroup(this, "texturelod", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
5887 
5888     // textureLodOffset() cases
5889     static TexFuncCaseSpec textureLodOffsetCases[] = {
5890         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                            EvalFunc                            Flags
5891         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5892                   false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset, evalTexture2DLodOffset, BOTH),
5893         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
5894                   false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset, evalTexture2DLodOffset, BOTH),
5895         CASE_SPEC(isampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5896                   -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapIntOffset, evalTexture2DLodOffset, BOTH),
5897         CASE_SPEC(usampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
5898                   -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset, evalTexture2DLodOffset, BOTH),
5899 
5900         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5901                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, true, IVec3(-8, 7, 0), tex2DArrayMipmapFixedOffset,
5902                   evalTexture2DArrayLodOffset, BOTH),
5903         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
5904                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFloatOffset,
5905                   evalTexture2DArrayLodOffset, BOTH),
5906         CASE_SPEC(isampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5907                   false, -1.0f, 8.0f, true, IVec3(-8, 7, 0), tex2DArrayMipmapIntOffset, evalTexture2DArrayLodOffset,
5908                   BOTH),
5909         CASE_SPEC(usampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
5910                   false, -1.0f, 8.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapUintOffset, evalTexture2DArrayLodOffset,
5911                   BOTH),
5912 
5913         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5914                   false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapFixedOffset, evalTexture3DLodOffset, BOTH),
5915         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
5916                   false, -1.0f, 7.0f, true, IVec3(7, 3, -8), tex3DMipmapFloatOffset, evalTexture3DLodOffset, BOTH),
5917         CASE_SPEC(isampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5918                   -1.0f, 7.0f, true, IVec3(3, -8, 7), tex3DMipmapIntOffset, evalTexture3DLodOffset, BOTH),
5919         CASE_SPEC(usampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
5920                   -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapUintOffset, evalTexture3DLodOffset, BOTH),
5921 
5922         CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
5923                   false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapFixedOffset, evalTexture1DLodOffset, BOTH),
5924         CASE_SPEC(sampler1d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
5925                   false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset, evalTexture1DLodOffset, BOTH),
5926         CASE_SPEC(isampler1d, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5927                   -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapIntOffset, evalTexture1DLodOffset, BOTH),
5928         CASE_SPEC(usampler1d, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f), false,
5929                   -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset, evalTexture1DLodOffset, BOTH),
5930 
5931         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5932                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DArrayMipmapFixedOffset,
5933                   evalTexture1DArrayLodOffset, BOTH),
5934         CASE_SPEC(sampler1darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5935                   Vec4(1.5f, 3.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapFloatOffset,
5936                   evalTexture1DArrayLodOffset, BOTH),
5937         CASE_SPEC(isampler1darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5938                   false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DArrayMipmapIntOffset, evalTexture1DArrayLodOffset,
5939                   BOTH),
5940         CASE_SPEC(usampler1darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f), Vec4(1.5f, 3.5f, 0.0f, 0.0f),
5941                   false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapUintOffset, evalTexture1DArrayLodOffset,
5942                   BOTH),
5943 
5944         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
5945                   false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapShadowOffset, evalTexture2DShadowLodOffset,
5946                   BOTH),
5947         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 1.0f, 0.0f),
5948                   false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapShadowOffset, evalTexture1DShadowLodOffset,
5949                   BOTH),
5950         CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
5951                   Vec4(1.5f, 3.5f, 1.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DArrayMipmapShadowOffset,
5952                   evalTexture1DArrayShadowLodOffset, BOTH),
5953     };
5954 
5955     {
5956         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "texturelodoffset");
5957         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
5958         {
5959             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureLodOffsetCases); ++j)
5960             {
5961                 textureLodOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
5962                 textureLodOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
5963                 textureLodOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
5964             }
5965             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureLodOffsetCases,
5966                             DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
5967         }
5968         addChild(offsetGroup);
5969     }
5970 
5971     // textureProjLod() cases
5972     static const TexFuncCaseSpec textureProjLodCases[] = {
5973         //          Name                            Function                    MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                    Flags
5974         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5975                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed,
5976                   evalTexture2DProjLod3, BOTH),
5977         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5978                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat,
5979                   evalTexture2DProjLod3, BOTH),
5980         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5981                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt,
5982                   evalTexture2DProjLod3, BOTH),
5983         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
5984                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint,
5985                   evalTexture2DProjLod3, BOTH),
5986 
5987         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5988                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed,
5989                   evalTexture2DProjLod, BOTH),
5990         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5991                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat,
5992                   evalTexture2DProjLod, BOTH),
5993         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5994                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt,
5995                   evalTexture2DProjLod, BOTH),
5996         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
5997                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint,
5998                   evalTexture2DProjLod, BOTH),
5999 
6000         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6001                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFixed,
6002                   evalTexture3DProjLod, BOTH),
6003         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6004                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFloat,
6005                   evalTexture3DProjLod, BOTH),
6006         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6007                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapInt,
6008                   evalTexture3DProjLod, BOTH),
6009         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6010                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapUint,
6011                   evalTexture3DProjLod, BOTH),
6012 
6013         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6014                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFixed,
6015                   evalTexture1DProjLod2, BOTH),
6016         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6017                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFloat,
6018                   evalTexture1DProjLod2, BOTH),
6019         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6020                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapInt,
6021                   evalTexture1DProjLod2, BOTH),
6022         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6023                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapUint,
6024                   evalTexture1DProjLod2, BOTH),
6025 
6026         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6027                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFixed,
6028                   evalTexture1DProjLod, BOTH),
6029         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6030                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapFloat,
6031                   evalTexture1DProjLod, BOTH),
6032         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6033                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapInt,
6034                   evalTexture1DProjLod, BOTH),
6035         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6036                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapUint,
6037                   evalTexture1DProjLod, BOTH),
6038 
6039         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
6040                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapShadow,
6041                   evalTexture2DShadowProjLod, BOTH),
6042         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.0f, 0.0f, 1.5f),
6043                   Vec4(-2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex1DMipmapShadow,
6044                   evalTexture1DShadowProjLod, BOTH),
6045     };
6046     createCaseGroup(this, "textureprojlod", textureProjLodCases, DE_LENGTH_OF_ARRAY(textureProjLodCases));
6047 
6048     // textureProjLodOffset() cases
6049     static TexFuncCaseSpec textureProjLodOffsetCases[] = {
6050         //          Name                            Function                    MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                        EvalFunc                        Flags
6051         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6052                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset,
6053                   evalTexture2DProjLod3Offset, BOTH),
6054         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6055                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
6056                   evalTexture2DProjLod3Offset, BOTH),
6057         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6058                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapIntOffset,
6059                   evalTexture2DProjLod3Offset, BOTH),
6060         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6061                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset,
6062                   evalTexture2DProjLod3Offset, BOTH),
6063 
6064         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6065                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset,
6066                   evalTexture2DProjLodOffset, BOTH),
6067         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6068                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
6069                   evalTexture2DProjLodOffset, BOTH),
6070         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6071                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapIntOffset,
6072                   evalTexture2DProjLodOffset, BOTH),
6073         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6074                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUintOffset,
6075                   evalTexture2DProjLodOffset, BOTH),
6076 
6077         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6078                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapFixedOffset,
6079                   evalTexture3DProjLodOffset, BOTH),
6080         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6081                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(7, 3, -8), tex3DMipmapFloatOffset,
6082                   evalTexture3DProjLodOffset, BOTH),
6083         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6084                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(3, -8, 7), tex3DMipmapIntOffset,
6085                   evalTexture3DProjLodOffset, BOTH),
6086         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6087                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapUintOffset,
6088                   evalTexture3DProjLodOffset, BOTH),
6089 
6090         CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6091                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapFixedOffset,
6092                   evalTexture1DProjLod2Offset, BOTH),
6093         CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6094                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset,
6095                   evalTexture1DProjLod2Offset, BOTH),
6096         CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6097                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapIntOffset,
6098                   evalTexture1DProjLod2Offset, BOTH),
6099         CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJLOD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6100                   Vec4(2.25f, 1.5f, 0.0f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset,
6101                   evalTexture1DProjLod2Offset, BOTH),
6102 
6103         CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6104                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapFixedOffset,
6105                   evalTexture1DProjLodOffset, BOTH),
6106         CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6107                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapFloatOffset,
6108                   evalTexture1DProjLodOffset, BOTH),
6109         CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6110                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 0, 0), tex1DMipmapIntOffset,
6111                   evalTexture1DProjLodOffset, BOTH),
6112         CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6113                   Vec4(2.25f, 0.0f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapUintOffset,
6114                   evalTexture1DProjLodOffset, BOTH),
6115 
6116         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
6117                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapShadowOffset,
6118                   evalTexture2DShadowProjLodOffset, BOTH),
6119         CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.0f, 0.0f, 1.5f),
6120                   Vec4(-2.25f, 0.0f, 1.5f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, 0, 0), tex1DMipmapShadowOffset,
6121                   evalTexture1DShadowProjLodOffset, BOTH),
6122     };
6123 
6124     {
6125         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "textureprojlodoffset");
6126         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
6127         {
6128             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases); ++j)
6129             {
6130                 textureProjLodOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
6131                 textureProjLodOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
6132                 textureProjLodOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
6133             }
6134             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureProjLodOffsetCases,
6135                             DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
6136         }
6137         addChild(offsetGroup);
6138     }
6139 
6140     // textureGrad() cases
6141     // \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
6142     static const TexFuncCaseSpec textureGradCases[] = {
6143         //          Name                            Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset        Format                    EvalFunc                Flags
6144         GRAD_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6145                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6146                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
6147                        evalTexture2DGrad, BOTH),
6148         GRAD_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6149                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6150                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
6151                        evalTexture2DGrad, BOTH),
6152         GRAD_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
6153                        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),
6154                        false, IVec3(0), tex2DMipmapInt, evalTexture2DGrad, BOTH),
6155         GRAD_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
6156                        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),
6157                        false, IVec3(0), tex2DMipmapUint, evalTexture2DGrad, BOTH),
6158 
6159         GRAD_CASE_SPEC(samplercube_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6160                        Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6161                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapFixed,
6162                        evalTextureCubeGrad, BOTH),
6163         GRAD_CASE_SPEC(samplercube_float, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
6164                        Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6165                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapFloat,
6166                        evalTextureCubeGrad, BOTH),
6167         GRAD_CASE_SPEC(isamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6168                        Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6169                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapInt,
6170                        evalTextureCubeGrad, BOTH),
6171         GRAD_CASE_SPEC(usamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
6172                        Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6173                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), texCubeMipmapUint,
6174                        evalTextureCubeGrad, BOTH),
6175 
6176         GRAD_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6177                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6178                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapFixed,
6179                        evalTexture2DArrayGrad, BOTH),
6180         GRAD_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6181                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6182                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapFloat,
6183                        evalTexture2DArrayGrad, BOTH),
6184         GRAD_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6185                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6186                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapInt,
6187                        evalTexture2DArrayGrad, BOTH),
6188         GRAD_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6189                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6190                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DArrayMipmapUint,
6191                        evalTexture2DArrayGrad, BOTH),
6192 
6193         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6194                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6195                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFixed,
6196                        evalTexture3DGrad, BOTH),
6197         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6198                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6199                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
6200                        evalTexture3DGrad, VERTEX),
6201         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6202                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6203                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
6204                        evalTexture3DGrad, FRAGMENT),
6205         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6206                        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),
6207                        false, IVec3(0), tex3DMipmapInt, evalTexture3DGrad, BOTH),
6208         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6209                        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),
6210                        false, IVec3(0), tex3DMipmapUint, evalTexture3DGrad, VERTEX),
6211         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6212                        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),
6213                        false, IVec3(0), tex3DMipmapUint, evalTexture3DGrad, FRAGMENT),
6214 
6215         GRAD_CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6216                        Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6217                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFixed,
6218                        evalTexture1DGrad, BOTH),
6219         GRAD_CASE_SPEC(sampler1d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6220                        Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6221                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFloat,
6222                        evalTexture1DGrad, BOTH),
6223         GRAD_CASE_SPEC(isampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
6224                        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),
6225                        false, IVec3(0), tex1DMipmapInt, evalTexture1DGrad, BOTH),
6226         GRAD_CASE_SPEC(usampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
6227                        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),
6228                        false, IVec3(0), tex1DMipmapUint, evalTexture1DGrad, BOTH),
6229 
6230         GRAD_CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6231                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6232                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapFixed,
6233                        evalTexture1DArrayGrad, BOTH),
6234         GRAD_CASE_SPEC(sampler1darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6235                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6236                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapFloat,
6237                        evalTexture1DArrayGrad, BOTH),
6238         GRAD_CASE_SPEC(isampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6239                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6240                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapInt,
6241                        evalTexture1DArrayGrad, BOTH),
6242         GRAD_CASE_SPEC(usampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6243                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6244                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapUint,
6245                        evalTexture1DArrayGrad, BOTH),
6246 
6247         GRAD_CASE_SPEC(samplercubearray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
6248                        Vec4(1.0f, 1.0f, 1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6249                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeArrayMipmapFixed,
6250                        evalTextureCubeArrayGrad, BOTH),
6251         GRAD_CASE_SPEC(samplercubearray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
6252                        Vec4(1.0f, 1.0f, -1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6253                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeArrayMipmapFloat,
6254                        evalTextureCubeArrayGrad, BOTH),
6255         GRAD_CASE_SPEC(isamplercubearray, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
6256                        Vec4(1.0f, 1.0f, 1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6257                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), texCubeArrayMipmapInt,
6258                        evalTextureCubeArrayGrad, BOTH),
6259         GRAD_CASE_SPEC(usamplercubearray, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
6260                        Vec4(1.0f, 1.0f, -1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6261                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), texCubeArrayMipmapUint,
6262                        evalTextureCubeArrayGrad, BOTH),
6263 
6264         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6265                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6266                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
6267                        evalTexture2DShadowGrad, BOTH),
6268         GRAD_CASE_SPEC(samplercubeshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6269                        Vec4(1.0f, 1.0f, 1.01f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6270                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapShadow,
6271                        evalTextureCubeShadowGrad, BOTH),
6272         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6273                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6274                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapShadow,
6275                        evalTexture2DArrayShadowGrad, VERTEX),
6276         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6277                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6278                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), false, IVec3(0), tex2DArrayMipmapShadow,
6279                        evalTexture2DArrayShadowGrad, FRAGMENT),
6280         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6281                        Vec4(1.5f, 0.0f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6282                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapShadow,
6283                        evalTexture1DShadowGrad, BOTH),
6284         GRAD_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6285                        Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6286                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapShadow,
6287                        evalTexture1DArrayShadowGrad, VERTEX),
6288         GRAD_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6289                        Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6290                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DArrayMipmapShadow,
6291                        evalTexture1DArrayShadowGrad, FRAGMENT),
6292     };
6293     createCaseGroup(this, "texturegrad", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
6294 
6295     // textureGradClampARB() cases
6296     static const TexFuncCaseSpec textureGradClampCases[] = {
6297         //          Name                                    Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset        LodClamp    Format                    EvalFunc                        Flags
6298         GRADCLAMP_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6299                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6300                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex2DMipmapFixed,
6301                             evalTexture2DGradClamp, FRAGMENT),
6302         GRADCLAMP_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6303                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6304                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex2DMipmapFloat,
6305                             evalTexture2DGradClamp, FRAGMENT),
6306         GRADCLAMP_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6307                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6308                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex2DMipmapInt,
6309                             evalTexture2DGradClamp, FRAGMENT),
6310         GRADCLAMP_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6311                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6312                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), 5.0f, tex2DMipmapUint,
6313                             evalTexture2DGradClamp, FRAGMENT),
6314 
6315         GRADCLAMP_CASE_SPEC(samplercube_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6316                             Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6317                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, texCubeMipmapFixed,
6318                             evalTextureCubeGradClamp, FRAGMENT),
6319         GRADCLAMP_CASE_SPEC(samplercube_float, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
6320                             Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6321                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, texCubeMipmapFloat,
6322                             evalTextureCubeGradClamp, FRAGMENT),
6323         GRADCLAMP_CASE_SPEC(isamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6324                             Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6325                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, texCubeMipmapInt,
6326                             evalTextureCubeGradClamp, FRAGMENT),
6327         GRADCLAMP_CASE_SPEC(usamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
6328                             Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6329                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), 5.0f, texCubeMipmapUint,
6330                             evalTextureCubeGradClamp, FRAGMENT),
6331 
6332         GRADCLAMP_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6333                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6334                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f,
6335                             tex2DArrayMipmapFixed, evalTexture2DArrayGradClamp, FRAGMENT),
6336         GRADCLAMP_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6337                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6338                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f,
6339                             tex2DArrayMipmapFloat, evalTexture2DArrayGradClamp, FRAGMENT),
6340         GRADCLAMP_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6341                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6342                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex2DArrayMipmapInt,
6343                             evalTexture2DArrayGradClamp, FRAGMENT),
6344         GRADCLAMP_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6345                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6346                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), 5.0f, tex2DArrayMipmapUint,
6347                             evalTexture2DArrayGradClamp, FRAGMENT),
6348 
6349         GRADCLAMP_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6350                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6351                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex3DMipmapFixed,
6352                             evalTexture3DGradClamp, FRAGMENT),
6353         GRADCLAMP_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6354                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6355                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex3DMipmapFloat,
6356                             evalTexture3DGradClamp, FRAGMENT),
6357         GRADCLAMP_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6358                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6359                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex3DMipmapInt,
6360                             evalTexture3DGradClamp, FRAGMENT),
6361         GRADCLAMP_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6362                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6363                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), false, IVec3(0), 5.0f, tex3DMipmapUint,
6364                             evalTexture3DGradClamp, FRAGMENT),
6365 
6366         GRADCLAMP_CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6367                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6368                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DMipmapFixed,
6369                             evalTexture1DGradClamp, FRAGMENT),
6370         GRADCLAMP_CASE_SPEC(sampler1d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6371                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6372                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DMipmapFloat,
6373                             evalTexture1DGradClamp, FRAGMENT),
6374         GRADCLAMP_CASE_SPEC(isampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6375                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6376                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DMipmapInt,
6377                             evalTexture1DGradClamp, FRAGMENT),
6378         GRADCLAMP_CASE_SPEC(usampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6379                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6380                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DMipmapUint,
6381                             evalTexture1DGradClamp, FRAGMENT),
6382 
6383         GRADCLAMP_CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6384                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6385                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f,
6386                             tex1DArrayMipmapFixed, evalTexture1DArrayGradClamp, FRAGMENT),
6387         GRADCLAMP_CASE_SPEC(sampler1darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6388                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6389                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f,
6390                             tex1DArrayMipmapFloat, evalTexture1DArrayGradClamp, FRAGMENT),
6391         GRADCLAMP_CASE_SPEC(isampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6392                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6393                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DArrayMipmapInt,
6394                             evalTexture1DArrayGradClamp, FRAGMENT),
6395         GRADCLAMP_CASE_SPEC(usampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6396                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6397                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DArrayMipmapUint,
6398                             evalTexture1DArrayGradClamp, FRAGMENT),
6399 
6400         GRADCLAMP_CASE_SPEC(samplercubearray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
6401                             Vec4(1.0f, 1.0f, 1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6402                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 4.0f,
6403                             texCubeArrayMipmapFixed, evalTextureCubeArrayGradClamp, FRAGMENT),
6404         GRADCLAMP_CASE_SPEC(samplercubearray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
6405                             Vec4(1.0f, 1.0f, -1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6406                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 4.0f,
6407                             texCubeArrayMipmapFloat, evalTextureCubeArrayGradClamp, FRAGMENT),
6408         GRADCLAMP_CASE_SPEC(isamplercubearray, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, -0.5f),
6409                             Vec4(1.0f, 1.0f, 1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6410                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 4.0f,
6411                             texCubeArrayMipmapInt, evalTextureCubeArrayGradClamp, FRAGMENT),
6412         GRADCLAMP_CASE_SPEC(usamplercubearray, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, -0.5f),
6413                             Vec4(1.0f, 1.0f, -1.01f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6414                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), 4.0f,
6415                             texCubeArrayMipmapUint, evalTextureCubeArrayGradClamp, FRAGMENT),
6416 
6417         GRADCLAMP_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6418                             Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6419                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex2DMipmapShadow,
6420                             evalTexture2DShadowGradClamp, FRAGMENT),
6421         GRADCLAMP_CASE_SPEC(samplercubeshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
6422                             Vec4(1.0f, 1.0f, 1.01f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f),
6423                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, texCubeMipmapShadow,
6424                             evalTextureCubeShadowGradClamp, FRAGMENT),
6425         GRADCLAMP_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6426                             Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6427                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), false, IVec3(0), 5.0f,
6428                             tex2DArrayMipmapShadow, evalTexture2DArrayShadowGradClamp, FRAGMENT),
6429         GRADCLAMP_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6430                             Vec4(1.5f, 0.0f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6431                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), 5.0f, tex1DMipmapShadow,
6432                             evalTexture1DShadowGradClamp, FRAGMENT),
6433         GRADCLAMP_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6434                             Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6435                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), 5.0f,
6436                             tex1DArrayMipmapShadow, evalTexture1DArrayShadowGradClamp, FRAGMENT),
6437     };
6438     createCaseGroup(this, "texturegradclamp", textureGradClampCases, DE_LENGTH_OF_ARRAY(textureGradClampCases));
6439 
6440     // textureGradOffset() cases
6441     static TexFuncCaseSpec textureGradOffsetCases[] = {
6442         //          Name                            Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset                Format                            EvalFunc                            Flags
6443         GRAD_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6444                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6445                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset,
6446                        evalTexture2DGradOffset, BOTH),
6447         GRAD_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6448                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6449                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
6450                        evalTexture2DGradOffset, BOTH),
6451         GRAD_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
6452                        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),
6453                        true, IVec3(-8, 7, 0), tex2DMipmapIntOffset, evalTexture2DGradOffset, BOTH),
6454         GRAD_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
6455                        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),
6456                        true, IVec3(7, -8, 0), tex2DMipmapUintOffset, evalTexture2DGradOffset, BOTH),
6457 
6458         GRAD_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6459                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6460                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0),
6461                        tex2DArrayMipmapFixedOffset, evalTexture2DArrayGradOffset, BOTH),
6462         GRAD_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6463                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6464                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0),
6465                        tex2DArrayMipmapFloatOffset, evalTexture2DArrayGradOffset, BOTH),
6466         GRAD_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6467                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6468                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0),
6469                        tex2DArrayMipmapIntOffset, evalTexture2DArrayGradOffset, BOTH),
6470         GRAD_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6471                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6472                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0),
6473                        tex2DArrayMipmapUintOffset, evalTexture2DArrayGradOffset, BOTH),
6474 
6475         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6476                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6477                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapFixedOffset,
6478                        evalTexture3DGradOffset, BOTH),
6479         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6480                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6481                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapFloatOffset,
6482                        evalTexture3DGradOffset, VERTEX),
6483         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6484                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6485                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(3, -8, 7), tex3DMipmapFloatOffset,
6486                        evalTexture3DGradOffset, FRAGMENT),
6487         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6488                        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),
6489                        true, IVec3(-8, 7, 3), tex3DMipmapIntOffset, evalTexture3DGradOffset, BOTH),
6490         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6491                        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),
6492                        true, IVec3(7, 3, -8), tex3DMipmapUintOffset, evalTexture3DGradOffset, VERTEX),
6493         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
6494                        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),
6495                        true, IVec3(3, -8, 7), tex3DMipmapUintOffset, evalTexture3DGradOffset, FRAGMENT),
6496 
6497         GRAD_CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6498                        Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6499                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), tex1DMipmapFixedOffset,
6500                        evalTexture1DGradOffset, BOTH),
6501         GRAD_CASE_SPEC(sampler1d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6502                        Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6503                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0), tex1DMipmapFloatOffset,
6504                        evalTexture1DGradOffset, BOTH),
6505         GRAD_CASE_SPEC(isampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
6506                        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),
6507                        true, IVec3(-8, 0, 0), tex1DMipmapIntOffset, evalTexture1DGradOffset, BOTH),
6508         GRAD_CASE_SPEC(usampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f), Vec4(1.5f, 0.0f, 0.0f, 0.0f),
6509                        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),
6510                        true, IVec3(7, 0, 0), tex1DMipmapUintOffset, evalTexture1DGradOffset, BOTH),
6511 
6512         GRAD_CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6513                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6514                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 0, 0),
6515                        tex1DArrayMipmapFixedOffset, evalTexture1DArrayGradOffset, BOTH),
6516         GRAD_CASE_SPEC(sampler1darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6517                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6518                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0),
6519                        tex1DArrayMipmapFloatOffset, evalTexture1DArrayGradOffset, BOTH),
6520         GRAD_CASE_SPEC(isampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6521                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6522                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 0, 0),
6523                        tex1DArrayMipmapIntOffset, evalTexture1DArrayGradOffset, BOTH),
6524         GRAD_CASE_SPEC(usampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6525                        Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6526                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(7, 0, 0), tex1DArrayMipmapUintOffset,
6527                        evalTexture1DArrayGradOffset, BOTH),
6528 
6529         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6530                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6531                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapShadowOffset,
6532                        evalTexture2DShadowGradOffset, VERTEX),
6533         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6534                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f),
6535                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapShadowOffset,
6536                        evalTexture2DShadowGradOffset, FRAGMENT),
6537         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6538                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6539                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0),
6540                        tex2DArrayMipmapShadowOffset, evalTexture2DArrayShadowGradOffset, VERTEX),
6541         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6542                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6543                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), true, IVec3(7, -8, 0),
6544                        tex2DArrayMipmapShadowOffset, evalTexture2DArrayShadowGradOffset, FRAGMENT),
6545         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6546                        Vec4(1.5f, 0.0f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6547                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), tex1DMipmapShadowOffset,
6548                        evalTexture1DShadowGradOffset, VERTEX),
6549         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6550                        Vec4(1.5f, 0.0f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6551                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0), tex1DMipmapShadowOffset,
6552                        evalTexture1DShadowGradOffset, FRAGMENT),
6553         GRAD_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6554                        Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6555                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(-8, 0, 0),
6556                        tex1DArrayMipmapShadowOffset, evalTexture1DArrayShadowGradOffset, VERTEX),
6557         GRAD_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6558                        Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6559                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(7, 0, 0),
6560                        tex1DArrayMipmapShadowOffset, evalTexture1DArrayShadowGradOffset, FRAGMENT),
6561     };
6562 
6563     {
6564         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "texturegradoffset");
6565         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
6566         {
6567             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureGradOffsetCases); ++j)
6568             {
6569                 textureGradOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
6570                 textureGradOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
6571                 textureGradOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
6572             }
6573             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureGradOffsetCases,
6574                             DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
6575         }
6576         addChild(offsetGroup);
6577     }
6578 
6579     // textureGradOffsetClampARB() cases
6580     static TexFuncCaseSpec textureGradOffsetClampCases[] = {
6581         //          Name                                Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset                LodClamp    Format                            EvalFunc                                    Flags
6582         GRADCLAMP_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6583                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6584                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), 5.0f,
6585                             tex2DMipmapFixedOffset, evalTexture2DGradOffsetClamp, FRAGMENT),
6586         GRADCLAMP_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6587                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6588                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6589                             tex2DMipmapFloatOffset, evalTexture2DGradOffsetClamp, FRAGMENT),
6590         GRADCLAMP_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6591                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6592                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), 5.0f,
6593                             tex2DMipmapIntOffset, evalTexture2DGradOffsetClamp, FRAGMENT),
6594         GRADCLAMP_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6595                             Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6596                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6597                             tex2DMipmapUintOffset, evalTexture2DGradOffsetClamp, FRAGMENT),
6598 
6599         GRADCLAMP_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6600                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6601                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), 5.0f,
6602                             tex2DArrayMipmapFixedOffset, evalTexture2DArrayGradOffsetClamp, FRAGMENT),
6603         GRADCLAMP_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6604                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6605                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6606                             tex2DArrayMipmapFloatOffset, evalTexture2DArrayGradOffsetClamp, FRAGMENT),
6607         GRADCLAMP_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6608                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6609                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), 5.0f,
6610                             tex2DArrayMipmapIntOffset, evalTexture2DArrayGradOffsetClamp, FRAGMENT),
6611         GRADCLAMP_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6612                             Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6613                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6614                             tex2DArrayMipmapUintOffset, evalTexture2DArrayGradOffsetClamp, FRAGMENT),
6615 
6616         GRADCLAMP_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6617                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6618                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), 5.0f,
6619                             tex3DMipmapFixedOffset, evalTexture3DGradOffsetClamp, FRAGMENT),
6620         GRADCLAMP_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6621                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6622                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(3, -8, 7), 5.0f,
6623                             tex3DMipmapFloatOffset, evalTexture3DGradOffsetClamp, FRAGMENT),
6624         GRADCLAMP_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6625                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6626                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), 5.0f,
6627                             tex3DMipmapIntOffset, evalTexture3DGradOffsetClamp, FRAGMENT),
6628         GRADCLAMP_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
6629                             Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6630                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), true, IVec3(3, -8, 7), 5.0f,
6631                             tex3DMipmapUintOffset, evalTexture3DGradOffsetClamp, FRAGMENT),
6632 
6633         GRADCLAMP_CASE_SPEC(sampler1d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6634                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6635                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), 5.0f,
6636                             tex1DMipmapFixedOffset, evalTexture1DGradOffsetClamp, FRAGMENT),
6637         GRADCLAMP_CASE_SPEC(sampler1d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6638                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6639                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6640                             tex1DMipmapFloatOffset, evalTexture1DGradOffsetClamp, FRAGMENT),
6641         GRADCLAMP_CASE_SPEC(isampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6642                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6643                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), 5.0f,
6644                             tex1DMipmapIntOffset, evalTexture1DGradOffsetClamp, FRAGMENT),
6645         GRADCLAMP_CASE_SPEC(usampler1d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6646                             Vec4(1.5f, 0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6647                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6648                             tex1DMipmapUintOffset, evalTexture1DGradOffsetClamp, FRAGMENT),
6649 
6650         GRADCLAMP_CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6651                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6652                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), 5.0f,
6653                             tex1DArrayMipmapFixedOffset, evalTexture1DArrayGradOffsetClamp, FRAGMENT),
6654         GRADCLAMP_CASE_SPEC(sampler1darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6655                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6656                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6657                             tex1DArrayMipmapFloatOffset, evalTexture1DArrayGradOffsetClamp, FRAGMENT),
6658         GRADCLAMP_CASE_SPEC(isampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6659                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6660                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 0, 0), 5.0f,
6661                             tex1DArrayMipmapIntOffset, evalTexture1DArrayGradOffsetClamp, FRAGMENT),
6662         GRADCLAMP_CASE_SPEC(usampler1darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6663                             Vec4(1.5f, 3.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6664                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6665                             tex1DArrayMipmapUintOffset, evalTexture1DArrayGradOffsetClamp, FRAGMENT),
6666 
6667         GRADCLAMP_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
6668                             Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f),
6669                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6670                             tex2DMipmapShadowOffset, evalTexture2DShadowGradOffsetClamp, FRAGMENT),
6671         GRADCLAMP_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
6672                             Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6673                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), true, IVec3(7, -8, 0), 5.0f,
6674                             tex2DArrayMipmapShadowOffset, evalTexture2DArrayShadowGradOffsetClamp, FRAGMENT),
6675         GRADCLAMP_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, 0.0f, 0.0f, 0.0f),
6676                             Vec4(1.5f, 0.0f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6677                             Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6678                             tex1DMipmapShadowOffset, evalTexture1DShadowGradOffsetClamp, FRAGMENT),
6679         GRADCLAMP_CASE_SPEC(sampler1darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.5f, 0.0f, 0.0f),
6680                             Vec4(1.5f, 3.5f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6681                             Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(7, 0, 0), 5.0f,
6682                             tex1DArrayMipmapShadowOffset, evalTexture1DArrayShadowGradOffsetClamp, FRAGMENT),
6683     };
6684 
6685     {
6686         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "texturegradoffsetclamp");
6687         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
6688         {
6689             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureGradOffsetClampCases); ++j)
6690             {
6691                 textureGradOffsetClampCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
6692                 textureGradOffsetClampCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
6693                 textureGradOffsetClampCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
6694             }
6695             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureGradOffsetClampCases,
6696                             DE_LENGTH_OF_ARRAY(textureGradOffsetClampCases));
6697         }
6698         addChild(offsetGroup);
6699     }
6700 
6701     // textureProjGrad() cases
6702     static const TexFuncCaseSpec textureProjGradCases[] = {
6703         //          Name                            Function                    MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset        Format                    EvalFunc                    Flags
6704         GRAD_CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6705                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6706                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
6707                        evalTexture2DProjGrad3, BOTH),
6708         GRAD_CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6709                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6710                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
6711                        evalTexture2DProjGrad3, BOTH),
6712         GRAD_CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6713                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6714                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapInt,
6715                        evalTexture2DProjGrad3, BOTH),
6716         GRAD_CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6717                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6718                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DMipmapUint,
6719                        evalTexture2DProjGrad3, BOTH),
6720 
6721         GRAD_CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6722                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6723                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
6724                        evalTexture2DProjGrad, BOTH),
6725         GRAD_CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6726                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6727                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
6728                        evalTexture2DProjGrad, BOTH),
6729         GRAD_CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6730                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6731                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapInt,
6732                        evalTexture2DProjGrad, BOTH),
6733         GRAD_CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6734                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6735                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DMipmapUint,
6736                        evalTexture2DProjGrad, BOTH),
6737 
6738         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6739                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6740                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFixed,
6741                        evalTexture3DProjGrad, BOTH),
6742         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6743                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6744                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
6745                        evalTexture3DProjGrad, VERTEX),
6746         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6747                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6748                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
6749                        evalTexture3DProjGrad, FRAGMENT),
6750         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6751                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6752                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapInt,
6753                        evalTexture3DProjGrad, BOTH),
6754         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6755                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6756                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex3DMipmapUint,
6757                        evalTexture3DProjGrad, VERTEX),
6758         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6759                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6760                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), false, IVec3(0), tex3DMipmapUint,
6761                        evalTexture3DProjGrad, FRAGMENT),
6762 
6763         GRAD_CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6764                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6765                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFixed,
6766                        evalTexture1DProjGrad2, BOTH),
6767         GRAD_CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6768                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6769                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFloat,
6770                        evalTexture1DProjGrad2, BOTH),
6771         GRAD_CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6772                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6773                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapInt,
6774                        evalTexture1DProjGrad2, BOTH),
6775         GRAD_CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6776                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6777                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapUint,
6778                        evalTexture1DProjGrad2, BOTH),
6779 
6780         GRAD_CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6781                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6782                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFixed,
6783                        evalTexture1DProjGrad, BOTH),
6784         GRAD_CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6785                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6786                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapFloat,
6787                        evalTexture1DProjGrad, BOTH),
6788         GRAD_CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6789                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6790                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapInt,
6791                        evalTexture1DProjGrad, BOTH),
6792         GRAD_CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6793                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6794                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapUint,
6795                        evalTexture1DProjGrad, BOTH),
6796 
6797         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
6798                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6799                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
6800                        evalTexture2DShadowProjGrad, VERTEX),
6801         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
6802                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6803                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
6804                        evalTexture2DShadowProjGrad, FRAGMENT),
6805         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.0f, 0.0f, -1.5f),
6806                        Vec4(-2.25f, 0.0f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6807                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapShadow,
6808                        evalTexture1DShadowProjGrad, VERTEX),
6809         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.0f, 0.0f, -1.5f),
6810                        Vec4(-2.25f, 0.0f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6811                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex1DMipmapShadow,
6812                        evalTexture1DShadowProjGrad, FRAGMENT),
6813     };
6814     createCaseGroup(this, "textureprojgrad", textureProjGradCases, DE_LENGTH_OF_ARRAY(textureProjGradCases));
6815 
6816     // textureProjGradOffset() cases
6817     static TexFuncCaseSpec textureProjGradOffsetCases[] = {
6818         //          Name                            Function                    MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset                Format                        EvalFunc                            Flags
6819         GRAD_CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6820                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6821                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset,
6822                        evalTexture2DProjGrad3Offset, BOTH),
6823         GRAD_CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6824                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6825                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
6826                        evalTexture2DProjGrad3Offset, BOTH),
6827         GRAD_CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6828                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6829                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapIntOffset,
6830                        evalTexture2DProjGrad3Offset, BOTH),
6831         GRAD_CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
6832                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6833                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapUintOffset,
6834                        evalTexture2DProjGrad3Offset, BOTH),
6835 
6836         GRAD_CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6837                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6838                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixedOffset,
6839                        evalTexture2DProjGradOffset, BOTH),
6840         GRAD_CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6841                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6842                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloatOffset,
6843                        evalTexture2DProjGradOffset, BOTH),
6844         GRAD_CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6845                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6846                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapIntOffset,
6847                        evalTexture2DProjGradOffset, BOTH),
6848         GRAD_CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
6849                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6850                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapUintOffset,
6851                        evalTexture2DProjGradOffset, BOTH),
6852 
6853         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6854                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6855                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapFixedOffset,
6856                        evalTexture3DProjGradOffset, BOTH),
6857         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6858                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
6859                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapFloatOffset,
6860                        evalTexture3DProjGradOffset, VERTEX),
6861         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6862                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
6863                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(3, -8, 7), tex3DMipmapFloatOffset,
6864                        evalTexture3DProjGradOffset, FRAGMENT),
6865         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6866                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6867                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapIntOffset,
6868                        evalTexture3DProjGradOffset, BOTH),
6869         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6870                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6871                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapUintOffset,
6872                        evalTexture3DProjGradOffset, VERTEX),
6873         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
6874                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6875                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), true, IVec3(3, -8, 7), tex3DMipmapUintOffset,
6876                        evalTexture3DProjGradOffset, FRAGMENT),
6877 
6878         GRAD_CASE_SPEC(sampler1d_vec2_fixed, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6879                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6880                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex1DMipmapFixedOffset,
6881                        evalTexture1DProjGrad2Offset, BOTH),
6882         GRAD_CASE_SPEC(sampler1d_vec2_float, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6883                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6884                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex1DMipmapFloatOffset,
6885                        evalTexture1DProjGrad2Offset, BOTH),
6886         GRAD_CASE_SPEC(isampler1d_vec2, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6887                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6888                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex1DMipmapIntOffset,
6889                        evalTexture1DProjGrad2Offset, BOTH),
6890         GRAD_CASE_SPEC(usampler1d_vec2, FUNCTION_TEXTUREPROJGRAD2, Vec4(-0.3f, 1.5f, 0.0f, 0.0f),
6891                        Vec4(2.25f, 1.5f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6892                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex1DMipmapUintOffset,
6893                        evalTexture1DProjGrad2Offset, BOTH),
6894 
6895         GRAD_CASE_SPEC(sampler1d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6896                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6897                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex1DMipmapFixedOffset,
6898                        evalTexture1DProjGradOffset, BOTH),
6899         GRAD_CASE_SPEC(sampler1d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6900                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f),
6901                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex1DMipmapFloatOffset,
6902                        evalTexture1DProjGradOffset, BOTH),
6903         GRAD_CASE_SPEC(isampler1d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6904                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6905                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex1DMipmapIntOffset,
6906                        evalTexture1DProjGradOffset, BOTH),
6907         GRAD_CASE_SPEC(usampler1d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, 0.0f, 0.0f, 1.5f),
6908                        Vec4(2.25f, 0.0f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6909                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex1DMipmapUintOffset,
6910                        evalTexture1DProjGradOffset, BOTH),
6911 
6912         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
6913                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6914                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapShadowOffset,
6915                        evalTexture2DShadowProjGradOffset, VERTEX),
6916         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
6917                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6918                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapShadowOffset,
6919                        evalTexture2DShadowProjGradOffset, FRAGMENT),
6920         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.0f, 0.0f, -1.5f),
6921                        Vec4(-2.25f, 0.0f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
6922                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex1DMipmapShadowOffset,
6923                        evalTexture1DShadowProjGradOffset, VERTEX),
6924         GRAD_CASE_SPEC(sampler1dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.0f, 0.0f, -1.5f),
6925                        Vec4(-2.25f, 0.0f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
6926                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex1DMipmapShadowOffset,
6927                        evalTexture1DShadowProjGradOffset, FRAGMENT),
6928     };
6929 
6930     {
6931         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "textureprojgradoffset");
6932         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
6933         {
6934             for (int j = 0; j < DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases); ++j)
6935             {
6936                 textureProjGradOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
6937                 textureProjGradOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
6938                 textureProjGradOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
6939             }
6940             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, textureProjGradOffsetCases,
6941                             DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
6942         }
6943         addChild(offsetGroup);
6944     }
6945 
6946     // texelFetch() cases
6947     // \note Level is constant across quad
6948     static const TexFuncCaseSpec texelFetchCases[] = {
6949         //          Name                            Function                MinCoord                            MaxCoord                        Bias?    MinLod    MaxLod    Offset?    Offset        Format                        EvalFunc                Flags
6950         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(255.9f, 255.9f, 0.0f, 0.0f),
6951                   false, 0.0f, 0.0f, false, IVec3(0), tex2DTexelFetchFixed, evalTexelFetch2D, BOTH),
6952         CASE_SPEC(sampler2d_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(127.9f, 127.9f, 0.0f, 0.0f),
6953                   false, 1.0f, 1.0f, false, IVec3(0), tex2DTexelFetchFloat, evalTexelFetch2D, BOTH),
6954         CASE_SPEC(isampler2d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 63.9f, 0.0f, 0.0f), false,
6955                   2.0f, 2.0f, false, IVec3(0), tex2DTexelFetchInt, evalTexelFetch2D, BOTH),
6956         CASE_SPEC(usampler2d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 15.9f, 0.0f, 0.0f), false,
6957                   4.0f, 4.0f, false, IVec3(0), tex2DTexelFetchUint, evalTexelFetch2D, BOTH),
6958 
6959         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6960                   Vec4(127.9f, 127.9f, 3.9f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayTexelFetchFixed,
6961                   evalTexelFetch2DArray, BOTH),
6962         CASE_SPEC(sampler2darray_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6963                   Vec4(63.9f, 63.9f, 3.9f, 0.0f), false, 1.0f, 1.0f, false, IVec3(0), tex2DArrayTexelFetchFloat,
6964                   evalTexelFetch2DArray, BOTH),
6965         CASE_SPEC(isampler2darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(31.9f, 31.9f, 3.9f, 0.0f),
6966                   false, 2.0f, 2.0f, false, IVec3(0), tex2DArrayTexelFetchInt, evalTexelFetch2DArray, BOTH),
6967         CASE_SPEC(usampler2darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 15.9f, 3.9f, 0.0f),
6968                   false, 3.0f, 3.0f, false, IVec3(0), tex2DArrayTexelFetchUint, evalTexelFetch2DArray, BOTH),
6969 
6970         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 31.9f, 31.9f, 0.0f),
6971                   false, 0.0f, 0.0f, false, IVec3(0), tex3DTexelFetchFixed, evalTexelFetch3D, BOTH),
6972         CASE_SPEC(sampler3d_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(31.9f, 15.9f, 15.9f, 0.0f),
6973                   false, 1.0f, 1.0f, false, IVec3(0), tex3DTexelFetchFloat, evalTexelFetch3D, BOTH),
6974         CASE_SPEC(isampler3d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 7.9f, 7.9f, 0.0f), false,
6975                   2.0f, 2.0f, false, IVec3(0), tex3DTexelFetchInt, evalTexelFetch3D, BOTH),
6976         CASE_SPEC(usampler3d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 31.9f, 31.9f, 0.0f), false,
6977                   0.0f, 0.0f, false, IVec3(0), tex3DTexelFetchUint, evalTexelFetch3D, BOTH),
6978 
6979         CASE_SPEC(sampler1d_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(255.9f, 0.0f, 0.0f, 0.0f),
6980                   false, 0.0f, 0.0f, false, IVec3(0), tex1DTexelFetchFixed, evalTexelFetch1D, BOTH),
6981         CASE_SPEC(sampler1d_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(127.9f, 0.0f, 0.0f, 0.0f),
6982                   false, 1.0f, 1.0f, false, IVec3(0), tex1DTexelFetchFloat, evalTexelFetch1D, BOTH),
6983         CASE_SPEC(isampler1d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 0.0f, 0.0f, 0.0f), false,
6984                   2.0f, 2.0f, false, IVec3(0), tex1DTexelFetchInt, evalTexelFetch1D, BOTH),
6985         CASE_SPEC(usampler1d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 0.0f, 0.0f, 0.0f), false,
6986                   4.0f, 4.0f, false, IVec3(0), tex1DTexelFetchUint, evalTexelFetch1D, BOTH),
6987 
6988         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6989                   Vec4(255.9f, 3.9f, 0.0f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex1DArrayTexelFetchFixed,
6990                   evalTexelFetch1DArray, BOTH),
6991         CASE_SPEC(sampler1darray_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
6992                   Vec4(127.9f, 3.9f, 0.0f, 0.0f), false, 1.0f, 1.0f, false, IVec3(0), tex1DArrayTexelFetchFloat,
6993                   evalTexelFetch1DArray, BOTH),
6994         CASE_SPEC(isampler1darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 3.9f, 0.0f, 0.0f),
6995                   false, 2.0f, 2.0f, false, IVec3(0), tex1DArrayTexelFetchInt, evalTexelFetch1DArray, BOTH),
6996         CASE_SPEC(usampler1darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 3.9f, 0.0f, 0.0f),
6997                   false, 4.0f, 4.0f, false, IVec3(0), tex1DArrayTexelFetchUint, evalTexelFetch1DArray, BOTH),
6998     };
6999     createCaseGroup(this, "texelfetch", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
7000 
7001     // texelFetchOffset() cases
7002     static TexFuncCaseSpec texelFetchOffsetCases[] = {
7003         //          Name                            Function                MinCoord                        MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                                EvalFunc                Flags
7004         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, 0.0f, 0.0f), Vec4(11.9f, -4.0f, 0.0f, 0.0f),
7005                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DTexelFetchFixedOffset, evalTexelFetch2D, BOTH),
7006         CASE_SPEC(sampler2d_float, FUNCTION_TEXELFETCH, Vec4(-7.9f, 8.0f, 0.0f, 0.0f), Vec4(-6.0f, 9.9f, 0.0f, 0.0f),
7007                   false, 1.0f, 1.0f, true, IVec3(7, -8, 0), tex2DTexelFetchFloatOffset, evalTexelFetch2D, BOTH),
7008         CASE_SPEC(isampler2d, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, 0.0f, 0.0f), Vec4(9.9f, -6.0f, 0.0f, 0.0f), false,
7009                   1.0f, 1.0f, true, IVec3(-8, 7, 0), tex2DTexelFetchIntOffset, evalTexelFetch2D, BOTH),
7010         CASE_SPEC(usampler2d, FUNCTION_TEXELFETCH, Vec4(-7.9f, 8.0f, 0.0f, 0.0f), Vec4(-4.0f, 11.9f, 0.0f, 0.0f), false,
7011                   0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DTexelFetchUintOffset, evalTexelFetch2D, BOTH),
7012 
7013         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, 0.0f, 0.0f),
7014                   Vec4(11.9f, -4.0f, 3.9f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0),
7015                   tex2DArrayTexelFetchFixedOffset, evalTexelFetch2DArray, BOTH),
7016         CASE_SPEC(sampler2darray_float, FUNCTION_TEXELFETCH, Vec4(-7.9f, 8.0f, 0.0f, 0.0f),
7017                   Vec4(-6.0f, 9.9f, 3.9f, 0.0f), false, 1.0f, 1.0f, true, IVec3(7, -8, 0),
7018                   tex2DArrayTexelFetchFloatOffset, evalTexelFetch2DArray, BOTH),
7019         CASE_SPEC(isampler2darray, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, 0.0f, 0.0f), Vec4(9.9f, -6.0f, 3.9f, 0.0f),
7020                   false, 1.0f, 1.0f, true, IVec3(-8, 7, 0), tex2DArrayTexelFetchIntOffset, evalTexelFetch2DArray, BOTH),
7021         CASE_SPEC(usampler2darray, FUNCTION_TEXELFETCH, Vec4(-7.9f, 8.0f, 0.0f, 0.0f), Vec4(-4.0f, 11.9f, 3.9f, 0.0f),
7022                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayTexelFetchUintOffset, evalTexelFetch2DArray,
7023                   BOTH),
7024 
7025         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, -3.0f, 0.0f), Vec4(11.9f, -4.0f, 0.9f, 0.0f),
7026                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DTexelFetchFixedOffset, evalTexelFetch3D, BOTH),
7027         CASE_SPEC(sampler3d_float, FUNCTION_TEXELFETCH, Vec4(-7.9f, -3.9f, 8.0f, 0.0f), Vec4(-6.0f, -2.0f, 9.9f, 0.0f),
7028                   false, 1.0f, 1.0f, true, IVec3(7, 3, -8), tex3DTexelFetchFloatOffset, evalTexelFetch3D, BOTH),
7029         CASE_SPEC(isampler3d, FUNCTION_TEXELFETCH, Vec4(-3.9f, 8.0f, -7.9f, 0.0f), Vec4(-2.0f, 9.9f, -6.0f, 0.0f),
7030                   false, 1.0f, 1.0f, true, IVec3(3, -8, 7), tex3DTexelFetchIntOffset, evalTexelFetch3D, BOTH),
7031         CASE_SPEC(usampler3d, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.9f, -3.9f, 0.0f), Vec4(9.9f, -6.0f, -2.0f, 0.0f),
7032                   false, 1.0f, 1.0f, true, IVec3(-8, 7, 3), tex3DTexelFetchUintOffset, evalTexelFetch3D, BOTH),
7033 
7034         CASE_SPEC(sampler1d_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, 0.0f, 0.0f, 0.0f), Vec4(11.9f, 0.0f, 0.0f, 0.0f),
7035                   false, 0.0f, 0.0f, true, IVec3(-8, 0, 0), tex1DTexelFetchFixedOffset, evalTexelFetch1D, BOTH),
7036         CASE_SPEC(sampler1d_float, FUNCTION_TEXELFETCH, Vec4(-7.9f, 0.0f, 0.0f, 0.0f), Vec4(-6.0f, 0.0f, 0.0f, 0.0f),
7037                   false, 1.0f, 1.0f, true, IVec3(7, 0, 0), tex1DTexelFetchFloatOffset, evalTexelFetch1D, BOTH),
7038         CASE_SPEC(isampler1d, FUNCTION_TEXELFETCH, Vec4(8.0f, 0.0f, 0.0f, 0.0f), Vec4(9.9f, 0.0f, 0.0f, 0.0f), false,
7039                   1.0f, 1.0f, true, IVec3(-8, 0, 0), tex1DTexelFetchIntOffset, evalTexelFetch1D, BOTH),
7040         CASE_SPEC(usampler1d, FUNCTION_TEXELFETCH, Vec4(-7.9f, 0.0f, 0.0f, 0.0f), Vec4(-4.0f, 0.0f, 0.0f, 0.0f), false,
7041                   0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DTexelFetchUintOffset, evalTexelFetch1D, BOTH),
7042 
7043         CASE_SPEC(sampler1darray_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, 0.0f, 0.0f, 0.0f),
7044                   Vec4(11.9f, 3.9f, 0.0f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 0, 0),
7045                   tex1DArrayTexelFetchFixedOffset, evalTexelFetch1DArray, BOTH),
7046         CASE_SPEC(sampler1darray_float, FUNCTION_TEXELFETCH, Vec4(-7.9f, 0.0f, 0.0f, 0.0f),
7047                   Vec4(-6.0f, 3.9f, 0.0f, 0.0f), false, 1.0f, 1.0f, true, IVec3(7, 0, 0),
7048                   tex1DArrayTexelFetchFloatOffset, evalTexelFetch1DArray, BOTH),
7049         CASE_SPEC(isampler1darray, FUNCTION_TEXELFETCH, Vec4(8.0f, 0.0f, 0.0f, 0.0f), Vec4(9.9f, 3.9f, 0.0f, 0.0f),
7050                   false, 1.0f, 1.0f, true, IVec3(-8, 0, 0), tex1DArrayTexelFetchIntOffset, evalTexelFetch1DArray, BOTH),
7051         CASE_SPEC(usampler1darray, FUNCTION_TEXELFETCH, Vec4(-7.9f, 0.0f, 0.0f, 0.0f), Vec4(-4.0f, 3.9f, 0.0f, 0.0f),
7052                   false, 0.0f, 0.0f, true, IVec3(7, 0, 0), tex1DArrayTexelFetchUintOffset, evalTexelFetch1DArray, BOTH),
7053     };
7054 
7055     {
7056         tcu::TestCaseGroup *offsetGroup = new tcu::TestCaseGroup(m_testCtx, "texelfetchoffset");
7057         for (int i = 0; i < DE_LENGTH_OF_ARRAY(wrappingModesForOffset); ++i)
7058         {
7059             for (int j = 0; j < DE_LENGTH_OF_ARRAY(texelFetchOffsetCases); ++j)
7060             {
7061                 texelFetchOffsetCases[j].texSpec.sampler.wrapS = wrappingModesForOffset[i].mode;
7062                 texelFetchOffsetCases[j].texSpec.sampler.wrapT = wrappingModesForOffset[i].mode;
7063                 texelFetchOffsetCases[j].texSpec.sampler.wrapR = wrappingModesForOffset[i].mode;
7064             }
7065             createCaseGroup(offsetGroup, wrappingModesForOffset[i].name, texelFetchOffsetCases,
7066                             DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
7067         }
7068         addChild(offsetGroup);
7069     }
7070 
7071     // texture query functions
7072     {
7073         struct TexQueryFuncCaseSpec
7074         {
7075             const char *name;
7076             const char *samplerName;
7077             TextureSpec textureSpec;
7078         };
7079 
7080         de::MovePtr<tcu::TestCaseGroup> queryGroup(new tcu::TestCaseGroup(m_testCtx, "query"));
7081 
7082         // textureSize() cases
7083         {
7084             const TexQueryFuncCaseSpec textureSizeCases[] = {
7085                 {"sampler2d_fixed", "sampler2D", tex2DFixed},
7086                 {"sampler2d_float", "sampler2D", tex2DFloat},
7087                 {"isampler2d", "isampler2D", tex2DInt},
7088                 {"usampler2d", "usampler2D", tex2DUint},
7089                 {"sampler2dshadow", "sampler2DShadow", tex2DShadow},
7090                 {"sampler3d_fixed", "sampler3D", tex3DFixed},
7091                 {"sampler3d_float", "sampler3D", tex3DFloat},
7092                 {"isampler3d", "isampler3D", tex3DInt},
7093                 {"usampler3d", "usampler3D", tex3DUint},
7094                 {"samplercube_fixed", "samplerCube", texCubeFixed},
7095                 {"samplercube_float", "samplerCube", texCubeFloat},
7096                 {"isamplercube", "isamplerCube", texCubeInt},
7097                 {"usamplercube", "usamplerCube", texCubeUint},
7098                 {"samplercubeshadow", "samplerCubeShadow", texCubeShadow},
7099                 {"sampler2darray_fixed", "sampler2DArray", tex2DArrayFixed},
7100                 {"sampler2darray_float", "sampler2DArray", tex2DArrayFloat},
7101                 {"isampler2darray", "isampler2DArray", tex2DArrayInt},
7102                 {"usampler2darray", "usampler2DArray", tex2DArrayUint},
7103                 {"sampler2darrayshadow", "sampler2DArrayShadow", tex2DArrayShadow},
7104                 {"samplercubearray_fixed", "samplerCubeArray", texCubeArrayFixed},
7105                 {"samplercubearray_float", "samplerCubeArray", texCubeArrayFloat},
7106                 {"isamplercubearray", "isamplerCubeArray", texCubeArrayInt},
7107                 {"usamplercubearray", "usamplerCubeArray", texCubeArrayUint},
7108                 {"samplercubearrayshadow", "samplerCubeArrayShadow", texCubeArrayShadow},
7109                 {"sampler1d_fixed", "sampler1D", tex1DFixed},
7110                 {"sampler1d_float", "sampler1D", tex1DFloat},
7111                 {"isampler1d", "isampler1D", tex1DInt},
7112                 {"usampler1d", "usampler1D", tex1DUint},
7113                 {"sampler1dshadow", "sampler1DShadow", tex1DShadow},
7114                 {"sampler1darray_fixed", "sampler1DArray", tex1DArrayFixed},
7115                 {"sampler1darray_float", "sampler1DArray", tex1DArrayFloat},
7116                 {"isampler1darray", "isampler1DArray", tex1DArrayInt},
7117                 {"usampler1darray", "usampler1DArray", tex1DArrayUint},
7118                 {"sampler1darrayshadow", "sampler1DArrayShadow", tex1DArrayShadow},
7119             };
7120 
7121             de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(m_testCtx, "texturesize"));
7122 
7123             for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
7124             {
7125                 const TexQueryFuncCaseSpec &caseSpec = textureSizeCases[ndx];
7126 
7127                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),
7128                                                      caseSpec.samplerName, caseSpec.textureSpec, true,
7129                                                      QUERYFUNCTION_TEXTURESIZE));
7130                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"),
7131                                                      caseSpec.samplerName, caseSpec.textureSpec, false,
7132                                                      QUERYFUNCTION_TEXTURESIZE));
7133             }
7134 
7135             // additional coverage for textureSize special cases
7136             addFunctionCaseWithPrograms(group.get(), "oob_lod", SpecialCases::textureSizeOOBPrograms,
7137                                         SpecialCases::textureSizeOOBTest);
7138 
7139             queryGroup->addChild(group.release());
7140         }
7141 
7142         // textureSize() cases for multisample textures
7143         {
7144             const TexQueryFuncCaseSpec textureSizeMSCases[] = {
7145                 {"sampler2dms_fixed", "sampler2DMS", tex2DFixed},
7146                 {"sampler2dms_float", "sampler2DMS", tex2DFloat},
7147                 {"isampler2dms", "isampler2DMS", tex2DInt},
7148                 {"usampler2dms", "usampler2DMS", tex2DUint},
7149                 {"sampler2dmsarray_fixed", "sampler2DMSArray", tex2DArrayFixed},
7150                 {"sampler2dmsarray_float", "sampler2DMSArray", tex2DArrayFloat},
7151                 {"isampler2dmsarray", "isampler2DMSArray", tex2DArrayInt},
7152                 {"usampler2dmsarray", "usampler2DMSArray", tex2DArrayUint},
7153             };
7154 
7155             de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(m_testCtx, "texturesizems"));
7156 
7157             for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeMSCases); ++ndx)
7158             {
7159                 const TexQueryFuncCaseSpec &caseSpec = textureSizeMSCases[ndx];
7160 
7161                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),
7162                                                      caseSpec.samplerName, caseSpec.textureSpec, true,
7163                                                      QUERYFUNCTION_TEXTURESIZEMS));
7164                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"),
7165                                                      caseSpec.samplerName, caseSpec.textureSpec, false,
7166                                                      QUERYFUNCTION_TEXTURESIZEMS));
7167             }
7168 
7169             queryGroup->addChild(group.release());
7170         }
7171 
7172         // textureSamples() cases
7173         {
7174             const TexQueryFuncCaseSpec textureSamplesCases[] = {
7175                 {"sampler2dms_fixed", "sampler2DMS", tex2DFixed},
7176                 {"sampler2dms_float", "sampler2DMS", tex2DFloat},
7177                 {"isampler2dms", "isampler2DMS", tex2DInt},
7178                 {"usampler2dms", "usampler2DMS", tex2DUint},
7179                 {"sampler2dmsarray_fixed", "sampler2DMSArray", tex2DArrayFixed},
7180                 {"sampler2dmsarray_float", "sampler2DMSArray", tex2DArrayFloat},
7181                 {"isampler2dmsarray", "isampler2DMSArray", tex2DArrayInt},
7182                 {"usampler2dmsarray", "usampler2DMSArray", tex2DArrayUint},
7183             };
7184 
7185             de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(m_testCtx, "texturesamples"));
7186 
7187             for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSamplesCases); ++ndx)
7188             {
7189                 const TexQueryFuncCaseSpec &caseSpec = textureSamplesCases[ndx];
7190 
7191                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),
7192                                                      caseSpec.samplerName, caseSpec.textureSpec, true,
7193                                                      QUERYFUNCTION_TEXTURESAMPLES));
7194                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"),
7195                                                      caseSpec.samplerName, caseSpec.textureSpec, false,
7196                                                      QUERYFUNCTION_TEXTURESAMPLES));
7197             }
7198 
7199             queryGroup->addChild(group.release());
7200         }
7201 
7202         // textureQueryLevels() cases
7203         {
7204             const TexQueryFuncCaseSpec textureQueryLevelsCases[] = {
7205                 {"sampler2d_fixed", "sampler2D", tex2DFixed},
7206                 {"sampler2d_float", "sampler2D", tex2DFloat},
7207                 {"isampler2d", "isampler2D", tex2DInt},
7208                 {"usampler2d", "usampler2D", tex2DUint},
7209                 {"sampler2dshadow", "sampler2DShadow", tex2DShadow},
7210                 {"sampler3d_fixed", "sampler3D", tex3DFixed},
7211                 {"sampler3d_float", "sampler3D", tex3DFloat},
7212                 {"isampler3d", "isampler3D", tex3DInt},
7213                 {"usampler3d", "usampler3D", tex3DUint},
7214                 {"samplercube_fixed", "samplerCube", texCubeFixed},
7215                 {"samplercube_float", "samplerCube", texCubeFloat},
7216                 {"isamplercube", "isamplerCube", texCubeInt},
7217                 {"usamplercube", "usamplerCube", texCubeUint},
7218                 {"samplercubeshadow", "samplerCubeShadow", texCubeShadow},
7219                 {"sampler2darray_fixed", "sampler2DArray", tex2DArrayFixed},
7220                 {"sampler2darray_float", "sampler2DArray", tex2DArrayFloat},
7221                 {"isampler2darray", "isampler2DArray", tex2DArrayInt},
7222                 {"usampler2darray", "usampler2DArray", tex2DArrayUint},
7223                 {"sampler2darrayshadow", "sampler2DArrayShadow", tex2DArrayShadow},
7224                 {"samplercubearray_fixed", "samplerCubeArray", texCubeArrayFixed},
7225                 {"samplercubearray_float", "samplerCubeArray", texCubeArrayFloat},
7226                 {"isamplercubearray", "isamplerCubeArray", texCubeArrayInt},
7227                 {"usamplercubearray", "usamplerCubeArray", texCubeArrayUint},
7228                 {"samplercubearrayshadow", "samplerCubeArrayShadow", texCubeArrayShadow},
7229                 {"sampler1d_fixed", "sampler1D", tex1DFixed},
7230                 {"sampler1d_float", "sampler1D", tex1DFloat},
7231                 {"isampler1d", "isampler1D", tex1DInt},
7232                 {"usampler1d", "usampler1D", tex1DUint},
7233                 {"sampler1dshadow", "sampler1DShadow", tex1DShadow},
7234                 {"sampler1darray_fixed", "sampler1DArray", tex1DArrayFixed},
7235                 {"sampler1darray_float", "sampler1DArray", tex1DArrayFloat},
7236                 {"isampler1darray", "isampler1DArray", tex1DArrayInt},
7237                 {"usampler1darray", "usampler1DArray", tex1DArrayUint},
7238                 {"sampler1darrayshadow", "sampler1DArrayShadow", tex1DArrayShadow},
7239             };
7240 
7241             de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(m_testCtx, "texturequerylevels"));
7242 
7243             for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLevelsCases); ++ndx)
7244             {
7245                 const TexQueryFuncCaseSpec &caseSpec = textureQueryLevelsCases[ndx];
7246 
7247                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_vertex"),
7248                                                      caseSpec.samplerName, caseSpec.textureSpec, true,
7249                                                      QUERYFUNCTION_TEXTUREQUERYLEVELS));
7250                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"),
7251                                                      caseSpec.samplerName, caseSpec.textureSpec, false,
7252                                                      QUERYFUNCTION_TEXTUREQUERYLEVELS));
7253             }
7254 
7255             queryGroup->addChild(group.release());
7256         }
7257 
7258         // textureQueryLod() cases
7259         {
7260             const TexQueryFuncCaseSpec textureQueryLodCases[] = {
7261                 {"sampler2d_fixed", "sampler2D", tex2DMipmapFixed},
7262                 {"sampler2d_float", "sampler2D", tex2DMipmapFloat},
7263                 {"isampler2d", "isampler2D", tex2DMipmapInt},
7264                 {"usampler2d", "usampler2D", tex2DMipmapUint},
7265                 {"sampler2dshadow", "sampler2DShadow", tex2DMipmapShadow},
7266                 {"sampler3d_fixed", "sampler3D", tex3DMipmapFixed},
7267                 {"sampler3d_float", "sampler3D", tex3DMipmapFloat},
7268                 {"isampler3d", "isampler3D", tex3DMipmapInt},
7269                 {"usampler3d", "usampler3D", tex3DMipmapUint},
7270                 {"samplercube_fixed", "samplerCube", texCubeMipmapFixed},
7271                 {"samplercube_float", "samplerCube", texCubeMipmapFloat},
7272                 {"isamplercube", "isamplerCube", texCubeMipmapInt},
7273                 {"usamplercube", "usamplerCube", texCubeMipmapUint},
7274                 {"samplercubeshadow", "samplerCubeShadow", texCubeMipmapShadow},
7275                 {"sampler2darray_fixed", "sampler2DArray", tex2DArrayMipmapFixed},
7276                 {"sampler2darray_float", "sampler2DArray", tex2DArrayMipmapFloat},
7277                 {"isampler2darray", "isampler2DArray", tex2DArrayMipmapInt},
7278                 {"usampler2darray", "usampler2DArray", tex2DArrayMipmapUint},
7279                 {"sampler2darrayshadow", "sampler2DArrayShadow", tex2DArrayMipmapShadow},
7280                 {"samplercubearray_fixed", "samplerCubeArray", texCubeArrayMipmapFixed},
7281                 {"samplercubearray_float", "samplerCubeArray", texCubeArrayMipmapFloat},
7282                 {"isamplercubearray", "isamplerCubeArray", texCubeArrayMipmapInt},
7283                 {"usamplercubearray", "usamplerCubeArray", texCubeArrayMipmapUint},
7284                 {"samplercubearrayshadow", "samplerCubeArrayShadow", texCubeArrayMipmapShadow},
7285                 {"sampler1d_fixed", "sampler1D", tex1DMipmapFixed},
7286                 {"sampler1d_float", "sampler1D", tex1DMipmapFloat},
7287                 {"isampler1d", "isampler1D", tex1DMipmapInt},
7288                 {"usampler1d", "usampler1D", tex1DMipmapUint},
7289                 {"sampler1dshadow", "sampler1DShadow", tex1DMipmapShadow},
7290                 {"sampler1darray_fixed", "sampler1DArray", tex1DArrayMipmapFixed},
7291                 {"sampler1darray_float", "sampler1DArray", tex1DArrayMipmapFloat},
7292                 {"isampler1darray", "isampler1DArray", tex1DArrayMipmapInt},
7293                 {"usampler1darray", "usampler1DArray", tex1DArrayMipmapUint},
7294                 {"sampler1darrayshadow", "sampler1DArrayShadow", tex1DArrayMipmapShadow},
7295             };
7296 
7297             de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(m_testCtx, "texturequerylod"));
7298 
7299             for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureQueryLodCases); ++ndx)
7300             {
7301                 const TexQueryFuncCaseSpec &caseSpec = textureQueryLodCases[ndx];
7302 
7303                 // available only in fragment shader
7304                 group->addChild(new TextureQueryCase(m_testCtx, (std::string(caseSpec.name) + "_fragment"),
7305                                                      caseSpec.samplerName, caseSpec.textureSpec, false,
7306                                                      QUERYFUNCTION_TEXTUREQUERYLOD));
7307                 group->addChild(new TextureQueryCase(
7308                     m_testCtx, (std::string(caseSpec.name) + "_zero_uv_width_fragment"), caseSpec.samplerName,
7309                     caseSpec.textureSpec, false, QUERYFUNCTION_TEXTUREQUERYLOD, QLODTM_ZERO_UV_WIDTH));
7310             }
7311 
7312             queryGroup->addChild(group.release());
7313         }
7314 
7315         addChild(queryGroup.release());
7316     }
7317 }
7318 
7319 } // namespace
7320 
createTextureFunctionTests(tcu::TestContext & testCtx)7321 tcu::TestCaseGroup *createTextureFunctionTests(tcu::TestContext &testCtx)
7322 {
7323     return new ShaderTextureFunctionTests(testCtx);
7324 }
7325 
7326 } // namespace sr
7327 } // namespace vkt
7328