xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cTextureGatherTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "gl4cTextureGatherTests.hpp"
25 #include "glcTestSubcase.hpp"
26 #include "gluContextInfo.hpp"
27 #include "gluPixelTransfer.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuRenderTarget.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuTestLog.hpp"
34 #include "tcuVector.hpp"
35 #include <cstdarg>
36 #include <math.h>
37 #include <string>
38 #include <vector>
39 
40 namespace gl4cts
41 {
42 
43 using namespace glw;
44 using tcu::IVec4;
45 using tcu::UVec4;
46 using tcu::Vec2;
47 using tcu::Vec3;
48 using tcu::Vec4;
49 
50 namespace
51 {
52 
53 class TGBase : public deqp::SubcaseBase
54 {
55 public:
~TGBase()56     virtual ~TGBase()
57     {
58     }
59 
TGBase()60     TGBase() : renderTarget(m_context.getRenderContext().getRenderTarget()), pixelFormat(renderTarget.getPixelFormat())
61     {
62         g_color_eps = Vec4(
63             1.f / (float)(1 << deMin32(8, pixelFormat.redBits)), 1.f / (float)(1 << deMin32(8, pixelFormat.greenBits)),
64             1.f / (float)(1 << deMin32(8, pixelFormat.blueBits)), 1.f / (float)(1 << pixelFormat.alphaBits));
65     }
66 
67     const tcu::RenderTarget &renderTarget;
68     const tcu::PixelFormat &pixelFormat;
69     Vec4 g_color_eps;
70 
GetWindowWidth()71     int GetWindowWidth()
72     {
73         return renderTarget.getWidth();
74     }
75 
GetWindowHeight()76     int GetWindowHeight()
77     {
78         return renderTarget.getHeight();
79     }
80 
Title()81     virtual std::string Title()
82     {
83         return "";
84     }
85 
Purpose()86     virtual std::string Purpose()
87     {
88         return "";
89     }
90 
Method()91     virtual std::string Method()
92     {
93         return "";
94     }
95 
PassCriteria()96     virtual std::string PassCriteria()
97     {
98         return "";
99     }
100 
CreateProgram(const char * src_vs,const char * src_tcs,const char * src_tes,const char * src_gs,const char * src_fs)101     GLuint CreateProgram(const char *src_vs, const char *src_tcs, const char *src_tes, const char *src_gs,
102                          const char *src_fs)
103     {
104         const GLuint p = glCreateProgram();
105 
106         if (src_vs)
107         {
108             GLuint sh = glCreateShader(GL_VERTEX_SHADER);
109             glAttachShader(p, sh);
110             glDeleteShader(sh);
111             glShaderSource(sh, 1, &src_vs, NULL);
112             glCompileShader(sh);
113         }
114         if (src_tcs)
115         {
116             GLuint sh = glCreateShader(GL_TESS_CONTROL_SHADER);
117             glAttachShader(p, sh);
118             glDeleteShader(sh);
119             glShaderSource(sh, 1, &src_tcs, NULL);
120             glCompileShader(sh);
121         }
122         if (src_tes)
123         {
124             GLuint sh = glCreateShader(GL_TESS_EVALUATION_SHADER);
125             glAttachShader(p, sh);
126             glDeleteShader(sh);
127             glShaderSource(sh, 1, &src_tes, NULL);
128             glCompileShader(sh);
129         }
130         if (src_gs)
131         {
132             GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
133             glAttachShader(p, sh);
134             glDeleteShader(sh);
135             glShaderSource(sh, 1, &src_gs, NULL);
136             glCompileShader(sh);
137         }
138         if (src_fs)
139         {
140             GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
141             glAttachShader(p, sh);
142             glDeleteShader(sh);
143             glShaderSource(sh, 1, &src_fs, NULL);
144             glCompileShader(sh);
145         }
146         return p;
147     }
148 
CreateComputeProgram(const std::string & cs)149     GLuint CreateComputeProgram(const std::string &cs)
150     {
151         const GLuint p = glCreateProgram();
152 
153         if (!cs.empty())
154         {
155             const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
156             glAttachShader(p, sh);
157             glDeleteShader(sh);
158             const char *const src[1] = {cs.c_str()};
159             glShaderSource(sh, 1, src, NULL);
160             glCompileShader(sh);
161         }
162 
163         return p;
164     }
165 
CheckProgram(GLuint program,bool * compile_error=NULL)166     bool CheckProgram(GLuint program, bool *compile_error = NULL)
167     {
168         GLint compile_status = GL_TRUE;
169         GLint status;
170         glGetProgramiv(program, GL_LINK_STATUS, &status);
171 
172         if (status == GL_FALSE)
173         {
174             GLint attached_shaders;
175             glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
176 
177             if (attached_shaders > 0)
178             {
179                 std::vector<GLuint> shaders(attached_shaders);
180                 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
181 
182                 for (GLint i = 0; i < attached_shaders; ++i)
183                 {
184                     GLenum type;
185                     glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
186                     switch (type)
187                     {
188                     case GL_VERTEX_SHADER:
189                         m_context.getTestContext().getLog()
190                             << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
191                         break;
192                     case GL_TESS_CONTROL_SHADER:
193                         m_context.getTestContext().getLog()
194                             << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
195                             << tcu::TestLog::EndMessage;
196                         break;
197                     case GL_TESS_EVALUATION_SHADER:
198                         m_context.getTestContext().getLog()
199                             << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
200                             << tcu::TestLog::EndMessage;
201                         break;
202                     case GL_GEOMETRY_SHADER:
203                         m_context.getTestContext().getLog()
204                             << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
205                         break;
206                     case GL_FRAGMENT_SHADER:
207                         m_context.getTestContext().getLog()
208                             << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
209                         break;
210                     case GL_COMPUTE_SHADER:
211                         m_context.getTestContext().getLog()
212                             << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
213                         break;
214                     default:
215                         m_context.getTestContext().getLog()
216                             << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
217                     }
218 
219                     GLint res;
220                     glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
221                     if (res != GL_TRUE)
222                         compile_status = res;
223 
224                     GLint length;
225                     glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
226                     if (length > 0)
227                     {
228                         std::vector<GLchar> source(length);
229                         glGetShaderSource(shaders[i], length, NULL, &source[0]);
230                         m_context.getTestContext().getLog()
231                             << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
232                     }
233 
234                     glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
235                     if (length > 0)
236                     {
237                         std::vector<GLchar> log(length);
238                         glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
239                         m_context.getTestContext().getLog()
240                             << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
241                     }
242                 }
243             }
244 
245             GLint length;
246             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
247             if (length > 0)
248             {
249                 std::vector<GLchar> log(length);
250                 glGetProgramInfoLog(program, length, NULL, &log[0]);
251                 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
252             }
253         }
254 
255         if (compile_error)
256             *compile_error = (compile_status == GL_TRUE ? false : true);
257         if (compile_status != GL_TRUE)
258             return false;
259         return status == GL_TRUE ? true : false;
260     }
261 
distance(GLfloat p0,GLfloat p1)262     GLfloat distance(GLfloat p0, GLfloat p1)
263     {
264         return de::abs(p0 - p1);
265     }
266 
ColorEqual(const Vec4 & c0,const Vec4 & c1,const Vec4 & epsilon)267     inline bool ColorEqual(const Vec4 &c0, const Vec4 &c1, const Vec4 &epsilon)
268     {
269         if (distance(c0.x(), c1.x()) > epsilon.x())
270             return false;
271         if (distance(c0.y(), c1.y()) > epsilon.y())
272             return false;
273         if (distance(c0.z(), c1.z()) > epsilon.z())
274             return false;
275         if (distance(c0.w(), c1.w()) > epsilon.w())
276             return false;
277         return true;
278     }
279 
Setup()280     virtual long Setup()
281     {
282         return NO_ERROR;
283     }
284 
Cleanup()285     virtual long Cleanup()
286     {
287         return NO_ERROR;
288     }
289 };
290 
291 class GatherEnumsTest : public TGBase
292 {
Title()293     virtual std::string Title()
294     {
295         return "Basic Enum Test";
296     }
297 
Purpose()298     virtual std::string Purpose()
299     {
300         return "Verify that gather related enums are correct.";
301     }
302 
Method()303     virtual std::string Method()
304     {
305         return "Query GL_*_TEXTURE_GATHER_OFFSET enums.";
306     }
307 
PassCriteria()308     virtual std::string PassCriteria()
309     {
310         return "Values of enums meet GL spec requirements.";
311     }
312 
Run()313     virtual long Run()
314     {
315         GLint res;
316         glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
317         if (res > -8)
318         {
319             return ERROR;
320         }
321         glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
322         if (res < 7)
323         {
324             return ERROR;
325         }
326         return NO_ERROR;
327     }
328 };
329 
330 class GatherGLSLCompile : public TGBase
331 {
332     GLuint program;
333 
Title()334     virtual std::string Title()
335     {
336         return "GLSL Compile Test";
337     }
338 
Purpose()339     virtual std::string Purpose()
340     {
341         return "Verify that gather functions are visible in the shaders.";
342     }
343 
Method()344     virtual std::string Method()
345     {
346         return "Create shaders which use all types of gather functions.";
347     }
348 
PassCriteria()349     virtual std::string PassCriteria()
350     {
351         return "Programs compile and link successfuly.";
352     }
353 
Uniforms()354     virtual std::string Uniforms()
355     {
356         return "uniform sampler2D tex_2d;                  \n"
357                "uniform isamplerCube itex_cube;            \n"
358                "uniform usampler2DArray utex_2da;          \n"
359                "uniform isampler2DRect itex_2dr;           \n"
360                ""
361                "uniform sampler2DRectShadow tex_2drs;      \n"
362                "uniform sampler2DShadow tex_2ds;           \n"
363                "uniform samplerCubeShadow tex_cubes;       \n"
364                "uniform sampler2DArrayShadow tex_2das;     \n";
365     }
366 
Sampling()367     virtual std::string Sampling()
368     {
369         return "    textureGather(tex_2d,vec2(1));          \n"
370                "    textureGather(itex_cube,vec3(1));       \n"
371                "    textureGather(utex_2da,vec3(1));        \n"
372                "    textureGather(itex_2dr,vec2(1));        \n"
373                ""
374                "    textureGather(tex_2drs,vec2(1), 0.5);   \n"
375                "    textureGather(tex_2ds,vec2(1), 0.5);    \n"
376                "    textureGather(tex_cubes,vec3(1), 0.5);  \n"
377                "    textureGather(tex_2das,vec3(1), 0.5);   \n"
378                ""
379                "    textureGatherOffset(tex_2d,vec2(1), ivec2(0));          \n"
380                "    textureGatherOffset(utex_2da,vec3(1), ivec2(0));        \n"
381                "    textureGatherOffset(itex_2dr,vec2(1), ivec2(0));        \n"
382                ""
383                "    textureGatherOffset(tex_2drs,vec2(1), 0.5, ivec2(0));   \n"
384                "    textureGatherOffset(tex_2ds,vec2(1), 0.5, ivec2(0));    \n"
385                "    textureGatherOffset(tex_2das,vec3(1), 0.5, ivec2(0));   \n"
386                ""
387                "    const ivec2 offsets[4] = ivec2[](ivec2(0), ivec2(0), ivec2(0), ivec2(0)); \n"
388                "    textureGatherOffsets(tex_2d,vec2(1), offsets);          \n"
389                "    textureGatherOffsets(utex_2da,vec3(1), offsets);        \n"
390                "    textureGatherOffsets(itex_2dr,vec2(1), offsets);        \n"
391                ""
392                "    textureGatherOffsets(tex_2drs,vec2(1), 0.5, offsets);   \n"
393                "    textureGatherOffsets(tex_2ds,vec2(1), 0.5, offsets);    \n"
394                "    textureGatherOffsets(tex_2das,vec3(1), 0.5, offsets);   \n";
395     }
396 
VertexShader()397     virtual std::string VertexShader()
398     {
399         return "#version 400                               \n" + Uniforms() +
400                "  void main() {                            \n" + Sampling() +
401                "    gl_Position = vec4(1);                 \n"
402                "  }                                        \n";
403     }
404 
FragmentShader()405     virtual std::string FragmentShader()
406     {
407         return "#version 400                               \n"
408                "out vec4 color;                            \n" +
409                Uniforms() + "  void main() {                            \n" + Sampling() +
410                "    color = vec4(1);                       \n"
411                "  }                                        \n";
412     }
413 
Run()414     virtual long Run()
415     {
416         program = CreateProgram(VertexShader().c_str(), NULL, NULL, NULL, FragmentShader().c_str());
417         glLinkProgram(program);
418         if (!CheckProgram(program))
419             return ERROR;
420         return NO_ERROR;
421     }
422 
Cleanup()423     virtual long Cleanup()
424     {
425         glDeleteProgram(program);
426         return NO_ERROR;
427     }
428 };
429 
430 class GatherBase : public TGBase
431 {
432 public:
433     GLuint tex, fbo, rbo, program, vao, vbo;
434 
CreateTexture2DRgb(bool base_level=false)435     virtual GLvoid CreateTexture2DRgb(bool base_level = false)
436     {
437         GLenum internal_format = GL_RGB32F;
438         GLenum format          = GL_RGB;
439         const GLint csize      = base_level ? 64 : 32;
440         GLint size             = csize;
441         GLenum target          = GL_TEXTURE_2D;
442         GLenum tex_type        = GL_FLOAT;
443 
444         glGenTextures(1, &tex);
445         glBindTexture(target, tex);
446         for (int i = 0; size > 0; ++i, size /= 2)
447         {
448             glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
449         }
450         std::vector<Vec3> pixels(csize * csize, Vec3(1.0));
451         glTexSubImage2D(target, 0, 0, 0, csize, csize, format, tex_type, &pixels[0]);
452         glGenerateMipmap(target);
453 
454         Vec3 data[4] = {Vec3(12. / 16, 13. / 16, 14. / 16), Vec3(8. / 16, 9. / 16, 10. / 16),
455                         Vec3(0. / 16, 1. / 16, 2. / 16), Vec3(4. / 16, 5. / 16, 6. / 16)};
456 
457         glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
458         glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
459         glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
460         glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
461         glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
462 
463         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
464         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
465         glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
466     }
467 
CreateTexture2DRg(bool base_level=false)468     virtual GLvoid CreateTexture2DRg(bool base_level = false)
469     {
470         GLenum internal_format = GL_RG32F;
471         GLenum format          = GL_RG;
472         const GLint csize      = base_level ? 64 : 32;
473         GLint size             = csize;
474         GLenum target          = GL_TEXTURE_2D;
475         GLenum tex_type        = GL_FLOAT;
476 
477         glGenTextures(1, &tex);
478         glBindTexture(target, tex);
479         for (int i = 0; size > 0; ++i, size /= 2)
480         {
481             glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
482         }
483         std::vector<Vec2> pixels(csize * csize, Vec2(1.0));
484         glTexSubImage2D(target, 0, 0, 0, csize, csize, format, tex_type, &pixels[0]);
485         glGenerateMipmap(target);
486 
487         Vec2 data[4] = {Vec2(12. / 16, 13. / 16), Vec2(8. / 16, 9. / 16), Vec2(0. / 16, 1. / 16),
488                         Vec2(4. / 16, 5. / 16)};
489 
490         glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
491         glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
492         glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
493         glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
494         glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
495 
496         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
497         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
498         glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
499     }
500 
CreateTexture2DR(bool base_level=false)501     virtual GLvoid CreateTexture2DR(bool base_level = false)
502     {
503         GLenum internal_format = GL_R32F;
504         GLenum format          = GL_RED;
505         const GLint csize      = base_level ? 64 : 32;
506         GLint size             = csize;
507         GLenum target          = GL_TEXTURE_2D;
508         GLenum tex_type        = GL_FLOAT;
509 
510         glGenTextures(1, &tex);
511         glBindTexture(target, tex);
512         for (int i = 0; size > 0; ++i, size /= 2)
513         {
514             glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
515         }
516         std::vector<GLfloat> pixels(csize * csize, 1.0);
517         glTexSubImage2D(target, 0, 0, 0, csize, csize, format, tex_type, &pixels[0]);
518         glGenerateMipmap(target);
519 
520         GLfloat data[4] = {12. / 16., 8. / 16., 0. / 16., 4. / 16.};
521 
522         glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
523         glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
524         glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
525         glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
526         glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
527 
528         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
529         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
530         glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
531     }
532 
CreateTexture2DInt(bool rect=false)533     virtual GLvoid CreateTexture2DInt(bool rect = false)
534     {
535         GLenum internal_format = InternalFormat();
536         const GLint csize      = 32;
537         GLint size             = csize;
538         GLenum target          = rect ? GL_TEXTURE_RECTANGLE : GL_TEXTURE_2D;
539 
540         glGenTextures(1, &tex);
541         glBindTexture(target, tex);
542         if (!rect)
543         {
544             for (int i = 0; size > 0; ++i, size /= 2)
545             {
546                 glTexImage2D(target, i, internal_format, size, size, 0, GL_RGBA_INTEGER, GL_INT, 0);
547             }
548         }
549         else
550         {
551             glTexImage2D(target, 0, internal_format, size, size, 0, GL_RGBA_INTEGER, GL_INT, 0);
552         }
553         std::vector<IVec4> pixels(csize * csize, IVec4(999));
554         glTexSubImage2D(target, 0, 0, 0, csize, csize, GL_RGBA_INTEGER, GL_INT, &pixels[0]);
555 
556         IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
557 
558         glTexSubImage2D(target, 0, 22, 25, 2, 2, GL_RGBA_INTEGER, GL_INT, data);
559         glTexSubImage2D(target, 0, 16, 10, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 0);
560         glTexSubImage2D(target, 0, 11, 2, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 1);
561         glTexSubImage2D(target, 0, 24, 13, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 2);
562         glTexSubImage2D(target, 0, 9, 14, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 3);
563 
564         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
565         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
566         glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
567         glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
568         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
569     }
570 
CreateTexture2DArrayInt(int slices,int data_slice)571     virtual GLvoid CreateTexture2DArrayInt(int slices, int data_slice)
572     {
573         GLenum internal_format = InternalFormat();
574         const GLint csize      = 32;
575         GLint size             = csize;
576 
577         glGenTextures(1, &tex);
578         glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
579         for (int i = 0; size > 0; ++i, size /= 2)
580         {
581             glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, GL_RGBA_INTEGER, GL_INT, 0);
582         }
583         std::vector<IVec4> pixels(csize * csize, IVec4(999));
584         for (int i = 0; i < slices; ++i)
585         {
586             glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, csize, csize, 1, GL_RGBA_INTEGER, GL_INT, &pixels[0]);
587         }
588 
589         IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
590 
591         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, GL_RGBA_INTEGER, GL_INT, data);
592         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 0);
593         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 1);
594         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 2);
595         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 3);
596 
597         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
598         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
599         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
600         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
601         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
602     }
603 
CreateTextureCubeArray(int slices,int data_slice)604     virtual GLvoid CreateTextureCubeArray(int slices, int data_slice)
605     {
606         GLenum internal_format = InternalFormat();
607         GLenum format          = Format();
608         const GLint csize      = 32;
609         GLint size             = csize;
610 
611         glGenTextures(1, &tex);
612         glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
613         for (int i = 0; size > 0; ++i, size /= 2)
614         {
615             glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, internal_format, size, size, 6 * slices, 0, format, GL_FLOAT, 0);
616         }
617         std::vector<Vec4> pixels(csize * csize, Vec4(1.0));
618         for (int j = 0; j < 6 * slices; ++j)
619         {
620             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, j, csize, csize, 1, format, GL_FLOAT, &pixels[0]);
621         }
622 
623         if (format != GL_DEPTH_COMPONENT)
624         {
625             glGenerateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY);
626         }
627 
628         Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
629                         Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
630 
631         Vec4 depthData(data[0][0], data[1][0], data[2][0], data[3][0]);
632         Vec4 *packedData = (format == GL_DEPTH_COMPONENT) ? &depthData : data;
633 
634         for (int i = 0; i < 6; ++i)
635         {
636             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 22, 25, (6 * data_slice) + i, 2, 2, 1, format, GL_FLOAT,
637                             packedData);
638             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 16, 10, (6 * data_slice) + i, 1, 1, 1, format, GL_FLOAT,
639                             data + 0);
640             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 11, 2, (6 * data_slice) + i, 1, 1, 1, format, GL_FLOAT,
641                             data + 1);
642             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 24, 13, (6 * data_slice) + i, 1, 1, 1, format, GL_FLOAT,
643                             data + 2);
644             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 9, 14, (6 * data_slice) + i, 1, 1, 1, format, GL_FLOAT,
645                             data + 3);
646         }
647 
648         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
649         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
650         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
651     }
652 
CreateTextureCubeArrayInt(int slices,int data_slice)653     virtual GLvoid CreateTextureCubeArrayInt(int slices, int data_slice)
654     {
655         GLenum internal_format = InternalFormat();
656         GLenum format          = GL_RGBA_INTEGER;
657         const GLint csize      = 32;
658         GLint size             = csize;
659 
660         glGenTextures(1, &tex);
661         glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
662         for (int i = 0; size > 0; ++i, size /= 2)
663         {
664             glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, internal_format, size, size, 6 * slices, 0, format, GL_INT, 0);
665         }
666         std::vector<IVec4> pixels(csize * csize, IVec4(999));
667         for (int j = 0; j < 6 * slices; ++j)
668         {
669             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, j, csize, csize, 1, format, GL_INT, &pixels[0]);
670         }
671 
672         IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
673 
674         for (int i = 0; i < 6; ++i)
675         {
676             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 22, 25, (6 * data_slice) + i, 2, 2, 1, format, GL_INT, data);
677             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 9, 14, (6 * data_slice) + i, 1, 1, 1, format, GL_INT,
678                             data + 3);
679             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 16, 10, (6 * data_slice) + i, 1, 1, 1, format, GL_INT,
680                             data + 0);
681             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 11, 2, (6 * data_slice) + i, 1, 1, 1, format, GL_INT,
682                             data + 1);
683             glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 24, 13, (6 * data_slice) + i, 1, 1, 1, format, GL_INT,
684                             data + 2);
685         }
686 
687         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
688         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
689         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
690         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
691         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
692     }
693 
CreateTexture2DArray(int slices,int data_slice)694     virtual GLvoid CreateTexture2DArray(int slices, int data_slice)
695     {
696         GLenum internal_format = InternalFormat();
697         GLenum format          = Format();
698         const GLint csize      = 32;
699         GLint size             = csize;
700 
701         glGenTextures(1, &tex);
702         glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
703         for (int i = 0; size > 0; ++i, size /= 2)
704         {
705             glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, format, GL_FLOAT, 0);
706         }
707         std::vector<Vec4> pixels(csize * csize, Vec4(1.0));
708         for (int i = 0; i < slices; ++i)
709         {
710             glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, csize, csize, 1, format, GL_FLOAT, &pixels[0]);
711         }
712 
713         if (format != GL_DEPTH_COMPONENT)
714         {
715             glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
716         }
717 
718         Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
719                         Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
720 
721         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, format, GL_FLOAT, data);
722         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, format, GL_FLOAT, data + 0);
723         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, format, GL_FLOAT, data + 1);
724         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, format, GL_FLOAT, data + 2);
725         glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, format, GL_FLOAT, data + 3);
726 
727         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
728         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
729         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
730     }
731 
CreateTextureCubeInt()732     virtual GLvoid CreateTextureCubeInt()
733     {
734         GLenum internal_format = InternalFormat();
735         const GLint csize      = 32;
736         GLint size             = csize;
737 
738         const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
739                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
740                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
741 
742         glGenTextures(1, &tex);
743         glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
744         for (int i = 0; size > 0; ++i, size /= 2)
745         {
746             for (int j = 0; j < 6; ++j)
747             {
748                 glTexImage2D(faces[j], i, internal_format, size, size, 0, GL_RGBA_INTEGER, GL_INT, 0);
749             }
750         }
751         std::vector<IVec4> pixels(csize * csize, IVec4(999));
752         for (int j = 0; j < 6; ++j)
753         {
754             glTexSubImage2D(faces[j], 0, 0, 0, csize, csize, GL_RGBA_INTEGER, GL_INT, &pixels[0]);
755         }
756 
757         IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
758 
759         for (int j = 0; j < 6; ++j)
760         {
761             glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, GL_RGBA_INTEGER, GL_INT, data);
762             glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 0);
763             glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 1);
764             glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 2);
765             glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, GL_RGBA_INTEGER, GL_INT, data + 3);
766         }
767 
768         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
769         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
770         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
771         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
772         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
773     }
774 
CreateTextureCube()775     virtual GLvoid CreateTextureCube()
776     {
777         GLenum internal_format = InternalFormat();
778         GLenum format          = Format();
779         const GLint csize      = 32;
780         GLint size             = csize;
781 
782         const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
783                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
784                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
785 
786         glGenTextures(1, &tex);
787         glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
788         for (int i = 0; size > 0; ++i, size /= 2)
789         {
790             for (int j = 0; j < 6; ++j)
791             {
792                 glTexImage2D(faces[j], i, internal_format, size, size, 0, format, GL_FLOAT, 0);
793             }
794         }
795         std::vector<Vec4> pixels(csize * csize, Vec4(1.0));
796         for (int j = 0; j < 6; ++j)
797         {
798             glTexSubImage2D(faces[j], 0, 0, 0, csize, csize, format, GL_FLOAT, &pixels[0]);
799         }
800 
801         if (format != GL_DEPTH_COMPONENT)
802         {
803             glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
804         }
805 
806         Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
807                         Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
808 
809         Vec4 depthData(data[0][0], data[1][0], data[2][0], data[3][0]);
810         Vec4 *packedData = (format == GL_DEPTH_COMPONENT) ? &depthData : data;
811 
812         for (int j = 0; j < 6; ++j)
813         {
814             glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, format, GL_FLOAT, packedData);
815             glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, format, GL_FLOAT, data + 0);
816             glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, format, GL_FLOAT, data + 1);
817             glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, format, GL_FLOAT, data + 2);
818             glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, format, GL_FLOAT, data + 3);
819         }
820 
821         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
822         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
823         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
824     }
825 
CreateTexture2D(bool rect=false,bool base_level=false)826     virtual GLvoid CreateTexture2D(bool rect = false, bool base_level = false)
827     {
828         GLenum internal_format = InternalFormat();
829         GLenum format          = Format();
830         const GLint csize      = base_level ? 64 : 32;
831         GLint size             = csize;
832         GLenum target          = rect ? GL_TEXTURE_RECTANGLE : GL_TEXTURE_2D;
833 
834         glGenTextures(1, &tex);
835         glBindTexture(target, tex);
836         if (!rect)
837         {
838             for (int i = 0; size > 0; ++i, size /= 2)
839             {
840                 glTexImage2D(target, i, internal_format, size, size, 0, format, GL_FLOAT, 0);
841             }
842         }
843         else
844         {
845             glTexImage2D(target, 0, internal_format, size, size, 0, format, GL_FLOAT, 0);
846         }
847         std::vector<Vec4> pixels(csize * csize, Vec4(1.0));
848         glTexSubImage2D(target, 0, 0, 0, csize, csize, format, GL_FLOAT, &pixels[0]);
849 
850         if (!rect && format != GL_DEPTH_COMPONENT)
851         {
852             glGenerateMipmap(target);
853         }
854 
855         Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
856                         Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
857 
858         glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, GL_FLOAT, data);
859         glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, GL_FLOAT, data + 0);
860         glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, GL_FLOAT, data + 1);
861         glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, GL_FLOAT, data + 2);
862         glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, GL_FLOAT, data + 3);
863 
864         glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
865         glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
866         glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
867 
868         if (base_level)
869             glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 1);
870     }
871 
FallthroughVertexShader()872     virtual std::string FallthroughVertexShader()
873     {
874         return "#version 400                     \n"
875                "in vec4 v_in_0;                  \n"
876                "flat out vec4 v_out_0;           \n"
877                "void main() {                    \n"
878                "    gl_Position = vec4(0,0,0,1);                \n"
879                "    v_out_0 = v_in_0;                           \n"
880                "}";
881     }
882 
FallthroughFragmentShader()883     virtual std::string FallthroughFragmentShader()
884     {
885         return "#version 400                     \n"
886                "out " +
887                Type() +
888                " f_out_0;                \n"
889                "flat in " +
890                Type() +
891                " v_out_0;            \n"
892                "void main() {                    \n"
893                "    f_out_0 = v_out_0;           \n"
894                "}";
895     }
896 
TestFunction()897     virtual std::string TestFunction()
898     {
899         return Sampler() + TextBody();
900     }
901 
Type()902     virtual std::string Type()
903     {
904         return "vec4";
905     }
906 
Sampler()907     virtual std::string Sampler()
908     {
909         return "uniform sampler2D my_sampler;                      \n";
910     }
911 
TextBody()912     virtual std::string TextBody()
913     {
914         return Type() + " test_function(vec4 p) {                       \n"
915                         "    return textureGather(my_sampler, vec2(p.x, p.y));           \n"
916                         "}\n";
917     }
918 
VertexShader()919     virtual std::string VertexShader()
920     {
921         return "#version 400                                       \n"
922                "#extension GL_ARB_texture_cube_map_array : enable  \n"
923                ""
924                "in vec4 v_in_0;                                    \n"
925                "flat out " +
926                Type() + " v_out_0;                   \n" + TestFunction() +
927                "void main() {                                      \n"
928                "    gl_Position = vec4(0,0,0,1);                   \n"
929                "    v_out_0 = test_function(v_in_0);               \n"
930                "}";
931     }
932 
FragmentShader()933     virtual std::string FragmentShader()
934     {
935         return "#version 400                                       \n"
936                "#extension GL_ARB_texture_cube_map_array : enable  \n"
937                ""
938                "flat in vec4 v_out_0;                              \n"
939                "out " +
940                Type() + " f_out_0;                        \n" + TestFunction() +
941                "void main() {                                      \n"
942                "    f_out_0 = test_function(v_out_0);              \n"
943                "}";
944     }
945 
ComputeShader()946     virtual std::string ComputeShader()
947     {
948         return "#version 420 core                                           \n"
949                "#extension GL_ARB_shader_storage_buffer_object : require    \n"
950                "#extension GL_ARB_compute_shader : require            \n"
951                "#extension GL_ARB_texture_cube_map_array : enable     \n"
952                "layout(local_size_x = 1, local_size_y = 1) in;        \n"
953                "layout(std430) buffer Output {                        \n"
954                "  " +
955                Type() +
956                " data;                                \n"
957                "} g_out;                                              \n"
958                "uniform vec4 cs_in;                                   \n" +
959                TestFunction() +
960                "void main() {                                         \n"
961                "  g_out.data = test_function(cs_in);                  \n"
962                "}                                                     \n";
963     }
964 
Init()965     virtual void Init()
966     {
967         CreateTexture2D();
968     }
969 
SetRbo()970     virtual void SetRbo()
971     {
972         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
973     }
974 
Verify()975     virtual long Verify()
976     {
977         Vec4 data;
978         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, &data);
979         if (!ColorEqual(data, Expected(), g_color_eps))
980         {
981             m_context.getTestContext().getLog()
982                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
983                 << Expected().z() << ", " << Expected().w() << ", got: " << data.x() << ", " << data.y() << ", "
984                 << data.z() << ", " << data.w() << ", epsilon: " << g_color_eps.x() << ", " << g_color_eps.y() << ", "
985                 << g_color_eps.z() << ", " << g_color_eps.w() << tcu::TestLog::EndMessage;
986             return ERROR;
987         }
988         return NO_ERROR;
989     }
990 
Expected()991     virtual Vec4 Expected()
992     {
993         return Vec4(0. / 16, 4. / 16, 8. / 16, 12. / 16);
994     }
995 
InternalFormat()996     virtual GLenum InternalFormat()
997     {
998         return GL_RGBA32F;
999     }
1000 
Format()1001     virtual GLenum Format()
1002     {
1003         return GL_RGBA;
1004     }
1005 
BufferData()1006     virtual Vec4 BufferData()
1007     {
1008         return Vec4(23. / 32, 26. / 32, 5, 3);
1009     }
1010 
Supported()1011     virtual bool Supported()
1012     {
1013         return true;
1014     }
1015 
Run()1016     virtual long Run()
1017     {
1018 
1019         if (!Supported())
1020             return NO_ERROR;
1021         Init();
1022 
1023         glGenFramebuffers(1, &fbo);
1024         glGenRenderbuffers(1, &rbo);
1025         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1026         SetRbo();
1027         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1028         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1029         GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
1030         glDrawBuffers(1, &drawBuffer);
1031         GLfloat colorf[4] = {0, 0, 0, 0};
1032         glClearBufferfv(GL_COLOR, 0, colorf);
1033         glViewport(0, 0, 1, 1);
1034 
1035         glGenVertexArrays(1, &vao);
1036         glBindVertexArray(vao);
1037         glGenBuffers(1, &vbo);
1038         glBindBuffer(GL_ARRAY_BUFFER, vbo);
1039         glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
1040         glEnableVertexAttribArray(0);
1041         Vec4 buffData = BufferData();
1042         glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
1043 
1044         for (int i = 0; i < 2; ++i)
1045         {
1046             if (i == 0)
1047                 program = CreateProgram(VertexShader().c_str(), NULL, NULL, NULL, FallthroughFragmentShader().c_str());
1048             else
1049                 program = CreateProgram(FallthroughVertexShader().c_str(), NULL, NULL, NULL, FragmentShader().c_str());
1050             glBindAttribLocation(program, 0, "v_in_0");
1051             glBindFragDataLocation(program, 0, "f_out_0");
1052             glLinkProgram(program);
1053             if (!CheckProgram(program))
1054                 return ERROR;
1055             glUseProgram(program);
1056 
1057             glDrawArrays(GL_POINTS, 0, 1);
1058             glReadBuffer(GL_COLOR_ATTACHMENT0);
1059 
1060             glDeleteProgram(program);
1061 
1062             if (Verify() == ERROR)
1063                 return ERROR;
1064         }
1065 
1066         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
1067         {
1068             m_context.getTestContext().getLog()
1069                 << tcu::TestLog::Message << "Expected "
1070                 << "GL_ARB_compute_shader or GL_ARB_compute_shader not supported, skipping compute stage"
1071                 << tcu::TestLog::EndMessage;
1072             return NO_ERROR;
1073         }
1074         else
1075         {
1076             return TestCompute();
1077         }
1078     }
1079 
TestCompute()1080     virtual long TestCompute()
1081     {
1082         GLuint m_buffer;
1083 
1084         program = CreateComputeProgram(ComputeShader());
1085         glLinkProgram(program);
1086         if (!CheckProgram(program))
1087             return ERROR;
1088         glUseProgram(program);
1089 
1090         glUniform4f(glGetUniformLocation(program, "cs_in"), BufferData().x(), BufferData().y(), BufferData().z(),
1091                     BufferData().w());
1092 
1093         glGenBuffers(1, &m_buffer);
1094         glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
1095         glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Vec4), NULL, GL_DYNAMIC_DRAW);
1096         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1097 
1098         glDispatchCompute(1, 1, 1);
1099 
1100         glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
1101         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1102         long error = VerifyCompute();
1103         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1104         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1105         glDeleteBuffers(1, &m_buffer);
1106 
1107         return error;
1108     }
1109 
VerifyCompute()1110     virtual long VerifyCompute()
1111     {
1112         Vec4 *data;
1113         data = static_cast<Vec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Vec4), GL_MAP_READ_BIT));
1114         if (!ColorEqual(data[0], Expected(), g_color_eps))
1115         { // for unorms
1116             m_context.getTestContext().getLog()
1117                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1118                 << Expected().z() << ", " << Expected().w() << " got: " << data[0].x() << ", " << data[0].y() << ", "
1119                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1120             return ERROR;
1121         }
1122         return NO_ERROR;
1123     }
1124 
Cleanup()1125     virtual long Cleanup()
1126     {
1127         glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
1128         glDisableVertexAttribArray(0);
1129         glDeleteTextures(1, &tex);
1130         glDeleteVertexArrays(1, &vao);
1131         glDeleteBuffers(1, &vbo);
1132         glDeleteRenderbuffers(1, &rbo);
1133         glDeleteFramebuffers(1, &fbo);
1134         glDeleteProgram(program);
1135         return NO_ERROR;
1136     }
1137 };
1138 
1139 class PlainGatherFloat2DRgba : public GatherBase
1140 {
1141 };
1142 
1143 class PlainGatherFloat2DRg : public GatherBase
1144 {
1145 public:
TestFunction()1146     virtual std::string TestFunction()
1147     {
1148         return "uniform sampler2D my_sampler;                                   \n"
1149                ""
1150                "vec4 test_function(vec4 p) {                                    \n"
1151                "    return textureGather(my_sampler, vec2(p.x, p.y), 1);        \n"
1152                "}\n";
1153     }
1154 
Expected()1155     virtual Vec4 Expected()
1156     {
1157         return Vec4(1. / 16, 5. / 16, 9. / 16, 13. / 16);
1158     }
1159 
InternalFormat()1160     virtual GLenum InternalFormat()
1161     {
1162         return GL_RG32F;
1163     }
1164 };
1165 
1166 class PlainGatherUnorm2D : public GatherBase
1167 {
1168 public:
InternalFormat()1169     virtual GLenum InternalFormat()
1170     {
1171         return GL_RGBA16;
1172     }
1173 
TestFunction()1174     virtual std::string TestFunction()
1175     {
1176         return "uniform sampler2D my_sampler;                                   \n"
1177                ""
1178                "vec4 test_function(vec4 p) {                                    \n"
1179                "    return textureGather(my_sampler, vec2(p.x, p.y), 0);        \n"
1180                "}\n";
1181     }
1182 };
1183 
1184 class PlainGatherInt2DRgba : public GatherBase
1185 {
1186 public:
InternalFormat()1187     virtual GLenum InternalFormat()
1188     {
1189         return GL_RGBA32I;
1190     }
1191 
Init()1192     virtual void Init()
1193     {
1194         CreateTexture2DInt();
1195     }
1196 
SetRbo()1197     virtual void SetRbo()
1198     {
1199         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
1200     }
1201 
Verify()1202     virtual long Verify()
1203     {
1204         IVec4 data;
1205         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
1206         if (data != IVec4(0, 4, 8, 12))
1207         {
1208             m_context.getTestContext().getLog()
1209                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
1210                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1211             return ERROR;
1212         }
1213         return NO_ERROR;
1214     }
1215 
VerifyCompute()1216     virtual long VerifyCompute()
1217     {
1218         IVec4 *data;
1219         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1220         if (data[0] != IVec4(0, 4, 8, 12))
1221         {
1222             m_context.getTestContext().getLog()
1223                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1224                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1225                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1226             return ERROR;
1227         }
1228         return NO_ERROR;
1229     }
1230 
Sampler()1231     virtual std::string Sampler()
1232     {
1233         return "uniform isampler2D my_sampler;                     \n";
1234     }
1235 
Type()1236     virtual std::string Type()
1237     {
1238         return "ivec4";
1239     }
1240 };
1241 
1242 class PlainGatherInt2DRg : public PlainGatherInt2DRgba
1243 {
1244 public:
InternalFormat()1245     virtual GLenum InternalFormat()
1246     {
1247         return GL_RG32I;
1248     }
1249 };
1250 
1251 class PlainGatherUint2D : public GatherBase
1252 {
1253 public:
InternalFormat()1254     virtual GLenum InternalFormat()
1255     {
1256         return GL_RGBA32UI;
1257     }
1258 
Init()1259     virtual void Init()
1260     {
1261         CreateTexture2DInt();
1262     }
1263 
SetRbo()1264     virtual void SetRbo()
1265     {
1266         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 1, 1);
1267     }
1268 
Verify()1269     virtual long Verify()
1270     {
1271         IVec4 data;
1272         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data);
1273         if (data != IVec4(2, 6, 10, 14))
1274         {
1275             m_context.getTestContext().getLog()
1276                 << tcu::TestLog::Message << "Expected 2, 6, 10, 14, got: " << data.x() << ", " << data.y() << ", "
1277                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1278             return ERROR;
1279         }
1280         return NO_ERROR;
1281     }
1282 
VerifyCompute()1283     virtual long VerifyCompute()
1284     {
1285         IVec4 *data;
1286         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1287         if (data[0] != IVec4(2, 6, 10, 14))
1288         {
1289             m_context.getTestContext().getLog()
1290                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1291                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1292                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1293             return ERROR;
1294         }
1295         return NO_ERROR;
1296     }
1297 
Sampler()1298     virtual std::string Sampler()
1299     {
1300         return "uniform usampler2D my_sampler;                     \n";
1301     }
1302 
BufferData()1303     virtual Vec4 BufferData()
1304     {
1305         return Vec4(22.9f / 32, 25.9f / 32, 2, 2);
1306     }
1307 
Type()1308     virtual std::string Type()
1309     {
1310         return "uvec4";
1311     }
1312 
TextBody()1313     virtual std::string TextBody()
1314     {
1315         return Type() + " test_function(vec4 p) {                                   \n"
1316                         "    return textureGather(my_sampler, vec2(p.x, p.y), 2);            \n"
1317                         "}\n";
1318     }
1319 };
1320 
1321 class PlainGatherDepth2D : public GatherBase
1322 {
1323 public:
InternalFormat()1324     virtual GLenum InternalFormat()
1325     {
1326         return GL_DEPTH_COMPONENT32F;
1327     }
1328 
Format()1329     virtual GLenum Format()
1330     {
1331         return GL_DEPTH_COMPONENT;
1332     }
1333 
Init()1334     virtual void Init()
1335     {
1336         CreateTexture2D();
1337         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1338     }
1339 
Expected()1340     virtual Vec4 Expected()
1341     {
1342         return Vec4(1, 1, 0, 0);
1343     }
1344 
BufferData()1345     virtual Vec4 BufferData()
1346     {
1347         return Vec4(23. / 32, 26. / 32, 13.5 / 16, 3);
1348     }
1349 
Sampler()1350     virtual std::string Sampler()
1351     {
1352         return "uniform sampler2DShadow my_sampler;                     \n";
1353     }
1354 
TextBody()1355     virtual std::string TextBody()
1356     {
1357         return Type() + " test_function(vec4 p) {                                \n"
1358                         "    return textureGather(my_sampler, vec2(p.x, p.y), p.z);       \n"
1359                         "}\n";
1360     }
1361 };
1362 
1363 class PlainGatherFloat2DArray : public GatherBase
1364 {
1365 public:
Init()1366     virtual void Init()
1367     {
1368         CreateTexture2DArray(9, 5);
1369     }
1370 
Sampler()1371     virtual std::string Sampler()
1372     {
1373         return "uniform sampler2DArray my_sampler;                     \n";
1374     }
1375 
TextBody()1376     virtual std::string TextBody()
1377     {
1378         return Type() + " test_function(vec4 p) {                                \n"
1379                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z));       \n"
1380                         "}\n";
1381     }
1382 };
1383 
1384 class PlainGatherUnorm2DArray : public GatherBase
1385 {
1386 public:
Init()1387     virtual void Init()
1388     {
1389         CreateTexture2DArray(7, 3);
1390     }
1391 
Sampler()1392     virtual std::string Sampler()
1393     {
1394         return "uniform sampler2DArray my_sampler;                     \n";
1395     }
1396 
TextBody()1397     virtual std::string TextBody()
1398     {
1399         return Type() + " test_function(vec4 p) {                                \n"
1400                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.w));       \n"
1401                         "}\n";
1402     }
1403 
InternalFormat()1404     virtual GLenum InternalFormat()
1405     {
1406         return GL_RGBA16;
1407     }
1408 };
1409 
1410 class PlainGatherInt2DArray : public GatherBase
1411 {
1412 public:
Init()1413     virtual void Init()
1414     {
1415         CreateTexture2DArrayInt(20, 11);
1416     }
1417 
InternalFormat()1418     virtual GLenum InternalFormat()
1419     {
1420         return GL_RGBA32I;
1421     }
1422 
SetRbo()1423     virtual void SetRbo()
1424     {
1425         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
1426     }
1427 
Verify()1428     virtual long Verify()
1429     {
1430         IVec4 data;
1431         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
1432         if (data != IVec4(3, 7, 11, 15))
1433         {
1434             m_context.getTestContext().getLog()
1435                 << tcu::TestLog::Message << "Expected 3, 7, 11, 15, got: " << data.x() << ", " << data.y() << ", "
1436                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1437             return ERROR;
1438         }
1439         return NO_ERROR;
1440     }
1441 
VerifyCompute()1442     virtual long VerifyCompute()
1443     {
1444         IVec4 *data;
1445         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1446         if (data[0] != IVec4(3, 7, 11, 15))
1447         {
1448             m_context.getTestContext().getLog()
1449                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1450                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1451                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1452             return ERROR;
1453         }
1454         return NO_ERROR;
1455     }
1456 
Type()1457     virtual std::string Type()
1458     {
1459         return "ivec4";
1460     }
1461 
BufferData()1462     virtual Vec4 BufferData()
1463     {
1464         return Vec4(23. / 32, 26. / 32, 11, 3);
1465     }
1466 
Sampler()1467     virtual std::string Sampler()
1468     {
1469         return "uniform isampler2DArray my_sampler;                     \n";
1470     }
1471 
TextBody()1472     virtual std::string TextBody()
1473     {
1474         return Type() + " test_function(vec4 p) {                                \n"
1475                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), 3);    \n"
1476                         "}\n";
1477     }
1478 };
1479 
1480 class PlainGatherUint2DArray : public GatherBase
1481 {
1482 public:
Init()1483     virtual void Init()
1484     {
1485         CreateTexture2DArrayInt(3, 1);
1486     }
1487 
InternalFormat()1488     virtual GLenum InternalFormat()
1489     {
1490         return GL_RGBA32UI;
1491     }
1492 
SetRbo()1493     virtual void SetRbo()
1494     {
1495         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 1, 1);
1496     }
1497 
Verify()1498     virtual long Verify()
1499     {
1500         IVec4 data;
1501         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data);
1502         if (data != IVec4(0, 4, 8, 12))
1503         {
1504             m_context.getTestContext().getLog()
1505                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
1506                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1507             return ERROR;
1508         }
1509         return NO_ERROR;
1510     }
1511 
VerifyCompute()1512     virtual long VerifyCompute()
1513     {
1514         IVec4 *data;
1515         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1516         if (data[0] != IVec4(0, 4, 8, 12))
1517         {
1518             m_context.getTestContext().getLog()
1519                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1520                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1521                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1522             return ERROR;
1523         }
1524         return NO_ERROR;
1525     }
1526 
Type()1527     virtual std::string Type()
1528     {
1529         return "uvec4";
1530     }
1531 
BufferData()1532     virtual Vec4 BufferData()
1533     {
1534         return Vec4(23. / 32, 26. / 32, 1, 3);
1535     }
1536 
Sampler()1537     virtual std::string Sampler()
1538     {
1539         return "uniform usampler2DArray my_sampler;                     \n";
1540     }
1541 
TextBody()1542     virtual std::string TextBody()
1543     {
1544         return Type() + " test_function(vec4 p) {                                \n"
1545                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z));       \n"
1546                         "}\n";
1547     }
1548 };
1549 
1550 class PlainGatherDepth2DArray : public GatherBase
1551 {
1552 public:
InternalFormat()1553     virtual GLenum InternalFormat()
1554     {
1555         return GL_DEPTH_COMPONENT32F;
1556     }
1557 
Format()1558     virtual GLenum Format()
1559     {
1560         return GL_DEPTH_COMPONENT;
1561     }
1562 
Init()1563     virtual void Init()
1564     {
1565         CreateTexture2DArray(9, 5);
1566         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1567     }
1568 
Expected()1569     virtual Vec4 Expected()
1570     {
1571         return Vec4(1, 1, 0, 0);
1572     }
1573 
BufferData()1574     virtual Vec4 BufferData()
1575     {
1576         return Vec4(23. / 32, 26. / 32, 5, 13.5 / 16);
1577     }
1578 
Sampler()1579     virtual std::string Sampler()
1580     {
1581         return "uniform sampler2DArrayShadow my_sampler;                     \n";
1582     }
1583 
TextBody()1584     virtual std::string TextBody()
1585     {
1586         return Type() + " test_function(vec4 p) {                                \n"
1587                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w);       \n"
1588                         "}\n";
1589     }
1590 };
1591 
1592 class PlainGatherFloatCubeRgba : public GatherBase
1593 {
1594 public:
Init()1595     virtual void Init()
1596     {
1597         CreateTextureCube();
1598     }
1599 
BufferData()1600     virtual Vec4 BufferData()
1601     {
1602         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1603     }
1604 
Sampler()1605     virtual std::string Sampler()
1606     {
1607         return "uniform samplerCube my_sampler;                     \n";
1608     }
1609 
TextBody()1610     virtual std::string TextBody()
1611     {
1612         return Type() + " test_function(vec4 p) {                                \n"
1613                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z));       \n"
1614                         "}\n";
1615     }
1616 };
1617 
1618 class PlainGatherFloatCubeRg : public GatherBase
1619 {
1620 public:
Init()1621     virtual void Init()
1622     {
1623         CreateTextureCube();
1624     }
1625 
BufferData()1626     virtual Vec4 BufferData()
1627     {
1628         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1629     }
1630 
Sampler()1631     virtual std::string Sampler()
1632     {
1633         return "uniform samplerCube my_sampler;                     \n";
1634     }
1635 
TextBody()1636     virtual std::string TextBody()
1637     {
1638         return Type() + " test_function(vec4 p) {                                \n"
1639                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), 1);    \n"
1640                         "}\n";
1641     }
1642 
Expected()1643     virtual Vec4 Expected()
1644     {
1645         return Vec4(1. / 16, 5. / 16, 9. / 16, 13. / 16);
1646     }
1647 
InternalFormat()1648     virtual GLenum InternalFormat()
1649     {
1650         return GL_RG32F;
1651     }
1652 };
1653 
1654 class PlainGatherUnormCube : public GatherBase
1655 {
1656 public:
Init()1657     virtual void Init()
1658     {
1659         CreateTextureCube();
1660     }
1661 
BufferData()1662     virtual Vec4 BufferData()
1663     {
1664         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1665     }
1666 
Sampler()1667     virtual std::string Sampler()
1668     {
1669         return "uniform samplerCube my_sampler;                     \n";
1670     }
1671 
TextBody()1672     virtual std::string TextBody()
1673     {
1674         return Type() + " test_function(vec4 p) {                                \n"
1675                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z));       \n"
1676                         "}\n";
1677     }
1678 
InternalFormat()1679     virtual GLenum InternalFormat()
1680     {
1681         return GL_RGBA16;
1682     }
1683 };
1684 
1685 class PlainGatherIntCubeRgba : public GatherBase
1686 {
1687 public:
Init()1688     virtual void Init()
1689     {
1690         CreateTextureCubeInt();
1691     }
1692 
BufferData()1693     virtual Vec4 BufferData()
1694     {
1695         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1696     }
1697 
Sampler()1698     virtual std::string Sampler()
1699     {
1700         return "uniform isamplerCube my_sampler;                     \n";
1701     }
1702 
TextBody()1703     virtual std::string TextBody()
1704     {
1705         return Type() + " test_function(vec4 p) {                                \n"
1706                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z));       \n"
1707                         "}\n";
1708     }
1709 
InternalFormat()1710     virtual GLenum InternalFormat()
1711     {
1712         return GL_RGBA32I;
1713     }
1714 
SetRbo()1715     virtual void SetRbo()
1716     {
1717         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
1718     }
1719 
Verify()1720     virtual long Verify()
1721     {
1722         IVec4 data;
1723         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
1724         if (data != IVec4(0, 4, 8, 12))
1725         {
1726             m_context.getTestContext().getLog()
1727                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
1728                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1729             return ERROR;
1730         }
1731         return NO_ERROR;
1732     }
1733 
VerifyCompute()1734     virtual long VerifyCompute()
1735     {
1736         IVec4 *data;
1737         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1738         if (data[0] != IVec4(0, 4, 8, 12))
1739         {
1740             m_context.getTestContext().getLog()
1741                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1742                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1743                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1744             return ERROR;
1745         }
1746         return NO_ERROR;
1747     }
1748 
Type()1749     virtual std::string Type()
1750     {
1751         return "ivec4";
1752     }
1753 };
1754 
1755 class PlainGatherIntCubeRg : public GatherBase
1756 {
1757 public:
Init()1758     virtual void Init()
1759     {
1760         CreateTextureCubeInt();
1761     }
1762 
BufferData()1763     virtual Vec4 BufferData()
1764     {
1765         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1766     }
1767 
Sampler()1768     virtual std::string Sampler()
1769     {
1770         return "uniform isamplerCube my_sampler;                     \n";
1771     }
1772 
TextBody()1773     virtual std::string TextBody()
1774     {
1775         return Type() + " test_function(vec4 p) {                                \n"
1776                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), 1);    \n"
1777                         "}\n";
1778     }
1779 
InternalFormat()1780     virtual GLenum InternalFormat()
1781     {
1782         return GL_RG32I;
1783     }
1784 
SetRbo()1785     virtual void SetRbo()
1786     {
1787         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
1788     }
1789 
Verify()1790     virtual long Verify()
1791     {
1792         IVec4 data;
1793         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
1794         if (data != IVec4(1, 5, 9, 13))
1795         {
1796             m_context.getTestContext().getLog()
1797                 << tcu::TestLog::Message << "Expected 1, 5, 9, 13, got: " << data.x() << ", " << data.y() << ", "
1798                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1799             return ERROR;
1800         }
1801         return NO_ERROR;
1802     }
1803 
VerifyCompute()1804     virtual long VerifyCompute()
1805     {
1806         IVec4 *data;
1807         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1808         if (data[0] != IVec4(1, 5, 9, 13))
1809         {
1810             m_context.getTestContext().getLog()
1811                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1812                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1813                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1814             return ERROR;
1815         }
1816         return NO_ERROR;
1817     }
1818 
Type()1819     virtual std::string Type()
1820     {
1821         return "ivec4";
1822     }
1823 };
1824 
1825 class PlainGatherUintCube : public GatherBase
1826 {
1827 public:
Init()1828     virtual void Init()
1829     {
1830         CreateTextureCubeInt();
1831     }
1832 
BufferData()1833     virtual Vec4 BufferData()
1834     {
1835         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1836     }
1837 
Sampler()1838     virtual std::string Sampler()
1839     {
1840         return "uniform usamplerCube my_sampler;                     \n";
1841     }
1842 
TextBody()1843     virtual std::string TextBody()
1844     {
1845         return Type() + " test_function(vec4 p) {                                \n"
1846                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), 0);    \n"
1847                         "}\n";
1848     }
1849 
InternalFormat()1850     virtual GLenum InternalFormat()
1851     {
1852         return GL_RGBA32UI;
1853     }
1854 
SetRbo()1855     virtual void SetRbo()
1856     {
1857         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 1, 1);
1858     }
1859 
Verify()1860     virtual long Verify()
1861     {
1862         IVec4 data;
1863         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
1864         if (data != IVec4(0, 4, 8, 12))
1865         {
1866             m_context.getTestContext().getLog()
1867                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
1868                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
1869             return ERROR;
1870         }
1871         return NO_ERROR;
1872     }
1873 
VerifyCompute()1874     virtual long VerifyCompute()
1875     {
1876         IVec4 *data;
1877         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
1878         if (data[0] != IVec4(0, 4, 8, 12))
1879         {
1880             m_context.getTestContext().getLog()
1881                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
1882                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
1883                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
1884             return ERROR;
1885         }
1886         return NO_ERROR;
1887     }
1888 
Type()1889     virtual std::string Type()
1890     {
1891         return "uvec4";
1892     }
1893 };
1894 
1895 class PlainGatherDepthCube : public GatherBase
1896 {
1897 public:
Init()1898     virtual void Init()
1899     {
1900         CreateTextureCube();
1901         glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1902     }
1903 
InternalFormat()1904     virtual GLenum InternalFormat()
1905     {
1906         return GL_DEPTH_COMPONENT32F;
1907     }
1908 
Format()1909     virtual GLenum Format()
1910     {
1911         return GL_DEPTH_COMPONENT;
1912     }
1913 
BufferData()1914     virtual Vec4 BufferData()
1915     {
1916         return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1917     }
1918 
Sampler()1919     virtual std::string Sampler()
1920     {
1921         return "uniform samplerCubeShadow my_sampler;                     \n";
1922     }
1923 
TextBody()1924     virtual std::string TextBody()
1925     {
1926         return Type() + " test_function(vec4 p) {                                \n"
1927                         "    return textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w);  \n"
1928                         "}\n";
1929     }
1930 
Expected()1931     virtual Vec4 Expected()
1932     {
1933         return Vec4(0, 0, 1, 1);
1934     }
1935 };
1936 
1937 class PlainGatherFloatCubeArray : public GatherBase
1938 {
1939 public:
Supported()1940     virtual bool Supported()
1941     {
1942         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_cube_map_array"))
1943         {
1944             OutputNotSupported("GL_ARB_texture_cube_map_array not supported");
1945             return false;
1946         }
1947         return true;
1948     }
1949 
Init()1950     virtual void Init()
1951     {
1952         CreateTextureCubeArray(9, 5);
1953     }
1954 
BufferData()1955     virtual Vec4 BufferData()
1956     {
1957         return Vec4(7. / 16, -10. / 16, 1, 5);
1958     }
1959 
Sampler()1960     virtual std::string Sampler()
1961     {
1962         return "uniform samplerCubeArray my_sampler;                     \n";
1963     }
1964 
TextBody()1965     virtual std::string TextBody()
1966     {
1967         return Type() + " test_function(vec4 p) {              \n"
1968                         "    return textureGather(my_sampler, p);       \n"
1969                         "}\n";
1970     }
1971 };
1972 
1973 class PlainGatherUnormCubeArray : public GatherBase
1974 {
1975 public:
Supported()1976     virtual bool Supported()
1977     {
1978         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_cube_map_array"))
1979         {
1980             OutputNotSupported("GL_ARB_texture_cube_map_array not supported");
1981             return false;
1982         }
1983         return true;
1984     }
1985 
Init()1986     virtual void Init()
1987     {
1988         CreateTextureCubeArray(7, 3);
1989     }
1990 
BufferData()1991     virtual Vec4 BufferData()
1992     {
1993         return Vec4(7. / 16, -10. / 16, 1, 3);
1994     }
1995 
Sampler()1996     virtual std::string Sampler()
1997     {
1998         return "uniform samplerCubeArray my_sampler;                     \n";
1999     }
2000 
TextBody()2001     virtual std::string TextBody()
2002     {
2003         return Type() + " test_function(vec4 p) {              \n"
2004                         "    return textureGather(my_sampler, p);       \n"
2005                         "}\n";
2006     }
2007 
InternalFormat()2008     virtual GLenum InternalFormat()
2009     {
2010         return GL_RGBA16;
2011     }
2012 };
2013 
2014 class PlainGatherIntCubeArray : public GatherBase
2015 {
2016 public:
Supported()2017     virtual bool Supported()
2018     {
2019         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_cube_map_array"))
2020         {
2021             OutputNotSupported("GL_ARB_texture_cube_map_array not supported");
2022             return false;
2023         }
2024         return true;
2025     }
2026 
Init()2027     virtual void Init()
2028     {
2029         CreateTextureCubeArrayInt(20, 11);
2030     }
2031 
BufferData()2032     virtual Vec4 BufferData()
2033     {
2034         return Vec4(7. / 16, -10. / 16, 1, 11);
2035     }
2036 
Sampler()2037     virtual std::string Sampler()
2038     {
2039         return "uniform isamplerCubeArray my_sampler;                     \n";
2040     }
2041 
TextBody()2042     virtual std::string TextBody()
2043     {
2044         return Type() + " test_function(vec4 p) {              \n"
2045                         "    return textureGather(my_sampler, p);       \n"
2046                         "}\n";
2047     }
2048 
InternalFormat()2049     virtual GLenum InternalFormat()
2050     {
2051         return GL_RGBA32I;
2052     }
2053 
SetRbo()2054     virtual void SetRbo()
2055     {
2056         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
2057     }
2058 
Verify()2059     virtual long Verify()
2060     {
2061         IVec4 data;
2062         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
2063         if (data != IVec4(0, 4, 8, 12))
2064         {
2065             m_context.getTestContext().getLog()
2066                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
2067                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
2068             return ERROR;
2069         }
2070         return NO_ERROR;
2071     }
2072 
VerifyCompute()2073     virtual long VerifyCompute()
2074     {
2075         IVec4 *data;
2076         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2077         if (data[0] != IVec4(0, 4, 8, 12))
2078         {
2079             m_context.getTestContext().getLog()
2080                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
2081                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
2082                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
2083             return ERROR;
2084         }
2085         return NO_ERROR;
2086     }
2087 
Type()2088     virtual std::string Type()
2089     {
2090         return "ivec4";
2091     }
2092 };
2093 
2094 class PlainGatherUintCubeArray : public GatherBase
2095 {
2096 public:
Supported()2097     virtual bool Supported()
2098     {
2099         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_cube_map_array"))
2100         {
2101             OutputNotSupported("GL_ARB_texture_cube_map_array not supported");
2102             return false;
2103         }
2104         return true;
2105     }
2106 
Init()2107     virtual void Init()
2108     {
2109         CreateTextureCubeArrayInt(3, 1);
2110     }
2111 
BufferData()2112     virtual Vec4 BufferData()
2113     {
2114         return Vec4(7. / 16, -10. / 16, 1, 1);
2115     }
2116 
Sampler()2117     virtual std::string Sampler()
2118     {
2119         return "uniform usamplerCubeArray my_sampler;                     \n";
2120     }
2121 
TextBody()2122     virtual std::string TextBody()
2123     {
2124         return Type() + " test_function(vec4 p) {              \n"
2125                         "    return textureGather(my_sampler, p);       \n"
2126                         "}\n";
2127     }
2128 
InternalFormat()2129     virtual GLenum InternalFormat()
2130     {
2131         return GL_RGBA32UI;
2132     }
2133 
SetRbo()2134     virtual void SetRbo()
2135     {
2136         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 1, 1);
2137     }
2138 
Verify()2139     virtual long Verify()
2140     {
2141         UVec4 data;
2142         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data);
2143         if (data != UVec4(0, 4, 8, 12))
2144         {
2145             m_context.getTestContext().getLog()
2146                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
2147                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
2148             return ERROR;
2149         }
2150         return NO_ERROR;
2151     }
2152 
VerifyCompute()2153     virtual long VerifyCompute()
2154     {
2155         IVec4 *data;
2156         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2157         if (data[0] != IVec4(0, 4, 8, 12))
2158         {
2159             m_context.getTestContext().getLog()
2160                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
2161                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
2162                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
2163             return ERROR;
2164         }
2165         return NO_ERROR;
2166     }
2167 
Type()2168     virtual std::string Type()
2169     {
2170         return "uvec4";
2171     }
2172 };
2173 
2174 class PlainGatherDepthCubeArray : public GatherBase
2175 {
2176 public:
Supported()2177     virtual bool Supported()
2178     {
2179         if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_cube_map_array"))
2180         {
2181             OutputNotSupported("GL_ARB_texture_cube_map_array not supported");
2182             return false;
2183         }
2184         return true;
2185     }
2186 
Init()2187     virtual void Init()
2188     {
2189         CreateTextureCubeArray(7, 3);
2190         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2191     }
2192 
BufferData()2193     virtual Vec4 BufferData()
2194     {
2195         return Vec4(7. / 16, -10. / 16, 1, 3);
2196     }
2197 
Sampler()2198     virtual std::string Sampler()
2199     {
2200         return "uniform samplerCubeArrayShadow my_sampler;                     \n";
2201     }
2202 
TextBody()2203     virtual std::string TextBody()
2204     {
2205         return Type() + " test_function(vec4 p) {                   \n"
2206                         "    return textureGather(my_sampler, p, 7.5/16);    \n"
2207                         "}\n";
2208     }
2209 
InternalFormat()2210     virtual GLenum InternalFormat()
2211     {
2212         return GL_DEPTH_COMPONENT32F;
2213     }
2214 
Format()2215     virtual GLenum Format()
2216     {
2217         return GL_DEPTH_COMPONENT;
2218     }
2219 
Expected()2220     virtual Vec4 Expected()
2221     {
2222         return Vec4(0, 0, 1, 1);
2223     }
2224 };
2225 
2226 class PlainGatherFloat2DRect : public GatherBase
2227 {
2228 public:
Init()2229     virtual void Init()
2230     {
2231         CreateTexture2D(true);
2232     }
2233 
BufferData()2234     virtual Vec4 BufferData()
2235     {
2236         return Vec4(23, 26, 0, 0);
2237     }
2238 
Sampler()2239     virtual std::string Sampler()
2240     {
2241         return "uniform sampler2DRect my_sampler;                     \n";
2242     }
2243 
Expected()2244     virtual Vec4 Expected()
2245     {
2246         return Vec4(1. / 16, 5. / 16, 9. / 16, 13. / 16);
2247     }
2248 
TextBody()2249     virtual std::string TextBody()
2250     {
2251         return Type() + " test_function(vec4 p) {                          \n"
2252                         "    return textureGather(my_sampler, vec2(p.x, p.y), 1);   \n"
2253                         "}\n";
2254     }
2255 };
2256 
2257 class PlainGatherUnorm2DRect : public GatherBase
2258 {
2259 public:
Init()2260     virtual void Init()
2261     {
2262         CreateTexture2D(true);
2263     }
2264 
BufferData()2265     virtual Vec4 BufferData()
2266     {
2267         return Vec4(23, 26, 0, 0);
2268     }
2269 
Sampler()2270     virtual std::string Sampler()
2271     {
2272         return "uniform sampler2DRect my_sampler;                     \n";
2273     }
2274 
TextBody()2275     virtual std::string TextBody()
2276     {
2277         return Type() + " test_function(vec4 p) {                       \n"
2278                         "    return textureGather(my_sampler, vec2(p.x, p.y));   \n"
2279                         "}\n";
2280     }
2281 
InternalFormat()2282     virtual GLenum InternalFormat()
2283     {
2284         return GL_RGBA16;
2285     }
2286 };
2287 
2288 class PlainGatherInt2DRect : public GatherBase
2289 {
2290 public:
Init()2291     virtual void Init()
2292     {
2293         CreateTexture2DInt(true);
2294     }
2295 
BufferData()2296     virtual Vec4 BufferData()
2297     {
2298         return Vec4(22.9f, 25.9f, 0, 0);
2299     }
2300 
Sampler()2301     virtual std::string Sampler()
2302     {
2303         return "uniform isampler2DRect my_sampler;                     \n";
2304     }
2305 
TextBody()2306     virtual std::string TextBody()
2307     {
2308         return Type() + " test_function(vec4 p) {                        \n"
2309                         "    return textureGather(my_sampler, vec2(p.x, p.y));    \n"
2310                         "}\n";
2311     }
2312 
InternalFormat()2313     virtual GLenum InternalFormat()
2314     {
2315         return GL_RGBA32I;
2316     }
2317 
SetRbo()2318     virtual void SetRbo()
2319     {
2320         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32I, 1, 1);
2321     }
2322 
Verify()2323     virtual long Verify()
2324     {
2325         IVec4 data;
2326         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_INT, &data);
2327         if (data != IVec4(0, 4, 8, 12))
2328         {
2329             m_context.getTestContext().getLog()
2330                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
2331                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
2332             return ERROR;
2333         }
2334         return NO_ERROR;
2335     }
2336 
VerifyCompute()2337     virtual long VerifyCompute()
2338     {
2339         IVec4 *data;
2340         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2341         if (data[0] != IVec4(0, 4, 8, 12))
2342         {
2343             m_context.getTestContext().getLog()
2344                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
2345                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
2346                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
2347             return ERROR;
2348         }
2349         return NO_ERROR;
2350     }
2351 
Type()2352     virtual std::string Type()
2353     {
2354         return "ivec4";
2355     }
2356 };
2357 
2358 class PlainGatherUint2DRect : public GatherBase
2359 {
2360 public:
Init()2361     virtual void Init()
2362     {
2363         CreateTexture2DInt(true);
2364     }
2365 
BufferData()2366     virtual Vec4 BufferData()
2367     {
2368         return Vec4(22.9f, 25.9f, 0, 0);
2369     }
2370 
Sampler()2371     virtual std::string Sampler()
2372     {
2373         return "uniform usampler2DRect my_sampler;                     \n";
2374     }
2375 
TextBody()2376     virtual std::string TextBody()
2377     {
2378         return Type() + " test_function(vec4 p) {                        \n"
2379                         "    return textureGather(my_sampler, vec2(p.x, p.y));    \n"
2380                         "}\n";
2381     }
2382 
InternalFormat()2383     virtual GLenum InternalFormat()
2384     {
2385         return GL_RGBA32UI;
2386     }
2387 
SetRbo()2388     virtual void SetRbo()
2389     {
2390         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 1, 1);
2391     }
2392 
Verify()2393     virtual long Verify()
2394     {
2395         UVec4 data;
2396         glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data);
2397         if (data != UVec4(0, 4, 8, 12))
2398         {
2399             m_context.getTestContext().getLog()
2400                 << tcu::TestLog::Message << "Expected 0, 4, 8, 12, got: " << data.x() << ", " << data.y() << ", "
2401                 << data.z() << ", " << data.w() << tcu::TestLog::EndMessage;
2402             return ERROR;
2403         }
2404         return NO_ERROR;
2405     }
2406 
VerifyCompute()2407     virtual long VerifyCompute()
2408     {
2409         IVec4 *data;
2410         data = static_cast<IVec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2411         if (data[0] != IVec4(0, 4, 8, 12))
2412         {
2413             m_context.getTestContext().getLog()
2414                 << tcu::TestLog::Message << "Expected " << Expected().x() << ", " << Expected().y() << ", "
2415                 << Expected().z() << ", " << Expected().w() << ", got: " << data[0].x() << ", " << data[0].y() << ", "
2416                 << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
2417             return ERROR;
2418         }
2419         return NO_ERROR;
2420     }
2421 
Type()2422     virtual std::string Type()
2423     {
2424         return "uvec4";
2425     }
2426 };
2427 
2428 class PlainGatherDepth2DRect : public GatherBase
2429 {
2430 public:
Init()2431     virtual void Init()
2432     {
2433         CreateTexture2D(true);
2434         glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2435     }
2436 
BufferData()2437     virtual Vec4 BufferData()
2438     {
2439         return Vec4(23, 26, 13.5 / 16, 3);
2440     }
2441 
Sampler()2442     virtual std::string Sampler()
2443     {
2444         return "uniform sampler2DRectShadow my_sampler;                     \n";
2445     }
2446 
TextBody()2447     virtual std::string TextBody()
2448     {
2449         return Type() + " test_function(vec4 p) {                             \n"
2450                         "    return textureGather(my_sampler, vec2(p.x, p.y), p.z);    \n"
2451                         "}\n";
2452     }
2453 
InternalFormat()2454     virtual GLenum InternalFormat()
2455     {
2456         return GL_DEPTH_COMPONENT32F;
2457     }
2458 
Format()2459     virtual GLenum Format()
2460     {
2461         return GL_DEPTH_COMPONENT;
2462     }
2463 
Expected()2464     virtual Vec4 Expected()
2465     {
2466         return Vec4(1, 1, 0, 0);
2467     }
2468 };
2469 
2470 class OffsetGatherFloat2D : public GatherBase
2471 {
BufferData()2472     virtual Vec4 BufferData()
2473     {
2474         return Vec4(19. / 32, 22. / 32, 4, 4);
2475     }
2476 
TextBody()2477     virtual std::string TextBody()
2478     {
2479         return Type() + " test_function(vec4 p) {                                               \n"
2480                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.z)));    \n"
2481                         "}\n";
2482     }
2483 };
2484 
2485 class OffsetGatherUnorm2D : public PlainGatherUnorm2D
2486 {
BufferData()2487     virtual Vec4 BufferData()
2488     {
2489         return Vec4(19. / 32, 22. / 32, 4, 4);
2490     }
2491 
TestFunction()2492     virtual std::string TestFunction()
2493     {
2494         return "uniform sampler2D my_sampler;                                   \n"
2495                ""
2496                "vec4 test_function(vec4 p) {                                                    \n"
2497                "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.z)));    \n"
2498                "}\n";
2499     }
2500 };
2501 
2502 class OffsetGatherInt2D : public PlainGatherInt2DRgba
2503 {
BufferData()2504     virtual Vec4 BufferData()
2505     {
2506         return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 4);
2507     }
2508 
TextBody()2509     virtual std::string TextBody()
2510     {
2511         return Type() + " test_function(vec4 p) {                                               \n"
2512                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.z)));    \n"
2513                         "}\n";
2514     }
2515 };
2516 
2517 class OffsetGatherUint2D : public PlainGatherUint2D
2518 {
BufferData()2519     virtual Vec4 BufferData()
2520     {
2521         return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 2);
2522     }
2523 
TextBody()2524     virtual std::string TextBody()
2525     {
2526         return Type() + " test_function(vec4 p) {                                                          \n"
2527                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.z)), 2);            \n"
2528                         "}\n";
2529     }
2530 };
2531 
2532 class OffsetGatherDepth2D : public PlainGatherDepth2D
2533 {
BufferData()2534     virtual Vec4 BufferData()
2535     {
2536         return Vec4(19. / 32, 22. / 32, 4, 13.5 / 16);
2537     }
2538 
TextBody()2539     virtual std::string TextBody()
2540     {
2541         return Type() + " test_function(vec4 p) {                                               \n"
2542                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), p.w, ivec2(int(p.z)));    \n"
2543                         "}\n";
2544     }
2545 };
2546 
2547 class OffsetGatherFloat2DArray : public PlainGatherFloat2DArray
2548 {
BufferData()2549     virtual Vec4 BufferData()
2550     {
2551         return Vec4(19. / 32, 22. / 32, 5, 4);
2552     }
2553 
TextBody()2554     virtual std::string TextBody()
2555     {
2556         return Type() + " test_function(vec4 p) {                                                    \n"
2557                         "    return textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), ivec2(int(p.w)));    \n"
2558                         "}\n";
2559     }
2560 };
2561 
2562 class OffsetGatherUnorm2DArray : public PlainGatherUnorm2DArray
2563 {
BufferData()2564     virtual Vec4 BufferData()
2565     {
2566         return Vec4(19. / 32, 22. / 32, 3, 4);
2567     }
2568 
TextBody()2569     virtual std::string TextBody()
2570     {
2571         return Type() + " test_function(vec4 p) {                                                    \n"
2572                         "    return textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), ivec2(int(p.w)));    \n"
2573                         "}\n";
2574     }
2575 };
2576 
2577 class OffsetGatherInt2DArray : public PlainGatherInt2DArray
2578 {
BufferData()2579     virtual Vec4 BufferData()
2580     {
2581         return Vec4(19. / 32, 22. / 32, 11, 4);
2582     }
2583 
TextBody()2584     virtual std::string TextBody()
2585     {
2586         return Type() + " test_function(vec4 p) {                                                    \n"
2587                         "    return textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), ivec2(int(p.w)), 3); \n"
2588                         "}\n";
2589     }
2590 };
2591 
2592 class OffsetGatherUint2DArray : public PlainGatherUint2DArray
2593 {
BufferData()2594     virtual Vec4 BufferData()
2595     {
2596         return Vec4(19. / 32, 22. / 32, 1, 4);
2597     }
2598 
TextBody()2599     virtual std::string TextBody()
2600     {
2601         return Type() + " test_function(vec4 p) {                                                    \n"
2602                         "    return textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), ivec2(int(p.w)));    \n"
2603                         "}\n";
2604     }
2605 };
2606 
2607 class OffsetGatherDepth2DArray : public PlainGatherDepth2DArray
2608 {
Init()2609     virtual void Init()
2610     {
2611         CreateTexture2DArray(7, 3);
2612         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2613     }
2614 
BufferData()2615     virtual Vec4 BufferData()
2616     {
2617         return Vec4(19. / 32, 22. / 32, 3, 4);
2618     }
2619 
TextBody()2620     virtual std::string TextBody()
2621     {
2622         return Type() +
2623                " test_function(vec4 p) {                                                                   \n"
2624                "    return textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), p.y + (5./32), ivec2(int(p.w)));    \n"
2625                "}\n";
2626     }
2627 };
2628 
2629 class OffsetGatherFloat2DRect : public PlainGatherFloat2DRect
2630 {
BufferData()2631     virtual Vec4 BufferData()
2632     {
2633         return Vec4(19, 22, 0, 4);
2634     }
2635 
TextBody()2636     virtual std::string TextBody()
2637     {
2638         return Type() + " test_function(vec4 p) {                                                  \n"
2639                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.w)), 1);    \n"
2640                         "}\n";
2641     }
2642 };
2643 
2644 class OffsetGatherUnorm2DRect : public PlainGatherUnorm2DRect
2645 {
BufferData()2646     virtual Vec4 BufferData()
2647     {
2648         return Vec4(30.9f, 18.9f, -8.f, 7.f);
2649     }
2650 
TextBody()2651     virtual std::string TextBody()
2652     {
2653         return Type() + " test_function(vec4 p) {                                                         \n"
2654                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.z), int(p.w)));    \n"
2655                         "}\n";
2656     }
2657 };
2658 
2659 class OffsetGatherInt2DRect : public PlainGatherInt2DRect
2660 {
BufferData()2661     virtual Vec4 BufferData()
2662     {
2663         return Vec4(22.9f, 25.9f, 0, 0);
2664     }
2665 
TextBody()2666     virtual std::string TextBody()
2667     {
2668         return Type() + " test_function(vec4 p) {                                               \n"
2669                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.w)));    \n"
2670                         "}\n";
2671     }
2672 };
2673 
2674 class OffsetGatherUint2DRect : public PlainGatherUint2DRect
2675 {
BufferData()2676     virtual Vec4 BufferData()
2677     {
2678         return Vec4(26.9f, 29.9f, 0, -4);
2679     }
2680 
TextBody()2681     virtual std::string TextBody()
2682     {
2683         return Type() + " test_function(vec4 p) {                                               \n"
2684                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(int(p.w)));    \n"
2685                         "}\n";
2686     }
2687 };
2688 
2689 class OffsetGatherDepth2DRect : public PlainGatherDepth2DRect
2690 {
BufferData()2691     virtual Vec4 BufferData()
2692     {
2693         return Vec4(19, 22, 13.5 / 16, 4);
2694     }
2695 
TextBody()2696     virtual std::string TextBody()
2697     {
2698         return Type() + " test_function(vec4 p) {                                                    \n"
2699                         "    return textureGatherOffset(my_sampler, vec2(p.x, p.y), p.z, ivec2(int(p.w)));    \n"
2700                         "}\n";
2701     }
2702 };
2703 
2704 class OffsetsGatherFloat2D : public OffsetGatherFloat2D
2705 {
BufferData()2706     virtual Vec4 BufferData()
2707     {
2708         return Vec4(18. / 32, 8. / 32, 0, 0);
2709     }
2710 
TextBody()2711     virtual std::string TextBody()
2712     {
2713         return Type() +
2714                " test_function(vec4 p) {                                                             \n"
2715                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2716                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2717                "}\n";
2718     }
2719 };
2720 
2721 class OffsetsGatherUnorm2D : public OffsetGatherUnorm2D
2722 {
BufferData()2723     virtual Vec4 BufferData()
2724     {
2725         return Vec4(18. / 32, 8. / 32, 0, 0);
2726     }
2727 
TestFunction()2728     virtual std::string TestFunction()
2729     {
2730         return "uniform sampler2D my_sampler;                                   \n"
2731                ""
2732                "vec4  test_function(vec4 p) {                                                             \n"
2733                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2734                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2735                "}\n";
2736     }
2737 };
2738 
2739 class OffsetsGatherInt2D : public OffsetGatherInt2D
2740 {
BufferData()2741     virtual Vec4 BufferData()
2742     {
2743         return Vec4(18. / 32, 8. / 32, 0, 0);
2744     }
2745 
TextBody()2746     virtual std::string TextBody()
2747     {
2748         return Type() +
2749                " test_function(vec4 p) {                                                             \n"
2750                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2751                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2752                "}\n";
2753     }
2754 };
2755 
2756 class OffsetsGatherUint2D : public OffsetGatherUint2D
2757 {
BufferData()2758     virtual Vec4 BufferData()
2759     {
2760         return Vec4(18. / 32, 8. / 32, 2, 2);
2761     }
2762 
TextBody()2763     virtual std::string TextBody()
2764     {
2765         return Type() +
2766                " test_function(vec4 p) {                                                             \n"
2767                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2768                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets, 2);                      \n"
2769                "}\n";
2770     }
2771 };
2772 
2773 class OffsetsGatherDepth2D : public OffsetGatherDepth2D
2774 {
BufferData()2775     virtual Vec4 BufferData()
2776     {
2777         return Vec4(18. / 32, 8. / 32, 0.49f, 0);
2778     }
2779 
TextBody()2780     virtual std::string TextBody()
2781     {
2782         return Type() +
2783                " test_function(vec4 p) {                                                             \n"
2784                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2785                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), p.z, offsets);                    \n"
2786                "}\n";
2787     }
2788 
Expected()2789     virtual Vec4 Expected()
2790     {
2791         return Vec4(0, 0, 1, 1);
2792     }
2793 };
2794 
2795 class OffsetsGatherFloat2DArray : public PlainGatherFloat2DArray
2796 {
Init()2797     virtual void Init()
2798     {
2799         CreateTexture2DArray(3, 1);
2800     }
2801 
BufferData()2802     virtual Vec4 BufferData()
2803     {
2804         return Vec4(18. / 32, 8. / 32, 1, 0);
2805     }
2806 
TextBody()2807     virtual std::string TextBody()
2808     {
2809         return Type() +
2810                " test_function(vec4 p) {                                                             \n"
2811                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2812                "    return textureGatherOffsets(my_sampler, vec3(p.x, p.y, p.z), offsets);                    \n"
2813                "}\n";
2814     }
2815 };
2816 
2817 class OffsetsGatherUnorm2DArray : public PlainGatherUnorm2DArray
2818 {
Init()2819     virtual void Init()
2820     {
2821         CreateTexture2DArray(3, 1);
2822     }
2823 
BufferData()2824     virtual Vec4 BufferData()
2825     {
2826         return Vec4(18. / 32, 8. / 32, 1, 0);
2827     }
2828 
TextBody()2829     virtual std::string TextBody()
2830     {
2831         return Type() +
2832                " test_function(vec4 p) {                                                             \n"
2833                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2834                "    return textureGatherOffsets(my_sampler, vec3(p.x, p.y, p.z), offsets);                    \n"
2835                "}\n";
2836     }
2837 };
2838 
2839 class OffsetsGatherInt2DArray : public PlainGatherInt2DArray
2840 {
Init()2841     virtual void Init()
2842     {
2843         CreateTexture2DArrayInt(3, 1);
2844     }
2845 
BufferData()2846     virtual Vec4 BufferData()
2847     {
2848         return Vec4(18. / 32, 8. / 32, 1, 0);
2849     }
2850 
TextBody()2851     virtual std::string TextBody()
2852     {
2853         return Type() +
2854                " test_function(vec4 p) {                                                             \n"
2855                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2856                "    return textureGatherOffsets(my_sampler, vec3(p.x, p.y, p.z), offsets, 3);                 \n"
2857                "}\n";
2858     }
2859 };
2860 
2861 class OffsetsGatherUint2DArray : public PlainGatherUint2DArray
2862 {
Init()2863     virtual void Init()
2864     {
2865         CreateTexture2DArrayInt(3, 1);
2866     }
2867 
BufferData()2868     virtual Vec4 BufferData()
2869     {
2870         return Vec4(18. / 32, 8. / 32, 1, 0);
2871     }
2872 
TextBody()2873     virtual std::string TextBody()
2874     {
2875         return Type() +
2876                " test_function(vec4 p) {                                                             \n"
2877                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2878                "    return textureGatherOffsets(my_sampler, vec3(p.x, p.y, p.z), offsets);                    \n"
2879                "}\n";
2880     }
2881 };
2882 
2883 class OffsetsGatherDepth2DArray : public PlainGatherDepth2DArray
2884 {
Init()2885     virtual void Init()
2886     {
2887         CreateTexture2DArray(3, 1);
2888         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2889     }
2890 
BufferData()2891     virtual Vec4 BufferData()
2892     {
2893         return Vec4(18. / 32, 8. / 32, 1, 0.49f);
2894     }
2895 
TextBody()2896     virtual std::string TextBody()
2897     {
2898         return Type() +
2899                " test_function(vec4 p) {                                                             \n"
2900                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2901                "    return textureGatherOffsets(my_sampler, vec3(p.x, p.y, p.z), p.w, offsets);               \n"
2902                "}\n";
2903     }
2904 
Expected()2905     virtual Vec4 Expected()
2906     {
2907         return Vec4(0, 0, 1, 1);
2908     }
2909 };
2910 
2911 class OffsetsGatherFloat2DRect : public PlainGatherFloat2DRect
2912 {
BufferData()2913     virtual Vec4 BufferData()
2914     {
2915         return Vec4(18, 8, 0, 0);
2916     }
2917 
TextBody()2918     virtual std::string TextBody()
2919     {
2920         return Type() +
2921                " test_function(vec4 p) {                                                             \n"
2922                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2923                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets, 1);                      \n"
2924                "}\n";
2925     }
2926 };
2927 
2928 class OffsetsGatherUnorm2DRect : public PlainGatherUnorm2DRect
2929 {
BufferData()2930     virtual Vec4 BufferData()
2931     {
2932         return Vec4(18, 8, 0, 0);
2933     }
2934 
TextBody()2935     virtual std::string TextBody()
2936     {
2937         return Type() +
2938                " test_function(vec4 p) {                                                             \n"
2939                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2940                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2941                "}\n";
2942     }
2943 };
2944 
2945 class OffsetsGatherInt2DRect : public PlainGatherUint2DRect
2946 {
BufferData()2947     virtual Vec4 BufferData()
2948     {
2949         return Vec4(17.9f, 7.9f, 0, 0);
2950     }
2951 
TextBody()2952     virtual std::string TextBody()
2953     {
2954         return Type() +
2955                " test_function(vec4 p) {                                                             \n"
2956                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2957                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2958                "}\n";
2959     }
2960 };
2961 
2962 class OffsetsGatherUint2DRect : public PlainGatherUint2DRect
2963 {
BufferData()2964     virtual Vec4 BufferData()
2965     {
2966         return Vec4(17.9f, 7.9f, 0, 0);
2967     }
2968 
TextBody()2969     virtual std::string TextBody()
2970     {
2971         return Type() +
2972                " test_function(vec4 p) {                                                             \n"
2973                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2974                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), offsets);                         \n"
2975                "}\n";
2976     }
2977 };
2978 
2979 class OffsetsGatherDepth2DRect : public PlainGatherDepth2DRect
2980 {
BufferData()2981     virtual Vec4 BufferData()
2982     {
2983         return Vec4(17.9f, 7.9f, 0.49f, 0);
2984     }
2985 
TextBody()2986     virtual std::string TextBody()
2987     {
2988         return Type() +
2989                " test_function(vec4 p) {                                                             \n"
2990                "    const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3)); \n"
2991                "    return textureGatherOffsets(my_sampler, vec2(p.x, p.y), p.z, offsets);                    \n"
2992                "}\n";
2993     }
2994 
Expected()2995     virtual Vec4 Expected()
2996     {
2997         return Vec4(0, 0, 1, 1);
2998     }
2999 };
3000 
3001 class Swizzle : public PlainGatherFloat2DRgba
3002 {
TestFunction()3003     virtual std::string TestFunction()
3004     {
3005         return "uniform sampler2D my_sampler;                                   \n"
3006                ""
3007                "vec4 test_function(vec4 p) {                                    \n"
3008                "    return textureGather(my_sampler, vec2(p.x, p.y), 1).yzww;   \n"
3009                "}\n";
3010     }
3011 
Expected()3012     virtual Vec4 Expected()
3013     {
3014         return Vec4(5. / 16, 9. / 16, 13. / 16, 13. / 16);
3015     }
3016 };
3017 
3018 class BaseLevel : public PlainGatherFloat2DRgba
3019 {
Init()3020     virtual void Init()
3021     {
3022         CreateTexture2D(false, true);
3023     }
3024 };
3025 
3026 class IncompleteTexture : public PlainGatherFloat2DRgba
3027 {
Init()3028     virtual void Init()
3029     {
3030         CreateTexture2D();
3031         glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
3032     }
3033 
Expected()3034     virtual Vec4 Expected()
3035     {
3036         return Vec4(0);
3037     }
3038 };
3039 
3040 class IncompleteTextureLastComp : public PlainGatherFloat2DRgba
3041 {
Init()3042     virtual void Init()
3043     {
3044         CreateTexture2D();
3045         glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
3046     }
3047 
Expected()3048     virtual Vec4 Expected()
3049     {
3050         return Vec4(1);
3051     }
3052 
TestFunction()3053     virtual std::string TestFunction()
3054     {
3055         return "uniform sampler2D my_sampler;                                   \n"
3056                ""
3057                "vec4 test_function(vec4 p) {                                    \n"
3058                "    return textureGather(my_sampler, vec2(p.x, p.y), 3);        \n"
3059                "}\n";
3060     }
3061 };
3062 
3063 class TriangleDraw : public GatherBase
3064 {
3065     GLuint program, rbo, fbo, vao, vbo;
3066 
VertexShader()3067     virtual std::string VertexShader()
3068     {
3069         return "#version 400                                  \n"
3070                "out vec2 texcoords;                           \n"
3071                "in vec4 Vertex;                               \n"
3072                "void main() {                                 \n"
3073                "   gl_Position = Vertex;                      \n"
3074                "   texcoords = (Vertex.xy + vec2(1.0)) / 2.0; \n"
3075                "}\n";
3076     }
3077 
FragmentShader()3078     virtual std::string FragmentShader()
3079     {
3080         return "#version 400                                      \n"
3081                "in vec2 texcoords;                                \n"
3082                "out vec4 FragColor;                               \n"
3083                "uniform sampler2D tex;                            \n"
3084                "void main() {                                     \n"
3085                "   FragColor = textureGather(tex, texcoords, 2);  \n"
3086                "}\n";
3087     }
3088 
Run()3089     virtual long Run()
3090     {
3091         glGenFramebuffers(1, &fbo);
3092         glGenRenderbuffers(1, &rbo);
3093         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3094         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 100, 100);
3095         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3096         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3097         GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
3098         glDrawBuffers(1, &drawBuffer);
3099         GLfloat colorf[4] = {0, 0, 0, 0};
3100         glClearBufferfv(GL_COLOR, 0, colorf);
3101         glViewport(0, 0, 100, 100);
3102 
3103         program = CreateProgram(VertexShader().c_str(), NULL, NULL, NULL, FragmentShader().c_str());
3104         glBindAttribLocation(program, 0, "Vertex");
3105         glBindFragDataLocation(program, 0, "FragColor");
3106         glLinkProgram(program);
3107         if (!CheckProgram(program))
3108             return ERROR;
3109         glUseProgram(program);
3110 
3111         glGenTextures(1, &tex);
3112         glBindTexture(GL_TEXTURE_2D, tex);
3113         std::vector<Vec4> data(100 * 100, Vec4(0.25, 0.5, 0.75, 1));
3114         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 100, 100, 0, GL_RGBA, GL_FLOAT, &data[0]);
3115         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3116         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3117         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
3118         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3119         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3120 
3121         GLuint l_vao;
3122         glGenVertexArrays(1, &l_vao);
3123         glBindVertexArray(l_vao);
3124         glGenBuffers(1, &vbo);
3125         glBindBuffer(GL_ARRAY_BUFFER, vbo);
3126         GLfloat buffData[16] = {-1, 1, 0, 1, -1, -1, 0, 1, 1, 1, 0, 1, 1, -1, 0, 1};
3127         glBufferData(GL_ARRAY_BUFFER, sizeof(buffData), buffData, GL_STATIC_DRAW);
3128         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
3129         glEnableVertexAttribArray(0);
3130         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3131         glDisableVertexAttribArray(0);
3132         glDeleteVertexArrays(1, &l_vao);
3133         glBindBuffer(GL_ARRAY_BUFFER, 0);
3134 
3135         glReadBuffer(GL_COLOR_ATTACHMENT0);
3136         std::vector<Vec4> read(100 * 100, Vec4(0));
3137         glReadPixels(0, 0, 100, 100, GL_RGBA, GL_FLOAT, &read[0]);
3138         for (unsigned int i = 0; i < read.size(); ++i)
3139         {
3140             if (read[i] != Vec4(0.75))
3141             {
3142                 m_context.getTestContext().getLog()
3143                     << tcu::TestLog::Message << "Got: " << read[i].x() << " " << read[i].y() << " " << read[i].z()
3144                     << " " << read[i].w() << ", expected vec4(0.25)" << tcu::TestLog::EndMessage;
3145                 return ERROR;
3146             }
3147         }
3148 
3149         return NO_ERROR;
3150     }
3151 
Cleanup()3152     virtual long Cleanup()
3153     {
3154         glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3155         glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
3156         glDeleteTextures(1, &tex);
3157         glDeleteFramebuffers(1, &fbo);
3158         glDeleteRenderbuffers(1, &rbo);
3159         glDeleteVertexArrays(1, &vao);
3160         glDeleteBuffers(1, &vbo);
3161         glDeleteProgram(program);
3162         return NO_ERROR;
3163     }
3164 };
3165 
3166 class PlainGatherFloat2DSrgb : public GatherBase
3167 {
3168 public:
Expected()3169     virtual Vec4 Expected()
3170     {
3171         return Vec4(0.f, 0.0512695f, 0.21582f, 0.519531f);
3172     }
3173 
InternalFormat()3174     virtual GLenum InternalFormat()
3175     {
3176         return GL_SRGB8_ALPHA8;
3177     }
3178 };
3179 
3180 class PlainGatherFloat2DSrgbAlpha : public GatherBase
3181 {
3182 public:
TestFunction()3183     virtual std::string TestFunction()
3184     {
3185         return "uniform sampler2D my_sampler;                                   \n"
3186                ""
3187                "vec4 test_function(vec4 p) {                                    \n"
3188                "    return textureGather(my_sampler, vec2(p.x, p.y), 3);        \n"
3189                "}\n";
3190     }
3191 
Expected()3192     virtual Vec4 Expected()
3193     {
3194         return Vec4(3. / 16, 7. / 16, 11. / 16, 15. / 16);
3195     }
3196 
InternalFormat()3197     virtual GLenum InternalFormat()
3198     {
3199         return GL_SRGB8_ALPHA8;
3200     }
3201 };
3202 
3203 class GatherGeometryShader : public GatherBase
3204 {
VertexShader()3205     virtual std::string VertexShader()
3206     {
3207         return "#version 400                       \n"
3208                "in vec4 v_in_0;                    \n"
3209                "out vec4 d;                        \n"
3210                "void main() {                      \n"
3211                "   gl_Position = vec4(0, 0, 0, 1); \n"
3212                "   d = v_in_0;                     \n"
3213                "}";
3214     }
3215 
GeometryShader()3216     virtual std::string GeometryShader()
3217     {
3218         return "#version 400                                                  \n"
3219                "layout(points) in;                                            \n"
3220                "layout(points, max_vertices = 1) out;                         \n"
3221                "out vec4 col;                                                 \n"
3222                "in vec4 d[1];                                                 \n"
3223                "uniform sampler2D tex;                                        \n"
3224                ""
3225                "void main() {                                                 \n"
3226                "   vec4 v1 = textureGather(tex, vec2(d[0].x, d[0].y));                                               \n"
3227                "   vec4 v2 = textureGatherOffset(tex, vec2(d[0].x, d[0].y) - vec2(4./32), ivec2(4));                 \n"
3228                "   const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3));         \n"
3229                "   vec4 v3 = textureGatherOffsets(tex, vec2(d[0].x, d[0].y) - vec2(5./32, 18./32), offsets);         \n"
3230                "   vec4 expected = vec4(0./16, 4./16, 8./16, 12./16);                                                \n"
3231                "   float error = 0.0;                                         \n"
3232                ""
3233                "   if (v1 != expected)    \n"
3234                "       error += 0.01;     \n"
3235                "   if (v2 != expected)    \n"
3236                "       error += 0.02;     \n"
3237                "   if (v3 != expected)    \n"
3238                "       error += 0.04;     \n"
3239                ""
3240                "   if (error != 0.0)                         \n"
3241                "       col = vec4(v1.x, v2.y, v3.z, d[0].x); \n"
3242                "   else                                      \n"
3243                "       col = vec4(0, 1, 0, 1);               \n"
3244                ""
3245                "   gl_Position = vec4(0, 0, 0, 1);         \n"
3246                "   EmitVertex();                           \n"
3247                "   EndPrimitive();                         \n"
3248                "}";
3249     }
3250 
FragmentShader()3251     virtual std::string FragmentShader()
3252     {
3253         return "#version 400               \n"
3254                "in vec4 col;               \n"
3255                "out vec4 f_out_0;          \n"
3256                "void main() {              \n"
3257                "   f_out_0 = col;          \n"
3258                "}";
3259     }
3260 
Run()3261     virtual long Run()
3262     {
3263         if (!Supported())
3264             return NO_ERROR;
3265         Init();
3266 
3267         glGenFramebuffers(1, &fbo);
3268         glGenRenderbuffers(1, &rbo);
3269         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3270         SetRbo();
3271         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3272         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3273         GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
3274         glDrawBuffers(1, &drawBuffer);
3275         GLfloat colorf[4] = {0, 0, 0, 0};
3276         glClearBufferfv(GL_COLOR, 0, colorf);
3277         glViewport(0, 0, 1, 1);
3278 
3279         glGenVertexArrays(1, &vao);
3280         glBindVertexArray(vao);
3281         glGenBuffers(1, &vbo);
3282         glBindBuffer(GL_ARRAY_BUFFER, vbo);
3283         glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
3284         glEnableVertexAttribArray(0);
3285         Vec4 buffData = BufferData();
3286         glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
3287 
3288         program = CreateProgram(VertexShader().c_str(), NULL, NULL, GeometryShader().c_str(), FragmentShader().c_str());
3289         glBindAttribLocation(program, 0, "v_in_0");
3290         glBindFragDataLocation(program, 0, "f_out_0");
3291         glLinkProgram(program);
3292         if (!CheckProgram(program))
3293             return ERROR;
3294         glUseProgram(program);
3295 
3296         glDrawArrays(GL_POINTS, 0, 1);
3297         glReadBuffer(GL_COLOR_ATTACHMENT0);
3298 
3299         glDeleteProgram(program);
3300         Vec4 data;
3301         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, &data);
3302         if (!ColorEqual(data, Vec4(0, 1, 0, 1), g_color_eps))
3303         {
3304             m_context.getTestContext().getLog()
3305                 << tcu::TestLog::Message << "Expected Vec4(0, 1, 0, 1), got: " << data.x() << ", " << data.y() << ", "
3306                 << data.z() << ", " << data.w() << ", epsilon: " << g_color_eps.x() << ", " << g_color_eps.y() << ", "
3307                 << g_color_eps.z() << ", " << g_color_eps.w() << tcu::TestLog::EndMessage;
3308             return ERROR;
3309         }
3310         return NO_ERROR;
3311     }
3312 };
3313 
3314 class GatherTesselationShader : public GatherBase
3315 {
VertexShader()3316     virtual std::string VertexShader()
3317     {
3318         return "#version 400               \n"
3319                "in vec4 v_in_0;            \n"
3320                "out vec4 d;                \n"
3321                "void main() {              \n"
3322                "   gl_Position = vec4(0, 0, 0, 1); \n"
3323                "   d = v_in_0;             \n"
3324                "}";
3325     }
3326 
ControlShader()3327     virtual std::string ControlShader()
3328     {
3329         return "#version 400                                                  \n"
3330                "layout(vertices = 1) out;                                     \n"
3331                "out vec4 ccol[];                                              \n"
3332                "in vec4 d[];                                                  \n"
3333                "out vec4 d_con[];                                             \n"
3334                "uniform sampler2D tex;                                        \n"
3335                ""
3336                "void main() {                                        \n"
3337                "   vec4 v1 = textureGather(tex, vec2(d[0].x, d[0].y));                                               \n"
3338                "   vec4 v2 = textureGatherOffset(tex, vec2(d[0].x, d[0].y) - vec2(4./32), ivec2(4));                 \n"
3339                "   const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3));         \n"
3340                "   vec4 v3 = textureGatherOffsets(tex, vec2(d[0].x, d[0].y) - vec2(5./32, 18./32), offsets);         \n"
3341                "   vec4 expected = vec4(0./16, 4./16, 8./16, 12./16);                                                \n"
3342                "   float error = 0.0;                                         \n"
3343                ""
3344                "   if (v1 != expected)    \n"
3345                "       error += 0.01;     \n"
3346                "   if (v2 != expected)    \n"
3347                "       error += 0.02;     \n"
3348                "   if (v3 != expected)    \n"
3349                "       error += 0.04;     \n"
3350                ""
3351                "   if (error != 0.0)                                            \n"
3352                "       ccol[gl_InvocationID] = vec4(v1.x, v2.y, d[0].x, 1);      \n"
3353                "   else                                                         \n"
3354                "       ccol[gl_InvocationID] = vec4(0, 1, 0, 1);                \n"
3355                ""
3356                "   d_con[gl_InvocationID] = d[gl_InvocationID];                                 \n"
3357                "   gl_out[gl_InvocationID].gl_Position = vec4(0, 0, 0, 1);                      \n"
3358                "   gl_TessLevelInner[0] = 1.0;                                                  \n"
3359                "   gl_TessLevelOuter[0] = 1.0;                                                  \n"
3360                "   gl_TessLevelOuter[1] = 1.0;                                                  \n"
3361                "   gl_TessLevelOuter[2] = 1.0;                                                  \n"
3362                "}";
3363     }
3364 
EvalShader()3365     virtual std::string EvalShader()
3366     {
3367         return "#version 400                                                  \n"
3368                "layout(triangles, point_mode) in;                             \n"
3369                "in vec4 ccol[];                                               \n"
3370                "in vec4 d_con[];                                              \n"
3371                "out vec4 ecol;                                                \n"
3372                "uniform sampler2D tex;                                        \n"
3373                ""
3374                "void main() {                                        \n"
3375                "   vec4 v1 = textureGather(tex, vec2(d_con[0].x, d_con[0].y));                                         "
3376                "      \n"
3377                "   vec4 v2 = textureGatherOffset(tex, vec2(d_con[0].x, d_con[0].y) - vec2(4./32), ivec2(4));           "
3378                "      \n"
3379                "   const ivec2 offsets[4] = ivec2[](ivec2(7, 6), ivec2(-8, 7), ivec2(-6, -5), ivec2(-1, 3));           "
3380                "      \n"
3381                "   vec4 v3 = textureGatherOffsets(tex, vec2(d_con[0].x, d_con[0].y) - vec2(5./32, 18./32), offsets);   "
3382                "      \n"
3383                "   vec4 expected = vec4(0./16, 4./16, 8./16, 12./16);                                                  "
3384                "      \n"
3385                "   float error = 0.0;                                         \n"
3386                ""
3387                "   if (v1 != expected)    \n"
3388                "       error += 0.01;     \n"
3389                "   if (v2 != expected)    \n"
3390                "       error += 0.02;     \n"
3391                "   if (v3 != expected)    \n"
3392                "       error += 0.04;     \n"
3393                ""
3394                "   if (error != 0.0)                                          \n"
3395                "       ecol = vec4(v1.x, v2.y, d_con[0].x, -1);                      \n"
3396                "   else if (ccol[0] != vec4(0, 1, 0, 1))     \n"
3397                "       ecol = ccol[0];                       \n"
3398                "   else                                      \n"
3399                "       ecol = vec4(0, 1, 0, 1);              \n"
3400                ""
3401                "   gl_Position = vec4(0, 0, 0, 1);   \n"
3402                "}";
3403     }
3404 
FragmentShader()3405     virtual std::string FragmentShader()
3406     {
3407         return "#version 400               \n"
3408                "in vec4 ecol;              \n"
3409                "out vec4 f_out_0;          \n"
3410                "void main() {              \n"
3411                "   f_out_0 = ecol;         \n"
3412                "}";
3413     }
3414 
Run()3415     virtual long Run()
3416     {
3417 
3418         if (!Supported())
3419             return NO_ERROR;
3420         Init();
3421 
3422         glGenFramebuffers(1, &fbo);
3423         glGenRenderbuffers(1, &rbo);
3424         glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3425         SetRbo();
3426         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3427         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3428         GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
3429         glDrawBuffers(1, &drawBuffer);
3430         GLfloat colorf[4] = {0, 0, 0, 0};
3431         glClearBufferfv(GL_COLOR, 0, colorf);
3432         glViewport(0, 0, 1, 1);
3433 
3434         glGenVertexArrays(1, &vao);
3435         glBindVertexArray(vao);
3436         glGenBuffers(1, &vbo);
3437         glBindBuffer(GL_ARRAY_BUFFER, vbo);
3438         glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
3439         glEnableVertexAttribArray(0);
3440         Vec4 buffData = BufferData();
3441         glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
3442 
3443         program = CreateProgram(VertexShader().c_str(), ControlShader().c_str(), EvalShader().c_str(), NULL,
3444                                 FragmentShader().c_str());
3445         glBindAttribLocation(program, 0, "v_in_0");
3446         glBindFragDataLocation(program, 0, "f_out_0");
3447         glLinkProgram(program);
3448         if (!CheckProgram(program))
3449             return ERROR;
3450         glUseProgram(program);
3451 
3452         glPatchParameteri(GL_PATCH_VERTICES, 1);
3453         glDrawArrays(GL_PATCHES, 0, 1);
3454         glReadBuffer(GL_COLOR_ATTACHMENT0);
3455 
3456         glDeleteProgram(program);
3457         Vec4 data;
3458         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, &data);
3459         if (!ColorEqual(data, Vec4(0, 1, 0, 1), g_color_eps))
3460         {
3461             m_context.getTestContext().getLog()
3462                 << tcu::TestLog::Message << "Expected Vec4(0, 1, 0, 1), got: " << data.x() << ", " << data.y() << ", "
3463                 << data.z() << ", " << data.w() << ", epsilon: " << g_color_eps.x() << ", " << g_color_eps.y() << ", "
3464                 << g_color_eps.z() << ", " << g_color_eps.w() << tcu::TestLog::EndMessage;
3465             return ERROR;
3466         }
3467         return NO_ERROR;
3468     }
3469 };
3470 
3471 class PlainGatherFloat2DRgb : public GatherBase
3472 {
3473 public:
Init()3474     virtual void Init()
3475     {
3476         CreateTexture2DRgb();
3477     }
3478 };
3479 
3480 class PlainGatherFloat2DR : public GatherBase
3481 {
3482 public:
Init()3483     virtual void Init()
3484     {
3485         CreateTexture2DR();
3486     }
3487 };
3488 
3489 class OffsetGatherFloat2DRgb : public OffsetGatherFloat2D
3490 {
3491 public:
Init()3492     virtual void Init()
3493     {
3494         CreateTexture2DRgb();
3495     }
3496 };
3497 
3498 class OffsetGatherFloat2DRg : public OffsetGatherFloat2D
3499 {
3500 public:
Init()3501     virtual void Init()
3502     {
3503         CreateTexture2DRg();
3504     }
3505 };
3506 
3507 class OffsetGatherFloat2DR : public OffsetGatherFloat2D
3508 {
3509 public:
Init()3510     virtual void Init()
3511     {
3512         CreateTexture2DR();
3513     }
3514 };
3515 
3516 } // anonymous namespace
3517 
TextureGatherTests(deqp::Context & context)3518 TextureGatherTests::TextureGatherTests(deqp::Context &context) : TestCaseGroup(context, "texture_gather", "")
3519 {
3520 }
3521 
~TextureGatherTests(void)3522 TextureGatherTests::~TextureGatherTests(void)
3523 {
3524 }
3525 
init()3526 void TextureGatherTests::init()
3527 {
3528     using namespace deqp;
3529     addChild(new TestSubcase(m_context, "api-enums", TestSubcase::Create<GatherEnumsTest>));
3530     addChild(new TestSubcase(m_context, "gather-glsl-compile", TestSubcase::Create<GatherGLSLCompile>));
3531     addChild(new TestSubcase(m_context, "plain-gather-float-2d-rgba", TestSubcase::Create<PlainGatherFloat2DRgba>));
3532     addChild(new TestSubcase(m_context, "plain-gather-float-2d-rg", TestSubcase::Create<PlainGatherFloat2DRg>));
3533     addChild(new TestSubcase(m_context, "plain-gather-unorm-2d", TestSubcase::Create<PlainGatherUnorm2D>));
3534     addChild(new TestSubcase(m_context, "plain-gather-int-2d-rgba", TestSubcase::Create<PlainGatherInt2DRgba>));
3535     addChild(new TestSubcase(m_context, "plain-gather-int-2d-rg", TestSubcase::Create<PlainGatherInt2DRg>));
3536     addChild(new TestSubcase(m_context, "plain-gather-uint-2d", TestSubcase::Create<PlainGatherUint2D>));
3537     addChild(new TestSubcase(m_context, "plain-gather-depth-2d", TestSubcase::Create<PlainGatherDepth2D>));
3538     addChild(new TestSubcase(m_context, "plain-gather-float-2darray", TestSubcase::Create<PlainGatherFloat2DArray>));
3539     addChild(new TestSubcase(m_context, "plain-gather-unorm-2darray", TestSubcase::Create<PlainGatherUnorm2DArray>));
3540     addChild(new TestSubcase(m_context, "plain-gather-int-2darray", TestSubcase::Create<PlainGatherInt2DArray>));
3541     addChild(new TestSubcase(m_context, "plain-gather-uint-2darray", TestSubcase::Create<PlainGatherUint2DArray>));
3542     addChild(new TestSubcase(m_context, "plain-gather-depth-2darray", TestSubcase::Create<PlainGatherDepth2DArray>));
3543     addChild(new TestSubcase(m_context, "plain-gather-float-cube-rgba", TestSubcase::Create<PlainGatherFloatCubeRgba>));
3544     addChild(new TestSubcase(m_context, "plain-gather-float-cube-rg", TestSubcase::Create<PlainGatherFloatCubeRg>));
3545     addChild(new TestSubcase(m_context, "plain-gather-unorm-cube", TestSubcase::Create<PlainGatherUnormCube>));
3546     addChild(new TestSubcase(m_context, "plain-gather-int-cube-rgba", TestSubcase::Create<PlainGatherIntCubeRgba>));
3547     addChild(new TestSubcase(m_context, "plain-gather-int-cube-rg", TestSubcase::Create<PlainGatherIntCubeRg>));
3548     addChild(new TestSubcase(m_context, "plain-gather-uint-cube", TestSubcase::Create<PlainGatherUintCube>));
3549     addChild(new TestSubcase(m_context, "plain-gather-depth-cube", TestSubcase::Create<PlainGatherDepthCube>));
3550     addChild(
3551         new TestSubcase(m_context, "plain-gather-float-cube-array", TestSubcase::Create<PlainGatherFloatCubeArray>));
3552     addChild(
3553         new TestSubcase(m_context, "plain-gather-unorm-cube-array", TestSubcase::Create<PlainGatherUnormCubeArray>));
3554     addChild(new TestSubcase(m_context, "plain-gather-int-cube-array", TestSubcase::Create<PlainGatherIntCubeArray>));
3555     addChild(new TestSubcase(m_context, "plain-gather-uint-cube-array", TestSubcase::Create<PlainGatherUintCubeArray>));
3556     addChild(
3557         new TestSubcase(m_context, "plain-gather-depth-cube-array", TestSubcase::Create<PlainGatherDepthCubeArray>));
3558     addChild(new TestSubcase(m_context, "plain-gather-float-2drect", TestSubcase::Create<PlainGatherFloat2DRect>));
3559     addChild(new TestSubcase(m_context, "plain-gather-unorm-2drect", TestSubcase::Create<PlainGatherUnorm2DRect>));
3560     addChild(new TestSubcase(m_context, "plain-gather-int-2drect", TestSubcase::Create<PlainGatherInt2DRect>));
3561     addChild(new TestSubcase(m_context, "plain-gather-uint-2drect", TestSubcase::Create<PlainGatherUint2DRect>));
3562     addChild(new TestSubcase(m_context, "plain-gather-depth-2drect", TestSubcase::Create<PlainGatherDepth2DRect>));
3563     addChild(new TestSubcase(m_context, "offset-gather-float-2d", TestSubcase::Create<OffsetGatherFloat2D>));
3564     addChild(new TestSubcase(m_context, "offset-gather-unorm-2d", TestSubcase::Create<OffsetGatherUnorm2D>));
3565     addChild(new TestSubcase(m_context, "offset-gather-int-2d", TestSubcase::Create<OffsetGatherInt2D>));
3566     addChild(new TestSubcase(m_context, "offset-gather-uint-2d", TestSubcase::Create<OffsetGatherUint2D>));
3567     addChild(new TestSubcase(m_context, "offset-gather-depth-2d", TestSubcase::Create<OffsetGatherDepth2D>));
3568     addChild(new TestSubcase(m_context, "offset-gather-float-2darray", TestSubcase::Create<OffsetGatherFloat2DArray>));
3569     addChild(new TestSubcase(m_context, "offset-gather-unorm-2darray", TestSubcase::Create<OffsetGatherUnorm2DArray>));
3570     addChild(new TestSubcase(m_context, "offset-gather-int-2darray", TestSubcase::Create<OffsetGatherInt2DArray>));
3571     addChild(new TestSubcase(m_context, "offset-gather-uint-2darray", TestSubcase::Create<OffsetGatherUint2DArray>));
3572     addChild(new TestSubcase(m_context, "offset-gather-depth-2darray", TestSubcase::Create<OffsetGatherDepth2DArray>));
3573     addChild(new TestSubcase(m_context, "offset-gather-float-2drect", TestSubcase::Create<OffsetGatherFloat2DRect>));
3574     addChild(new TestSubcase(m_context, "offset-gather-unorm-2drect", TestSubcase::Create<OffsetGatherUnorm2DRect>));
3575     addChild(new TestSubcase(m_context, "offset-gather-int-2drect", TestSubcase::Create<OffsetGatherInt2DRect>));
3576     addChild(new TestSubcase(m_context, "offset-gather-uint-2drect", TestSubcase::Create<OffsetGatherUint2DRect>));
3577     addChild(new TestSubcase(m_context, "offset-gather-depth-2drect", TestSubcase::Create<OffsetGatherDepth2DRect>));
3578     addChild(new TestSubcase(m_context, "offsets-gather-float-2d", TestSubcase::Create<OffsetsGatherFloat2D>));
3579     addChild(new TestSubcase(m_context, "offsets-gather-unorm-2d", TestSubcase::Create<OffsetsGatherUnorm2D>));
3580     addChild(new TestSubcase(m_context, "offsets-gather-int-2d", TestSubcase::Create<OffsetsGatherInt2D>));
3581     addChild(new TestSubcase(m_context, "offsets-gather-uint-2d", TestSubcase::Create<OffsetsGatherUint2D>));
3582     addChild(new TestSubcase(m_context, "offsets-gather-depth-2d", TestSubcase::Create<OffsetsGatherDepth2D>));
3583     addChild(
3584         new TestSubcase(m_context, "offsets-gather-float-2darray", TestSubcase::Create<OffsetsGatherFloat2DArray>));
3585     addChild(
3586         new TestSubcase(m_context, "offsets-gather-unorm-2darray", TestSubcase::Create<OffsetsGatherUnorm2DArray>));
3587     addChild(new TestSubcase(m_context, "offsets-gather-int-2darray", TestSubcase::Create<OffsetsGatherInt2DArray>));
3588     addChild(new TestSubcase(m_context, "offsets-gather-uint-2darray", TestSubcase::Create<OffsetsGatherUint2DArray>));
3589     addChild(
3590         new TestSubcase(m_context, "offsets-gather-depth-2darray", TestSubcase::Create<OffsetsGatherDepth2DArray>));
3591     addChild(new TestSubcase(m_context, "offsets-gather-float-2drect", TestSubcase::Create<OffsetsGatherFloat2DRect>));
3592     addChild(new TestSubcase(m_context, "offsets-gather-unorm-2drect", TestSubcase::Create<OffsetsGatherUnorm2DRect>));
3593     addChild(new TestSubcase(m_context, "offsets-gather-int-2drect", TestSubcase::Create<OffsetsGatherInt2DRect>));
3594     addChild(new TestSubcase(m_context, "offsets-gather-uint-2drect", TestSubcase::Create<OffsetsGatherUint2DRect>));
3595     addChild(new TestSubcase(m_context, "offsets-gather-depth-2drect", TestSubcase::Create<OffsetsGatherDepth2DRect>));
3596     addChild(new TestSubcase(m_context, "swizzle", TestSubcase::Create<Swizzle>));
3597     addChild(new TestSubcase(m_context, "base-level", TestSubcase::Create<BaseLevel>));
3598     addChild(new TestSubcase(m_context, "incomplete-texture", TestSubcase::Create<IncompleteTexture>));
3599     addChild(
3600         new TestSubcase(m_context, "incomplete-texture-last-comp", TestSubcase::Create<IncompleteTextureLastComp>));
3601     addChild(new TestSubcase(m_context, "triangle-draw", TestSubcase::Create<TriangleDraw>));
3602     addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb", TestSubcase::Create<PlainGatherFloat2DSrgb>));
3603     addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb-alpha",
3604                              TestSubcase::Create<PlainGatherFloat2DSrgbAlpha>));
3605     addChild(new TestSubcase(m_context, "gather-geometry-shader", TestSubcase::Create<GatherGeometryShader>));
3606     addChild(new TestSubcase(m_context, "gather-tesselation-shader", TestSubcase::Create<GatherTesselationShader>));
3607     addChild(new TestSubcase(m_context, "plain-gather-float-2d-rgb", TestSubcase::Create<PlainGatherFloat2DRgb>));
3608     addChild(new TestSubcase(m_context, "plain-gather-float-2d-r", TestSubcase::Create<PlainGatherFloat2DR>));
3609     addChild(new TestSubcase(m_context, "offset-gather-float-2d-rgb", TestSubcase::Create<OffsetGatherFloat2DRgb>));
3610     addChild(new TestSubcase(m_context, "offset-gather-float-2d-rg", TestSubcase::Create<OffsetGatherFloat2DRg>));
3611     addChild(new TestSubcase(m_context, "offset-gather-float-2d-r", TestSubcase::Create<OffsetGatherFloat2DR>));
3612 }
3613 
3614 } // namespace gl4cts
3615