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 "es31cTextureGatherTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include "tcuMatrix.hpp"
28 #include "tcuMatrixUtil.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include <cstdarg>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34
35 namespace glcts
36 {
37
38 using namespace glw;
39 using tcu::IVec4;
40 using tcu::UVec4;
41 using tcu::Vec2;
42 using tcu::Vec3;
43 using tcu::Vec4;
44
45 namespace
46 {
47
48 class TGBase : public glcts::SubcaseBase
49 {
50 public:
~TGBase()51 virtual ~TGBase()
52 {
53 }
54
TGBase()55 TGBase() : renderTarget(m_context.getRenderContext().getRenderTarget()), pixelFormat(renderTarget.getPixelFormat())
56 {
57 }
58
59 const tcu::RenderTarget &renderTarget;
60 const tcu::PixelFormat &pixelFormat;
61
GetWindowWidth()62 int GetWindowWidth()
63 {
64 return renderTarget.getWidth();
65 }
66
GetWindowHeight()67 int GetWindowHeight()
68 {
69 return renderTarget.getHeight();
70 }
71
Title()72 virtual std::string Title()
73 {
74 return "";
75 }
76
Purpose()77 virtual std::string Purpose()
78 {
79 return "";
80 }
81
Method()82 virtual std::string Method()
83 {
84 return "";
85 }
86
PassCriteria()87 virtual std::string PassCriteria()
88 {
89 return "";
90 }
91
CreateProgram(const char * src_vs,const char * src_fs)92 GLuint CreateProgram(const char *src_vs, const char *src_fs)
93 {
94 const GLuint p = glCreateProgram();
95 if (src_vs)
96 {
97 GLuint sh = glCreateShader(GL_VERTEX_SHADER);
98 glAttachShader(p, sh);
99 glDeleteShader(sh);
100 glShaderSource(sh, 1, &src_vs, NULL);
101 glCompileShader(sh);
102 }
103 if (src_fs)
104 {
105 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
106 glAttachShader(p, sh);
107 glDeleteShader(sh);
108 glShaderSource(sh, 1, &src_fs, NULL);
109 glCompileShader(sh);
110 }
111 return p;
112 }
113
CreateComputeProgram(const std::string & cs)114 GLuint CreateComputeProgram(const std::string &cs)
115 {
116 const GLuint p = glCreateProgram();
117 if (!cs.empty())
118 {
119 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
120 glAttachShader(p, sh);
121 glDeleteShader(sh);
122 const char *const src[1] = {cs.c_str()};
123 glShaderSource(sh, 1, src, NULL);
124 glCompileShader(sh);
125 }
126 return p;
127 }
128
CheckProgram(GLuint program,bool * compile_error=NULL)129 bool CheckProgram(GLuint program, bool *compile_error = NULL)
130 {
131 GLint compile_status = GL_TRUE;
132 GLint status;
133 glGetProgramiv(program, GL_LINK_STATUS, &status);
134
135 if (status == GL_FALSE)
136 {
137 GLint attached_shaders;
138 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
139
140 if (attached_shaders > 0)
141 {
142 std::vector<GLuint> shaders(attached_shaders);
143 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
144
145 for (GLint i = 0; i < attached_shaders; ++i)
146 {
147 GLenum type;
148 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
149 switch (type)
150 {
151 case GL_VERTEX_SHADER:
152 m_context.getTestContext().getLog()
153 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
154 break;
155 case GL_FRAGMENT_SHADER:
156 m_context.getTestContext().getLog()
157 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
158 break;
159 case GL_COMPUTE_SHADER:
160 m_context.getTestContext().getLog()
161 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
162 break;
163 default:
164 m_context.getTestContext().getLog()
165 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
166 }
167
168 GLint res;
169 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
170 if (res != GL_TRUE)
171 compile_status = res;
172
173 GLint length;
174 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
175 if (length > 0)
176 {
177 std::vector<GLchar> source(length);
178 glGetShaderSource(shaders[i], length, NULL, &source[0]);
179 m_context.getTestContext().getLog()
180 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
181 }
182
183 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
184 if (length > 0)
185 {
186 std::vector<GLchar> log(length);
187 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
188 m_context.getTestContext().getLog()
189 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
190 }
191 }
192 }
193
194 GLint length;
195 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
196 if (length > 0)
197 {
198 std::vector<GLchar> log(length);
199 glGetProgramInfoLog(program, length, NULL, &log[0]);
200 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
201 }
202 }
203
204 if (compile_error)
205 *compile_error = (compile_status == GL_TRUE ? false : true);
206 if (compile_status != GL_TRUE)
207 return false;
208 return status == GL_TRUE ? true : false;
209 }
210
Setup()211 virtual long Setup()
212 {
213 return NO_ERROR;
214 }
215
Cleanup()216 virtual long Cleanup()
217 {
218 return NO_ERROR;
219 }
220 };
221
222 class GatherEnumsTest : public TGBase
223 {
Title()224 virtual std::string Title()
225 {
226 return "Basic Enum Test";
227 }
228
Purpose()229 virtual std::string Purpose()
230 {
231 return "Verify that gather related enums are correct.";
232 }
233
Method()234 virtual std::string Method()
235 {
236 return "Query GL_*_TEXTURE_GATHER_OFFSET enums.";
237 }
238
PassCriteria()239 virtual std::string PassCriteria()
240 {
241 return "Values of enums meet GL spec requirements.";
242 }
243
Run()244 virtual long Run()
245 {
246 GLint res;
247 glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
248 if (res > -8)
249 {
250 return ERROR;
251 }
252 glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
253 if (res < 7)
254 {
255 return ERROR;
256 }
257 return NO_ERROR;
258 }
259 };
260
261 class GatherGLSLCompile : public TGBase
262 {
263 GLuint program;
264
Title()265 virtual std::string Title()
266 {
267 return "GLSL Compile Test";
268 }
269
Purpose()270 virtual std::string Purpose()
271 {
272 return "Verify that gather functions are visible in the shaders.";
273 }
274
Method()275 virtual std::string Method()
276 {
277 return "Create shaders which use all types of gather functions.";
278 }
279
PassCriteria()280 virtual std::string PassCriteria()
281 {
282 return "Programs compile and link successfuly.";
283 }
284
Uniforms()285 virtual std::string Uniforms()
286 {
287 return "uniform mediump sampler2D tex_2d; \n"
288 "uniform mediump isamplerCube itex_cube; \n"
289 "uniform mediump usampler2DArray utex_2da; \n"
290 ""
291 "uniform mediump sampler2DShadow tex_2ds; \n"
292 "uniform mediump samplerCubeShadow tex_cubes; \n"
293 "uniform mediump sampler2DArrayShadow tex_2das; \n";
294 }
295
Sampling()296 virtual std::string Sampling()
297 {
298 return " textureGather(tex_2d,vec2(1)); \n"
299 " textureGather(itex_cube,vec3(1)); \n"
300 " textureGather(utex_2da,vec3(1)); \n"
301 ""
302 " textureGather(tex_2ds,vec2(1), 0.5); \n"
303 " textureGather(tex_cubes,vec3(1), 0.5); \n"
304 " textureGather(tex_2das,vec3(1), 0.5); \n"
305 ""
306 " textureGatherOffset(tex_2d,vec2(1), ivec2(0)); \n"
307 " textureGatherOffset(utex_2da,vec3(1), ivec2(0)); \n"
308 ""
309 " textureGatherOffset(tex_2ds,vec2(1), 0.5, ivec2(0)); \n"
310 " textureGatherOffset(tex_2das,vec3(1), 0.5, ivec2(0)); \n";
311 }
312
VertexShader()313 virtual std::string VertexShader()
314 {
315 return "#version 310 es \n" + Uniforms() +
316 " void main() { \n" + Sampling() +
317 " gl_Position = vec4(1); \n"
318 " } \n";
319 }
320
FragmentShader()321 virtual std::string FragmentShader()
322 {
323 return "#version 310 es \n"
324 "precision highp float; \n"
325 "out mediump vec4 color; \n" +
326 Uniforms() + " void main() { \n" + Sampling() +
327 " color = vec4(1); \n"
328 " } \n";
329 }
330
Run()331 virtual long Run()
332 {
333 program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str());
334 glLinkProgram(program);
335 if (!CheckProgram(program))
336 return ERROR;
337 return NO_ERROR;
338 }
339
Cleanup()340 virtual long Cleanup()
341 {
342 glDeleteProgram(program);
343 return NO_ERROR;
344 }
345 };
346
347 class GatherBase : public TGBase
348 {
349 public:
350 GLuint tex, fbo, rbo, program, vao, vbo;
351
IsFloatingPointTexture(GLenum internal_format)352 bool IsFloatingPointTexture(GLenum internal_format)
353 {
354 switch (internal_format)
355 {
356 case GL_R32F:
357 case GL_RG32F:
358 case GL_RGB32F:
359 case GL_RGBA32F:
360 case GL_DEPTH_COMPONENT32F:
361 return true;
362 }
363
364 return false;
365 }
366
CreateTexture2DRgb(bool base_level=false)367 virtual GLvoid CreateTexture2DRgb(bool base_level = false)
368 {
369 GLenum internal_format = GL_RGB32F;
370 GLenum format = GL_RGB;
371 const GLint csize = base_level ? 64 : 32;
372 GLint size = csize;
373 GLenum target = GL_TEXTURE_2D;
374 GLenum tex_type = GL_FLOAT;
375
376 glGenTextures(1, &tex);
377 glBindTexture(target, tex);
378 for (int i = 0; size > 0; ++i, size /= 2)
379 {
380 std::vector<Vec3> pixels(size * size, Vec3(1.0));
381 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
382 }
383
384 Vec3 data[4] = {Vec3(12. / 16, 13. / 16, 14. / 16), Vec3(8. / 16, 9. / 16, 10. / 16),
385 Vec3(0. / 16, 1. / 16, 2. / 16), Vec3(4. / 16, 5. / 16, 6. / 16)};
386
387 glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
388 glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
389 glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
390 glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
391 glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
392
393 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
394 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
395 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
396
397 if (IsFloatingPointTexture(internal_format))
398 {
399 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
400 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
401 }
402 }
403
CreateTexture2DRg(bool base_level=false)404 virtual GLvoid CreateTexture2DRg(bool base_level = false)
405 {
406 GLenum internal_format = GL_RG32F;
407 GLenum format = GL_RG;
408 const GLint csize = base_level ? 64 : 32;
409 GLint size = csize;
410 GLenum target = GL_TEXTURE_2D;
411 GLenum tex_type = GL_FLOAT;
412
413 glGenTextures(1, &tex);
414 glBindTexture(target, tex);
415 for (int i = 0; size > 0; ++i, size /= 2)
416 {
417 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
418 std::vector<Vec2> pixels(size * size, Vec2(1.0));
419 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
420 }
421
422 Vec2 data[4] = {Vec2(12. / 16, 13. / 16), Vec2(8. / 16, 9. / 16), Vec2(0. / 16, 1. / 16),
423 Vec2(4. / 16, 5. / 16)};
424
425 glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
426 glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
427 glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
428 glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
429 glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
430
431 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
432 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
433 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
434
435 if (IsFloatingPointTexture(internal_format))
436 {
437 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
438 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
439 }
440 }
441
CreateTexture2DR(bool base_level=false)442 virtual GLvoid CreateTexture2DR(bool base_level = false)
443 {
444 GLenum internal_format = GL_R32F;
445 GLenum format = GL_RED;
446 const GLint csize = base_level ? 64 : 32;
447 GLint size = csize;
448 GLenum target = GL_TEXTURE_2D;
449 GLenum tex_type = GL_FLOAT;
450
451 glGenTextures(1, &tex);
452 glBindTexture(target, tex);
453 for (int i = 0; size > 0; ++i, size /= 2)
454 {
455 std::vector<GLfloat> pixels(size * size, 1.0);
456 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
457 }
458
459 GLfloat data[4] = {12. / 16., 8. / 16., 0. / 16., 4. / 16.};
460
461 glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
462 glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
463 glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
464 glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
465 glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
466
467 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
468 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
469 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
470
471 if (IsFloatingPointTexture(internal_format))
472 {
473 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
474 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
475 }
476 }
477
CreateTexture2DInt()478 virtual GLvoid CreateTexture2DInt()
479 {
480 GLenum internal_format = InternalFormat();
481 const GLint csize = 32;
482 GLint size = csize;
483 GLenum target = GL_TEXTURE_2D;
484 GLenum tex_type = Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
485
486 glGenTextures(1, &tex);
487 glBindTexture(target, tex);
488 for (int i = 0; size > 0; ++i, size /= 2)
489 {
490 glTexImage2D(target, i, internal_format, size, size, 0, GL_RGBA_INTEGER, tex_type, 0);
491 }
492 std::vector<IVec4> pixels(csize * csize, IVec4(999));
493 glTexSubImage2D(target, 0, 0, 0, csize, csize, GL_RGBA_INTEGER, tex_type, &pixels[0]);
494
495 IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
496
497 glTexSubImage2D(target, 0, 22, 25, 2, 2, GL_RGBA_INTEGER, tex_type, data);
498 glTexSubImage2D(target, 0, 16, 10, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
499 glTexSubImage2D(target, 0, 11, 2, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
500 glTexSubImage2D(target, 0, 24, 13, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
501 glTexSubImage2D(target, 0, 9, 14, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
502
503 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
504 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
505 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
506 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
507 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
508 }
509
CreateTexture2DArrayInt(int slices,int data_slice)510 virtual GLvoid CreateTexture2DArrayInt(int slices, int data_slice)
511 {
512 GLenum internal_format = InternalFormat();
513 const GLint csize = 32;
514 GLint size = csize;
515 GLenum tex_type = Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
516
517 glGenTextures(1, &tex);
518 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
519 for (int i = 0; size > 0; ++i, size /= 2)
520 {
521 glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, GL_RGBA_INTEGER, tex_type, 0);
522 }
523 std::vector<IVec4> pixels(csize * csize, IVec4(999));
524 for (int i = 0; i < slices; ++i)
525 {
526 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, csize, csize, 1, GL_RGBA_INTEGER, tex_type, &pixels[0]);
527 }
528
529 IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
530
531 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, GL_RGBA_INTEGER, tex_type, data);
532 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
533 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
534 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
535 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
536
537 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
538 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
539 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
540 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
541 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
542 }
543
CreateTexture2DArray(int slices,int data_slice)544 virtual GLvoid CreateTexture2DArray(int slices, int data_slice)
545 {
546 GLenum internal_format = InternalFormat();
547 GLenum format = Format();
548 const GLint csize = 32;
549 GLint size = csize;
550
551 glGenTextures(1, &tex);
552 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
553 for (int i = 0; size > 0; ++i, size /= 2)
554 {
555 std::vector<Vec4> pixels(size * size * slices, Vec4(1.0));
556 glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, format, GL_FLOAT, &pixels[0]);
557 }
558
559 Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
560 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
561
562 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, format, GL_FLOAT, data);
563 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, format, GL_FLOAT, data + 0);
564 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, format, GL_FLOAT, data + 1);
565 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, format, GL_FLOAT, data + 2);
566 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, format, GL_FLOAT, data + 3);
567
568 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
569 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
570 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
571
572 if (IsFloatingPointTexture(internal_format))
573 {
574 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
575 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
576 }
577 }
578
CreateTextureCubeInt()579 virtual GLvoid CreateTextureCubeInt()
580 {
581 GLenum internal_format = InternalFormat();
582 const GLint csize = 32;
583 GLint size = csize;
584 GLenum tex_type = Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
585
586 const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
587 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
588 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
589
590 glGenTextures(1, &tex);
591 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
592 for (int i = 0; size > 0; ++i, size /= 2)
593 {
594 for (int j = 0; j < 6; ++j)
595 {
596 glTexImage2D(faces[j], i, internal_format, size, size, 0, GL_RGBA_INTEGER, tex_type, 0);
597 }
598 }
599 std::vector<IVec4> pixels(csize * csize, IVec4(999));
600 for (int j = 0; j < 6; ++j)
601 {
602 glTexSubImage2D(faces[j], 0, 0, 0, csize, csize, GL_RGBA_INTEGER, tex_type, &pixels[0]);
603 }
604
605 IVec4 data[4] = {IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7)};
606
607 for (int j = 0; j < 6; ++j)
608 {
609 glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, GL_RGBA_INTEGER, tex_type, data);
610 glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
611 glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
612 glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
613 glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
614 }
615
616 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
617 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
618 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
619 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
620 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
621 }
622
CreateTextureCube()623 virtual GLvoid CreateTextureCube()
624 {
625 GLenum internal_format = InternalFormat();
626 GLenum format = Format();
627 const GLint csize = 32;
628 GLint size = csize;
629
630 const GLenum faces[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
631 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
632 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
633
634 glGenTextures(1, &tex);
635 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
636 for (int i = 0; size > 0; ++i, size /= 2)
637 {
638 std::vector<Vec4> pixels(size * size, Vec4(1.0));
639 for (int j = 0; j < 6; ++j)
640 {
641 glTexImage2D(faces[j], i, internal_format, size, size, 0, format, GL_FLOAT, &pixels[0]);
642 }
643 }
644
645 Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
646 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
647
648 Vec4 depthData(data[0][0], data[1][0], data[2][0], data[3][0]);
649 Vec4 *packedData = (format == GL_DEPTH_COMPONENT) ? &depthData : data;
650
651 for (int j = 0; j < 6; ++j)
652 {
653 glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, format, GL_FLOAT, packedData);
654 glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, format, GL_FLOAT, data + 0);
655 glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, format, GL_FLOAT, data + 1);
656 glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, format, GL_FLOAT, data + 2);
657 glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, format, GL_FLOAT, data + 3);
658 }
659
660 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
661 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
662 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
663
664 if (IsFloatingPointTexture(internal_format))
665 {
666 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
667 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
668 }
669 }
670
CreateTextureSRGB()671 virtual GLvoid CreateTextureSRGB()
672 {
673 GLenum internal_format = InternalFormat();
674 GLenum format = Format();
675 const GLint csize = 32;
676 GLint size = csize;
677 GLenum target = GL_TEXTURE_2D;
678 GLenum tex_type = GL_UNSIGNED_BYTE;
679
680 glGenTextures(1, &tex);
681 glBindTexture(target, tex);
682 for (int i = 0; size > 0; ++i, size /= 2)
683 {
684 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
685 }
686 std::vector<GLubyte> pixels(csize * csize * 4, 255);
687 glTexSubImage2D(target, 0, 0, 0, csize, csize, format, tex_type, &pixels[0]);
688
689 if (format != GL_DEPTH_COMPONENT)
690 {
691 glGenerateMipmap(target);
692 }
693
694 GLubyte data[16] = {240, 13, 14, 15, 160, 9, 10, 11, 0, 1, 2, 3, 80, 5, 6, 7};
695
696 glTexSubImage2D(target, 0, 22, 25, 2, 2, format, tex_type, data);
697 glTexSubImage2D(target, 0, 16, 10, 1, 1, format, tex_type, data + 0);
698 glTexSubImage2D(target, 0, 11, 2, 1, 1, format, tex_type, data + 4);
699 glTexSubImage2D(target, 0, 24, 13, 1, 1, format, tex_type, data + 8);
700 glTexSubImage2D(target, 0, 9, 14, 1, 1, format, tex_type, data + 12);
701
702 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
703 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
704 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
705 }
706
CreateTexture2D(bool base_level=false)707 virtual GLvoid CreateTexture2D(bool base_level = false)
708 {
709 GLenum internal_format = InternalFormat();
710 GLenum format = Format();
711 const GLint csize = base_level ? 64 : 32;
712 GLint size = csize;
713 GLenum target = GL_TEXTURE_2D;
714 GLenum tex_type = InternalFormat() == GL_SRGB8_ALPHA8 ? GL_UNSIGNED_BYTE : GL_FLOAT;
715
716 glGenTextures(1, &tex);
717 glBindTexture(target, tex);
718 for (int i = 0; size > 0; ++i, size /= 2)
719 {
720 std::vector<Vec4> pixels(size * size, Vec4(1.0));
721 glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
722 }
723
724 Vec4 data[4] = {Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
725 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16)};
726
727 glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
728 glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
729 glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
730 glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
731 glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
732
733 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
734 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
735 glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
736
737 if (IsFloatingPointTexture(internal_format))
738 {
739 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
740 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
741 }
742
743 if (base_level)
744 glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 1);
745 }
746
FallthroughVertexShader()747 virtual std::string FallthroughVertexShader()
748 {
749 return "#version 310 es \n"
750 "in vec4 v_in_0; \n"
751 "flat out vec4 v_out_0; \n"
752 "void main() { \n"
753 " gl_Position = vec4(0,0,0,1); \n"
754 "#ifdef GL_ES \n"
755 " gl_PointSize = 1.0f; \n"
756 "#endif \n"
757 " v_out_0 = v_in_0; \n"
758 "}";
759 }
760
FallthroughFragmentShader()761 virtual std::string FallthroughFragmentShader()
762 {
763 return "#version 310 es \n"
764 "precision highp float; \n"
765 "out mediump vec4 f_out_0; \n"
766 "flat in mediump vec4 v_out_0; \n"
767 "void main() { \n"
768 " f_out_0 = v_out_0; \n"
769 "}";
770 }
771
TestFunction()772 virtual std::string TestFunction()
773 {
774 return Sampler() + TextBody();
775 }
776
Sampler()777 virtual std::string Sampler()
778 {
779 return "uniform mediump sampler2D my_sampler; \n";
780 }
781
Type()782 virtual std::string Type()
783 {
784 return "vec4";
785 }
786
TextBody()787 virtual std::string TextBody()
788 {
789 std::string str_if = " if (all(lessThanEqual(abs(tmp - " + Expected() + "), vec4(0.039)))) { \n";
790 if (Type().find('u') != std::string::npos || Type().find('i') != std::string::npos)
791 {
792 str_if = " if (tmp == " + Expected() + ") { \n";
793 }
794 return "vec4 test_function(vec4 p) { "
795 "\n" +
796 Offset() + " mediump " + Type() + " tmp = " + Gather() +
797 "; \n" + str_if +
798 " return vec4(0.0, 1.0, 0.0, 1.0); \n"
799 " } else { \n"
800 " return vec4(float(tmp.x), float(tmp.y), float(tmp.z), float(tmp.w)); \n"
801 " } \n"
802 "}\n";
803 }
804
Gather()805 virtual std::string Gather()
806 {
807 return "textureGather(my_sampler, vec2(p.x, p.y))";
808 }
809
Offset()810 virtual std::string Offset()
811 {
812 return "";
813 }
814
VertexShader()815 virtual std::string VertexShader()
816 {
817 return "#version 310 es \n"
818 ""
819 "in mediump vec4 v_in_0; \n"
820 "flat out mediump vec4 v_out_0; \n" +
821 TestFunction() +
822 "void main() { \n"
823 " gl_Position = vec4(0, 0, 0, 1); \n"
824 "#ifdef GL_ES \n"
825 " gl_PointSize = 1.0f; \n"
826 "#endif \n"
827 " v_out_0 = test_function(v_in_0); \n"
828 "}";
829 }
830
FragmentShader()831 virtual std::string FragmentShader()
832 {
833 return "#version 310 es \n"
834 ""
835 "precision highp float; \n"
836 "flat in mediump vec4 v_out_0; \n"
837 "out mediump vec4 f_out_0; \n" +
838 TestFunction() +
839 "void main() { \n"
840 " f_out_0 = test_function(v_out_0); \n"
841 "}";
842 }
843
ComputeShader()844 virtual std::string ComputeShader()
845 {
846 return "#version 310 es \n"
847 "layout(local_size_x = 1, local_size_y = 1) in; \n"
848 "layout(std430) buffer Output { \n"
849 " mediump vec4 data; \n"
850 "} g_out; \n"
851 "uniform mediump vec4 cs_in; \n" +
852 TestFunction() +
853 "void main() { \n"
854 " g_out.data = test_function(cs_in); \n"
855 "} \n";
856 }
857
Init()858 virtual void Init()
859 {
860 CreateTexture2D();
861 }
862
Verify()863 virtual long Verify()
864 {
865 std::vector<GLubyte> data(4);
866 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
867 if (data[0] != 0 || data[1] != 255 || data[2] != 0 || data[3] != 255)
868 {
869 m_context.getTestContext().getLog()
870 << tcu::TestLog::Message << "Expected Vec4(0, 255, 0, 255), got: " << data[0] << ", " << data[1] << ", "
871 << data[2] << ", " << data[3] << tcu::TestLog::EndMessage;
872 return ERROR;
873 }
874 return NO_ERROR;
875 }
876
Expected()877 virtual std::string Expected()
878 {
879 return "vec4(0./16., 4./16., 8./16., 12./16.)";
880 }
881
InternalFormat()882 virtual GLenum InternalFormat()
883 {
884 return GL_RGBA32F;
885 }
886
Format()887 virtual GLenum Format()
888 {
889 return GL_RGBA;
890 }
891
BufferData()892 virtual Vec4 BufferData()
893 {
894 return Vec4(23. / 32, 26. / 32, 5, 3);
895 }
896
Supported()897 virtual bool Supported()
898 {
899 return true;
900 }
901
Run()902 virtual long Run()
903 {
904 if (!Supported())
905 return NO_ERROR;
906 Init();
907
908 glGenFramebuffers(1, &fbo);
909 glGenRenderbuffers(1, &rbo);
910 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
911 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
912 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
913 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
914 GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
915 glDrawBuffers(1, &drawBuffer);
916 GLfloat colorf[4] = {0, 0, 0, 0};
917 glClearBufferfv(GL_COLOR, 0, colorf);
918 glViewport(0, 0, 1, 1);
919
920 glGenVertexArrays(1, &vao);
921 glBindVertexArray(vao);
922 glGenBuffers(1, &vbo);
923 glBindBuffer(GL_ARRAY_BUFFER, vbo);
924 glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
925 glEnableVertexAttribArray(0);
926 Vec4 buffData = BufferData();
927 glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
928
929 for (int i = 0; i < 2; ++i)
930 {
931 if (i == 0)
932 program = CreateProgram(VertexShader().c_str(), FallthroughFragmentShader().c_str());
933 else
934 program = CreateProgram(FallthroughVertexShader().c_str(), FragmentShader().c_str());
935 glBindAttribLocation(program, 0, "v_in_0");
936 glLinkProgram(program);
937 if (!CheckProgram(program))
938 return ERROR;
939 glUseProgram(program);
940
941 glDrawArrays(GL_POINTS, 0, 1);
942 glReadBuffer(GL_COLOR_ATTACHMENT0);
943
944 glDeleteProgram(program);
945
946 if (Verify() == ERROR)
947 return ERROR;
948 }
949
950 return TestCompute();
951 }
952
TestCompute()953 virtual long TestCompute()
954 {
955 GLuint m_buffer;
956
957 program = CreateComputeProgram(ComputeShader());
958 glLinkProgram(program);
959 if (!CheckProgram(program))
960 return ERROR;
961 glUseProgram(program);
962
963 glUniform4f(glGetUniformLocation(program, "cs_in"), BufferData().x(), BufferData().y(), BufferData().z(),
964 BufferData().w());
965
966 glGenBuffers(1, &m_buffer);
967 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
968 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Vec4), NULL, GL_DYNAMIC_DRAW);
969 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
970
971 glDispatchCompute(1, 1, 1);
972
973 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
974 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
975 long error = VerifyCompute();
976 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
977 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
978 glDeleteBuffers(1, &m_buffer);
979
980 return error;
981 }
982
VerifyCompute()983 virtual long VerifyCompute()
984 {
985 Vec4 *data;
986 data = static_cast<Vec4 *>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Vec4), GL_MAP_READ_BIT));
987 if (data[0] != Vec4(0, 1, 0, 1))
988 {
989 m_context.getTestContext().getLog()
990 << tcu::TestLog::Message << "Expected Vec4(0, 1, 0, 1), got: " << data[0].x() << ", " << data[0].y()
991 << ", " << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
992 return ERROR;
993 }
994 return NO_ERROR;
995 }
996
Cleanup()997 virtual long Cleanup()
998 {
999 glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
1000 glDisableVertexAttribArray(0);
1001 glDeleteTextures(1, &tex);
1002 glDeleteVertexArrays(1, &vao);
1003 glDeleteBuffers(1, &vbo);
1004 glDeleteRenderbuffers(1, &rbo);
1005 glDeleteFramebuffers(1, &fbo);
1006 glDeleteProgram(program);
1007 return NO_ERROR;
1008 }
1009 };
1010
1011 class PlainGatherFloat2D : public GatherBase
1012 {
1013 };
1014
1015 class PlainGatherInt2D : public GatherBase
1016 {
1017 public:
InternalFormat()1018 virtual GLenum InternalFormat()
1019 {
1020 return GL_RGBA32I;
1021 }
1022
Init()1023 virtual void Init()
1024 {
1025 CreateTexture2DInt();
1026 }
1027
Expected()1028 virtual std::string Expected()
1029 {
1030 return "ivec4(0, 4, 8, 12)";
1031 }
1032
Sampler()1033 virtual std::string Sampler()
1034 {
1035 return "uniform mediump isampler2D my_sampler; \n";
1036 }
1037
Type()1038 virtual std::string Type()
1039 {
1040 return "ivec4";
1041 }
1042 };
1043
1044 class PlainGatherUint2D : public GatherBase
1045 {
1046 public:
InternalFormat()1047 virtual GLenum InternalFormat()
1048 {
1049 return GL_RGBA32UI;
1050 }
1051
Init()1052 virtual void Init()
1053 {
1054 CreateTexture2DInt();
1055 }
1056
Expected()1057 virtual std::string Expected()
1058 {
1059 return "uvec4(2u, 6u, 10u, 14u)";
1060 }
1061
Sampler()1062 virtual std::string Sampler()
1063 {
1064 return "uniform mediump usampler2D my_sampler; \n";
1065 }
1066
BufferData()1067 virtual Vec4 BufferData()
1068 {
1069 return Vec4(22.9f / 32, 25.9f / 32, 2, 2);
1070 }
1071
Type()1072 virtual std::string Type()
1073 {
1074 return "uvec4";
1075 }
1076
Gather()1077 virtual std::string Gather()
1078 {
1079 return "textureGather(my_sampler, vec2(p.x, p.y), 2)";
1080 }
1081 };
1082
1083 class PlainGatherDepth2D : public GatherBase
1084 {
1085 public:
InternalFormat()1086 virtual GLenum InternalFormat()
1087 {
1088 return GL_DEPTH_COMPONENT32F;
1089 }
1090
Format()1091 virtual GLenum Format()
1092 {
1093 return GL_DEPTH_COMPONENT;
1094 }
1095
Init()1096 virtual void Init()
1097 {
1098 CreateTexture2D();
1099 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1100 }
1101
Expected()1102 virtual std::string Expected()
1103 {
1104 return "vec4(1.0, 1.0, 0.0, 0.0)";
1105 }
1106
BufferData()1107 virtual Vec4 BufferData()
1108 {
1109 return Vec4(23. / 32, 26. / 32, 13.5 / 16, 3);
1110 }
1111
Sampler()1112 virtual std::string Sampler()
1113 {
1114 return "uniform mediump sampler2DShadow my_sampler; \n";
1115 }
1116
Gather()1117 virtual std::string Gather()
1118 {
1119 return "textureGather(my_sampler, vec2(p.x, p.y), p.z)";
1120 }
1121 };
1122
1123 class PlainGatherFloat2DArray : public GatherBase
1124 {
1125 public:
Init()1126 virtual void Init()
1127 {
1128 CreateTexture2DArray(9, 5);
1129 }
1130
Sampler()1131 virtual std::string Sampler()
1132 {
1133 return "uniform mediump sampler2DArray my_sampler; \n";
1134 }
1135
Gather()1136 virtual std::string Gather()
1137 {
1138 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1139 }
1140 };
1141
1142 class PlainGatherInt2DArray : public GatherBase
1143 {
1144 public:
Init()1145 virtual void Init()
1146 {
1147 CreateTexture2DArrayInt(20, 11);
1148 }
1149
InternalFormat()1150 virtual GLenum InternalFormat()
1151 {
1152 return GL_RGBA32I;
1153 }
1154
Expected()1155 virtual std::string Expected()
1156 {
1157 return "ivec4(3, 7, 11, 15)";
1158 }
1159
Type()1160 virtual std::string Type()
1161 {
1162 return "ivec4";
1163 }
1164
BufferData()1165 virtual Vec4 BufferData()
1166 {
1167 return Vec4(23. / 32, 26. / 32, 11, 3);
1168 }
1169
Sampler()1170 virtual std::string Sampler()
1171 {
1172 return "uniform mediump isampler2DArray my_sampler; \n";
1173 }
1174
Gather()1175 virtual std::string Gather()
1176 {
1177 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 3)";
1178 }
1179 };
1180
1181 class PlainGatherUint2DArray : public GatherBase
1182 {
1183 public:
Init()1184 virtual void Init()
1185 {
1186 CreateTexture2DArrayInt(3, 1);
1187 }
1188
InternalFormat()1189 virtual GLenum InternalFormat()
1190 {
1191 return GL_RGBA32UI;
1192 }
1193
Expected()1194 virtual std::string Expected()
1195 {
1196 return "uvec4(0u, 4u, 8u, 12u)";
1197 }
1198
Type()1199 virtual std::string Type()
1200 {
1201 return "uvec4";
1202 }
1203
BufferData()1204 virtual Vec4 BufferData()
1205 {
1206 return Vec4(23. / 32, 26. / 32, 1, 3);
1207 }
1208
Sampler()1209 virtual std::string Sampler()
1210 {
1211 return "uniform mediump usampler2DArray my_sampler; \n";
1212 }
1213
Gather()1214 virtual std::string Gather()
1215 {
1216 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1217 }
1218 };
1219
1220 class PlainGatherDepth2DArray : public GatherBase
1221 {
1222 public:
InternalFormat()1223 virtual GLenum InternalFormat()
1224 {
1225 return GL_DEPTH_COMPONENT32F;
1226 }
1227
Format()1228 virtual GLenum Format()
1229 {
1230 return GL_DEPTH_COMPONENT;
1231 }
1232
Init()1233 virtual void Init()
1234 {
1235 CreateTexture2DArray(9, 5);
1236 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1237 }
1238
Expected()1239 virtual std::string Expected()
1240 {
1241 return "vec4(1.0, 1.0, 0.0, 0.0)";
1242 }
1243
BufferData()1244 virtual Vec4 BufferData()
1245 {
1246 return Vec4(23. / 32, 26. / 32, 5, 13.5 / 16);
1247 }
1248
Sampler()1249 virtual std::string Sampler()
1250 {
1251 return "uniform mediump sampler2DArrayShadow my_sampler; \n";
1252 }
1253
Gather()1254 virtual std::string Gather()
1255 {
1256 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1257 }
1258 };
1259
1260 class PlainGatherFloatCube : public GatherBase
1261 {
1262 public:
Init()1263 virtual void Init()
1264 {
1265 CreateTextureCube();
1266 }
1267
BufferData()1268 virtual Vec4 BufferData()
1269 {
1270 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1271 }
1272
Sampler()1273 virtual std::string Sampler()
1274 {
1275 return "uniform mediump samplerCube my_sampler; \n";
1276 }
1277
Gather()1278 virtual std::string Gather()
1279 {
1280 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1281 }
1282 };
1283
1284 class PlainGatherIntCube : public GatherBase
1285 {
1286 public:
Init()1287 virtual void Init()
1288 {
1289 CreateTextureCubeInt();
1290 }
1291
BufferData()1292 virtual Vec4 BufferData()
1293 {
1294 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1295 }
1296
Sampler()1297 virtual std::string Sampler()
1298 {
1299 return "uniform mediump isamplerCube my_sampler; \n";
1300 }
1301
Gather()1302 virtual std::string Gather()
1303 {
1304 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1305 }
1306
InternalFormat()1307 virtual GLenum InternalFormat()
1308 {
1309 return GL_RGBA32I;
1310 }
1311
Expected()1312 virtual std::string Expected()
1313 {
1314 return "ivec4(0, 4, 8, 12)";
1315 }
1316
Type()1317 virtual std::string Type()
1318 {
1319 return "ivec4";
1320 }
1321 };
1322
1323 class PlainGatherUintCube : public GatherBase
1324 {
1325 public:
Init()1326 virtual void Init()
1327 {
1328 CreateTextureCubeInt();
1329 }
1330
BufferData()1331 virtual Vec4 BufferData()
1332 {
1333 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1334 }
1335
Sampler()1336 virtual std::string Sampler()
1337 {
1338 return "uniform mediump usamplerCube my_sampler; \n";
1339 }
1340
Gather()1341 virtual std::string Gather()
1342 {
1343 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 0)";
1344 }
1345
InternalFormat()1346 virtual GLenum InternalFormat()
1347 {
1348 return GL_RGBA32UI;
1349 }
1350
Expected()1351 virtual std::string Expected()
1352 {
1353 return "uvec4(0u, 4u, 8u, 12u)";
1354 }
1355
Type()1356 virtual std::string Type()
1357 {
1358 return "uvec4";
1359 }
1360 };
1361
1362 class PlainGatherDepthCube : public GatherBase
1363 {
1364 public:
Init()1365 virtual void Init()
1366 {
1367 CreateTextureCube();
1368 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1369 }
1370
InternalFormat()1371 virtual GLenum InternalFormat()
1372 {
1373 return GL_DEPTH_COMPONENT32F;
1374 }
1375
Format()1376 virtual GLenum Format()
1377 {
1378 return GL_DEPTH_COMPONENT;
1379 }
1380
BufferData()1381 virtual Vec4 BufferData()
1382 {
1383 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1384 }
1385
Sampler()1386 virtual std::string Sampler()
1387 {
1388 return "uniform mediump samplerCubeShadow my_sampler; \n";
1389 }
1390
Gather()1391 virtual std::string Gather()
1392 {
1393 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1394 }
1395
Expected()1396 virtual std::string Expected()
1397 {
1398 return "vec4(0.0, 0.0, 1.0, 1.0)";
1399 }
1400 };
1401
1402 class OffsetGatherFloat2D : public GatherBase
1403 {
BufferData()1404 virtual Vec4 BufferData()
1405 {
1406 return Vec4(19. / 32, 22. / 32, 4, 4);
1407 }
1408
Offset()1409 virtual std::string Offset()
1410 {
1411 return "const mediump ivec2 offset = ivec2(4); \n";
1412 }
1413
Gather()1414 virtual std::string Gather()
1415 {
1416 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1417 }
1418 };
1419
1420 class OffsetGatherInt2D : public PlainGatherInt2D
1421 {
BufferData()1422 virtual Vec4 BufferData()
1423 {
1424 return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 4);
1425 }
1426
Offset()1427 virtual std::string Offset()
1428 {
1429 return "const mediump ivec2 offset = ivec2(4); \n";
1430 }
1431
Gather()1432 virtual std::string Gather()
1433 {
1434 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1435 }
1436 };
1437
1438 class OffsetGatherUint2D : public PlainGatherUint2D
1439 {
BufferData()1440 virtual Vec4 BufferData()
1441 {
1442 return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 2);
1443 }
1444
Offset()1445 virtual std::string Offset()
1446 {
1447 return "const mediump ivec2 offset = ivec2(4); \n";
1448 }
1449
Gather()1450 virtual std::string Gather()
1451 {
1452 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset, 2)";
1453 }
1454 };
1455
1456 class OffsetGatherDepth2D : public PlainGatherDepth2D
1457 {
BufferData()1458 virtual Vec4 BufferData()
1459 {
1460 return Vec4(19. / 32, 22. / 32, 4, 13.5 / 16);
1461 }
1462
Offset()1463 virtual std::string Offset()
1464 {
1465 return "const mediump ivec2 offset = ivec2(4); \n";
1466 }
1467
Gather()1468 virtual std::string Gather()
1469 {
1470 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), p.w, offset)";
1471 }
1472 };
1473
1474 class OffsetGatherFloat2DArray : public PlainGatherFloat2DArray
1475 {
BufferData()1476 virtual Vec4 BufferData()
1477 {
1478 return Vec4(19. / 32, 22. / 32, 5, 4);
1479 }
1480
Offset()1481 virtual std::string Offset()
1482 {
1483 return "const mediump ivec2 offset = ivec2(4); \n";
1484 }
1485
Gather()1486 virtual std::string Gather()
1487 {
1488 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset)";
1489 }
1490 };
1491
1492 class OffsetGatherInt2DArray : public PlainGatherInt2DArray
1493 {
BufferData()1494 virtual Vec4 BufferData()
1495 {
1496 return Vec4(19. / 32, 22. / 32, 11, 4);
1497 }
1498
Offset()1499 virtual std::string Offset()
1500 {
1501 return "const mediump ivec2 offset = ivec2(4); \n";
1502 }
1503
Gather()1504 virtual std::string Gather()
1505 {
1506 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 3)";
1507 }
1508 };
1509
1510 class OffsetGatherUint2DArray : public PlainGatherUint2DArray
1511 {
BufferData()1512 virtual Vec4 BufferData()
1513 {
1514 return Vec4(19. / 32, 22. / 32, 1, 4);
1515 }
1516
Offset()1517 virtual std::string Offset()
1518 {
1519 return "const mediump ivec2 offset = ivec2(4); \n";
1520 }
1521
Gather()1522 virtual std::string Gather()
1523 {
1524 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 0)";
1525 }
1526 };
1527
1528 class OffsetGatherDepth2DArray : public PlainGatherDepth2DArray
1529 {
Init()1530 virtual void Init()
1531 {
1532 CreateTexture2DArray(7, 3);
1533 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1534 }
1535
BufferData()1536 virtual Vec4 BufferData()
1537 {
1538 return Vec4(19. / 32, 22. / 32, 3, 4);
1539 }
1540
Offset()1541 virtual std::string Offset()
1542 {
1543 return "const mediump ivec2 offset = ivec2(4); \n";
1544 }
1545
Gather()1546 virtual std::string Gather()
1547 {
1548 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), p.y + (5.0/32.0), offset)";
1549 }
1550 };
1551
1552 class Swizzle : public PlainGatherFloat2D
1553 {
Gather()1554 virtual std::string Gather()
1555 {
1556 return "textureGather(my_sampler, vec2(p.x, p.y), 1).yzww";
1557 }
1558
Expected()1559 virtual std::string Expected()
1560 {
1561 return "vec4(5./16., 9./16., 13./16., 13./16.)";
1562 }
1563 };
1564
1565 class BaseLevel : public PlainGatherFloat2D
1566 {
Init()1567 virtual void Init()
1568 {
1569 CreateTexture2D(true);
1570 }
1571 };
1572
1573 class IncompleteTexture : public PlainGatherFloat2D
1574 {
Init()1575 virtual void Init()
1576 {
1577 CreateTexture2D();
1578 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1579 }
1580
Expected()1581 virtual std::string Expected()
1582 {
1583 return "vec4(0)";
1584 }
1585
Gather()1586 virtual std::string Gather()
1587 {
1588 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(0), 1)";
1589 }
1590 };
1591
1592 class IncompleteTextureLastComp : public PlainGatherFloat2D
1593 {
Init()1594 virtual void Init()
1595 {
1596 CreateTexture2D();
1597 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1598 }
1599
Expected()1600 virtual std::string Expected()
1601 {
1602 return "vec4(1.0)";
1603 }
1604
Gather()1605 virtual std::string Gather()
1606 {
1607 return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1608 }
1609 };
1610
1611 class TriangleDraw : public GatherBase
1612 {
1613 GLuint program, rbo, fbo, vao, vbo;
1614
VertexShader()1615 virtual std::string VertexShader()
1616 {
1617 return "#version 310 es \n"
1618 "flat out mediump vec2 texcoords; \n"
1619 "in mediump vec4 Vertex; \n"
1620 "void main() { \n"
1621 " gl_Position = Vertex; \n"
1622 " texcoords = (Vertex.xy + vec2(1.0)) / 2.0; \n"
1623 "}\n";
1624 }
1625
FragmentShader()1626 virtual std::string FragmentShader()
1627 {
1628 return "#version 310 es \n"
1629 "precision highp float; \n"
1630 "flat in mediump vec2 texcoords; \n"
1631 "out highp uvec4 FragColor; \n"
1632 "uniform mediump sampler2D tex; \n"
1633 "void main() { \n"
1634 " vec4 data = textureGather(tex, texcoords, 2); \n"
1635 " FragColor = floatBitsToUint(data); \n"
1636 "}\n";
1637 }
1638
Run()1639 virtual long Run()
1640 {
1641 glGenFramebuffers(1, &fbo);
1642 glGenRenderbuffers(1, &rbo);
1643 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1644 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 100, 100);
1645 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1646 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1647 GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
1648 glDrawBuffers(1, &drawBuffer);
1649 GLfloat colorf[4] = {0, 0, 0, 0};
1650 glClearBufferfv(GL_COLOR, 0, colorf);
1651 glViewport(0, 0, 100, 100);
1652
1653 program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str());
1654 glBindAttribLocation(program, 0, "Vertex");
1655 glLinkProgram(program);
1656 if (!CheckProgram(program))
1657 return ERROR;
1658 glUseProgram(program);
1659
1660 glGenTextures(1, &tex);
1661 glBindTexture(GL_TEXTURE_2D, tex);
1662 std::vector<Vec4> data(100 * 100, Vec4(0.25, 0.5, 0.75, 1));
1663 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 100, 100, 0, GL_RGBA, GL_FLOAT, &data[0]);
1664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1665 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1666 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1667 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1668 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1669
1670 glGenVertexArrays(1, &vao);
1671 glBindVertexArray(vao);
1672 glGenBuffers(1, &vbo);
1673 glBindBuffer(GL_ARRAY_BUFFER, vbo);
1674 GLfloat buffData[16] = {-1, 1, 0, 1, -1, -1, 0, 1, 1, 1, 0, 1, 1, -1, 0, 1};
1675 glBufferData(GL_ARRAY_BUFFER, sizeof(buffData), buffData, GL_STATIC_DRAW);
1676 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
1677 glEnableVertexAttribArray(0);
1678 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1679 glDisableVertexAttribArray(0);
1680 glDeleteVertexArrays(1, &vao);
1681 glBindBuffer(GL_ARRAY_BUFFER, 0);
1682
1683 glReadBuffer(GL_COLOR_ATTACHMENT0);
1684 std::vector<unsigned int> read(100 * 100 * 4, 0);
1685 glReadPixels(0, 0, 100, 100, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &read[0]);
1686 for (unsigned int i = 0; i < read.size() / 4; i += 4)
1687 {
1688 const GLfloat *rdata = (const GLfloat *)&read[i];
1689 Vec4 rvec(rdata[0], rdata[1], rdata[2], rdata[3]);
1690 if (rvec != Vec4(0.75))
1691 {
1692 m_context.getTestContext().getLog()
1693 << tcu::TestLog::Message << "Got: " << rvec.x() << " " << rvec.y() << " " << rvec.z() << " "
1694 << rvec.w() << ", expected vec4(0.75)" << tcu::TestLog::EndMessage;
1695 return ERROR;
1696 }
1697 }
1698
1699 return NO_ERROR;
1700 }
1701
Cleanup()1702 virtual long Cleanup()
1703 {
1704 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1705 glDisableVertexAttribArray(0);
1706 glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
1707 glDeleteTextures(1, &tex);
1708 glDeleteFramebuffers(1, &fbo);
1709 glDeleteRenderbuffers(1, &rbo);
1710 glDeleteVertexArrays(1, &vao);
1711 glDeleteBuffers(1, &vbo);
1712 glDeleteProgram(program);
1713 return NO_ERROR;
1714 }
1715 };
1716
1717 class PlainGatherFloat2DSrgb : public GatherBase
1718 {
1719 public:
Expected()1720 virtual std::string Expected()
1721 {
1722 return "vec4(0, 20.0/255.0, 90.0/255.0, 222.0/255.0)";
1723 }
1724
InternalFormat()1725 virtual GLenum InternalFormat()
1726 {
1727 return GL_SRGB8_ALPHA8;
1728 }
1729
Init()1730 virtual void Init()
1731 {
1732 CreateTextureSRGB();
1733 }
1734 };
1735
1736 class PlainGatherFloat2DSrgbAlpha : public GatherBase
1737 {
1738 public:
Gather()1739 virtual std::string Gather()
1740 {
1741 return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1742 }
1743
Expected()1744 virtual std::string Expected()
1745 {
1746 return "vec4(3.0/255.0, 7.0/255.0, 11.0/255.0, 15.0/255.0)";
1747 }
1748
InternalFormat()1749 virtual GLenum InternalFormat()
1750 {
1751 return GL_SRGB8_ALPHA8;
1752 }
1753
Init()1754 virtual void Init()
1755 {
1756 CreateTextureSRGB();
1757 }
1758 };
1759
1760 class PlainGatherFloat2DRgb : public GatherBase
1761 {
1762 public:
Init()1763 virtual void Init()
1764 {
1765 CreateTexture2DRgb();
1766 }
1767 };
1768
1769 class PlainGatherFloat2DRg : public GatherBase
1770 {
1771 public:
Init()1772 virtual void Init()
1773 {
1774 CreateTexture2DRg();
1775 }
1776 };
1777
1778 class PlainGatherFloat2DR : public GatherBase
1779 {
1780 public:
Init()1781 virtual void Init()
1782 {
1783 CreateTexture2DR();
1784 }
1785 };
1786
1787 class OffsetGatherFloat2DRgb : public OffsetGatherFloat2D
1788 {
1789 public:
Init()1790 virtual void Init()
1791 {
1792 CreateTexture2DRgb();
1793 }
1794 };
1795
1796 class OffsetGatherFloat2DRg : public OffsetGatherFloat2D
1797 {
1798 public:
Init()1799 virtual void Init()
1800 {
1801 CreateTexture2DRg();
1802 }
1803 };
1804
1805 class OffsetGatherFloat2DR : public OffsetGatherFloat2D
1806 {
1807 public:
Init()1808 virtual void Init()
1809 {
1810 CreateTexture2DR();
1811 }
1812 };
1813
1814 } // anonymous namespace
1815
TextureGatherTests(glcts::Context & context)1816 TextureGatherTests::TextureGatherTests(glcts::Context &context) : TestCaseGroup(context, "texture_gather", "")
1817 {
1818 }
1819
~TextureGatherTests(void)1820 TextureGatherTests::~TextureGatherTests(void)
1821 {
1822 }
1823
init()1824 void TextureGatherTests::init()
1825 {
1826 using namespace glcts;
1827 addChild(new TestSubcase(m_context, "api-enums", TestSubcase::Create<GatherEnumsTest>));
1828 addChild(new TestSubcase(m_context, "gather-glsl-compile", TestSubcase::Create<GatherGLSLCompile>));
1829 addChild(new TestSubcase(m_context, "plain-gather-float-2d", TestSubcase::Create<PlainGatherFloat2D>));
1830 addChild(new TestSubcase(m_context, "plain-gather-int-2d", TestSubcase::Create<PlainGatherInt2D>));
1831 addChild(new TestSubcase(m_context, "plain-gather-uint-2d", TestSubcase::Create<PlainGatherUint2D>));
1832 addChild(new TestSubcase(m_context, "plain-gather-depth-2d", TestSubcase::Create<PlainGatherDepth2D>));
1833 addChild(new TestSubcase(m_context, "plain-gather-float-2darray", TestSubcase::Create<PlainGatherFloat2DArray>));
1834 addChild(new TestSubcase(m_context, "plain-gather-int-2darray", TestSubcase::Create<PlainGatherInt2DArray>));
1835 addChild(new TestSubcase(m_context, "plain-gather-uint-2darray", TestSubcase::Create<PlainGatherUint2DArray>));
1836 addChild(new TestSubcase(m_context, "plain-gather-depth-2darray", TestSubcase::Create<PlainGatherDepth2DArray>));
1837 addChild(new TestSubcase(m_context, "plain-gather-float-cube-rgba", TestSubcase::Create<PlainGatherFloatCube>));
1838 addChild(new TestSubcase(m_context, "plain-gather-int-cube-rgba", TestSubcase::Create<PlainGatherIntCube>));
1839 addChild(new TestSubcase(m_context, "plain-gather-uint-cube", TestSubcase::Create<PlainGatherUintCube>));
1840 addChild(new TestSubcase(m_context, "plain-gather-depth-cube", TestSubcase::Create<PlainGatherDepthCube>));
1841 addChild(new TestSubcase(m_context, "offset-gather-float-2d", TestSubcase::Create<OffsetGatherFloat2D>));
1842 addChild(new TestSubcase(m_context, "offset-gather-int-2d", TestSubcase::Create<OffsetGatherInt2D>));
1843 addChild(new TestSubcase(m_context, "offset-gather-uint-2d", TestSubcase::Create<OffsetGatherUint2D>));
1844 addChild(new TestSubcase(m_context, "offset-gather-depth-2d", TestSubcase::Create<OffsetGatherDepth2D>));
1845 addChild(new TestSubcase(m_context, "offset-gather-float-2darray", TestSubcase::Create<OffsetGatherFloat2DArray>));
1846 addChild(new TestSubcase(m_context, "offset-gather-int-2darray", TestSubcase::Create<OffsetGatherInt2DArray>));
1847 addChild(new TestSubcase(m_context, "offset-gather-uint-2darray", TestSubcase::Create<OffsetGatherUint2DArray>));
1848 addChild(new TestSubcase(m_context, "offset-gather-depth-2darray", TestSubcase::Create<OffsetGatherDepth2DArray>));
1849 addChild(new TestSubcase(m_context, "swizzle", TestSubcase::Create<Swizzle>));
1850 addChild(new TestSubcase(m_context, "base-level", TestSubcase::Create<BaseLevel>));
1851 addChild(new TestSubcase(m_context, "incomplete-texture", TestSubcase::Create<IncompleteTexture>));
1852 addChild(
1853 new TestSubcase(m_context, "incomplete-texture-last-comp", TestSubcase::Create<IncompleteTextureLastComp>));
1854 addChild(new TestSubcase(m_context, "triangle-draw", TestSubcase::Create<TriangleDraw>));
1855 addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb", TestSubcase::Create<PlainGatherFloat2DSrgb>));
1856 addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb-alpha",
1857 TestSubcase::Create<PlainGatherFloat2DSrgbAlpha>));
1858 addChild(new TestSubcase(m_context, "plain-gather-float-2d-rgb", TestSubcase::Create<PlainGatherFloat2DRgb>));
1859 addChild(new TestSubcase(m_context, "plain-gather-float-2d-rg", TestSubcase::Create<PlainGatherFloat2DRg>));
1860 addChild(new TestSubcase(m_context, "plain-gather-float-2d-r", TestSubcase::Create<PlainGatherFloat2DR>));
1861 addChild(new TestSubcase(m_context, "offset-gather-float-2d-rgb", TestSubcase::Create<OffsetGatherFloat2DRgb>));
1862 addChild(new TestSubcase(m_context, "offset-gather-float-2d-rg", TestSubcase::Create<OffsetGatherFloat2DRg>));
1863 addChild(new TestSubcase(m_context, "offset-gather-float-2d-r", TestSubcase::Create<OffsetGatherFloat2DR>));
1864 }
1865 } // namespace glcts
1866