xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fShaderTextureFunctionTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture access function tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fShaderTextureFunctionTests.hpp"
25 #include "glsShaderRenderCase.hpp"
26 #include "glsShaderLibrary.hpp"
27 #include "glsTextureTestUtil.hpp"
28 #include "gluTexture.hpp"
29 #include "gluTextureUtil.hpp"
30 #include "gluPixelTransfer.hpp"
31 #include "gluStrUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuMatrix.hpp"
34 #include "tcuMatrixUtil.hpp"
35 #include "tcuTestLog.hpp"
36 #include "glwFunctions.hpp"
37 #include "deMath.h"
38 
39 #include <sstream>
40 
41 #include "glwEnums.hpp"
42 #include "glwFunctions.hpp"
43 
44 namespace deqp
45 {
46 namespace gles3
47 {
48 namespace Functional
49 {
50 
51 namespace
52 {
53 
54 using glu::TextureTestUtil::computeLodFromDerivates;
55 
56 enum Function
57 {
58     FUNCTION_TEXTURE = 0,  //!< texture(), textureOffset()
59     FUNCTION_TEXTUREPROJ,  //!< textureProj(), textureProjOffset()
60     FUNCTION_TEXTUREPROJ3, //!< textureProj(sampler2D, vec3)
61     FUNCTION_TEXTURELOD,   // ...
62     FUNCTION_TEXTUREPROJLOD,
63     FUNCTION_TEXTUREPROJLOD3, //!< textureProjLod(sampler2D, vec3)
64     FUNCTION_TEXTUREGRAD,
65     FUNCTION_TEXTUREPROJGRAD,
66     FUNCTION_TEXTUREPROJGRAD3, //!< textureProjGrad(sampler2D, vec3)
67     FUNCTION_TEXELFETCH,
68 
69     FUNCTION_LAST
70 };
71 
functionHasAutoLod(glu::ShaderType shaderType,Function function)72 inline bool functionHasAutoLod(glu::ShaderType shaderType, Function function)
73 {
74     return shaderType == glu::SHADERTYPE_FRAGMENT &&
75            (function == FUNCTION_TEXTURE || function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJ3);
76 }
77 
functionHasProj(Function function)78 inline bool functionHasProj(Function function)
79 {
80     return function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJ3 ||
81            function == FUNCTION_TEXTUREPROJLOD || function == FUNCTION_TEXTUREPROJGRAD ||
82            function == FUNCTION_TEXTUREPROJLOD3 || function == FUNCTION_TEXTUREPROJGRAD3;
83 }
84 
functionHasGrad(Function function)85 inline bool functionHasGrad(Function function)
86 {
87     return function == FUNCTION_TEXTUREGRAD || function == FUNCTION_TEXTUREPROJGRAD ||
88            function == FUNCTION_TEXTUREPROJGRAD3;
89 }
90 
functionHasLod(Function function)91 inline bool functionHasLod(Function function)
92 {
93     return function == FUNCTION_TEXTURELOD || function == FUNCTION_TEXTUREPROJLOD ||
94            function == FUNCTION_TEXTUREPROJLOD3 || function == FUNCTION_TEXELFETCH;
95 }
96 
97 struct TextureLookupSpec
98 {
99     Function function;
100 
101     tcu::Vec4 minCoord;
102     tcu::Vec4 maxCoord;
103 
104     // Bias
105     bool useBias;
106 
107     // Bias or Lod for *Lod* functions
108     float minLodBias;
109     float maxLodBias;
110 
111     // For *Grad* functions
112     tcu::Vec3 minDX;
113     tcu::Vec3 maxDX;
114     tcu::Vec3 minDY;
115     tcu::Vec3 maxDY;
116 
117     bool useOffset;
118     tcu::IVec3 offset;
119 
TextureLookupSpecdeqp::gles3::Functional::__anonffd091fa0111::TextureLookupSpec120     TextureLookupSpec(void)
121         : function(FUNCTION_LAST)
122         , minCoord(0.0f)
123         , maxCoord(1.0f)
124         , useBias(false)
125         , minLodBias(0.0f)
126         , maxLodBias(0.0f)
127         , minDX(0.0f)
128         , maxDX(0.0f)
129         , minDY(0.0f)
130         , maxDY(0.0f)
131         , useOffset(false)
132         , offset(0)
133     {
134     }
135 
TextureLookupSpecdeqp::gles3::Functional::__anonffd091fa0111::TextureLookupSpec136     TextureLookupSpec(Function function_, const tcu::Vec4 &minCoord_, const tcu::Vec4 &maxCoord_, bool useBias_,
137                       float minLodBias_, float maxLodBias_, const tcu::Vec3 &minDX_, const tcu::Vec3 &maxDX_,
138                       const tcu::Vec3 &minDY_, const tcu::Vec3 &maxDY_, bool useOffset_, const tcu::IVec3 &offset_)
139         : function(function_)
140         , minCoord(minCoord_)
141         , maxCoord(maxCoord_)
142         , useBias(useBias_)
143         , minLodBias(minLodBias_)
144         , maxLodBias(maxLodBias_)
145         , minDX(minDX_)
146         , maxDX(maxDX_)
147         , minDY(minDY_)
148         , maxDY(maxDY_)
149         , useOffset(useOffset_)
150         , offset(offset_)
151     {
152     }
153 };
154 
155 enum TextureType
156 {
157     TEXTURETYPE_2D,
158     TEXTURETYPE_CUBE_MAP,
159     TEXTURETYPE_2D_ARRAY,
160     TEXTURETYPE_3D,
161 
162     TEXTURETYPE_LAST
163 };
164 
165 struct TextureSpec
166 {
167     TextureType type; //!< Texture type (2D, cubemap, ...)
168     uint32_t format;  //!< Internal format.
169     int width;
170     int height;
171     int depth;
172     int numLevels;
173     tcu::Sampler sampler;
174 
TextureSpecdeqp::gles3::Functional::__anonffd091fa0111::TextureSpec175     TextureSpec(void) : type(TEXTURETYPE_LAST), format(GL_NONE), width(0), height(0), depth(0), numLevels(0)
176     {
177     }
178 
TextureSpecdeqp::gles3::Functional::__anonffd091fa0111::TextureSpec179     TextureSpec(TextureType type_, uint32_t format_, int width_, int height_, int depth_, int numLevels_,
180                 const tcu::Sampler &sampler_)
181         : type(type_)
182         , format(format_)
183         , width(width_)
184         , height(height_)
185         , depth(depth_)
186         , numLevels(numLevels_)
187         , sampler(sampler_)
188     {
189     }
190 };
191 
192 struct TexLookupParams
193 {
194     float lod;
195     tcu::IVec3 offset;
196     tcu::Vec4 scale;
197     tcu::Vec4 bias;
198 
TexLookupParamsdeqp::gles3::Functional::__anonffd091fa0111::TexLookupParams199     TexLookupParams(void) : lod(0.0f), offset(0), scale(1.0f), bias(0.0f)
200     {
201     }
202 };
203 
204 } // namespace
205 
206 using tcu::IVec2;
207 using tcu::IVec3;
208 using tcu::IVec4;
209 using tcu::Vec2;
210 using tcu::Vec3;
211 using tcu::Vec4;
212 
213 static const glu::TextureTestUtil::LodMode DEFAULT_LOD_MODE = glu::TextureTestUtil::LODMODE_EXACT;
214 
computeLodFromGrad2D(const gls::ShaderEvalContext & c)215 inline float computeLodFromGrad2D(const gls::ShaderEvalContext &c)
216 {
217     float w = (float)c.textures[0].tex2D->getWidth();
218     float h = (float)c.textures[0].tex2D->getHeight();
219     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[1].y() * h, c.in[2].x() * w,
220                                    c.in[2].y() * h);
221 }
222 
computeLodFromGrad2DArray(const gls::ShaderEvalContext & c)223 inline float computeLodFromGrad2DArray(const gls::ShaderEvalContext &c)
224 {
225     float w = (float)c.textures[0].tex2DArray->getWidth();
226     float h = (float)c.textures[0].tex2DArray->getHeight();
227     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * w, c.in[1].y() * h, c.in[2].x() * w,
228                                    c.in[2].y() * h);
229 }
230 
computeLodFromGrad3D(const gls::ShaderEvalContext & c)231 inline float computeLodFromGrad3D(const gls::ShaderEvalContext &c)
232 {
233     float w = (float)c.textures[0].tex3D->getWidth();
234     float h = (float)c.textures[0].tex3D->getHeight();
235     float d = (float)c.textures[0].tex3D->getDepth();
236     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,
237                                    c.in[2].y() * h, c.in[2].z() * d);
238 }
239 
computeLodFromGradCube(const gls::ShaderEvalContext & c)240 inline float computeLodFromGradCube(const gls::ShaderEvalContext &c)
241 {
242     // \note Major axis is always -Z or +Z
243     float m = de::abs(c.in[0].z());
244     float d = (float)c.textures[0].texCube->getSize();
245     float s = d / (2.0f * m);
246     float t = d / (2.0f * m);
247     return computeLodFromDerivates(DEFAULT_LOD_MODE, c.in[1].x() * s, c.in[1].y() * t, c.in[2].x() * s,
248                                    c.in[2].y() * t);
249 }
250 
251 typedef void (*TexEvalFunc)(gls::ShaderEvalContext &c, const TexLookupParams &lookupParams);
252 
texture2D(const gls::ShaderEvalContext & c,float s,float t,float lod)253 inline Vec4 texture2D(const gls::ShaderEvalContext &c, float s, float t, float lod)
254 {
255     return c.textures[0].tex2D->sample(c.textures[0].sampler, s, t, lod);
256 }
textureCube(const gls::ShaderEvalContext & c,float s,float t,float r,float lod)257 inline Vec4 textureCube(const gls::ShaderEvalContext &c, float s, float t, float r, float lod)
258 {
259     return c.textures[0].texCube->sample(c.textures[0].sampler, s, t, r, lod);
260 }
texture2DArray(const gls::ShaderEvalContext & c,float s,float t,float r,float lod)261 inline Vec4 texture2DArray(const gls::ShaderEvalContext &c, float s, float t, float r, float lod)
262 {
263     return c.textures[0].tex2DArray->sample(c.textures[0].sampler, s, t, r, lod);
264 }
texture3D(const gls::ShaderEvalContext & c,float s,float t,float r,float lod)265 inline Vec4 texture3D(const gls::ShaderEvalContext &c, float s, float t, float r, float lod)
266 {
267     return c.textures[0].tex3D->sample(c.textures[0].sampler, s, t, r, lod);
268 }
269 
texture2DShadow(const gls::ShaderEvalContext & c,float ref,float s,float t,float lod)270 inline float texture2DShadow(const gls::ShaderEvalContext &c, float ref, float s, float t, float lod)
271 {
272     return c.textures[0].tex2D->sampleCompare(c.textures[0].sampler, ref, s, t, lod);
273 }
textureCubeShadow(const gls::ShaderEvalContext & c,float ref,float s,float t,float r,float lod)274 inline float textureCubeShadow(const gls::ShaderEvalContext &c, float ref, float s, float t, float r, float lod)
275 {
276     return c.textures[0].texCube->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);
277 }
texture2DArrayShadow(const gls::ShaderEvalContext & c,float ref,float s,float t,float r,float lod)278 inline float texture2DArrayShadow(const gls::ShaderEvalContext &c, float ref, float s, float t, float r, float lod)
279 {
280     return c.textures[0].tex2DArray->sampleCompare(c.textures[0].sampler, ref, s, t, r, lod);
281 }
282 
texture2DOffset(const gls::ShaderEvalContext & c,float s,float t,float lod,IVec2 offset)283 inline Vec4 texture2DOffset(const gls::ShaderEvalContext &c, float s, float t, float lod, IVec2 offset)
284 {
285     return c.textures[0].tex2D->sampleOffset(c.textures[0].sampler, s, t, lod, offset);
286 }
texture2DArrayOffset(const gls::ShaderEvalContext & c,float s,float t,float r,float lod,IVec2 offset)287 inline Vec4 texture2DArrayOffset(const gls::ShaderEvalContext &c, float s, float t, float r, float lod, IVec2 offset)
288 {
289     return c.textures[0].tex2DArray->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);
290 }
texture3DOffset(const gls::ShaderEvalContext & c,float s,float t,float r,float lod,IVec3 offset)291 inline Vec4 texture3DOffset(const gls::ShaderEvalContext &c, float s, float t, float r, float lod, IVec3 offset)
292 {
293     return c.textures[0].tex3D->sampleOffset(c.textures[0].sampler, s, t, r, lod, offset);
294 }
295 
texture2DShadowOffset(const gls::ShaderEvalContext & c,float ref,float s,float t,float lod,IVec2 offset)296 inline float texture2DShadowOffset(const gls::ShaderEvalContext &c, float ref, float s, float t, float lod,
297                                    IVec2 offset)
298 {
299     return c.textures[0].tex2D->sampleCompareOffset(c.textures[0].sampler, ref, s, t, lod, offset);
300 }
texture2DArrayShadowOffset(const gls::ShaderEvalContext & c,float ref,float s,float t,float r,float lod,IVec2 offset)301 inline float texture2DArrayShadowOffset(const gls::ShaderEvalContext &c, float ref, float s, float t, float r,
302                                         float lod, IVec2 offset)
303 {
304     return c.textures[0].tex2DArray->sampleCompareOffset(c.textures[0].sampler, ref, s, t, r, lod, offset);
305 }
306 
307 // Eval functions.
evalTexture2D(gls::ShaderEvalContext & c,const TexLookupParams & p)308 static void evalTexture2D(gls::ShaderEvalContext &c, const TexLookupParams &p)
309 {
310     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod) * p.scale + p.bias;
311 }
evalTextureCube(gls::ShaderEvalContext & c,const TexLookupParams & p)312 static void evalTextureCube(gls::ShaderEvalContext &c, const TexLookupParams &p)
313 {
314     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
315 }
evalTexture2DArray(gls::ShaderEvalContext & c,const TexLookupParams & p)316 static void evalTexture2DArray(gls::ShaderEvalContext &c, const TexLookupParams &p)
317 {
318     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
319 }
evalTexture3D(gls::ShaderEvalContext & c,const TexLookupParams & p)320 static void evalTexture3D(gls::ShaderEvalContext &c, const TexLookupParams &p)
321 {
322     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod) * p.scale + p.bias;
323 }
324 
evalTexture2DBias(gls::ShaderEvalContext & c,const TexLookupParams & p)325 static void evalTexture2DBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
326 {
327     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x()) * p.scale + p.bias;
328 }
evalTextureCubeBias(gls::ShaderEvalContext & c,const TexLookupParams & p)329 static void evalTextureCubeBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
330 {
331     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;
332 }
evalTexture2DArrayBias(gls::ShaderEvalContext & c,const TexLookupParams & p)333 static void evalTexture2DArrayBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
334 {
335     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;
336 }
evalTexture3DBias(gls::ShaderEvalContext & c,const TexLookupParams & p)337 static void evalTexture3DBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
338 {
339     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;
340 }
341 
evalTexture2DProj3(gls::ShaderEvalContext & c,const TexLookupParams & p)342 static void evalTexture2DProj3(gls::ShaderEvalContext &c, const TexLookupParams &p)
343 {
344     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;
345 }
evalTexture2DProj3Bias(gls::ShaderEvalContext & c,const TexLookupParams & p)346 static void evalTexture2DProj3Bias(gls::ShaderEvalContext &c, const TexLookupParams &p)
347 {
348     c.color =
349         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;
350 }
evalTexture2DProj(gls::ShaderEvalContext & c,const TexLookupParams & p)351 static void evalTexture2DProj(gls::ShaderEvalContext &c, const TexLookupParams &p)
352 {
353     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;
354 }
evalTexture2DProjBias(gls::ShaderEvalContext & c,const TexLookupParams & p)355 static void evalTexture2DProjBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
356 {
357     c.color =
358         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;
359 }
evalTexture3DProj(gls::ShaderEvalContext & c,const TexLookupParams & p)360 static void evalTexture3DProj(gls::ShaderEvalContext &c, const TexLookupParams &p)
361 {
362     c.color =
363         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 +
364         p.bias;
365 }
evalTexture3DProjBias(gls::ShaderEvalContext & c,const TexLookupParams & p)366 static void evalTexture3DProjBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
367 {
368     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(),
369                         p.lod + c.in[1].x()) *
370                   p.scale +
371               p.bias;
372 }
373 
evalTexture2DLod(gls::ShaderEvalContext & c,const TexLookupParams & p)374 static void evalTexture2DLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
375 {
376     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), c.in[1].x()) * p.scale + p.bias;
377 }
evalTextureCubeLod(gls::ShaderEvalContext & c,const TexLookupParams & p)378 static void evalTextureCubeLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
379 {
380     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
381 }
evalTexture2DArrayLod(gls::ShaderEvalContext & c,const TexLookupParams & p)382 static void evalTexture2DArrayLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
383 {
384     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
385 }
evalTexture3DLod(gls::ShaderEvalContext & c,const TexLookupParams & p)386 static void evalTexture3DLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
387 {
388     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), c.in[1].x()) * p.scale + p.bias;
389 }
390 
evalTexture2DProjLod3(gls::ShaderEvalContext & c,const TexLookupParams & p)391 static void evalTexture2DProjLod3(gls::ShaderEvalContext &c, const TexLookupParams &p)
392 {
393     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;
394 }
evalTexture2DProjLod(gls::ShaderEvalContext & c,const TexLookupParams & p)395 static void evalTexture2DProjLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
396 {
397     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;
398 }
evalTexture3DProjLod(gls::ShaderEvalContext & c,const TexLookupParams & p)399 static void evalTexture3DProjLod(gls::ShaderEvalContext &c, const TexLookupParams &p)
400 {
401     c.color =
402         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()) *
403             p.scale +
404         p.bias;
405 }
406 
407 // Offset variants
408 
evalTexture2DOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)409 static void evalTexture2DOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
410 {
411     c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0, 1)) * p.scale + p.bias;
412 }
evalTexture2DArrayOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)413 static void evalTexture2DArrayOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
414 {
415     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 +
416               p.bias;
417 }
evalTexture3DOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)418 static void evalTexture3DOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
419 {
420     c.color = texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod, p.offset) * p.scale + p.bias;
421 }
422 
evalTexture2DOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)423 static void evalTexture2DOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
424 {
425     c.color =
426         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;
427 }
evalTexture2DArrayOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)428 static void evalTexture2DArrayOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
429 {
430     c.color =
431         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)) *
432             p.scale +
433         p.bias;
434 }
evalTexture3DOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)435 static void evalTexture3DOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
436 {
437     c.color =
438         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;
439 }
440 
evalTexture2DLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)441 static void evalTexture2DLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
442 {
443     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;
444 }
evalTexture2DArrayLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)445 static void evalTexture2DArrayLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
446 {
447     c.color =
448         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 +
449         p.bias;
450 }
evalTexture3DLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)451 static void evalTexture3DLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
452 {
453     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;
454 }
455 
evalTexture2DProj3Offset(gls::ShaderEvalContext & c,const TexLookupParams & p)456 static void evalTexture2DProj3Offset(gls::ShaderEvalContext &c, const TexLookupParams &p)
457 {
458     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)) *
459                   p.scale +
460               p.bias;
461 }
evalTexture2DProj3OffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)462 static void evalTexture2DProj3OffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
463 {
464     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(),
465                               p.offset.swizzle(0, 1)) *
466                   p.scale +
467               p.bias;
468 }
evalTexture2DProjOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)469 static void evalTexture2DProjOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
470 {
471     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)) *
472                   p.scale +
473               p.bias;
474 }
evalTexture2DProjOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)475 static void evalTexture2DProjOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
476 {
477     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(),
478                               p.offset.swizzle(0, 1)) *
479                   p.scale +
480               p.bias;
481 }
evalTexture3DProjOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)482 static void evalTexture3DProjOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
483 {
484     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,
485                               p.offset) *
486                   p.scale +
487               p.bias;
488 }
evalTexture3DProjOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)489 static void evalTexture3DProjOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
490 {
491     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(),
492                               p.lod + c.in[1].x(), p.offset) *
493                   p.scale +
494               p.bias;
495 }
496 
evalTexture2DProjLod3Offset(gls::ShaderEvalContext & c,const TexLookupParams & p)497 static void evalTexture2DProjLod3Offset(gls::ShaderEvalContext &c, const TexLookupParams &p)
498 {
499     c.color =
500         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)) *
501             p.scale +
502         p.bias;
503 }
evalTexture2DProjLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)504 static void evalTexture2DProjLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
505 {
506     c.color =
507         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)) *
508             p.scale +
509         p.bias;
510 }
evalTexture3DProjLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)511 static void evalTexture3DProjLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
512 {
513     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(),
514                               c.in[1].x(), p.offset) *
515                   p.scale +
516               p.bias;
517 }
518 
519 // Shadow variants
520 
evalTexture2DShadow(gls::ShaderEvalContext & c,const TexLookupParams & p)521 static void evalTexture2DShadow(gls::ShaderEvalContext &c, const TexLookupParams &p)
522 {
523     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod);
524 }
evalTexture2DShadowBias(gls::ShaderEvalContext & c,const TexLookupParams & p)525 static void evalTexture2DShadowBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
526 {
527     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod + c.in[1].x());
528 }
529 
evalTextureCubeShadow(gls::ShaderEvalContext & c,const TexLookupParams & p)530 static void evalTextureCubeShadow(gls::ShaderEvalContext &c, const TexLookupParams &p)
531 {
532     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod);
533 }
evalTextureCubeShadowBias(gls::ShaderEvalContext & c,const TexLookupParams & p)534 static void evalTextureCubeShadowBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
535 {
536     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());
537 }
538 
evalTexture2DArrayShadow(gls::ShaderEvalContext & c,const TexLookupParams & p)539 static void evalTexture2DArrayShadow(gls::ShaderEvalContext &c, const TexLookupParams &p)
540 {
541     c.color.x() = texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), p.lod);
542 }
543 
evalTexture2DShadowLod(gls::ShaderEvalContext & c,const TexLookupParams &)544 static void evalTexture2DShadowLod(gls::ShaderEvalContext &c, const TexLookupParams &)
545 {
546     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), c.in[1].x());
547 }
evalTexture2DShadowLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)548 static void evalTexture2DShadowLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
549 {
550     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));
551 }
552 
evalTexture2DShadowProj(gls::ShaderEvalContext & c,const TexLookupParams & p)553 static void evalTexture2DShadowProj(gls::ShaderEvalContext &c, const TexLookupParams &p)
554 {
555     c.color.x() =
556         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);
557 }
evalTexture2DShadowProjBias(gls::ShaderEvalContext & c,const TexLookupParams & p)558 static void evalTexture2DShadowProjBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
559 {
560     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(),
561                                   p.lod + c.in[1].x());
562 }
563 
evalTexture2DShadowProjLod(gls::ShaderEvalContext & c,const TexLookupParams &)564 static void evalTexture2DShadowProjLod(gls::ShaderEvalContext &c, const TexLookupParams &)
565 {
566     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(),
567                                   c.in[1].x());
568 }
evalTexture2DShadowProjLodOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)569 static void evalTexture2DShadowProjLodOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
570 {
571     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
572                                         c.in[0].y() / c.in[0].w(), c.in[1].x(), p.offset.swizzle(0, 1));
573 }
574 
evalTexture2DShadowOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)575 static void evalTexture2DShadowOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
576 {
577     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), p.lod, p.offset.swizzle(0, 1));
578 }
evalTexture2DShadowOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)579 static void evalTexture2DShadowOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
580 {
581     c.color.x() =
582         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));
583 }
584 
evalTexture2DShadowProjOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)585 static void evalTexture2DShadowProjOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
586 {
587     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
588                                         c.in[0].y() / c.in[0].w(), p.lod, p.offset.swizzle(0, 1));
589 }
evalTexture2DShadowProjOffsetBias(gls::ShaderEvalContext & c,const TexLookupParams & p)590 static void evalTexture2DShadowProjOffsetBias(gls::ShaderEvalContext &c, const TexLookupParams &p)
591 {
592     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
593                                         c.in[0].y() / c.in[0].w(), p.lod + c.in[1].x(), p.offset.swizzle(0, 1));
594 }
595 
596 // Gradient variarts
597 
evalTexture2DGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)598 static void evalTexture2DGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
599 {
600     c.color = texture2D(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c)) * p.scale + p.bias;
601 }
evalTextureCubeGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)602 static void evalTextureCubeGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
603 {
604     c.color = textureCube(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c)) * p.scale + p.bias;
605 }
evalTexture2DArrayGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)606 static void evalTexture2DArrayGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
607 {
608     c.color = texture2DArray(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c)) * p.scale + p.bias;
609 }
evalTexture3DGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)610 static void evalTexture3DGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
611 {
612     c.color = texture3D(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c)) * p.scale + p.bias;
613 }
614 
evalTexture2DShadowGrad(gls::ShaderEvalContext & c,const TexLookupParams &)615 static void evalTexture2DShadowGrad(gls::ShaderEvalContext &c, const TexLookupParams &)
616 {
617     c.color.x() = texture2DShadow(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c));
618 }
evalTextureCubeShadowGrad(gls::ShaderEvalContext & c,const TexLookupParams &)619 static void evalTextureCubeShadowGrad(gls::ShaderEvalContext &c, const TexLookupParams &)
620 {
621     c.color.x() = textureCubeShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGradCube(c));
622 }
evalTexture2DArrayShadowGrad(gls::ShaderEvalContext & c,const TexLookupParams &)623 static void evalTexture2DArrayShadowGrad(gls::ShaderEvalContext &c, const TexLookupParams &)
624 {
625     c.color.x() =
626         texture2DArrayShadow(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c));
627 }
628 
evalTexture2DGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)629 static void evalTexture2DGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
630 {
631     c.color = texture2DOffset(c, c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c), p.offset.swizzle(0, 1)) * p.scale +
632               p.bias;
633 }
evalTexture2DArrayGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)634 static void evalTexture2DArrayGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
635 {
636     c.color = texture2DArrayOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad2DArray(c),
637                                    p.offset.swizzle(0, 1)) *
638                   p.scale +
639               p.bias;
640 }
evalTexture3DGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)641 static void evalTexture3DGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
642 {
643     c.color =
644         texture3DOffset(c, c.in[0].x(), c.in[0].y(), c.in[0].z(), computeLodFromGrad3D(c), p.offset) * p.scale + p.bias;
645 }
646 
evalTexture2DShadowGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)647 static void evalTexture2DShadowGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
648 {
649     c.color.x() = texture2DShadowOffset(c, c.in[0].z(), c.in[0].x(), c.in[0].y(), computeLodFromGrad2D(c),
650                                         p.offset.swizzle(0, 1));
651 }
evalTexture2DArrayShadowGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)652 static void evalTexture2DArrayShadowGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
653 {
654     c.color.x() = texture2DArrayShadowOffset(c, c.in[0].w(), c.in[0].x(), c.in[0].y(), c.in[0].z(),
655                                              computeLodFromGrad2DArray(c), p.offset.swizzle(0, 1));
656 }
657 
evalTexture2DShadowProjGrad(gls::ShaderEvalContext & c,const TexLookupParams &)658 static void evalTexture2DShadowProjGrad(gls::ShaderEvalContext &c, const TexLookupParams &)
659 {
660     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(),
661                                   computeLodFromGrad2D(c));
662 }
evalTexture2DShadowProjGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)663 static void evalTexture2DShadowProjGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
664 {
665     c.color.x() = texture2DShadowOffset(c, c.in[0].z() / c.in[0].w(), c.in[0].x() / c.in[0].w(),
666                                         c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c), p.offset.swizzle(0, 1));
667 }
668 
evalTexture2DProjGrad3(gls::ShaderEvalContext & c,const TexLookupParams & p)669 static void evalTexture2DProjGrad3(gls::ShaderEvalContext &c, const TexLookupParams &p)
670 {
671     c.color =
672         texture2D(c, c.in[0].x() / c.in[0].z(), c.in[0].y() / c.in[0].z(), computeLodFromGrad2D(c)) * p.scale + p.bias;
673 }
evalTexture2DProjGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)674 static void evalTexture2DProjGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
675 {
676     c.color =
677         texture2D(c, c.in[0].x() / c.in[0].w(), c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c)) * p.scale + p.bias;
678 }
evalTexture3DProjGrad(gls::ShaderEvalContext & c,const TexLookupParams & p)679 static void evalTexture3DProjGrad(gls::ShaderEvalContext &c, const TexLookupParams &p)
680 {
681     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(),
682                         computeLodFromGrad3D(c)) *
683                   p.scale +
684               p.bias;
685 }
686 
evalTexture2DProjGrad3Offset(gls::ShaderEvalContext & c,const TexLookupParams & p)687 static void evalTexture2DProjGrad3Offset(gls::ShaderEvalContext &c, const TexLookupParams &p)
688 {
689     c.color = texture2DOffset(c, c.in[0].x() / c.in[0].z(), c.in[0].y() / c.in[0].z(), computeLodFromGrad2D(c),
690                               p.offset.swizzle(0, 1)) *
691                   p.scale +
692               p.bias;
693 }
evalTexture2DProjGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)694 static void evalTexture2DProjGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
695 {
696     c.color = texture2DOffset(c, c.in[0].x() / c.in[0].w(), c.in[0].y() / c.in[0].w(), computeLodFromGrad2D(c),
697                               p.offset.swizzle(0, 1)) *
698                   p.scale +
699               p.bias;
700 }
evalTexture3DProjGradOffset(gls::ShaderEvalContext & c,const TexLookupParams & p)701 static void evalTexture3DProjGradOffset(gls::ShaderEvalContext &c, const TexLookupParams &p)
702 {
703     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(),
704                               computeLodFromGrad3D(c), p.offset) *
705                   p.scale +
706               p.bias;
707 }
708 
709 // Texel fetch variants
710 
evalTexelFetch2D(gls::ShaderEvalContext & c,const TexLookupParams & p)711 static void evalTexelFetch2D(gls::ShaderEvalContext &c, const TexLookupParams &p)
712 {
713     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
714     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
715     int lod = deChopFloatToInt32(c.in[1].x());
716     c.color = c.textures[0].tex2D->getLevel(lod).getPixel(x, y) * p.scale + p.bias;
717 }
718 
evalTexelFetch2DArray(gls::ShaderEvalContext & c,const TexLookupParams & p)719 static void evalTexelFetch2DArray(gls::ShaderEvalContext &c, const TexLookupParams &p)
720 {
721     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
722     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
723     int l   = deChopFloatToInt32(c.in[0].z());
724     int lod = deChopFloatToInt32(c.in[1].x());
725     c.color = c.textures[0].tex2DArray->getLevel(lod).getPixel(x, y, l) * p.scale + p.bias;
726 }
727 
evalTexelFetch3D(gls::ShaderEvalContext & c,const TexLookupParams & p)728 static void evalTexelFetch3D(gls::ShaderEvalContext &c, const TexLookupParams &p)
729 {
730     int x   = deChopFloatToInt32(c.in[0].x()) + p.offset.x();
731     int y   = deChopFloatToInt32(c.in[0].y()) + p.offset.y();
732     int z   = deChopFloatToInt32(c.in[0].z()) + p.offset.z();
733     int lod = deChopFloatToInt32(c.in[1].x());
734     c.color = c.textures[0].tex3D->getLevel(lod).getPixel(x, y, z) * p.scale + p.bias;
735 }
736 
737 class TexLookupEvaluator : public gls::ShaderEvaluator
738 {
739 public:
TexLookupEvaluator(TexEvalFunc evalFunc,const TexLookupParams & lookupParams)740     TexLookupEvaluator(TexEvalFunc evalFunc, const TexLookupParams &lookupParams)
741         : m_evalFunc(evalFunc)
742         , m_lookupParams(lookupParams)
743     {
744     }
745 
evaluate(gls::ShaderEvalContext & ctx)746     virtual void evaluate(gls::ShaderEvalContext &ctx)
747     {
748         m_evalFunc(ctx, m_lookupParams);
749     }
750 
751 private:
752     TexEvalFunc m_evalFunc;
753     const TexLookupParams &m_lookupParams;
754 };
755 
756 class ShaderTextureFunctionCase : public gls::ShaderRenderCase
757 {
758 public:
759     ShaderTextureFunctionCase(Context &context, const char *name, const char *desc, const TextureLookupSpec &lookup,
760                               const TextureSpec &texture, TexEvalFunc evalFunc, bool isVertexCase);
761     ~ShaderTextureFunctionCase(void);
762 
763     void init(void);
764     void deinit(void);
765 
766 protected:
767     void setupUniforms(int programID, const tcu::Vec4 &constCoords);
768 
769 private:
770     void initTexture(void);
771     void initShaderSources(void);
772 
773     TextureLookupSpec m_lookupSpec;
774     TextureSpec m_textureSpec;
775 
776     TexLookupParams m_lookupParams;
777     TexLookupEvaluator m_evaluator;
778 
779     glu::Texture2D *m_texture2D;
780     glu::TextureCube *m_textureCube;
781     glu::Texture2DArray *m_texture2DArray;
782     glu::Texture3D *m_texture3D;
783 };
784 
ShaderTextureFunctionCase(Context & context,const char * name,const char * desc,const TextureLookupSpec & lookup,const TextureSpec & texture,TexEvalFunc evalFunc,bool isVertexCase)785 ShaderTextureFunctionCase::ShaderTextureFunctionCase(Context &context, const char *name, const char *desc,
786                                                      const TextureLookupSpec &lookup, const TextureSpec &texture,
787                                                      TexEvalFunc evalFunc, bool isVertexCase)
788     : gls::ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc,
789                             isVertexCase, m_evaluator)
790     , m_lookupSpec(lookup)
791     , m_textureSpec(texture)
792     , m_evaluator(evalFunc, m_lookupParams)
793     , m_texture2D(DE_NULL)
794     , m_textureCube(DE_NULL)
795     , m_texture2DArray(DE_NULL)
796     , m_texture3D(DE_NULL)
797 {
798 }
799 
~ShaderTextureFunctionCase(void)800 ShaderTextureFunctionCase::~ShaderTextureFunctionCase(void)
801 {
802     delete m_texture2D;
803     delete m_textureCube;
804     delete m_texture2DArray;
805     delete m_texture3D;
806 }
807 
init(void)808 void ShaderTextureFunctionCase::init(void)
809 {
810     {
811         // Base coord scale & bias
812         Vec4 s = m_lookupSpec.maxCoord - m_lookupSpec.minCoord;
813         Vec4 b = m_lookupSpec.minCoord;
814 
815         float baseCoordTrans[] = {s.x(),        0.0f,         0.f, b.x(),
816                                   0.f,          s.y(),        0.f, b.y(),
817                                   s.z() / 2.f,  -s.z() / 2.f, 0.f, s.z() / 2.f + b.z(),
818                                   -s.w() / 2.f, s.w() / 2.f,  0.f, s.w() / 2.f + b.w()};
819 
820         m_userAttribTransforms.push_back(tcu::Mat4(baseCoordTrans));
821     }
822 
823     bool hasLodBias = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
824     bool isGrad     = functionHasGrad(m_lookupSpec.function);
825     DE_ASSERT(!isGrad || !hasLodBias);
826 
827     if (hasLodBias)
828     {
829         float s               = m_lookupSpec.maxLodBias - m_lookupSpec.minLodBias;
830         float b               = m_lookupSpec.minLodBias;
831         float lodCoordTrans[] = {s / 2.0f, s / 2.0f, 0.f,  b,    0.0f, 0.0f, 0.0f, 0.0f,
832                                  0.0f,     0.0f,     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
833 
834         m_userAttribTransforms.push_back(tcu::Mat4(lodCoordTrans));
835     }
836     else if (isGrad)
837     {
838         Vec3 sx             = m_lookupSpec.maxDX - m_lookupSpec.minDX;
839         Vec3 sy             = m_lookupSpec.maxDY - m_lookupSpec.minDY;
840         float gradDxTrans[] = {sx.x() / 2.0f, sx.x() / 2.0f, 0.f,  m_lookupSpec.minDX.x(),
841                                sx.y() / 2.0f, sx.y() / 2.0f, 0.0f, m_lookupSpec.minDX.y(),
842                                sx.z() / 2.0f, sx.z() / 2.0f, 0.0f, m_lookupSpec.minDX.z(),
843                                0.0f,          0.0f,          0.0f, 0.0f};
844         float gradDyTrans[] = {-sy.x() / 2.0f, -sy.x() / 2.0f, 0.f,  m_lookupSpec.maxDY.x(),
845                                -sy.y() / 2.0f, -sy.y() / 2.0f, 0.0f, m_lookupSpec.maxDY.y(),
846                                -sy.z() / 2.0f, -sy.z() / 2.0f, 0.0f, m_lookupSpec.maxDY.z(),
847                                0.0f,           0.0f,           0.0f, 0.0f};
848 
849         m_userAttribTransforms.push_back(tcu::Mat4(gradDxTrans));
850         m_userAttribTransforms.push_back(tcu::Mat4(gradDyTrans));
851     }
852 
853     initShaderSources();
854     initTexture();
855 
856     gls::ShaderRenderCase::init();
857 }
858 
initTexture(void)859 void ShaderTextureFunctionCase::initTexture(void)
860 {
861     static const IVec4 texCubeSwz[] = {IVec4(0, 0, 1, 1), IVec4(1, 1, 0, 0), IVec4(0, 1, 0, 1),
862                                        IVec4(1, 0, 1, 0), IVec4(0, 1, 1, 0), IVec4(1, 0, 0, 1)};
863     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(texCubeSwz) == tcu::CUBEFACE_LAST);
864 
865     tcu::TextureFormat texFmt      = glu::mapGLInternalFormat(m_textureSpec.format);
866     tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
867     tcu::IVec2 viewportSize        = getViewportSize();
868     bool useProj = functionHasProj(m_lookupSpec.function) && !functionHasGrad(m_lookupSpec.function) &&
869                    !functionHasLod(m_lookupSpec.function);
870     bool isAutoLod = functionHasAutoLod(m_isVertexCase ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT,
871                                         m_lookupSpec.function); // LOD can vary significantly
872     float proj = useProj ? 1.0f / m_lookupSpec.minCoord[m_lookupSpec.function == FUNCTION_TEXTUREPROJ3 ? 2 : 3] : 1.0f;
873 
874     switch (m_textureSpec.type)
875     {
876     case TEXTURETYPE_2D:
877     {
878         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
879         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
880         Vec4 cBias       = fmtInfo.valueMin;
881         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
882 
883         m_texture2D = new glu::Texture2D(m_renderCtx, m_textureSpec.format, m_textureSpec.width, m_textureSpec.height);
884         for (int level = 0; level < m_textureSpec.numLevels; level++)
885         {
886             float fA    = float(level) * levelStep;
887             float fB    = 1.0f - fA;
888             Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
889             Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
890 
891             m_texture2D->getRefTexture().allocLevel(level);
892             tcu::fillWithGrid(m_texture2D->getRefTexture().getLevel(level), de::max(1, baseCellSize >> level), colorA,
893                               colorB);
894         }
895         m_texture2D->upload();
896 
897         // Compute LOD.
898         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
899                      (float)viewportSize[0];
900         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
901                      (float)viewportSize[1];
902         m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
903 
904         // Append to texture list.
905         m_textures.push_back(gls::TextureBinding(m_texture2D, m_textureSpec.sampler));
906         break;
907     }
908 
909     case TEXTURETYPE_CUBE_MAP:
910     {
911         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
912         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
913         Vec4 cBias       = fmtInfo.valueMin;
914         Vec4 cCorner     = cBias + cScale * 0.5f;
915         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
916 
917         DE_ASSERT(m_textureSpec.width == m_textureSpec.height);
918         m_textureCube = new glu::TextureCube(m_renderCtx, m_textureSpec.format, m_textureSpec.width);
919         for (int level = 0; level < m_textureSpec.numLevels; level++)
920         {
921             float fA = float(level) * levelStep;
922             float fB = 1.0f - fA;
923             Vec2 f(fA, fB);
924 
925             for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
926             {
927                 const IVec4 &swzA = texCubeSwz[face];
928                 IVec4 swzB        = 1 - swzA;
929                 Vec4 colorA       = cBias + cScale * f.swizzle(swzA[0], swzA[1], swzA[2], swzA[3]);
930                 Vec4 colorB       = cBias + cScale * f.swizzle(swzB[0], swzB[1], swzB[2], swzB[3]);
931 
932                 m_textureCube->getRefTexture().allocLevel((tcu::CubeFace)face, level);
933 
934                 {
935                     const tcu::PixelBufferAccess access =
936                         m_textureCube->getRefTexture().getLevelFace(level, (tcu::CubeFace)face);
937                     const int lastPix = access.getWidth() - 1;
938 
939                     tcu::fillWithGrid(access, de::max(1, baseCellSize >> level), colorA, colorB);
940 
941                     // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
942                     access.setPixel(cCorner, 0, 0);
943                     access.setPixel(cCorner, 0, lastPix);
944                     access.setPixel(cCorner, lastPix, 0);
945                     access.setPixel(cCorner, lastPix, lastPix);
946                 }
947             }
948         }
949         m_textureCube->upload();
950 
951         // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
952         DE_ASSERT(de::abs(m_lookupSpec.minCoord[2] - m_lookupSpec.maxCoord[2]) < 0.005);
953         DE_ASSERT(de::abs(m_lookupSpec.minCoord[0]) < de::abs(m_lookupSpec.minCoord[2]) &&
954                   de::abs(m_lookupSpec.maxCoord[0]) < de::abs(m_lookupSpec.minCoord[2]));
955         DE_ASSERT(de::abs(m_lookupSpec.minCoord[1]) < de::abs(m_lookupSpec.minCoord[2]) &&
956                   de::abs(m_lookupSpec.maxCoord[1]) < de::abs(m_lookupSpec.minCoord[2]));
957 
958         tcu::CubeFaceFloatCoords c00 = tcu::getCubeFaceCoords(
959             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
960         tcu::CubeFaceFloatCoords c10 = tcu::getCubeFaceCoords(
961             Vec3(m_lookupSpec.maxCoord[0] * proj, m_lookupSpec.minCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
962         tcu::CubeFaceFloatCoords c01 = tcu::getCubeFaceCoords(
963             Vec3(m_lookupSpec.minCoord[0] * proj, m_lookupSpec.maxCoord[1] * proj, m_lookupSpec.minCoord[2] * proj));
964         float dudx = (c10.s - c00.s) * (float)m_textureSpec.width / (float)viewportSize[0];
965         float dvdy = (c01.t - c00.t) * (float)m_textureSpec.height / (float)viewportSize[1];
966 
967         m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
968 
969         m_textures.push_back(gls::TextureBinding(m_textureCube, m_textureSpec.sampler));
970         break;
971     }
972 
973     case TEXTURETYPE_2D_ARRAY:
974     {
975         float layerStep = 1.0f / (float)m_textureSpec.depth;
976         float levelStep =
977             isAutoLod ? 0.0f : 1.0f / (float)(de::max(1, m_textureSpec.numLevels - 1) * m_textureSpec.depth);
978         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
979         Vec4 cBias       = fmtInfo.valueMin;
980         int baseCellSize = de::min(m_textureSpec.width / 4, m_textureSpec.height / 4);
981 
982         m_texture2DArray = new glu::Texture2DArray(m_renderCtx, m_textureSpec.format, m_textureSpec.width,
983                                                    m_textureSpec.height, m_textureSpec.depth);
984         for (int level = 0; level < m_textureSpec.numLevels; level++)
985         {
986             m_texture2DArray->getRefTexture().allocLevel(level);
987             tcu::PixelBufferAccess levelAccess = m_texture2DArray->getRefTexture().getLevel(level);
988 
989             for (int layer = 0; layer < levelAccess.getDepth(); layer++)
990             {
991                 float fA    = (float)layer * layerStep + (float)level * levelStep;
992                 float fB    = 1.0f - fA;
993                 Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
994                 Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
995 
996                 tcu::fillWithGrid(
997                     tcu::getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1),
998                     de::max(1, baseCellSize >> level), colorA, colorB);
999             }
1000         }
1001         m_texture2DArray->upload();
1002 
1003         // Compute LOD.
1004         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1005                      (float)viewportSize[0];
1006         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
1007                      (float)viewportSize[1];
1008         m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, 0.0f, dvdy);
1009 
1010         // Append to texture list.
1011         m_textures.push_back(gls::TextureBinding(m_texture2DArray, m_textureSpec.sampler));
1012         break;
1013     }
1014 
1015     case TEXTURETYPE_3D:
1016     {
1017         float levelStep  = isAutoLod ? 0.0f : 1.0f / (float)de::max(1, m_textureSpec.numLevels - 1);
1018         Vec4 cScale      = fmtInfo.valueMax - fmtInfo.valueMin;
1019         Vec4 cBias       = fmtInfo.valueMin;
1020         int baseCellSize = de::min(de::min(m_textureSpec.width / 2, m_textureSpec.height / 2), m_textureSpec.depth / 2);
1021 
1022         m_texture3D = new glu::Texture3D(m_renderCtx, m_textureSpec.format, m_textureSpec.width, m_textureSpec.height,
1023                                          m_textureSpec.depth);
1024         for (int level = 0; level < m_textureSpec.numLevels; level++)
1025         {
1026             float fA    = (float)level * levelStep;
1027             float fB    = 1.0f - fA;
1028             Vec4 colorA = cBias + cScale * Vec4(fA, fB, fA, fB);
1029             Vec4 colorB = cBias + cScale * Vec4(fB, fA, fB, fA);
1030 
1031             m_texture3D->getRefTexture().allocLevel(level);
1032             tcu::fillWithGrid(m_texture3D->getRefTexture().getLevel(level), de::max(1, baseCellSize >> level), colorA,
1033                               colorB);
1034         }
1035         m_texture3D->upload();
1036 
1037         // Compute LOD.
1038         float dudx = (m_lookupSpec.maxCoord[0] - m_lookupSpec.minCoord[0]) * proj * (float)m_textureSpec.width /
1039                      (float)viewportSize[0];
1040         float dvdy = (m_lookupSpec.maxCoord[1] - m_lookupSpec.minCoord[1]) * proj * (float)m_textureSpec.height /
1041                      (float)viewportSize[1];
1042         float dwdx = (m_lookupSpec.maxCoord[2] - m_lookupSpec.minCoord[2]) * 0.5f * proj * (float)m_textureSpec.depth /
1043                      (float)viewportSize[0];
1044         float dwdy = (m_lookupSpec.maxCoord[2] - m_lookupSpec.minCoord[2]) * 0.5f * proj * (float)m_textureSpec.depth /
1045                      (float)viewportSize[1];
1046         m_lookupParams.lod = computeLodFromDerivates(DEFAULT_LOD_MODE, dudx, 0.0f, dwdx, 0.0f, dvdy, dwdy);
1047 
1048         // Append to texture list.
1049         m_textures.push_back(gls::TextureBinding(m_texture3D, m_textureSpec.sampler));
1050         break;
1051     }
1052 
1053     default:
1054         DE_ASSERT(false);
1055     }
1056 
1057     // Set lookup scale & bias
1058     m_lookupParams.scale  = fmtInfo.lookupScale;
1059     m_lookupParams.bias   = fmtInfo.lookupBias;
1060     m_lookupParams.offset = m_lookupSpec.offset;
1061 }
1062 
initShaderSources(void)1063 void ShaderTextureFunctionCase::initShaderSources(void)
1064 {
1065     Function function = m_lookupSpec.function;
1066     bool isVtxCase    = m_isVertexCase;
1067     bool isProj       = functionHasProj(function);
1068     bool isGrad       = functionHasGrad(function);
1069     bool isShadow     = m_textureSpec.sampler.compare != tcu::Sampler::COMPAREMODE_NONE;
1070     bool is2DProj4    = !isShadow && m_textureSpec.type == TEXTURETYPE_2D &&
1071                      (function == FUNCTION_TEXTUREPROJ || function == FUNCTION_TEXTUREPROJLOD ||
1072                       function == FUNCTION_TEXTUREPROJGRAD);
1073     bool isIntCoord           = function == FUNCTION_TEXELFETCH;
1074     bool hasLodBias           = functionHasLod(m_lookupSpec.function) || m_lookupSpec.useBias;
1075     int texCoordComps         = m_textureSpec.type == TEXTURETYPE_2D ? 2 : 3;
1076     int extraCoordComps       = (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
1077     glu::DataType coordType   = glu::getDataTypeFloatVec(texCoordComps + extraCoordComps);
1078     glu::Precision coordPrec  = glu::PRECISION_HIGHP;
1079     const char *coordTypeName = glu::getDataTypeName(coordType);
1080     const char *coordPrecName = glu::getPrecisionName(coordPrec);
1081     tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_textureSpec.format);
1082     glu::DataType samplerType = glu::TYPE_LAST;
1083     glu::DataType gradType    = (m_textureSpec.type == TEXTURETYPE_CUBE_MAP || m_textureSpec.type == TEXTURETYPE_3D) ?
1084                                     glu::TYPE_FLOAT_VEC3 :
1085                                     glu::TYPE_FLOAT_VEC2;
1086     const char *gradTypeName  = glu::getDataTypeName(gradType);
1087     const char *baseFuncName  = DE_NULL;
1088 
1089     DE_ASSERT(!isGrad || !hasLodBias);
1090 
1091     switch (m_textureSpec.type)
1092     {
1093     case TEXTURETYPE_2D:
1094         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_SHADOW : glu::getSampler2DType(texFmt);
1095         break;
1096     case TEXTURETYPE_CUBE_MAP:
1097         samplerType = isShadow ? glu::TYPE_SAMPLER_CUBE_SHADOW : glu::getSamplerCubeType(texFmt);
1098         break;
1099     case TEXTURETYPE_2D_ARRAY:
1100         samplerType = isShadow ? glu::TYPE_SAMPLER_2D_ARRAY_SHADOW : glu::getSampler2DArrayType(texFmt);
1101         break;
1102     case TEXTURETYPE_3D:
1103         DE_ASSERT(!isShadow);
1104         samplerType = glu::getSampler3DType(texFmt);
1105         break;
1106     default:
1107         DE_ASSERT(false);
1108     }
1109 
1110     switch (m_lookupSpec.function)
1111     {
1112     case FUNCTION_TEXTURE:
1113         baseFuncName = "texture";
1114         break;
1115     case FUNCTION_TEXTUREPROJ:
1116         baseFuncName = "textureProj";
1117         break;
1118     case FUNCTION_TEXTUREPROJ3:
1119         baseFuncName = "textureProj";
1120         break;
1121     case FUNCTION_TEXTURELOD:
1122         baseFuncName = "textureLod";
1123         break;
1124     case FUNCTION_TEXTUREPROJLOD:
1125         baseFuncName = "textureProjLod";
1126         break;
1127     case FUNCTION_TEXTUREPROJLOD3:
1128         baseFuncName = "textureProjLod";
1129         break;
1130     case FUNCTION_TEXTUREGRAD:
1131         baseFuncName = "textureGrad";
1132         break;
1133     case FUNCTION_TEXTUREPROJGRAD:
1134         baseFuncName = "textureProjGrad";
1135         break;
1136     case FUNCTION_TEXTUREPROJGRAD3:
1137         baseFuncName = "textureProjGrad";
1138         break;
1139     case FUNCTION_TEXELFETCH:
1140         baseFuncName = "texelFetch";
1141         break;
1142     default:
1143         DE_ASSERT(false);
1144     }
1145 
1146     std::ostringstream vert;
1147     std::ostringstream frag;
1148     std::ostringstream &op = isVtxCase ? vert : frag;
1149 
1150     vert << "#version 300 es\n"
1151          << "in highp vec4 a_position;\n"
1152          << "in " << coordPrecName << " " << coordTypeName << " a_in0;\n";
1153 
1154     if (isGrad)
1155     {
1156         vert << "in " << coordPrecName << " " << gradTypeName << " a_in1;\n";
1157         vert << "in " << coordPrecName << " " << gradTypeName << " a_in2;\n";
1158     }
1159     else if (hasLodBias)
1160         vert << "in " << coordPrecName << " float a_in1;\n";
1161 
1162     frag << "#version 300 es\n"
1163          << "layout(location = 0) out mediump vec4 o_color;\n";
1164 
1165     if (isVtxCase)
1166     {
1167         vert << "out mediump vec4 v_color;\n";
1168         frag << "in mediump vec4 v_color;\n";
1169     }
1170     else
1171     {
1172         vert << "out " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1173         frag << "in " << coordPrecName << " " << coordTypeName << " v_texCoord;\n";
1174 
1175         if (isGrad)
1176         {
1177             vert << "out " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1178             vert << "out " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1179             frag << "in " << coordPrecName << " " << gradTypeName << " v_gradX;\n";
1180             frag << "in " << coordPrecName << " " << gradTypeName << " v_gradY;\n";
1181         }
1182 
1183         if (hasLodBias)
1184         {
1185             vert << "out " << coordPrecName << " float v_lodBias;\n";
1186             frag << "in " << coordPrecName << " float v_lodBias;\n";
1187         }
1188     }
1189 
1190     // Uniforms
1191     op << "uniform highp " << glu::getDataTypeName(samplerType) << " u_sampler;\n"
1192        << "uniform highp vec4 u_scale;\n"
1193        << "uniform highp vec4 u_bias;\n";
1194 
1195     vert << "\nvoid main()\n{\n"
1196          << "\tgl_Position = a_position;\n";
1197     frag << "\nvoid main()\n{\n";
1198 
1199     if (isVtxCase)
1200         vert << "\tv_color = ";
1201     else
1202         frag << "\to_color = ";
1203 
1204     // Op.
1205     {
1206         const char *texCoord = isVtxCase ? "a_in0" : "v_texCoord";
1207         const char *gradX    = isVtxCase ? "a_in1" : "v_gradX";
1208         const char *gradY    = isVtxCase ? "a_in2" : "v_gradY";
1209         const char *lodBias  = isVtxCase ? "a_in1" : "v_lodBias";
1210 
1211         op << "vec4(" << baseFuncName;
1212         if (m_lookupSpec.useOffset)
1213             op << "Offset";
1214         op << "(u_sampler, ";
1215 
1216         if (isIntCoord)
1217             op << "ivec" << (texCoordComps + extraCoordComps) << "(";
1218 
1219         op << texCoord;
1220 
1221         if (isIntCoord)
1222             op << ")";
1223 
1224         if (isGrad)
1225             op << ", " << gradX << ", " << gradY;
1226 
1227         if (functionHasLod(function))
1228         {
1229             if (isIntCoord)
1230                 op << ", int(" << lodBias << ")";
1231             else
1232                 op << ", " << lodBias;
1233         }
1234 
1235         if (m_lookupSpec.useOffset)
1236         {
1237             int offsetComps = m_textureSpec.type == TEXTURETYPE_3D ? 3 : 2;
1238 
1239             op << ", ivec" << offsetComps << "(";
1240             for (int ndx = 0; ndx < offsetComps; ndx++)
1241             {
1242                 if (ndx != 0)
1243                     op << ", ";
1244                 op << m_lookupSpec.offset[ndx];
1245             }
1246             op << ")";
1247         }
1248 
1249         if (m_lookupSpec.useBias)
1250             op << ", " << lodBias;
1251 
1252         op << ")";
1253 
1254         if (isShadow)
1255             op << ", 0.0, 0.0, 1.0)";
1256         else
1257             op << ")*u_scale + u_bias";
1258 
1259         op << ";\n";
1260     }
1261 
1262     if (isVtxCase)
1263         frag << "\to_color = v_color;\n";
1264     else
1265     {
1266         vert << "\tv_texCoord = a_in0;\n";
1267 
1268         if (isGrad)
1269         {
1270             vert << "\tv_gradX = a_in1;\n";
1271             vert << "\tv_gradY = a_in2;\n";
1272         }
1273         else if (hasLodBias)
1274             vert << "\tv_lodBias = a_in1;\n";
1275     }
1276 
1277     vert << "}\n";
1278     frag << "}\n";
1279 
1280     m_vertShaderSource = vert.str();
1281     m_fragShaderSource = frag.str();
1282 }
1283 
deinit(void)1284 void ShaderTextureFunctionCase::deinit(void)
1285 {
1286     gls::ShaderRenderCase::deinit();
1287 
1288     delete m_texture2D;
1289     delete m_textureCube;
1290     delete m_texture2DArray;
1291     delete m_texture3D;
1292 
1293     m_texture2D      = DE_NULL;
1294     m_textureCube    = DE_NULL;
1295     m_texture2DArray = DE_NULL;
1296     m_texture3D      = DE_NULL;
1297 }
1298 
setupUniforms(int programID,const tcu::Vec4 &)1299 void ShaderTextureFunctionCase::setupUniforms(int programID, const tcu::Vec4 &)
1300 {
1301     const glw::Functions &gl = m_renderCtx.getFunctions();
1302     gl.uniform1i(gl.getUniformLocation(programID, "u_sampler"), 0);
1303     gl.uniform4fv(gl.getUniformLocation(programID, "u_scale"), 1, m_lookupParams.scale.getPtr());
1304     gl.uniform4fv(gl.getUniformLocation(programID, "u_bias"), 1, m_lookupParams.bias.getPtr());
1305 }
1306 
1307 class TextureSizeCase : public TestCase
1308 {
1309 public:
1310     TextureSizeCase(Context &context, const char *name, const char *desc, const char *samplerType,
1311                     const TextureSpec &texture, bool isVertexCase);
1312     ~TextureSizeCase(void);
1313 
1314     void deinit(void);
1315     IterateResult iterate(void);
1316 
1317 private:
1318     struct TestSize
1319     {
1320         tcu::IVec3 textureSize;
1321         int lod;
1322         int lodBase;
1323         tcu::IVec3 expectedSize;
1324     };
1325 
1326     bool initShader(void);
1327     void freeShader(void);
1328     bool testTextureSize(const TestSize &);
1329     std::string genVertexShader(void) const;
1330     std::string genFragmentShader(void) const;
1331     glw::GLenum getGLTextureTarget(void) const;
1332 
1333     const char *m_samplerTypeStr;
1334     const TextureSpec m_textureSpec;
1335     const bool m_isVertexCase;
1336     const bool m_has3DSize;
1337     glu::ShaderProgram *m_program;
1338     int m_iterationCounter;
1339 };
1340 
TextureSizeCase(Context & context,const char * name,const char * desc,const char * samplerType,const TextureSpec & texture,bool isVertexCase)1341 TextureSizeCase::TextureSizeCase(Context &context, const char *name, const char *desc, const char *samplerType,
1342                                  const TextureSpec &texture, bool isVertexCase)
1343     : TestCase(context, name, desc)
1344     , m_samplerTypeStr(samplerType)
1345     , m_textureSpec(texture)
1346     , m_isVertexCase(isVertexCase)
1347     , m_has3DSize(texture.type == TEXTURETYPE_3D || texture.type == TEXTURETYPE_2D_ARRAY)
1348     , m_program(DE_NULL)
1349     , m_iterationCounter(0)
1350 {
1351 }
1352 
~TextureSizeCase(void)1353 TextureSizeCase::~TextureSizeCase(void)
1354 {
1355     deinit();
1356 }
1357 
deinit(void)1358 void TextureSizeCase::deinit(void)
1359 {
1360     freeShader();
1361 }
1362 
iterate(void)1363 TestCase::IterateResult TextureSizeCase::iterate(void)
1364 {
1365     const int currentIteration = m_iterationCounter++;
1366     const TestSize testSizes[] = {
1367         {tcu::IVec3(1, 2, 1), 1, 0, tcu::IVec3(1, 1, 1)},
1368         {tcu::IVec3(1, 2, 1), 0, 0, tcu::IVec3(1, 2, 1)},
1369 
1370         {tcu::IVec3(1, 3, 2), 0, 0, tcu::IVec3(1, 3, 2)},
1371         {tcu::IVec3(1, 3, 2), 1, 0, tcu::IVec3(1, 1, 1)},
1372 
1373         {tcu::IVec3(100, 31, 18), 0, 0, tcu::IVec3(100, 31, 18)},
1374         {tcu::IVec3(100, 31, 18), 1, 0, tcu::IVec3(50, 15, 9)},
1375         {tcu::IVec3(100, 31, 18), 2, 0, tcu::IVec3(25, 7, 4)},
1376         {tcu::IVec3(100, 31, 18), 3, 0, tcu::IVec3(12, 3, 2)},
1377         {tcu::IVec3(100, 31, 18), 4, 0, tcu::IVec3(6, 1, 1)},
1378         {tcu::IVec3(100, 31, 18), 5, 0, tcu::IVec3(3, 1, 1)},
1379         {tcu::IVec3(100, 31, 18), 6, 0, tcu::IVec3(1, 1, 1)},
1380 
1381         {tcu::IVec3(100, 128, 32), 0, 0, tcu::IVec3(100, 128, 32)},
1382         {tcu::IVec3(100, 128, 32), 1, 0, tcu::IVec3(50, 64, 16)},
1383         {tcu::IVec3(100, 128, 32), 2, 0, tcu::IVec3(25, 32, 8)},
1384         {tcu::IVec3(100, 128, 32), 3, 0, tcu::IVec3(12, 16, 4)},
1385         {tcu::IVec3(100, 128, 32), 4, 0, tcu::IVec3(6, 8, 2)},
1386         {tcu::IVec3(100, 128, 32), 5, 0, tcu::IVec3(3, 4, 1)},
1387         {tcu::IVec3(100, 128, 32), 6, 0, tcu::IVec3(1, 2, 1)},
1388         {tcu::IVec3(100, 128, 32), 7, 0, tcu::IVec3(1, 1, 1)},
1389 
1390         // pow 2
1391         {tcu::IVec3(128, 64, 32), 0, 0, tcu::IVec3(128, 64, 32)},
1392         {tcu::IVec3(128, 64, 32), 1, 0, tcu::IVec3(64, 32, 16)},
1393         {tcu::IVec3(128, 64, 32), 2, 0, tcu::IVec3(32, 16, 8)},
1394         {tcu::IVec3(128, 64, 32), 3, 0, tcu::IVec3(16, 8, 4)},
1395         {tcu::IVec3(128, 64, 32), 4, 0, tcu::IVec3(8, 4, 2)},
1396         {tcu::IVec3(128, 64, 32), 5, 0, tcu::IVec3(4, 2, 1)},
1397         {tcu::IVec3(128, 64, 32), 6, 0, tcu::IVec3(2, 1, 1)},
1398         {tcu::IVec3(128, 64, 32), 7, 0, tcu::IVec3(1, 1, 1)},
1399 
1400         // w == h
1401         {tcu::IVec3(1, 1, 1), 0, 0, tcu::IVec3(1, 1, 1)},
1402         {tcu::IVec3(64, 64, 64), 0, 0, tcu::IVec3(64, 64, 64)},
1403         {tcu::IVec3(64, 64, 64), 1, 0, tcu::IVec3(32, 32, 32)},
1404         {tcu::IVec3(64, 64, 64), 2, 0, tcu::IVec3(16, 16, 16)},
1405         {tcu::IVec3(64, 64, 64), 3, 0, tcu::IVec3(8, 8, 8)},
1406         {tcu::IVec3(64, 64, 64), 4, 0, tcu::IVec3(4, 4, 4)},
1407 
1408         // with lod base
1409         {tcu::IVec3(100, 31, 18), 3, 1, tcu::IVec3(6, 1, 1)},
1410         {tcu::IVec3(128, 64, 32), 3, 1, tcu::IVec3(8, 4, 2)},
1411         {tcu::IVec3(64, 64, 64), 1, 1, tcu::IVec3(16, 16, 16)},
1412 
1413     };
1414     const int lastIterationIndex = DE_LENGTH_OF_ARRAY(testSizes) + 1;
1415 
1416     if (currentIteration == 0)
1417     {
1418         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1419         return initShader() ? CONTINUE : STOP;
1420     }
1421     else if (currentIteration == lastIterationIndex)
1422     {
1423         freeShader();
1424         return STOP;
1425     }
1426     else
1427     {
1428         if (!testTextureSize(testSizes[currentIteration - 1]))
1429             if (m_testCtx.getTestResult() != QP_TEST_RESULT_FAIL)
1430                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected texture size");
1431         return CONTINUE;
1432     }
1433 }
1434 
initShader(void)1435 bool TextureSizeCase::initShader(void)
1436 {
1437     const std::string vertSrc = genVertexShader();
1438     const std::string fragSrc = genFragmentShader();
1439 
1440     DE_ASSERT(m_program == DE_NULL);
1441     m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertSrc, fragSrc));
1442     m_context.getTestContext().getLog() << *m_program;
1443 
1444     if (!m_program->isOk())
1445     {
1446         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader failed");
1447         return false;
1448     }
1449 
1450     return true;
1451 }
1452 
freeShader(void)1453 void TextureSizeCase::freeShader(void)
1454 {
1455     delete m_program;
1456     m_program = DE_NULL;
1457 }
1458 
testTextureSize(const TestSize & testSize)1459 bool TextureSizeCase::testTextureSize(const TestSize &testSize)
1460 {
1461     using tcu::TestLog;
1462 
1463     const tcu::Vec4 triangle[3] = // covers entire viewport
1464         {
1465             tcu::Vec4(-1, -1, 0, 1),
1466             tcu::Vec4(4, -1, 0, 1),
1467             tcu::Vec4(-1, 4, 0, 1),
1468         };
1469 
1470     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1471 
1472     const glw::GLint positionLoc    = gl.getAttribLocation(m_program->getProgram(), "a_position");
1473     const glw::GLint samplerLoc     = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
1474     const glw::GLint sizeLoc        = gl.getUniformLocation(m_program->getProgram(), "u_texSize");
1475     const glw::GLint lodLoc         = gl.getUniformLocation(m_program->getProgram(), "u_lod");
1476     const glw::GLenum textureTarget = getGLTextureTarget();
1477     const bool isSquare             = testSize.textureSize.x() == testSize.textureSize.y();
1478     const bool is2DLodValid         = (testSize.textureSize.x() >> (testSize.lod + testSize.lodBase)) != 0 ||
1479                               (testSize.textureSize.y() >> (testSize.lod + testSize.lodBase)) != 0;
1480     bool success = true;
1481     glw::GLenum errorValue;
1482 
1483     // Skip incompatible cases
1484     if (m_textureSpec.type == TEXTURETYPE_CUBE_MAP && !isSquare)
1485         return true;
1486     if (m_textureSpec.type == TEXTURETYPE_2D && !is2DLodValid)
1487         return true;
1488     if (m_textureSpec.type == TEXTURETYPE_2D_ARRAY && !is2DLodValid)
1489         return true;
1490 
1491     // setup rendering
1492 
1493     gl.useProgram(m_program->getProgram());
1494     gl.uniform1i(samplerLoc, 0);
1495     gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
1496     gl.viewport(0, 0, 1, 1);
1497     gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, triangle);
1498     gl.enableVertexAttribArray(positionLoc);
1499 
1500     // setup texture
1501     {
1502         const int maxLevel = testSize.lod + testSize.lodBase;
1503         const int levels   = maxLevel + 1;
1504         glw::GLuint texId  = 0;
1505 
1506         // gen texture
1507         gl.genTextures(1, &texId);
1508         gl.bindTexture(textureTarget, texId);
1509         gl.texParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1510         gl.texParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1511         gl.texParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, testSize.lodBase);
1512 
1513         // set up texture
1514 
1515         switch (m_textureSpec.type)
1516         {
1517         case TEXTURETYPE_3D:
1518         {
1519             m_context.getTestContext().getLog()
1520                 << TestLog::Message << "Testing image size " << testSize.textureSize.x() << "x"
1521                 << testSize.textureSize.y() << "x" << testSize.textureSize.z() << TestLog::EndMessage;
1522             m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod
1523                                                 << ", base level: " << testSize.lodBase << TestLog::EndMessage;
1524             m_context.getTestContext().getLog()
1525                 << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x" << testSize.expectedSize.y()
1526                 << "x" << testSize.expectedSize.z() << TestLog::EndMessage;
1527 
1528             gl.uniform3iv(sizeLoc, 1, testSize.expectedSize.m_data);
1529             gl.uniform1iv(lodLoc, 1, &testSize.lod);
1530 
1531             gl.texStorage3D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(),
1532                             testSize.textureSize.y(), testSize.textureSize.z());
1533             break;
1534         }
1535 
1536         case TEXTURETYPE_2D:
1537         case TEXTURETYPE_CUBE_MAP:
1538         {
1539             m_context.getTestContext().getLog() << TestLog::Message << "Testing image size " << testSize.textureSize.x()
1540                                                 << "x" << testSize.textureSize.y() << TestLog::EndMessage;
1541             m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod
1542                                                 << ", base level: " << testSize.lodBase << TestLog::EndMessage;
1543             m_context.getTestContext().getLog() << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x"
1544                                                 << testSize.expectedSize.y() << TestLog::EndMessage;
1545 
1546             gl.uniform2iv(sizeLoc, 1, testSize.expectedSize.m_data);
1547             gl.uniform1iv(lodLoc, 1, &testSize.lod);
1548 
1549             gl.texStorage2D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(),
1550                             testSize.textureSize.y());
1551             break;
1552         }
1553 
1554         case TEXTURETYPE_2D_ARRAY:
1555         {
1556             tcu::IVec3 expectedSize(testSize.expectedSize.x(), testSize.expectedSize.y(), testSize.textureSize.z());
1557 
1558             m_context.getTestContext().getLog() << TestLog::Message << "Testing image size " << testSize.textureSize.x()
1559                                                 << "x" << testSize.textureSize.y() << " with "
1560                                                 << testSize.textureSize.z() << " layer(s)" << TestLog::EndMessage;
1561             m_context.getTestContext().getLog() << TestLog::Message << "Lod: " << testSize.lod
1562                                                 << ", base level: " << testSize.lodBase << TestLog::EndMessage;
1563             m_context.getTestContext().getLog()
1564                 << TestLog::Message << "Expecting: " << testSize.expectedSize.x() << "x" << testSize.expectedSize.y()
1565                 << " and " << testSize.textureSize.z() << " layer(s)" << TestLog::EndMessage;
1566 
1567             gl.uniform3iv(sizeLoc, 1, expectedSize.m_data);
1568             gl.uniform1iv(lodLoc, 1, &testSize.lod);
1569 
1570             gl.texStorage3D(textureTarget, levels, m_textureSpec.format, testSize.textureSize.x(),
1571                             testSize.textureSize.y(), testSize.textureSize.z());
1572             break;
1573         }
1574 
1575         default:
1576         {
1577             DE_ASSERT(false);
1578             break;
1579         }
1580         }
1581 
1582         errorValue = gl.getError();
1583         if (errorValue == GL_OUT_OF_MEMORY)
1584         {
1585             throw glu::OutOfMemoryError("Failed to allocate texture, got GL_OUT_OF_MEMORY.", "TexStorageXD", __FILE__,
1586                                         __LINE__);
1587         }
1588         else if (errorValue != GL_NO_ERROR)
1589         {
1590             // error is a failure too
1591             m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed, got "
1592                                                 << glu::getErrorStr(errorValue) << "." << tcu::TestLog::EndMessage;
1593             success = false;
1594         }
1595         else
1596         {
1597             // test
1598             const float colorTolerance = 0.1f;
1599             tcu::TextureLevel sample(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1,
1600                                      1);
1601             tcu::Vec4 outputColor;
1602 
1603             gl.clear(GL_COLOR_BUFFER_BIT);
1604             gl.drawArrays(GL_TRIANGLES, 0, 3);
1605             gl.finish();
1606 
1607             glu::readPixels(m_context.getRenderContext(), 0, 0, sample.getAccess());
1608 
1609             outputColor = sample.getAccess().getPixel(0, 0);
1610 
1611             if (outputColor.x() >= 1.0f - colorTolerance && outputColor.y() >= 1.0f - colorTolerance &&
1612                 outputColor.z() >= 1.0f - colorTolerance)
1613             {
1614                 // success
1615                 m_context.getTestContext().getLog() << TestLog::Message << "Passed" << TestLog::EndMessage;
1616             }
1617             else
1618             {
1619                 // failure
1620                 m_context.getTestContext().getLog() << TestLog::Message << "Failed" << TestLog::EndMessage;
1621                 success = false;
1622             }
1623         }
1624 
1625         // empty line to format log nicely
1626         m_context.getTestContext().getLog() << TestLog::Message << TestLog::EndMessage;
1627 
1628         // free
1629         gl.bindTexture(textureTarget, 0);
1630         gl.deleteTextures(1, &texId);
1631     }
1632 
1633     gl.useProgram(0);
1634 
1635     return success;
1636 }
1637 
genVertexShader() const1638 std::string TextureSizeCase::genVertexShader() const
1639 {
1640     std::ostringstream vert;
1641 
1642     vert << "#version 300 es\n"
1643          << "in highp vec4 a_position;\n";
1644 
1645     if (m_isVertexCase)
1646     {
1647         vert << "out mediump vec4 v_color;\n";
1648         vert << "uniform highp " << m_samplerTypeStr << " u_sampler;\n";
1649         vert << "uniform highp ivec" << (m_has3DSize ? 3 : 2) << " u_texSize;\n";
1650         vert << "uniform highp int u_lod;\n";
1651     }
1652 
1653     vert << "void main()\n{\n";
1654 
1655     if (m_isVertexCase)
1656         vert << "    v_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, "
1657                 "0.0, 1.0));\n";
1658 
1659     vert << "    gl_Position = a_position;\n"
1660          << "}\n";
1661 
1662     return vert.str();
1663 }
1664 
genFragmentShader() const1665 std::string TextureSizeCase::genFragmentShader() const
1666 {
1667     std::ostringstream frag;
1668 
1669     frag << "#version 300 es\n"
1670          << "layout(location = 0) out mediump vec4 o_color;\n";
1671 
1672     if (m_isVertexCase)
1673         frag << "in mediump vec4 v_color;\n";
1674 
1675     if (!m_isVertexCase)
1676     {
1677         frag << "uniform highp " << m_samplerTypeStr << " u_sampler;\n";
1678         frag << "uniform highp ivec" << (m_has3DSize ? 3 : 2) << " u_texSize;\n";
1679         frag << "uniform highp int u_lod;\n";
1680     }
1681 
1682     frag << "void main()\n{\n";
1683 
1684     if (!m_isVertexCase)
1685         frag << "    o_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, "
1686                 "0.0, 1.0));\n";
1687     else
1688         frag << "    o_color = v_color;\n";
1689 
1690     frag << "}\n";
1691 
1692     return frag.str();
1693 }
1694 
getGLTextureTarget() const1695 glw::GLenum TextureSizeCase::getGLTextureTarget() const
1696 {
1697     switch (m_textureSpec.type)
1698     {
1699     case TEXTURETYPE_2D:
1700         return GL_TEXTURE_2D;
1701     case TEXTURETYPE_CUBE_MAP:
1702         return GL_TEXTURE_CUBE_MAP;
1703     case TEXTURETYPE_2D_ARRAY:
1704         return GL_TEXTURE_2D_ARRAY;
1705     case TEXTURETYPE_3D:
1706         return GL_TEXTURE_3D;
1707     default:
1708         DE_ASSERT(false);
1709     }
1710     return 0;
1711 }
1712 
ShaderTextureFunctionTests(Context & context)1713 ShaderTextureFunctionTests::ShaderTextureFunctionTests(Context &context)
1714     : TestCaseGroup(context, "texture_functions", "Texture Access Function Tests")
1715 {
1716 }
1717 
~ShaderTextureFunctionTests(void)1718 ShaderTextureFunctionTests::~ShaderTextureFunctionTests(void)
1719 {
1720 }
1721 
1722 enum CaseFlags
1723 {
1724     VERTEX   = (1 << 0),
1725     FRAGMENT = (1 << 1),
1726     BOTH     = VERTEX | FRAGMENT
1727 };
1728 
1729 struct TexFuncCaseSpec
1730 {
1731     const char *name;
1732     TextureLookupSpec lookupSpec;
1733     TextureSpec texSpec;
1734     TexEvalFunc evalFunc;
1735     uint32_t flags;
1736 };
1737 
1738 #define CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, USEOFFSET, OFFSET, TEXSPEC, EVALFUNC,   \
1739                   FLAGS)                                                                                           \
1740     {                                                                                                              \
1741         #NAME,                                                                                                     \
1742             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, USEBIAS, MINLOD, MAXLOD, tcu::Vec3(0.0f), tcu::Vec3(0.0f), \
1743                               tcu::Vec3(0.0f), tcu::Vec3(0.0f), USEOFFSET, OFFSET),                                \
1744             TEXSPEC, EVALFUNC, FLAGS                                                                               \
1745     }
1746 #define GRAD_CASE_SPEC(NAME, FUNC, MINCOORD, MAXCOORD, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, OFFSET, TEXSPEC,    \
1747                        EVALFUNC, FLAGS)                                                                           \
1748     {                                                                                                             \
1749         #NAME,                                                                                                    \
1750             TextureLookupSpec(FUNC, MINCOORD, MAXCOORD, false, 0.0f, 0.0f, MINDX, MAXDX, MINDY, MAXDY, USEOFFSET, \
1751                               OFFSET),                                                                            \
1752             TEXSPEC, EVALFUNC, FLAGS                                                                              \
1753     }
1754 
createCaseGroup(TestCaseGroup * parent,const char * groupName,const char * groupDesc,const TexFuncCaseSpec * cases,int numCases)1755 static void createCaseGroup(TestCaseGroup *parent, const char *groupName, const char *groupDesc,
1756                             const TexFuncCaseSpec *cases, int numCases)
1757 {
1758     tcu::TestCaseGroup *group = new tcu::TestCaseGroup(parent->getTestContext(), groupName, groupDesc);
1759     parent->addChild(group);
1760 
1761     for (int ndx = 0; ndx < numCases; ndx++)
1762     {
1763         std::string name = cases[ndx].name;
1764         if (cases[ndx].flags & VERTEX)
1765             group->addChild(new ShaderTextureFunctionCase(parent->getContext(), (name + "_vertex").c_str(), "",
1766                                                           cases[ndx].lookupSpec, cases[ndx].texSpec,
1767                                                           cases[ndx].evalFunc, true));
1768         if (cases[ndx].flags & FRAGMENT)
1769             group->addChild(new ShaderTextureFunctionCase(parent->getContext(), (name + "_fragment").c_str(), "",
1770                                                           cases[ndx].lookupSpec, cases[ndx].texSpec,
1771                                                           cases[ndx].evalFunc, false));
1772     }
1773 }
1774 
init(void)1775 void ShaderTextureFunctionTests::init(void)
1776 {
1777     // Samplers
1778     static const tcu::Sampler samplerNearestNoMipmap(
1779         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST,
1780         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
1781         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1782     static const tcu::Sampler samplerLinearNoMipmap(
1783         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR,
1784         tcu::Sampler::LINEAR, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
1785         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1786     static const tcu::Sampler samplerNearestMipmap(
1787         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
1788         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
1789         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1790     static const tcu::Sampler samplerLinearMipmap(
1791         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR_MIPMAP_NEAREST,
1792         tcu::Sampler::LINEAR, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_NONE,
1793         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1794 
1795     static const tcu::Sampler samplerShadowNoMipmap(
1796         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST,
1797         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
1798         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1799     static const tcu::Sampler samplerShadowMipmap(
1800         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
1801         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, true /* normalized coords */, tcu::Sampler::COMPAREMODE_LESS,
1802         0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */, true /* seamless cube map */);
1803 
1804     static const tcu::Sampler samplerTexelFetch(
1805         tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST,
1806         tcu::Sampler::NEAREST, 0.0f /* LOD threshold */, false /* non-normalized coords */,
1807         tcu::Sampler::COMPAREMODE_NONE, 0 /* cmp channel */, tcu::Vec4(0.0f) /* border color */,
1808         true /* seamless cube map */);
1809 
1810     // Default textures.
1811     //                                                Type                    Format                    W        H        D    L    Sampler
1812     static const TextureSpec tex2DFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
1813     static const TextureSpec tex2DFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
1814     static const TextureSpec tex2DInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
1815     static const TextureSpec tex2DUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
1816     static const TextureSpec tex2DMipmapFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
1817     static const TextureSpec tex2DMipmapFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 9, samplerLinearMipmap);
1818     static const TextureSpec tex2DMipmapInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
1819     static const TextureSpec tex2DMipmapUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
1820 
1821     static const TextureSpec tex2DShadow(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 256, 256, 1, 9, samplerShadowNoMipmap);
1822     static const TextureSpec tex2DMipmapShadow(TEXTURETYPE_2D, GL_DEPTH_COMPONENT16, 256, 256, 1, 9,
1823                                                samplerShadowMipmap);
1824 
1825     static const TextureSpec tex2DTexelFetchFixed(TEXTURETYPE_2D, GL_RGBA8, 256, 256, 1, 9, samplerTexelFetch);
1826     static const TextureSpec tex2DTexelFetchFloat(TEXTURETYPE_2D, GL_RGBA16F, 256, 256, 1, 9, samplerTexelFetch);
1827     static const TextureSpec tex2DTexelFetchInt(TEXTURETYPE_2D, GL_RGBA8I, 256, 256, 1, 9, samplerTexelFetch);
1828     static const TextureSpec tex2DTexelFetchUint(TEXTURETYPE_2D, GL_RGBA8UI, 256, 256, 1, 9, samplerTexelFetch);
1829 
1830     static const TextureSpec texCubeFixed(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
1831     static const TextureSpec texCubeFloat(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
1832     static const TextureSpec texCubeInt(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
1833     static const TextureSpec texCubeUint(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
1834     static const TextureSpec texCubeMipmapFixed(TEXTURETYPE_CUBE_MAP, GL_RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
1835     static const TextureSpec texCubeMipmapFloat(TEXTURETYPE_CUBE_MAP, GL_RGBA16F, 128, 128, 1, 8, samplerLinearMipmap);
1836     static const TextureSpec texCubeMipmapInt(TEXTURETYPE_CUBE_MAP, GL_RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
1837     static const TextureSpec texCubeMipmapUint(TEXTURETYPE_CUBE_MAP, GL_RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
1838 
1839     static const TextureSpec texCubeShadow(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 256, 256, 1, 1,
1840                                            samplerShadowNoMipmap);
1841     static const TextureSpec texCubeMipmapShadow(TEXTURETYPE_CUBE_MAP, GL_DEPTH_COMPONENT16, 256, 256, 1, 9,
1842                                                  samplerShadowMipmap);
1843 
1844     static const TextureSpec tex2DArrayFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 1, samplerLinearNoMipmap);
1845     static const TextureSpec tex2DArrayFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 1, samplerLinearNoMipmap);
1846     static const TextureSpec tex2DArrayInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 1, samplerNearestNoMipmap);
1847     static const TextureSpec tex2DArrayUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 1, samplerNearestNoMipmap);
1848     static const TextureSpec tex2DArrayMipmapFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 8, samplerLinearMipmap);
1849     static const TextureSpec tex2DArrayMipmapFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 8,
1850                                                    samplerLinearMipmap);
1851     static const TextureSpec tex2DArrayMipmapInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 8, samplerNearestMipmap);
1852     static const TextureSpec tex2DArrayMipmapUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 8,
1853                                                   samplerNearestMipmap);
1854 
1855     static const TextureSpec tex2DArrayShadow(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 128, 128, 4, 1,
1856                                               samplerShadowNoMipmap);
1857     static const TextureSpec tex2DArrayMipmapShadow(TEXTURETYPE_2D_ARRAY, GL_DEPTH_COMPONENT16, 128, 128, 4, 8,
1858                                                     samplerShadowMipmap);
1859 
1860     static const TextureSpec tex2DArrayTexelFetchFixed(TEXTURETYPE_2D_ARRAY, GL_RGBA8, 128, 128, 4, 8,
1861                                                        samplerTexelFetch);
1862     static const TextureSpec tex2DArrayTexelFetchFloat(TEXTURETYPE_2D_ARRAY, GL_RGBA16F, 128, 128, 4, 8,
1863                                                        samplerTexelFetch);
1864     static const TextureSpec tex2DArrayTexelFetchInt(TEXTURETYPE_2D_ARRAY, GL_RGBA8I, 128, 128, 4, 8,
1865                                                      samplerTexelFetch);
1866     static const TextureSpec tex2DArrayTexelFetchUint(TEXTURETYPE_2D_ARRAY, GL_RGBA8UI, 128, 128, 4, 8,
1867                                                       samplerTexelFetch);
1868 
1869     static const TextureSpec tex3DFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 1, samplerLinearNoMipmap);
1870     static const TextureSpec tex3DFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 1, samplerLinearNoMipmap);
1871     static const TextureSpec tex3DInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 1, samplerNearestNoMipmap);
1872     static const TextureSpec tex3DUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 1, samplerNearestNoMipmap);
1873     static const TextureSpec tex3DMipmapFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 7, samplerLinearMipmap);
1874     static const TextureSpec tex3DMipmapFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 7, samplerLinearMipmap);
1875     static const TextureSpec tex3DMipmapInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 7, samplerNearestMipmap);
1876     static const TextureSpec tex3DMipmapUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 7, samplerNearestMipmap);
1877 
1878     static const TextureSpec tex3DTexelFetchFixed(TEXTURETYPE_3D, GL_RGBA8, 64, 32, 32, 7, samplerTexelFetch);
1879     static const TextureSpec tex3DTexelFetchFloat(TEXTURETYPE_3D, GL_RGBA16F, 64, 32, 32, 7, samplerTexelFetch);
1880     static const TextureSpec tex3DTexelFetchInt(TEXTURETYPE_3D, GL_RGBA8I, 64, 32, 32, 7, samplerTexelFetch);
1881     static const TextureSpec tex3DTexelFetchUint(TEXTURETYPE_3D, GL_RGBA8UI, 64, 32, 32, 7, samplerTexelFetch);
1882 
1883     // texture() cases
1884     static const TexFuncCaseSpec textureCases[] = {
1885         //          Name                            Function            MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
1886         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
1887                   false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2D, VERTEX),
1888         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
1889                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2D, FRAGMENT),
1890         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
1891                   false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2D, VERTEX),
1892         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
1893                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2D, FRAGMENT),
1894         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
1895                   0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2D, VERTEX),
1896         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
1897                   0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2D, FRAGMENT),
1898         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
1899                   0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2D, VERTEX),
1900         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
1901                   0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2D, FRAGMENT),
1902 
1903         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),
1904                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2DBias, FRAGMENT),
1905         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),
1906                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2DBias, FRAGMENT),
1907         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,
1908                   -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DBias, FRAGMENT),
1909         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,
1910                   -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DBias, FRAGMENT),
1911 
1912         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
1913                   false, 0.0f, 0.0f, false, IVec3(0), texCubeFixed, evalTextureCube, VERTEX),
1914         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
1915                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapFixed, evalTextureCube, FRAGMENT),
1916         CASE_SPEC(samplercube_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
1917                   false, 0.0f, 0.0f, false, IVec3(0), texCubeFloat, evalTextureCube, VERTEX),
1918         CASE_SPEC(samplercube_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
1919                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapFloat, evalTextureCube, FRAGMENT),
1920         CASE_SPEC(isamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f), false,
1921                   0.0f, 0.0f, false, IVec3(0), texCubeInt, evalTextureCube, VERTEX),
1922         CASE_SPEC(isamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f), false,
1923                   0.0f, 0.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCube, FRAGMENT),
1924         CASE_SPEC(usamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
1925                   false, 0.0f, 0.0f, false, IVec3(0), texCubeUint, evalTextureCube, VERTEX),
1926         CASE_SPEC(usamplercube, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
1927                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCube, FRAGMENT),
1928 
1929         CASE_SPEC(samplercube_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
1930                   Vec4(1.0f, 1.0f, 1.01f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapFixed,
1931                   evalTextureCubeBias, FRAGMENT),
1932         CASE_SPEC(samplercube_bias_float, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
1933                   Vec4(1.0f, 1.0f, -1.01f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapFloat,
1934                   evalTextureCubeBias, FRAGMENT),
1935         CASE_SPEC(isamplercube_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
1936                   true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCubeBias, FRAGMENT),
1937         CASE_SPEC(usamplercube_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
1938                   true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCubeBias, FRAGMENT),
1939 
1940         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1941                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayFixed, evalTexture2DArray, VERTEX),
1942         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1943                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapFixed, evalTexture2DArray, FRAGMENT),
1944         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1945                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayFloat, evalTexture2DArray, VERTEX),
1946         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1947                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapFloat, evalTexture2DArray, FRAGMENT),
1948         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1949                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayInt, evalTexture2DArray, VERTEX),
1950         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1951                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArray, FRAGMENT),
1952         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1953                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayUint, evalTexture2DArray, VERTEX),
1954         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1955                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArray, FRAGMENT),
1956 
1957         CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
1958                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapFixed,
1959                   evalTexture2DArrayBias, FRAGMENT),
1960         CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
1961                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapFloat,
1962                   evalTexture2DArrayBias, FRAGMENT),
1963         CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1964                   true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArrayBias, FRAGMENT),
1965         CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
1966                   true, -2.0f, 2.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArrayBias, FRAGMENT),
1967 
1968         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
1969                   false, 0.0f, 0.0f, false, IVec3(0), tex3DFixed, evalTexture3D, VERTEX),
1970         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
1971                   false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3D, FRAGMENT),
1972         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
1973                   false, 0.0f, 0.0f, false, IVec3(0), tex3DFloat, evalTexture3D, VERTEX),
1974         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
1975                   false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3D, FRAGMENT),
1976         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
1977                   0.0f, 0.0f, false, IVec3(0), tex3DInt, evalTexture3D, VERTEX),
1978         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
1979                   0.0f, 0.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3D, FRAGMENT),
1980         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
1981                   0.0f, 0.0f, false, IVec3(0), tex3DUint, evalTexture3D, VERTEX),
1982         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
1983                   0.0f, 0.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3D, FRAGMENT),
1984 
1985         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),
1986                   true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3DBias, FRAGMENT),
1987         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),
1988                   true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3DBias, FRAGMENT),
1989         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,
1990                   -2.0f, 2.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3DBias, FRAGMENT),
1991         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,
1992                   -2.0f, 2.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3DBias, FRAGMENT),
1993 
1994         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
1995                   false, 0.0f, 0.0f, false, IVec3(0), tex2DShadow, evalTexture2DShadow, VERTEX),
1996         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
1997                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadow, FRAGMENT),
1998         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
1999                   true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowBias, FRAGMENT),
2000 
2001         CASE_SPEC(samplercubeshadow, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 1.0f),
2002                   false, 0.0f, 0.0f, false, IVec3(0), texCubeShadow, evalTextureCubeShadow, VERTEX),
2003         CASE_SPEC(samplercubeshadow, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 1.0f),
2004                   false, 0.0f, 0.0f, false, IVec3(0), texCubeMipmapShadow, evalTextureCubeShadow, FRAGMENT),
2005         CASE_SPEC(samplercubeshadow_bias, FUNCTION_TEXTURE, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
2006                   Vec4(1.0f, 1.0f, 1.01f, 1.0f), true, -2.0f, 2.0f, false, IVec3(0), texCubeMipmapShadow,
2007                   evalTextureCubeShadowBias, FRAGMENT),
2008 
2009         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
2010                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayShadow, evalTexture2DArrayShadow, VERTEX),
2011         CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 1.0f),
2012                   false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayMipmapShadow, evalTexture2DArrayShadow, FRAGMENT)
2013 
2014         // Not in spec.
2015         //        CASE_SPEC(sampler2darrayshadow_bias, (FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f,  -0.5f,  0.0f), Vec4( 1.5f,  2.3f,  3.5f,  1.0f), true, -2.0f, 2.0f, Vec2(0.0f), Vec2(0.0f), false, IVec3(0)), tex2DArrayMipmapShadow, evalTexture2DArrayShadowBias, FRAGMENT)
2016     };
2017     createCaseGroup(this, "texture", "texture() Tests", textureCases, DE_LENGTH_OF_ARRAY(textureCases));
2018 
2019     // textureOffset() cases
2020     // \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
2021     static const TexFuncCaseSpec textureOffsetCases[] = {
2022         //          Name                            Function            MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                    EvalFunc                        Flags
2023         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2024                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixed, evalTexture2DOffset, VERTEX),
2025         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2026                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixed, evalTexture2DOffset, FRAGMENT),
2027         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2028                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloat, evalTexture2DOffset, VERTEX),
2029         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2030                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat, evalTexture2DOffset, FRAGMENT),
2031         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2032                   0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DInt, evalTexture2DOffset, VERTEX),
2033         CASE_SPEC(isampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2034                   0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapInt, evalTexture2DOffset, FRAGMENT),
2035         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2036                   0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUint, evalTexture2DOffset, VERTEX),
2037         CASE_SPEC(usampler2d, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2038                   0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUint, evalTexture2DOffset, FRAGMENT),
2039 
2040         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),
2041                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixed, evalTexture2DOffsetBias, FRAGMENT),
2042         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),
2043                   true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloat, evalTexture2DOffsetBias, FRAGMENT),
2044         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,
2045                   -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DInt, evalTexture2DOffsetBias, FRAGMENT),
2046         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,
2047                   -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUint, evalTexture2DOffsetBias, FRAGMENT),
2048 
2049         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2050                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayFixed, evalTexture2DArrayOffset, VERTEX),
2051         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2052                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFixed, evalTexture2DArrayOffset, FRAGMENT),
2053         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2054                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayFloat, evalTexture2DArrayOffset, VERTEX),
2055         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2056                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFloat, evalTexture2DArrayOffset, FRAGMENT),
2057         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2058                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayInt, evalTexture2DArrayOffset, VERTEX),
2059         CASE_SPEC(isampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2060                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapInt, evalTexture2DArrayOffset, FRAGMENT),
2061         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2062                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayUint, evalTexture2DArrayOffset, VERTEX),
2063         CASE_SPEC(usampler2darray, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2064                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapUint, evalTexture2DArrayOffset, FRAGMENT),
2065 
2066         CASE_SPEC(sampler2darray_bias_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2067                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DArrayFixed,
2068                   evalTexture2DArrayOffsetBias, FRAGMENT),
2069         CASE_SPEC(sampler2darray_bias_float, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2070                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DArrayFloat,
2071                   evalTexture2DArrayOffsetBias, FRAGMENT),
2072         CASE_SPEC(isampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2073                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DArrayInt, evalTexture2DArrayOffsetBias, FRAGMENT),
2074         CASE_SPEC(usampler2darray_bias, FUNCTION_TEXTURE, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2075                   true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DArrayUint, evalTexture2DArrayOffsetBias, FRAGMENT),
2076 
2077         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2078                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DFixed, evalTexture3DOffset, VERTEX),
2079         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2080                   false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapFixed, evalTexture3DOffset, FRAGMENT),
2081         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2082                   false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DFloat, evalTexture3DOffset, VERTEX),
2083         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2084                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DMipmapFloat, evalTexture3DOffset, FRAGMENT),
2085         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2086                   0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DInt, evalTexture3DOffset, VERTEX),
2087         CASE_SPEC(isampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2088                   0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DMipmapInt, evalTexture3DOffset, FRAGMENT),
2089         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2090                   0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DUint, evalTexture3DOffset, VERTEX),
2091         CASE_SPEC(usampler3d, FUNCTION_TEXTURE, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2092                   0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapUint, evalTexture3DOffset, FRAGMENT),
2093 
2094         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),
2095                   true, -2.0f, 1.0f, true, IVec3(-8, 7, 3), tex3DFixed, evalTexture3DOffsetBias, FRAGMENT),
2096         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),
2097                   true, -2.0f, 1.0f, true, IVec3(7, 3, -8), tex3DFloat, evalTexture3DOffsetBias, FRAGMENT),
2098         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,
2099                   -2.0f, 2.0f, true, IVec3(3, -8, 7), tex3DInt, evalTexture3DOffsetBias, FRAGMENT),
2100         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,
2101                   -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DUint, evalTexture3DOffsetBias, FRAGMENT),
2102 
2103         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
2104                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DShadow, evalTexture2DShadowOffset, VERTEX),
2105         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
2106                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapShadow, evalTexture2DShadowOffset, FRAGMENT),
2107         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTURE, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
2108                   true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DShadow, evalTexture2DShadowOffsetBias, FRAGMENT)};
2109     createCaseGroup(this, "textureoffset", "textureOffset() Tests", textureOffsetCases,
2110                     DE_LENGTH_OF_ARRAY(textureOffsetCases));
2111 
2112     // textureProj() cases
2113     // \note Currently uses constant divider!
2114     static const TexFuncCaseSpec textureProjCases[] = {
2115         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
2116         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2117                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2DProj3,
2118                   VERTEX),
2119         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2120                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed,
2121                   evalTexture2DProj3, FRAGMENT),
2122         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2123                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2DProj3,
2124                   VERTEX),
2125         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2126                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat,
2127                   evalTexture2DProj3, FRAGMENT),
2128         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2129                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2DProj3,
2130                   VERTEX),
2131         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2132                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt,
2133                   evalTexture2DProj3, FRAGMENT),
2134         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2135                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2DProj3,
2136                   VERTEX),
2137         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2138                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint,
2139                   evalTexture2DProj3, FRAGMENT),
2140 
2141         CASE_SPEC(sampler2d_vec3_bias_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2142                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed,
2143                   evalTexture2DProj3Bias, FRAGMENT),
2144         CASE_SPEC(sampler2d_vec3_bias_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2145                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat,
2146                   evalTexture2DProj3Bias, FRAGMENT),
2147         CASE_SPEC(isampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2148                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt,
2149                   evalTexture2DProj3Bias, FRAGMENT),
2150         CASE_SPEC(usampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2151                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint,
2152                   evalTexture2DProj3Bias, FRAGMENT),
2153 
2154         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2155                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFixed, evalTexture2DProj,
2156                   VERTEX),
2157         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2158                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFixed,
2159                   evalTexture2DProj, FRAGMENT),
2160         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2161                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DFloat, evalTexture2DProj,
2162                   VERTEX),
2163         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2164                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapFloat,
2165                   evalTexture2DProj, FRAGMENT),
2166         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2167                   false, 0.0f, 0.0f, false, IVec3(0), tex2DInt, evalTexture2DProj, VERTEX),
2168         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2169                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DProj, FRAGMENT),
2170         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2171                   false, 0.0f, 0.0f, false, IVec3(0), tex2DUint, evalTexture2DProj, VERTEX),
2172         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2173                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DProj, FRAGMENT),
2174 
2175         CASE_SPEC(sampler2d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2176                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFixed,
2177                   evalTexture2DProjBias, FRAGMENT),
2178         CASE_SPEC(sampler2d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2179                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapFloat,
2180                   evalTexture2DProjBias, FRAGMENT),
2181         CASE_SPEC(isampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2182                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapInt,
2183                   evalTexture2DProjBias, FRAGMENT),
2184         CASE_SPEC(usampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2185                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapUint,
2186                   evalTexture2DProjBias, FRAGMENT),
2187 
2188         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2189                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DFixed, evalTexture3DProj,
2190                   VERTEX),
2191         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2192                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFixed,
2193                   evalTexture3DProj, FRAGMENT),
2194         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2195                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DFloat, evalTexture3DProj,
2196                   VERTEX),
2197         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2198                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapFloat,
2199                   evalTexture3DProj, FRAGMENT),
2200         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2201                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DInt, evalTexture3DProj,
2202                   VERTEX),
2203         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2204                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapInt,
2205                   evalTexture3DProj, FRAGMENT),
2206         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2207                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DUint, evalTexture3DProj,
2208                   VERTEX),
2209         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2210                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, false, IVec3(0), tex3DMipmapUint,
2211                   evalTexture3DProj, FRAGMENT),
2212 
2213         CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2214                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFixed,
2215                   evalTexture3DProjBias, FRAGMENT),
2216         CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2217                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 1.0f, false, IVec3(0), tex3DMipmapFloat,
2218                   evalTexture3DProjBias, FRAGMENT),
2219         CASE_SPEC(isampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2220                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, false, IVec3(0), tex3DMipmapInt,
2221                   evalTexture3DProjBias, FRAGMENT),
2222         CASE_SPEC(usampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2223                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, false, IVec3(0), tex3DMipmapUint,
2224                   evalTexture3DProjBias, FRAGMENT),
2225 
2226         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
2227                   false, 0.0f, 0.0f, false, IVec3(0), tex2DShadow, evalTexture2DShadowProj, VERTEX),
2228         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
2229                   false, 0.0f, 0.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowProj, FRAGMENT),
2230         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
2231                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), true, -2.0f, 2.0f, false, IVec3(0), tex2DMipmapShadow,
2232                   evalTexture2DShadowProjBias, FRAGMENT)};
2233     createCaseGroup(this, "textureproj", "textureProj() Tests", textureProjCases, DE_LENGTH_OF_ARRAY(textureProjCases));
2234 
2235     // textureProjOffset() cases
2236     // \note Currently uses constant divider!
2237     static const TexFuncCaseSpec textureProjOffsetCases[] = {
2238         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                    EvalFunc                        Flags
2239         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2240                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixed,
2241                   evalTexture2DProj3Offset, VERTEX),
2242         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2243                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixed,
2244                   evalTexture2DProj3Offset, FRAGMENT),
2245         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2246                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloat,
2247                   evalTexture2DProj3Offset, VERTEX),
2248         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2249                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat,
2250                   evalTexture2DProj3Offset, FRAGMENT),
2251         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2252                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DInt,
2253                   evalTexture2DProj3Offset, VERTEX),
2254         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2255                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapInt,
2256                   evalTexture2DProj3Offset, FRAGMENT),
2257         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2258                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUint,
2259                   evalTexture2DProj3Offset, VERTEX),
2260         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2261                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUint,
2262                   evalTexture2DProj3Offset, FRAGMENT),
2263 
2264         CASE_SPEC(sampler2d_vec3_bias_fixed, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2265                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixed,
2266                   evalTexture2DProj3OffsetBias, FRAGMENT),
2267         CASE_SPEC(sampler2d_vec3_bias_float, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2268                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloat,
2269                   evalTexture2DProj3OffsetBias, FRAGMENT),
2270         CASE_SPEC(isampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2271                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DInt,
2272                   evalTexture2DProj3OffsetBias, FRAGMENT),
2273         CASE_SPEC(usampler2d_vec3_bias, FUNCTION_TEXTUREPROJ3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2274                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUint,
2275                   evalTexture2DProj3OffsetBias, FRAGMENT),
2276 
2277         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2278                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFixed,
2279                   evalTexture2DProjOffset, VERTEX),
2280         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2281                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFixed,
2282                   evalTexture2DProjOffset, FRAGMENT),
2283         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2284                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DFloat,
2285                   evalTexture2DProjOffset, VERTEX),
2286         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2287                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat,
2288                   evalTexture2DProjOffset, FRAGMENT),
2289         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2290                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DInt, evalTexture2DProjOffset, VERTEX),
2291         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2292                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapInt, evalTexture2DProjOffset, FRAGMENT),
2293         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2294                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DUint, evalTexture2DProjOffset, VERTEX),
2295         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f), Vec4(2.25f, 3.45f, 0.0f, 1.5f),
2296                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapUint, evalTexture2DProjOffset, FRAGMENT),
2297 
2298         CASE_SPEC(sampler2d_vec4_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2299                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DFixed,
2300                   evalTexture2DProjOffsetBias, FRAGMENT),
2301         CASE_SPEC(sampler2d_vec4_bias_float, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2302                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DFloat,
2303                   evalTexture2DProjOffsetBias, FRAGMENT),
2304         CASE_SPEC(isampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2305                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DInt,
2306                   evalTexture2DProjOffsetBias, FRAGMENT),
2307         CASE_SPEC(usampler2d_vec4_bias, FUNCTION_TEXTUREPROJ, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2308                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), true, -2.0f, 2.0f, true, IVec3(7, -8, 0), tex2DUint,
2309                   evalTexture2DProjOffsetBias, FRAGMENT),
2310 
2311         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2312                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DFixed,
2313                   evalTexture3DProjOffset, VERTEX),
2314         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2315                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapFixed,
2316                   evalTexture3DProjOffset, FRAGMENT),
2317         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2318                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DFloat,
2319                   evalTexture3DProjOffset, VERTEX),
2320         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2321                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DMipmapFloat,
2322                   evalTexture3DProjOffset, FRAGMENT),
2323         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2324                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DInt,
2325                   evalTexture3DProjOffset, VERTEX),
2326         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2327                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(3, -8, 7), tex3DMipmapInt,
2328                   evalTexture3DProjOffset, FRAGMENT),
2329         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2330                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DUint,
2331                   evalTexture3DProjOffset, VERTEX),
2332         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2333                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, 0.0f, 0.0f, true, IVec3(7, 3, -8), tex3DMipmapUint,
2334                   evalTexture3DProjOffset, FRAGMENT),
2335 
2336         CASE_SPEC(sampler3d_bias_fixed, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2337                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DFixed,
2338                   evalTexture3DProjOffsetBias, FRAGMENT),
2339         CASE_SPEC(sampler3d_bias_float, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2340                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(7, 3, -8), tex3DFloat,
2341                   evalTexture3DProjOffsetBias, FRAGMENT),
2342         CASE_SPEC(isampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2343                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(3, -8, 7), tex3DInt,
2344                   evalTexture3DProjOffsetBias, FRAGMENT),
2345         CASE_SPEC(usampler3d_bias, FUNCTION_TEXTUREPROJ, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2346                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 3), tex3DUint,
2347                   evalTexture3DProjOffsetBias, FRAGMENT),
2348 
2349         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
2350                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DShadow, evalTexture2DShadowProjOffset, VERTEX),
2351         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f), Vec4(-2.25f, -3.45f, 1.5f, 1.5f),
2352                   false, 0.0f, 0.0f, true, IVec3(7, -8, 0), tex2DMipmapShadow, evalTexture2DShadowProjOffset, FRAGMENT),
2353         CASE_SPEC(sampler2dshadow_bias, FUNCTION_TEXTUREPROJ, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
2354                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), true, -2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DShadow,
2355                   evalTexture2DShadowProjOffsetBias, FRAGMENT)};
2356     createCaseGroup(this, "textureprojoffset", "textureOffsetProj() Tests", textureProjOffsetCases,
2357                     DE_LENGTH_OF_ARRAY(textureProjOffsetCases));
2358 
2359     // textureLod() cases
2360     static const TexFuncCaseSpec textureLodCases[] = {
2361         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                Flags
2362         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2363                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed, evalTexture2DLod, BOTH),
2364         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2365                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat, evalTexture2DLod, BOTH),
2366         CASE_SPEC(isampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2367                   -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt, evalTexture2DLod, BOTH),
2368         CASE_SPEC(usampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2369                   -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint, evalTexture2DLod, BOTH),
2370 
2371         CASE_SPEC(samplercube_fixed, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
2372                   Vec4(1.0f, 1.0f, 1.01f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapFixed,
2373                   evalTextureCubeLod, BOTH),
2374         CASE_SPEC(samplercube_float, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
2375                   Vec4(1.0f, 1.0f, -1.01f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapFloat,
2376                   evalTextureCubeLod, BOTH),
2377         CASE_SPEC(isamplercube, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f), Vec4(1.0f, 1.0f, 1.01f, 0.0f),
2378                   false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapInt, evalTextureCubeLod, BOTH),
2379         CASE_SPEC(usamplercube, FUNCTION_TEXTURELOD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f), Vec4(1.0f, 1.0f, -1.01f, 0.0f),
2380                   false, -1.0f, 9.0f, false, IVec3(0), texCubeMipmapUint, evalTextureCubeLod, BOTH),
2381 
2382         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2383                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapFixed,
2384                   evalTexture2DArrayLod, BOTH),
2385         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2386                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapFloat,
2387                   evalTexture2DArrayLod, BOTH),
2388         CASE_SPEC(isampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2389                   false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapInt, evalTexture2DArrayLod, BOTH),
2390         CASE_SPEC(usampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2391                   false, -1.0f, 8.0f, false, IVec3(0), tex2DArrayMipmapUint, evalTexture2DArrayLod, BOTH),
2392 
2393         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2394                   false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFixed, evalTexture3DLod, BOTH),
2395         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2396                   false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFloat, evalTexture3DLod, BOTH),
2397         CASE_SPEC(isampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2398                   -1.0f, 7.0f, false, IVec3(0), tex3DMipmapInt, evalTexture3DLod, BOTH),
2399         CASE_SPEC(usampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2400                   -1.0f, 7.0f, false, IVec3(0), tex3DMipmapUint, evalTexture3DLod, BOTH),
2401 
2402         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
2403                   false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapShadow, evalTexture2DShadowLod, BOTH)};
2404     createCaseGroup(this, "texturelod", "textureLod() Tests", textureLodCases, DE_LENGTH_OF_ARRAY(textureLodCases));
2405 
2406     // textureLodOffset() cases
2407     static const TexFuncCaseSpec textureLodOffsetCases[] = {
2408         //          Name                            Function                MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                    EvalFunc                        Flags
2409         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2410                   false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixed, evalTexture2DLodOffset, BOTH),
2411         CASE_SPEC(sampler2d_float, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2412                   false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat, evalTexture2DLodOffset, BOTH),
2413         CASE_SPEC(isampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2414                   -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapInt, evalTexture2DLodOffset, BOTH),
2415         CASE_SPEC(usampler2d, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f), false,
2416                   -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUint, evalTexture2DLodOffset, BOTH),
2417 
2418         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2419                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, true, IVec3(-8, 7, 0), tex2DArrayMipmapFixed,
2420                   evalTexture2DArrayLodOffset, BOTH),
2421         CASE_SPEC(sampler2darray_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2422                   Vec4(1.5f, 2.3f, 3.5f, 0.0f), false, -1.0f, 8.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapFloat,
2423                   evalTexture2DArrayLodOffset, BOTH),
2424         CASE_SPEC(isampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2425                   false, -1.0f, 8.0f, true, IVec3(-8, 7, 0), tex2DArrayMipmapInt, evalTexture2DArrayLodOffset, BOTH),
2426         CASE_SPEC(usampler2darray, FUNCTION_TEXTURELOD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f), Vec4(1.5f, 2.3f, 3.5f, 0.0f),
2427                   false, -1.0f, 8.0f, true, IVec3(7, -8, 0), tex2DArrayMipmapUint, evalTexture2DArrayLodOffset, BOTH),
2428 
2429         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2430                   false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapFixed, evalTexture3DLodOffset, BOTH),
2431         CASE_SPEC(sampler3d_float, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2432                   false, -1.0f, 7.0f, true, IVec3(7, 3, -8), tex3DMipmapFloat, evalTexture3DLodOffset, BOTH),
2433         CASE_SPEC(isampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2434                   -1.0f, 7.0f, true, IVec3(3, -8, 7), tex3DMipmapInt, evalTexture3DLodOffset, BOTH),
2435         CASE_SPEC(usampler3d, FUNCTION_TEXTURELOD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f), false,
2436                   -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapUint, evalTexture3DLodOffset, BOTH),
2437 
2438         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTURELOD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 1.0f, 0.0f),
2439                   false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapShadow, evalTexture2DShadowLodOffset, BOTH)};
2440     createCaseGroup(this, "texturelodoffset", "textureLodOffset() Tests", textureLodOffsetCases,
2441                     DE_LENGTH_OF_ARRAY(textureLodOffsetCases));
2442 
2443     // textureProjLod() cases
2444     static const TexFuncCaseSpec textureProjLodCases[] = {
2445         //          Name                            Function                    MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset        Format                    EvalFunc                    Flags
2446         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2447                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed,
2448                   evalTexture2DProjLod3, BOTH),
2449         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2450                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat,
2451                   evalTexture2DProjLod3, BOTH),
2452         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2453                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt,
2454                   evalTexture2DProjLod3, BOTH),
2455         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2456                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint,
2457                   evalTexture2DProjLod3, BOTH),
2458 
2459         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2460                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFixed,
2461                   evalTexture2DProjLod, BOTH),
2462         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2463                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapFloat,
2464                   evalTexture2DProjLod, BOTH),
2465         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2466                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapInt,
2467                   evalTexture2DProjLod, BOTH),
2468         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2469                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapUint,
2470                   evalTexture2DProjLod, BOTH),
2471 
2472         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2473                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFixed,
2474                   evalTexture3DProjLod, BOTH),
2475         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2476                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapFloat,
2477                   evalTexture3DProjLod, BOTH),
2478         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2479                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapInt,
2480                   evalTexture3DProjLod, BOTH),
2481         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2482                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, false, IVec3(0), tex3DMipmapUint,
2483                   evalTexture3DProjLod, BOTH),
2484 
2485         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
2486                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), false, -1.0f, 9.0f, false, IVec3(0), tex2DMipmapShadow,
2487                   evalTexture2DShadowProjLod, BOTH)};
2488     createCaseGroup(this, "textureprojlod", "textureProjLod() Tests", textureProjLodCases,
2489                     DE_LENGTH_OF_ARRAY(textureProjLodCases));
2490 
2491     // textureProjLodOffset() cases
2492     static const TexFuncCaseSpec textureProjLodOffsetCases[] = {
2493         //          Name                            Function                    MinCoord                            MaxCoord                            Bias?    MinLod    MaxLod    Offset?    Offset                Format                    EvalFunc                                Flags
2494         CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2495                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixed,
2496                   evalTexture2DProjLod3Offset, BOTH),
2497         CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2498                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat,
2499                   evalTexture2DProjLod3Offset, BOTH),
2500         CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2501                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapInt,
2502                   evalTexture2DProjLod3Offset, BOTH),
2503         CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJLOD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2504                   Vec4(2.25f, 3.45f, 1.5f, 0.0f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUint,
2505                   evalTexture2DProjLod3Offset, BOTH),
2506 
2507         CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2508                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapFixed,
2509                   evalTexture2DProjLodOffset, BOTH),
2510         CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2511                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapFloat,
2512                   evalTexture2DProjLodOffset, BOTH),
2513         CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2514                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapInt,
2515                   evalTexture2DProjLodOffset, BOTH),
2516         CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJLOD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2517                   Vec4(2.25f, 3.45f, 0.0f, 1.5f), false, -1.0f, 9.0f, true, IVec3(7, -8, 0), tex2DMipmapUint,
2518                   evalTexture2DProjLodOffset, BOTH),
2519 
2520         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2521                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapFixed,
2522                   evalTexture3DProjLodOffset, BOTH),
2523         CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2524                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(7, 3, -8), tex3DMipmapFloat,
2525                   evalTexture3DProjLodOffset, BOTH),
2526         CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2527                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(3, -8, 7), tex3DMipmapInt,
2528                   evalTexture3DProjLodOffset, BOTH),
2529         CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJLOD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2530                   Vec4(-1.13f, -1.7f, -1.7f, -0.75f), false, -1.0f, 7.0f, true, IVec3(-8, 7, 3), tex3DMipmapUint,
2531                   evalTexture3DProjLodOffset, BOTH),
2532 
2533         CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJLOD, Vec4(0.2f, 0.6f, 0.0f, 1.5f),
2534                   Vec4(-2.25f, -3.45f, 1.5f, 1.5f), false, -1.0f, 9.0f, true, IVec3(-8, 7, 0), tex2DMipmapShadow,
2535                   evalTexture2DShadowProjLodOffset, BOTH)};
2536     createCaseGroup(this, "textureprojlodoffset", "textureProjLodOffset() Tests", textureProjLodOffsetCases,
2537                     DE_LENGTH_OF_ARRAY(textureProjLodOffsetCases));
2538 
2539     // textureGrad() cases
2540     // \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
2541     static const TexFuncCaseSpec textureGradCases[] = {
2542         //          Name                            Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset        Format                    EvalFunc                Flags
2543         GRAD_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2544                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2545                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
2546                        evalTexture2DGrad, BOTH),
2547         GRAD_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2548                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2549                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
2550                        evalTexture2DGrad, BOTH),
2551         GRAD_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2552                        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),
2553                        false, IVec3(0), tex2DMipmapInt, evalTexture2DGrad, BOTH),
2554         GRAD_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2555                        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),
2556                        false, IVec3(0), tex2DMipmapUint, evalTexture2DGrad, BOTH),
2557 
2558         GRAD_CASE_SPEC(samplercube_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
2559                        Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2560                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapFixed,
2561                        evalTextureCubeGrad, BOTH),
2562         GRAD_CASE_SPEC(samplercube_float, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
2563                        Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2564                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapFloat,
2565                        evalTextureCubeGrad, BOTH),
2566         GRAD_CASE_SPEC(isamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
2567                        Vec4(1.0f, 1.0f, 1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2568                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapInt,
2569                        evalTextureCubeGrad, BOTH),
2570         GRAD_CASE_SPEC(usamplercube, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, -1.01f, 0.0f),
2571                        Vec4(1.0f, 1.0f, -1.01f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2572                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), texCubeMipmapUint,
2573                        evalTextureCubeGrad, BOTH),
2574 
2575         GRAD_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2576                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2577                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapFixed,
2578                        evalTexture2DArrayGrad, BOTH),
2579         GRAD_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2580                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2581                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapFloat,
2582                        evalTexture2DArrayGrad, BOTH),
2583         GRAD_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2584                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2585                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapInt,
2586                        evalTexture2DArrayGrad, BOTH),
2587         GRAD_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2588                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2589                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DArrayMipmapUint,
2590                        evalTexture2DArrayGrad, BOTH),
2591 
2592         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2593                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2594                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFixed,
2595                        evalTexture3DGrad, BOTH),
2596         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2597                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2598                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
2599                        evalTexture3DGrad, VERTEX),
2600         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2601                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
2602                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
2603                        evalTexture3DGrad, FRAGMENT),
2604         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2605                        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),
2606                        false, IVec3(0), tex3DMipmapInt, evalTexture3DGrad, BOTH),
2607         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2608                        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),
2609                        false, IVec3(0), tex3DMipmapUint, evalTexture3DGrad, VERTEX),
2610         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2611                        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),
2612                        false, IVec3(0), tex3DMipmapUint, evalTexture3DGrad, FRAGMENT),
2613 
2614         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2615                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2616                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
2617                        evalTexture2DShadowGrad, BOTH),
2618         GRAD_CASE_SPEC(samplercubeshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.0f, -1.0f, 1.01f, 0.0f),
2619                        Vec4(1.0f, 1.0f, 1.01f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f),
2620                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), texCubeMipmapShadow,
2621                        evalTextureCubeShadowGrad, BOTH),
2622         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2623                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2624                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DArrayMipmapShadow,
2625                        evalTexture2DArrayShadowGrad, VERTEX),
2626         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2627                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2628                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), false, IVec3(0), tex2DArrayMipmapShadow,
2629                        evalTexture2DArrayShadowGrad, FRAGMENT)};
2630     createCaseGroup(this, "texturegrad", "textureGrad() Tests", textureGradCases, DE_LENGTH_OF_ARRAY(textureGradCases));
2631 
2632     // textureGradOffset() cases
2633     static const TexFuncCaseSpec textureGradOffsetCases[] = {
2634         //          Name                            Function                MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset                Format                    EvalFunc                            Flags
2635         GRAD_CASE_SPEC(sampler2d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2636                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2637                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixed,
2638                        evalTexture2DGradOffset, BOTH),
2639         GRAD_CASE_SPEC(sampler2d_float, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2640                        Vec4(1.5f, 2.3f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2641                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloat,
2642                        evalTexture2DGradOffset, BOTH),
2643         GRAD_CASE_SPEC(isampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2644                        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),
2645                        true, IVec3(-8, 7, 0), tex2DMipmapInt, evalTexture2DGradOffset, BOTH),
2646         GRAD_CASE_SPEC(usampler2d, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f), Vec4(1.5f, 2.3f, 0.0f, 0.0f),
2647                        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),
2648                        true, IVec3(7, -8, 0), tex2DMipmapUint, evalTexture2DGradOffset, BOTH),
2649 
2650         GRAD_CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2651                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2652                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DArrayMipmapFixed,
2653                        evalTexture2DArrayGradOffset, BOTH),
2654         GRAD_CASE_SPEC(sampler2darray_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2655                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2656                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DArrayMipmapFloat,
2657                        evalTexture2DArrayGradOffset, BOTH),
2658         GRAD_CASE_SPEC(isampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2659                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2660                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DArrayMipmapInt,
2661                        evalTexture2DArrayGradOffset, BOTH),
2662         GRAD_CASE_SPEC(usampler2darray, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2663                        Vec4(1.5f, 2.3f, 3.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2664                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DArrayMipmapUint,
2665                        evalTexture2DArrayGradOffset, BOTH),
2666 
2667         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2668                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2669                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapFixed,
2670                        evalTexture3DGradOffset, BOTH),
2671         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2672                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2673                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapFloat,
2674                        evalTexture3DGradOffset, VERTEX),
2675         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f),
2676                        Vec4(1.5f, 2.3f, 2.3f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
2677                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(3, -8, 7), tex3DMipmapFloat,
2678                        evalTexture3DGradOffset, FRAGMENT),
2679         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2680                        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),
2681                        true, IVec3(-8, 7, 3), tex3DMipmapInt, evalTexture3DGradOffset, BOTH),
2682         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2683                        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),
2684                        true, IVec3(7, 3, -8), tex3DMipmapUint, evalTexture3DGradOffset, VERTEX),
2685         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -1.4f, 0.1f, 0.0f), Vec4(1.5f, 2.3f, 2.3f, 0.0f),
2686                        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),
2687                        true, IVec3(3, -8, 7), tex3DMipmapUint, evalTexture3DGradOffset, FRAGMENT),
2688 
2689         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2690                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2691                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapShadow,
2692                        evalTexture2DShadowGradOffset, VERTEX),
2693         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREGRAD, Vec4(-0.2f, -0.4f, 0.0f, 0.0f),
2694                        Vec4(1.5f, 2.3f, 1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f),
2695                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapShadow,
2696                        evalTexture2DShadowGradOffset, FRAGMENT),
2697         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2698                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2699                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DArrayMipmapShadow,
2700                        evalTexture2DArrayShadowGradOffset, VERTEX),
2701         GRAD_CASE_SPEC(sampler2darrayshadow, FUNCTION_TEXTUREGRAD, Vec4(-1.2f, -0.4f, -0.5f, 0.0f),
2702                        Vec4(1.5f, 2.3f, 3.5f, 1.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2703                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DArrayMipmapShadow,
2704                        evalTexture2DArrayShadowGradOffset, FRAGMENT)};
2705     createCaseGroup(this, "texturegradoffset", "textureGradOffset() Tests", textureGradOffsetCases,
2706                     DE_LENGTH_OF_ARRAY(textureGradOffsetCases));
2707 
2708     // textureProjGrad() cases
2709     static const TexFuncCaseSpec textureProjGradCases[] = {
2710         //          Name                            Function                    MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset        Format                    EvalFunc                    Flags
2711         GRAD_CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2712                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2713                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
2714                        evalTexture2DProjGrad3, BOTH),
2715         GRAD_CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2716                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2717                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
2718                        evalTexture2DProjGrad3, BOTH),
2719         GRAD_CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2720                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2721                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapInt,
2722                        evalTexture2DProjGrad3, BOTH),
2723         GRAD_CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2724                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2725                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DMipmapUint,
2726                        evalTexture2DProjGrad3, BOTH),
2727 
2728         GRAD_CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2729                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2730                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFixed,
2731                        evalTexture2DProjGrad, BOTH),
2732         GRAD_CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2733                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2734                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapFloat,
2735                        evalTexture2DProjGrad, BOTH),
2736         GRAD_CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2737                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2738                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapInt,
2739                        evalTexture2DProjGrad, BOTH),
2740         GRAD_CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2741                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2742                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex2DMipmapUint,
2743                        evalTexture2DProjGrad, BOTH),
2744 
2745         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2746                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2747                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFixed,
2748                        evalTexture3DProjGrad, BOTH),
2749         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2750                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2751                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
2752                        evalTexture3DProjGrad, VERTEX),
2753         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2754                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
2755                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapFloat,
2756                        evalTexture3DProjGrad, FRAGMENT),
2757         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2758                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2759                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), false, IVec3(0), tex3DMipmapInt,
2760                        evalTexture3DProjGrad, BOTH),
2761         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2762                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2763                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), false, IVec3(0), tex3DMipmapUint,
2764                        evalTexture3DProjGrad, VERTEX),
2765         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2766                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2767                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), false, IVec3(0), tex3DMipmapUint,
2768                        evalTexture3DProjGrad, FRAGMENT),
2769 
2770         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
2771                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2772                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
2773                        evalTexture2DShadowProjGrad, VERTEX),
2774         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
2775                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2776                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), false, IVec3(0), tex2DMipmapShadow,
2777                        evalTexture2DShadowProjGrad, FRAGMENT)};
2778     createCaseGroup(this, "textureprojgrad", "textureProjGrad() Tests", textureProjGradCases,
2779                     DE_LENGTH_OF_ARRAY(textureProjGradCases));
2780 
2781     // textureProjGradOffset() cases
2782     static const TexFuncCaseSpec textureProjGradOffsetCases[] = {
2783         //          Name                            Function                    MinCoord                            MaxCoord                            MinDx                        MaxDx                        MinDy                        MaxDy                        Offset?    Offset                Format                    EvalFunc                            Flags
2784         GRAD_CASE_SPEC(sampler2d_vec3_fixed, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2785                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2786                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixed,
2787                        evalTexture2DProjGrad3Offset, BOTH),
2788         GRAD_CASE_SPEC(sampler2d_vec3_float, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2789                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2790                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloat,
2791                        evalTexture2DProjGrad3Offset, BOTH),
2792         GRAD_CASE_SPEC(isampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2793                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2794                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapInt,
2795                        evalTexture2DProjGrad3Offset, BOTH),
2796         GRAD_CASE_SPEC(usampler2d_vec3, FUNCTION_TEXTUREPROJGRAD3, Vec4(-0.3f, -0.6f, 1.5f, 0.0f),
2797                        Vec4(2.25f, 3.45f, 1.5f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2798                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapUint,
2799                        evalTexture2DProjGrad3Offset, BOTH),
2800 
2801         GRAD_CASE_SPEC(sampler2d_vec4_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2802                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2803                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapFixed,
2804                        evalTexture2DProjGradOffset, BOTH),
2805         GRAD_CASE_SPEC(sampler2d_vec4_float, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2806                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2807                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapFloat,
2808                        evalTexture2DProjGradOffset, BOTH),
2809         GRAD_CASE_SPEC(isampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2810                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2811                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapInt,
2812                        evalTexture2DProjGradOffset, BOTH),
2813         GRAD_CASE_SPEC(usampler2d_vec4, FUNCTION_TEXTUREPROJGRAD, Vec4(-0.3f, -0.6f, 0.0f, 1.5f),
2814                        Vec4(2.25f, 3.45f, 0.0f, 1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2815                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapUint,
2816                        evalTexture2DProjGradOffset, BOTH),
2817 
2818         GRAD_CASE_SPEC(sampler3d_fixed, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2819                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2820                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapFixed,
2821                        evalTexture3DProjGradOffset, BOTH),
2822         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2823                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f),
2824                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapFloat,
2825                        evalTexture3DProjGradOffset, VERTEX),
2826         GRAD_CASE_SPEC(sampler3d_float, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2827                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.2f),
2828                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(3, -8, 7), tex3DMipmapFloat,
2829                        evalTexture3DProjGradOffset, FRAGMENT),
2830         GRAD_CASE_SPEC(isampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2831                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2832                        Vec3(0.0f, 0.0f, 0.0f), Vec3(-0.2f, 0.0f, 0.0f), true, IVec3(-8, 7, 3), tex3DMipmapInt,
2833                        evalTexture3DProjGradOffset, BOTH),
2834         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2835                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2836                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.2f, 0.0f), true, IVec3(7, 3, -8), tex3DMipmapUint,
2837                        evalTexture3DProjGradOffset, VERTEX),
2838         GRAD_CASE_SPEC(usampler3d, FUNCTION_TEXTUREPROJGRAD, Vec4(0.9f, 1.05f, -0.08f, -0.75f),
2839                        Vec4(-1.13f, -1.7f, -1.7f, -0.75f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2840                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, -0.2f), true, IVec3(3, -8, 7), tex3DMipmapUint,
2841                        evalTexture3DProjGradOffset, FRAGMENT),
2842 
2843         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
2844                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.2f, 0.0f, 0.0f),
2845                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), true, IVec3(-8, 7, 0), tex2DMipmapShadow,
2846                        evalTexture2DShadowProjGradOffset, VERTEX),
2847         GRAD_CASE_SPEC(sampler2dshadow, FUNCTION_TEXTUREPROJGRAD, Vec4(0.2f, 0.6f, 0.0f, -1.5f),
2848                        Vec4(-2.25f, -3.45f, -1.5f, -1.5f), Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f),
2849                        Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -0.2f, 0.0f), true, IVec3(7, -8, 0), tex2DMipmapShadow,
2850                        evalTexture2DShadowProjGradOffset, FRAGMENT)};
2851     createCaseGroup(this, "textureprojgradoffset", "textureProjGradOffset() Tests", textureProjGradOffsetCases,
2852                     DE_LENGTH_OF_ARRAY(textureProjGradOffsetCases));
2853 
2854     // texelFetch() cases
2855     // \note Level is constant across quad
2856     static const TexFuncCaseSpec texelFetchCases[] = {
2857         //          Name                            Function                MinCoord                            MaxCoord                        Bias?    MinLod    MaxLod    Offset?    Offset        Format                        EvalFunc                Flags
2858         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(255.9f, 255.9f, 0.0f, 0.0f),
2859                   false, 0.0f, 0.0f, false, IVec3(0), tex2DTexelFetchFixed, evalTexelFetch2D, BOTH),
2860         CASE_SPEC(sampler2d_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(127.9f, 127.9f, 0.0f, 0.0f),
2861                   false, 1.0f, 1.0f, false, IVec3(0), tex2DTexelFetchFloat, evalTexelFetch2D, BOTH),
2862         CASE_SPEC(isampler2d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 63.9f, 0.0f, 0.0f), false,
2863                   2.0f, 2.0f, false, IVec3(0), tex2DTexelFetchInt, evalTexelFetch2D, BOTH),
2864         CASE_SPEC(usampler2d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 15.9f, 0.0f, 0.0f), false,
2865                   4.0f, 4.0f, false, IVec3(0), tex2DTexelFetchUint, evalTexelFetch2D, BOTH),
2866 
2867         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
2868                   Vec4(127.9f, 127.9f, 3.9f, 0.0f), false, 0.0f, 0.0f, false, IVec3(0), tex2DArrayTexelFetchFixed,
2869                   evalTexelFetch2DArray, BOTH),
2870         CASE_SPEC(sampler2darray_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f),
2871                   Vec4(63.9f, 63.9f, 3.9f, 0.0f), false, 1.0f, 1.0f, false, IVec3(0), tex2DArrayTexelFetchFloat,
2872                   evalTexelFetch2DArray, BOTH),
2873         CASE_SPEC(isampler2darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(31.9f, 31.9f, 3.9f, 0.0f),
2874                   false, 2.0f, 2.0f, false, IVec3(0), tex2DArrayTexelFetchInt, evalTexelFetch2DArray, BOTH),
2875         CASE_SPEC(usampler2darray, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 15.9f, 3.9f, 0.0f),
2876                   false, 3.0f, 3.0f, false, IVec3(0), tex2DArrayTexelFetchUint, evalTexelFetch2DArray, BOTH),
2877 
2878         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 31.9f, 31.9f, 0.0f),
2879                   false, 0.0f, 0.0f, false, IVec3(0), tex3DTexelFetchFixed, evalTexelFetch3D, BOTH),
2880         CASE_SPEC(sampler3d_float, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(31.9f, 15.9f, 15.9f, 0.0f),
2881                   false, 1.0f, 1.0f, false, IVec3(0), tex3DTexelFetchFloat, evalTexelFetch3D, BOTH),
2882         CASE_SPEC(isampler3d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(15.9f, 7.9f, 7.9f, 0.0f), false,
2883                   2.0f, 2.0f, false, IVec3(0), tex3DTexelFetchInt, evalTexelFetch3D, BOTH),
2884         CASE_SPEC(usampler3d, FUNCTION_TEXELFETCH, Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(63.9f, 31.9f, 31.9f, 0.0f), false,
2885                   0.0f, 0.0f, false, IVec3(0), tex3DTexelFetchUint, evalTexelFetch3D, BOTH)};
2886     createCaseGroup(this, "texelfetch", "texelFetch() Tests", texelFetchCases, DE_LENGTH_OF_ARRAY(texelFetchCases));
2887 
2888     // texelFetchOffset() cases
2889     static const TexFuncCaseSpec texelFetchOffsetCases[] = {
2890         //          Name                            Function                MinCoord                            MaxCoord                        Bias?    MinLod    MaxLod    Offset?    Offset        Format                        EvalFunc                Flags
2891         CASE_SPEC(sampler2d_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, 0.0f, 0.0f), Vec4(263.9f, 248.9f, 0.0f, 0.0f),
2892                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DTexelFetchFixed, evalTexelFetch2D, BOTH),
2893         CASE_SPEC(sampler2d_float, FUNCTION_TEXELFETCH, Vec4(-7.0f, 8.0f, 0.0f, 0.0f), Vec4(120.9f, 135.9f, 0.0f, 0.0f),
2894                   false, 1.0f, 1.0f, true, IVec3(7, -8, 0), tex2DTexelFetchFloat, evalTexelFetch2D, BOTH),
2895         CASE_SPEC(isampler2d, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, 0.0f, 0.0f), Vec4(71.9f, 56.9f, 0.0f, 0.0f), false,
2896                   2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DTexelFetchInt, evalTexelFetch2D, BOTH),
2897         CASE_SPEC(usampler2d, FUNCTION_TEXELFETCH, Vec4(-7.0f, 8.0f, 0.0f, 0.0f), Vec4(8.9f, 23.9f, 0.0f, 0.0f), false,
2898                   4.0f, 4.0f, true, IVec3(7, -8, 0), tex2DTexelFetchUint, evalTexelFetch2D, BOTH),
2899 
2900         CASE_SPEC(sampler2darray_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, 0.0f, 0.0f),
2901                   Vec4(135.9f, 120.9f, 3.9f, 0.0f), false, 0.0f, 0.0f, true, IVec3(-8, 7, 0), tex2DArrayTexelFetchFixed,
2902                   evalTexelFetch2DArray, BOTH),
2903         CASE_SPEC(sampler2darray_float, FUNCTION_TEXELFETCH, Vec4(-7.0f, 8.0f, 0.0f, 0.0f),
2904                   Vec4(56.9f, 71.9f, 3.9f, 0.0f), false, 1.0f, 1.0f, true, IVec3(7, -8, 0), tex2DArrayTexelFetchFloat,
2905                   evalTexelFetch2DArray, BOTH),
2906         CASE_SPEC(isampler2darray, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, 0.0f, 0.0f), Vec4(39.9f, 24.9f, 3.9f, 0.0f),
2907                   false, 2.0f, 2.0f, true, IVec3(-8, 7, 0), tex2DArrayTexelFetchInt, evalTexelFetch2DArray, BOTH),
2908         CASE_SPEC(usampler2darray, FUNCTION_TEXELFETCH, Vec4(-7.0f, 8.0f, 0.0f, 0.0f), Vec4(8.9f, 23.9f, 3.9f, 0.0f),
2909                   false, 3.0f, 3.0f, true, IVec3(7, -8, 0), tex2DArrayTexelFetchUint, evalTexelFetch2DArray, BOTH),
2910 
2911         CASE_SPEC(sampler3d_fixed, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, -3.0f, 0.0f), Vec4(71.9f, 24.9f, 28.9f, 0.0f),
2912                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DTexelFetchFixed, evalTexelFetch3D, BOTH),
2913         CASE_SPEC(sampler3d_float, FUNCTION_TEXELFETCH, Vec4(-7.0f, -3.0f, 8.0f, 0.0f), Vec4(24.9f, 12.9f, 23.9f, 0.0f),
2914                   false, 1.0f, 1.0f, true, IVec3(7, 3, -8), tex3DTexelFetchFloat, evalTexelFetch3D, BOTH),
2915         CASE_SPEC(isampler3d, FUNCTION_TEXELFETCH, Vec4(-3.0f, 8.0f, -7.0f, 0.0f), Vec4(12.9f, 15.9f, 0.9f, 0.0f),
2916                   false, 2.0f, 2.0f, true, IVec3(3, -8, 7), tex3DTexelFetchInt, evalTexelFetch3D, BOTH),
2917         CASE_SPEC(usampler3d, FUNCTION_TEXELFETCH, Vec4(8.0f, -7.0f, -3.0f, 0.0f), Vec4(71.9f, 24.9f, 28.9f, 0.0f),
2918                   false, 0.0f, 0.0f, true, IVec3(-8, 7, 3), tex3DTexelFetchUint, evalTexelFetch3D, BOTH)};
2919     createCaseGroup(this, "texelfetchoffset", "texelFetchOffset() Tests", texelFetchOffsetCases,
2920                     DE_LENGTH_OF_ARRAY(texelFetchOffsetCases));
2921 
2922     // textureSize() cases
2923     {
2924         struct TextureSizeCaseSpec
2925         {
2926             const char *name;
2927             const char *samplerName;
2928             TextureSpec textureSpec;
2929         } textureSizeCases[] = {
2930             {"sampler2d_fixed", "sampler2D", tex2DFixed},
2931             {"sampler2d_float", "sampler2D", tex2DFloat},
2932             {"isampler2d", "isampler2D", tex2DInt},
2933             {"usampler2d", "usampler2D", tex2DUint},
2934             {"sampler2dshadow", "sampler2DShadow", tex2DShadow},
2935             {"sampler3d_fixed", "sampler3D", tex3DFixed},
2936             {"sampler3d_float", "sampler3D", tex3DFloat},
2937             {"isampler3d", "isampler3D", tex3DInt},
2938             {"usampler3d", "usampler3D", tex3DUint},
2939             {"samplercube_fixed", "samplerCube", texCubeFixed},
2940             {"samplercube_float", "samplerCube", texCubeFloat},
2941             {"isamplercube", "isamplerCube", texCubeInt},
2942             {"usamplercube", "usamplerCube", texCubeUint},
2943             {"samplercubeshadow", "samplerCubeShadow", texCubeShadow},
2944             {"sampler2darray_fixed", "sampler2DArray", tex2DArrayFixed},
2945             {"sampler2darray_float", "sampler2DArray", tex2DArrayFloat},
2946             {"isampler2darray", "isampler2DArray", tex2DArrayInt},
2947             {"usampler2darray", "usampler2DArray", tex2DArrayUint},
2948             {"sampler2darrayshadow", "sampler2DArrayShadow", tex2DArrayShadow},
2949         };
2950 
2951         tcu::TestCaseGroup *group = new tcu::TestCaseGroup(m_testCtx, "texturesize", "textureSize() Tests");
2952         addChild(group);
2953 
2954         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureSizeCases); ++ndx)
2955         {
2956             group->addChild(
2957                 new TextureSizeCase(m_context, (std::string(textureSizeCases[ndx].name) + "_vertex").c_str(), "",
2958                                     textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, true));
2959             group->addChild(
2960                 new TextureSizeCase(m_context, (std::string(textureSizeCases[ndx].name) + "_fragment").c_str(), "",
2961                                     textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, false));
2962         }
2963     }
2964 
2965     // Negative cases.
2966     {
2967         gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
2968         std::vector<tcu::TestNode *> negativeCases = library.loadShaderFile("shaders/invalid_texture_functions.test");
2969 
2970         tcu::TestCaseGroup *group =
2971             new tcu::TestCaseGroup(m_testCtx, "invalid", "Invalid texture function usage", negativeCases);
2972         addChild(group);
2973     }
2974 }
2975 
2976 } // namespace Functional
2977 } // namespace gles3
2978 } // namespace deqp
2979