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::Vec4;
40 using tcu::Vec3;
41 using tcu::Vec2;
42 using tcu::IVec4;
43 using tcu::UVec4;
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() + "void main() { \n"
822 " gl_Position = vec4(0, 0, 0, 1); \n"
823 "#ifdef GL_ES \n"
824 " gl_PointSize = 1.0f; \n"
825 "#endif \n"
826 " v_out_0 = test_function(v_in_0); \n"
827 "}";
828 }
829
FragmentShader()830 virtual std::string FragmentShader()
831 {
832 return "#version 310 es \n"
833 ""
834 "precision highp float; \n"
835 "flat in mediump vec4 v_out_0; \n"
836 "out mediump vec4 f_out_0; \n" +
837 TestFunction() + "void main() { \n"
838 " f_out_0 = test_function(v_out_0); \n"
839 "}";
840 }
841
ComputeShader()842 virtual std::string ComputeShader()
843 {
844 return "#version 310 es \n"
845 "layout(local_size_x = 1, local_size_y = 1) in; \n"
846 "layout(std430) buffer Output { \n"
847 " mediump vec4 data; \n"
848 "} g_out; \n"
849 "uniform mediump vec4 cs_in; \n" +
850 TestFunction() + "void main() { \n"
851 " g_out.data = test_function(cs_in); \n"
852 "} \n";
853 }
854
Init()855 virtual void Init()
856 {
857 CreateTexture2D();
858 }
859
Verify()860 virtual long Verify()
861 {
862 std::vector<GLubyte> data(4);
863 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
864 if (data[0] != 0 || data[1] != 255 || data[2] != 0 || data[3] != 255)
865 {
866 m_context.getTestContext().getLog()
867 << tcu::TestLog::Message << "Expected Vec4(0, 255, 0, 255), got: " << data[0] << ", " << data[1] << ", "
868 << data[2] << ", " << data[3] << tcu::TestLog::EndMessage;
869 return ERROR;
870 }
871 return NO_ERROR;
872 }
873
Expected()874 virtual std::string Expected()
875 {
876 return "vec4(0./16., 4./16., 8./16., 12./16.)";
877 }
878
InternalFormat()879 virtual GLenum InternalFormat()
880 {
881 return GL_RGBA32F;
882 }
883
Format()884 virtual GLenum Format()
885 {
886 return GL_RGBA;
887 }
888
BufferData()889 virtual Vec4 BufferData()
890 {
891 return Vec4(23. / 32, 26. / 32, 5, 3);
892 }
893
Supported()894 virtual bool Supported()
895 {
896 return true;
897 }
898
Run()899 virtual long Run()
900 {
901 if (!Supported())
902 return NO_ERROR;
903 Init();
904
905 glGenFramebuffers(1, &fbo);
906 glGenRenderbuffers(1, &rbo);
907 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
908 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
909 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
910 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
911 GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
912 glDrawBuffers(1, &drawBuffer);
913 GLfloat colorf[4] = { 0, 0, 0, 0 };
914 glClearBufferfv(GL_COLOR, 0, colorf);
915 glViewport(0, 0, 1, 1);
916
917 glGenVertexArrays(1, &vao);
918 glBindVertexArray(vao);
919 glGenBuffers(1, &vbo);
920 glBindBuffer(GL_ARRAY_BUFFER, vbo);
921 glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
922 glEnableVertexAttribArray(0);
923 Vec4 buffData = BufferData();
924 glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
925
926 for (int i = 0; i < 2; ++i)
927 {
928 if (i == 0)
929 program = CreateProgram(VertexShader().c_str(), FallthroughFragmentShader().c_str());
930 else
931 program = CreateProgram(FallthroughVertexShader().c_str(), FragmentShader().c_str());
932 glBindAttribLocation(program, 0, "v_in_0");
933 glLinkProgram(program);
934 if (!CheckProgram(program))
935 return ERROR;
936 glUseProgram(program);
937
938 glDrawArrays(GL_POINTS, 0, 1);
939 glReadBuffer(GL_COLOR_ATTACHMENT0);
940
941 glDeleteProgram(program);
942
943 if (Verify() == ERROR)
944 return ERROR;
945 }
946
947 return TestCompute();
948 }
949
TestCompute()950 virtual long TestCompute()
951 {
952 GLuint m_buffer;
953
954 program = CreateComputeProgram(ComputeShader());
955 glLinkProgram(program);
956 if (!CheckProgram(program))
957 return ERROR;
958 glUseProgram(program);
959
960 glUniform4f(glGetUniformLocation(program, "cs_in"), BufferData().x(), BufferData().y(), BufferData().z(),
961 BufferData().w());
962
963 glGenBuffers(1, &m_buffer);
964 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
965 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Vec4), NULL, GL_DYNAMIC_DRAW);
966 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
967
968 glDispatchCompute(1, 1, 1);
969
970 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
971 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
972 long error = VerifyCompute();
973 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
974 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
975 glDeleteBuffers(1, &m_buffer);
976
977 return error;
978 }
979
VerifyCompute()980 virtual long VerifyCompute()
981 {
982 Vec4* data;
983 data = static_cast<Vec4*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Vec4), GL_MAP_READ_BIT));
984 if (data[0] != Vec4(0, 1, 0, 1))
985 {
986 m_context.getTestContext().getLog()
987 << tcu::TestLog::Message << "Expected Vec4(0, 1, 0, 1), got: " << data[0].x() << ", " << data[0].y()
988 << ", " << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
989 return ERROR;
990 }
991 return NO_ERROR;
992 }
993
Cleanup()994 virtual long Cleanup()
995 {
996 glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
997 glDisableVertexAttribArray(0);
998 glDeleteTextures(1, &tex);
999 glDeleteVertexArrays(1, &vao);
1000 glDeleteBuffers(1, &vbo);
1001 glDeleteRenderbuffers(1, &rbo);
1002 glDeleteFramebuffers(1, &fbo);
1003 glDeleteProgram(program);
1004 return NO_ERROR;
1005 }
1006 };
1007
1008 class PlainGatherFloat2D : public GatherBase
1009 {
1010 };
1011
1012 class PlainGatherInt2D : public GatherBase
1013 {
1014 public:
InternalFormat()1015 virtual GLenum InternalFormat()
1016 {
1017 return GL_RGBA32I;
1018 }
1019
Init()1020 virtual void Init()
1021 {
1022 CreateTexture2DInt();
1023 }
1024
Expected()1025 virtual std::string Expected()
1026 {
1027 return "ivec4(0, 4, 8, 12)";
1028 }
1029
Sampler()1030 virtual std::string Sampler()
1031 {
1032 return "uniform mediump isampler2D my_sampler; \n";
1033 }
1034
Type()1035 virtual std::string Type()
1036 {
1037 return "ivec4";
1038 }
1039 };
1040
1041 class PlainGatherUint2D : public GatherBase
1042 {
1043 public:
InternalFormat()1044 virtual GLenum InternalFormat()
1045 {
1046 return GL_RGBA32UI;
1047 }
1048
Init()1049 virtual void Init()
1050 {
1051 CreateTexture2DInt();
1052 }
1053
Expected()1054 virtual std::string Expected()
1055 {
1056 return "uvec4(2u, 6u, 10u, 14u)";
1057 }
1058
Sampler()1059 virtual std::string Sampler()
1060 {
1061 return "uniform mediump usampler2D my_sampler; \n";
1062 }
1063
BufferData()1064 virtual Vec4 BufferData()
1065 {
1066 return Vec4(22.9f / 32, 25.9f / 32, 2, 2);
1067 }
1068
Type()1069 virtual std::string Type()
1070 {
1071 return "uvec4";
1072 }
1073
Gather()1074 virtual std::string Gather()
1075 {
1076 return "textureGather(my_sampler, vec2(p.x, p.y), 2)";
1077 }
1078 };
1079
1080 class PlainGatherDepth2D : public GatherBase
1081 {
1082 public:
InternalFormat()1083 virtual GLenum InternalFormat()
1084 {
1085 return GL_DEPTH_COMPONENT32F;
1086 }
1087
Format()1088 virtual GLenum Format()
1089 {
1090 return GL_DEPTH_COMPONENT;
1091 }
1092
Init()1093 virtual void Init()
1094 {
1095 CreateTexture2D();
1096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1097 }
1098
Expected()1099 virtual std::string Expected()
1100 {
1101 return "vec4(1.0, 1.0, 0.0, 0.0)";
1102 }
1103
BufferData()1104 virtual Vec4 BufferData()
1105 {
1106 return Vec4(23. / 32, 26. / 32, 13.5 / 16, 3);
1107 }
1108
Sampler()1109 virtual std::string Sampler()
1110 {
1111 return "uniform mediump sampler2DShadow my_sampler; \n";
1112 }
1113
Gather()1114 virtual std::string Gather()
1115 {
1116 return "textureGather(my_sampler, vec2(p.x, p.y), p.z)";
1117 }
1118 };
1119
1120 class PlainGatherFloat2DArray : public GatherBase
1121 {
1122 public:
Init()1123 virtual void Init()
1124 {
1125 CreateTexture2DArray(9, 5);
1126 }
1127
Sampler()1128 virtual std::string Sampler()
1129 {
1130 return "uniform mediump sampler2DArray my_sampler; \n";
1131 }
1132
Gather()1133 virtual std::string Gather()
1134 {
1135 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1136 }
1137 };
1138
1139 class PlainGatherInt2DArray : public GatherBase
1140 {
1141 public:
Init()1142 virtual void Init()
1143 {
1144 CreateTexture2DArrayInt(20, 11);
1145 }
1146
InternalFormat()1147 virtual GLenum InternalFormat()
1148 {
1149 return GL_RGBA32I;
1150 }
1151
Expected()1152 virtual std::string Expected()
1153 {
1154 return "ivec4(3, 7, 11, 15)";
1155 }
1156
Type()1157 virtual std::string Type()
1158 {
1159 return "ivec4";
1160 }
1161
BufferData()1162 virtual Vec4 BufferData()
1163 {
1164 return Vec4(23. / 32, 26. / 32, 11, 3);
1165 }
1166
Sampler()1167 virtual std::string Sampler()
1168 {
1169 return "uniform mediump isampler2DArray my_sampler; \n";
1170 }
1171
Gather()1172 virtual std::string Gather()
1173 {
1174 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 3)";
1175 }
1176 };
1177
1178 class PlainGatherUint2DArray : public GatherBase
1179 {
1180 public:
Init()1181 virtual void Init()
1182 {
1183 CreateTexture2DArrayInt(3, 1);
1184 }
1185
InternalFormat()1186 virtual GLenum InternalFormat()
1187 {
1188 return GL_RGBA32UI;
1189 }
1190
Expected()1191 virtual std::string Expected()
1192 {
1193 return "uvec4(0u, 4u, 8u, 12u)";
1194 }
1195
Type()1196 virtual std::string Type()
1197 {
1198 return "uvec4";
1199 }
1200
BufferData()1201 virtual Vec4 BufferData()
1202 {
1203 return Vec4(23. / 32, 26. / 32, 1, 3);
1204 }
1205
Sampler()1206 virtual std::string Sampler()
1207 {
1208 return "uniform mediump usampler2DArray my_sampler; \n";
1209 }
1210
Gather()1211 virtual std::string Gather()
1212 {
1213 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1214 }
1215 };
1216
1217 class PlainGatherDepth2DArray : public GatherBase
1218 {
1219 public:
InternalFormat()1220 virtual GLenum InternalFormat()
1221 {
1222 return GL_DEPTH_COMPONENT32F;
1223 }
1224
Format()1225 virtual GLenum Format()
1226 {
1227 return GL_DEPTH_COMPONENT;
1228 }
1229
Init()1230 virtual void Init()
1231 {
1232 CreateTexture2DArray(9, 5);
1233 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1234 }
1235
Expected()1236 virtual std::string Expected()
1237 {
1238 return "vec4(1.0, 1.0, 0.0, 0.0)";
1239 }
1240
BufferData()1241 virtual Vec4 BufferData()
1242 {
1243 return Vec4(23. / 32, 26. / 32, 5, 13.5 / 16);
1244 }
1245
Sampler()1246 virtual std::string Sampler()
1247 {
1248 return "uniform mediump sampler2DArrayShadow my_sampler; \n";
1249 }
1250
Gather()1251 virtual std::string Gather()
1252 {
1253 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1254 }
1255 };
1256
1257 class PlainGatherFloatCube : public GatherBase
1258 {
1259 public:
Init()1260 virtual void Init()
1261 {
1262 CreateTextureCube();
1263 }
1264
BufferData()1265 virtual Vec4 BufferData()
1266 {
1267 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1268 }
1269
Sampler()1270 virtual std::string Sampler()
1271 {
1272 return "uniform mediump samplerCube my_sampler; \n";
1273 }
1274
Gather()1275 virtual std::string Gather()
1276 {
1277 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1278 }
1279 };
1280
1281 class PlainGatherIntCube : public GatherBase
1282 {
1283 public:
Init()1284 virtual void Init()
1285 {
1286 CreateTextureCubeInt();
1287 }
1288
BufferData()1289 virtual Vec4 BufferData()
1290 {
1291 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1292 }
1293
Sampler()1294 virtual std::string Sampler()
1295 {
1296 return "uniform mediump isamplerCube my_sampler; \n";
1297 }
1298
Gather()1299 virtual std::string Gather()
1300 {
1301 return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1302 }
1303
InternalFormat()1304 virtual GLenum InternalFormat()
1305 {
1306 return GL_RGBA32I;
1307 }
1308
Expected()1309 virtual std::string Expected()
1310 {
1311 return "ivec4(0, 4, 8, 12)";
1312 }
1313
Type()1314 virtual std::string Type()
1315 {
1316 return "ivec4";
1317 }
1318 };
1319
1320 class PlainGatherUintCube : public GatherBase
1321 {
1322 public:
Init()1323 virtual void Init()
1324 {
1325 CreateTextureCubeInt();
1326 }
1327
BufferData()1328 virtual Vec4 BufferData()
1329 {
1330 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1331 }
1332
Sampler()1333 virtual std::string Sampler()
1334 {
1335 return "uniform mediump usamplerCube my_sampler; \n";
1336 }
1337
Gather()1338 virtual std::string Gather()
1339 {
1340 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 0)";
1341 }
1342
InternalFormat()1343 virtual GLenum InternalFormat()
1344 {
1345 return GL_RGBA32UI;
1346 }
1347
Expected()1348 virtual std::string Expected()
1349 {
1350 return "uvec4(0u, 4u, 8u, 12u)";
1351 }
1352
Type()1353 virtual std::string Type()
1354 {
1355 return "uvec4";
1356 }
1357 };
1358
1359 class PlainGatherDepthCube : public GatherBase
1360 {
1361 public:
Init()1362 virtual void Init()
1363 {
1364 CreateTextureCube();
1365 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1366 }
1367
InternalFormat()1368 virtual GLenum InternalFormat()
1369 {
1370 return GL_DEPTH_COMPONENT32F;
1371 }
1372
Format()1373 virtual GLenum Format()
1374 {
1375 return GL_DEPTH_COMPONENT;
1376 }
1377
BufferData()1378 virtual Vec4 BufferData()
1379 {
1380 return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1381 }
1382
Sampler()1383 virtual std::string Sampler()
1384 {
1385 return "uniform mediump samplerCubeShadow my_sampler; \n";
1386 }
1387
Gather()1388 virtual std::string Gather()
1389 {
1390 return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1391 }
1392
Expected()1393 virtual std::string Expected()
1394 {
1395 return "vec4(0.0, 0.0, 1.0, 1.0)";
1396 }
1397 };
1398
1399 class OffsetGatherFloat2D : public GatherBase
1400 {
BufferData()1401 virtual Vec4 BufferData()
1402 {
1403 return Vec4(19. / 32, 22. / 32, 4, 4);
1404 }
1405
Offset()1406 virtual std::string Offset()
1407 {
1408 return "const mediump ivec2 offset = ivec2(4); \n";
1409 }
1410
Gather()1411 virtual std::string Gather()
1412 {
1413 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1414 }
1415 };
1416
1417 class OffsetGatherInt2D : public PlainGatherInt2D
1418 {
BufferData()1419 virtual Vec4 BufferData()
1420 {
1421 return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 4);
1422 }
1423
Offset()1424 virtual std::string Offset()
1425 {
1426 return "const mediump ivec2 offset = ivec2(4); \n";
1427 }
1428
Gather()1429 virtual std::string Gather()
1430 {
1431 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1432 }
1433 };
1434
1435 class OffsetGatherUint2D : public PlainGatherUint2D
1436 {
BufferData()1437 virtual Vec4 BufferData()
1438 {
1439 return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 2);
1440 }
1441
Offset()1442 virtual std::string Offset()
1443 {
1444 return "const mediump ivec2 offset = ivec2(4); \n";
1445 }
1446
Gather()1447 virtual std::string Gather()
1448 {
1449 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset, 2)";
1450 }
1451 };
1452
1453 class OffsetGatherDepth2D : public PlainGatherDepth2D
1454 {
BufferData()1455 virtual Vec4 BufferData()
1456 {
1457 return Vec4(19. / 32, 22. / 32, 4, 13.5 / 16);
1458 }
1459
Offset()1460 virtual std::string Offset()
1461 {
1462 return "const mediump ivec2 offset = ivec2(4); \n";
1463 }
1464
Gather()1465 virtual std::string Gather()
1466 {
1467 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), p.w, offset)";
1468 }
1469 };
1470
1471 class OffsetGatherFloat2DArray : public PlainGatherFloat2DArray
1472 {
BufferData()1473 virtual Vec4 BufferData()
1474 {
1475 return Vec4(19. / 32, 22. / 32, 5, 4);
1476 }
1477
Offset()1478 virtual std::string Offset()
1479 {
1480 return "const mediump ivec2 offset = ivec2(4); \n";
1481 }
1482
Gather()1483 virtual std::string Gather()
1484 {
1485 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset)";
1486 }
1487 };
1488
1489 class OffsetGatherInt2DArray : public PlainGatherInt2DArray
1490 {
BufferData()1491 virtual Vec4 BufferData()
1492 {
1493 return Vec4(19. / 32, 22. / 32, 11, 4);
1494 }
1495
Offset()1496 virtual std::string Offset()
1497 {
1498 return "const mediump ivec2 offset = ivec2(4); \n";
1499 }
1500
Gather()1501 virtual std::string Gather()
1502 {
1503 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 3)";
1504 }
1505 };
1506
1507 class OffsetGatherUint2DArray : public PlainGatherUint2DArray
1508 {
BufferData()1509 virtual Vec4 BufferData()
1510 {
1511 return Vec4(19. / 32, 22. / 32, 1, 4);
1512 }
1513
Offset()1514 virtual std::string Offset()
1515 {
1516 return "const mediump ivec2 offset = ivec2(4); \n";
1517 }
1518
Gather()1519 virtual std::string Gather()
1520 {
1521 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 0)";
1522 }
1523 };
1524
1525 class OffsetGatherDepth2DArray : public PlainGatherDepth2DArray
1526 {
Init()1527 virtual void Init()
1528 {
1529 CreateTexture2DArray(7, 3);
1530 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1531 }
1532
BufferData()1533 virtual Vec4 BufferData()
1534 {
1535 return Vec4(19. / 32, 22. / 32, 3, 4);
1536 }
1537
Offset()1538 virtual std::string Offset()
1539 {
1540 return "const mediump ivec2 offset = ivec2(4); \n";
1541 }
1542
Gather()1543 virtual std::string Gather()
1544 {
1545 return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), p.y + (5.0/32.0), offset)";
1546 }
1547 };
1548
1549 class Swizzle : public PlainGatherFloat2D
1550 {
Gather()1551 virtual std::string Gather()
1552 {
1553 return "textureGather(my_sampler, vec2(p.x, p.y), 1).yzww";
1554 }
1555
Expected()1556 virtual std::string Expected()
1557 {
1558 return "vec4(5./16., 9./16., 13./16., 13./16.)";
1559 }
1560 };
1561
1562 class BaseLevel : public PlainGatherFloat2D
1563 {
Init()1564 virtual void Init()
1565 {
1566 CreateTexture2D(true);
1567 }
1568 };
1569
1570 class IncompleteTexture : public PlainGatherFloat2D
1571 {
Init()1572 virtual void Init()
1573 {
1574 CreateTexture2D();
1575 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1576 }
1577
Expected()1578 virtual std::string Expected()
1579 {
1580 return "vec4(0)";
1581 }
1582
Gather()1583 virtual std::string Gather()
1584 {
1585 return "textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(0), 1)";
1586 }
1587 };
1588
1589 class IncompleteTextureLastComp : public PlainGatherFloat2D
1590 {
Init()1591 virtual void Init()
1592 {
1593 CreateTexture2D();
1594 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1595 }
1596
Expected()1597 virtual std::string Expected()
1598 {
1599 return "vec4(1.0)";
1600 }
1601
Gather()1602 virtual std::string Gather()
1603 {
1604 return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1605 }
1606 };
1607
1608 class TriangleDraw : public GatherBase
1609 {
1610 GLuint program, rbo, fbo, vao, vbo;
1611
VertexShader()1612 virtual std::string VertexShader()
1613 {
1614 return "#version 310 es \n"
1615 "flat out mediump vec2 texcoords; \n"
1616 "in mediump vec4 Vertex; \n"
1617 "void main() { \n"
1618 " gl_Position = Vertex; \n"
1619 " texcoords = (Vertex.xy + vec2(1.0)) / 2.0; \n"
1620 "}\n";
1621 }
1622
FragmentShader()1623 virtual std::string FragmentShader()
1624 {
1625 return "#version 310 es \n"
1626 "precision highp float; \n"
1627 "flat in mediump vec2 texcoords; \n"
1628 "out highp uvec4 FragColor; \n"
1629 "uniform mediump sampler2D tex; \n"
1630 "void main() { \n"
1631 " vec4 data = textureGather(tex, texcoords, 2); \n"
1632 " FragColor = floatBitsToUint(data); \n"
1633 "}\n";
1634 }
1635
Run()1636 virtual long Run()
1637 {
1638 glGenFramebuffers(1, &fbo);
1639 glGenRenderbuffers(1, &rbo);
1640 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1641 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 100, 100);
1642 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1643 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1644 GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
1645 glDrawBuffers(1, &drawBuffer);
1646 GLfloat colorf[4] = { 0, 0, 0, 0 };
1647 glClearBufferfv(GL_COLOR, 0, colorf);
1648 glViewport(0, 0, 100, 100);
1649
1650 program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str());
1651 glBindAttribLocation(program, 0, "Vertex");
1652 glLinkProgram(program);
1653 if (!CheckProgram(program))
1654 return ERROR;
1655 glUseProgram(program);
1656
1657 glGenTextures(1, &tex);
1658 glBindTexture(GL_TEXTURE_2D, tex);
1659 std::vector<Vec4> data(100 * 100, Vec4(0.25, 0.5, 0.75, 1));
1660 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 100, 100, 0, GL_RGBA, GL_FLOAT, &data[0]);
1661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1662 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1663 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1664 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1665 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1666
1667 glGenVertexArrays(1, &vao);
1668 glBindVertexArray(vao);
1669 glGenBuffers(1, &vbo);
1670 glBindBuffer(GL_ARRAY_BUFFER, vbo);
1671 GLfloat buffData[16] = { -1, 1, 0, 1, -1, -1, 0, 1, 1, 1, 0, 1, 1, -1, 0, 1 };
1672 glBufferData(GL_ARRAY_BUFFER, sizeof(buffData), buffData, GL_STATIC_DRAW);
1673 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
1674 glEnableVertexAttribArray(0);
1675 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1676 glDisableVertexAttribArray(0);
1677 glDeleteVertexArrays(1, &vao);
1678 glBindBuffer(GL_ARRAY_BUFFER, 0);
1679
1680 glReadBuffer(GL_COLOR_ATTACHMENT0);
1681 std::vector<unsigned int> read(100 * 100 * 4, 0);
1682 glReadPixels(0, 0, 100, 100, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &read[0]);
1683 for (unsigned int i = 0; i < read.size() / 4; i += 4)
1684 {
1685 const GLfloat* rdata = (const GLfloat*)&read[i];
1686 Vec4 rvec(rdata[0], rdata[1], rdata[2], rdata[3]);
1687 if (rvec != Vec4(0.75))
1688 {
1689 m_context.getTestContext().getLog()
1690 << tcu::TestLog::Message << "Got: " << rvec.x() << " " << rvec.y() << " " << rvec.z() << " "
1691 << rvec.w() << ", expected vec4(0.75)" << tcu::TestLog::EndMessage;
1692 return ERROR;
1693 }
1694 }
1695
1696 return NO_ERROR;
1697 }
1698
Cleanup()1699 virtual long Cleanup()
1700 {
1701 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1702 glDisableVertexAttribArray(0);
1703 glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
1704 glDeleteTextures(1, &tex);
1705 glDeleteFramebuffers(1, &fbo);
1706 glDeleteRenderbuffers(1, &rbo);
1707 glDeleteVertexArrays(1, &vao);
1708 glDeleteBuffers(1, &vbo);
1709 glDeleteProgram(program);
1710 return NO_ERROR;
1711 }
1712 };
1713
1714 class PlainGatherFloat2DSrgb : public GatherBase
1715 {
1716 public:
Expected()1717 virtual std::string Expected()
1718 {
1719 return "vec4(0, 20.0/255.0, 90.0/255.0, 222.0/255.0)";
1720 }
1721
InternalFormat()1722 virtual GLenum InternalFormat()
1723 {
1724 return GL_SRGB8_ALPHA8;
1725 }
1726
Init()1727 virtual void Init()
1728 {
1729 CreateTextureSRGB();
1730 }
1731 };
1732
1733 class PlainGatherFloat2DSrgbAlpha : public GatherBase
1734 {
1735 public:
Gather()1736 virtual std::string Gather()
1737 {
1738 return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1739 }
1740
Expected()1741 virtual std::string Expected()
1742 {
1743 return "vec4(3.0/255.0, 7.0/255.0, 11.0/255.0, 15.0/255.0)";
1744 }
1745
InternalFormat()1746 virtual GLenum InternalFormat()
1747 {
1748 return GL_SRGB8_ALPHA8;
1749 }
1750
Init()1751 virtual void Init()
1752 {
1753 CreateTextureSRGB();
1754 }
1755 };
1756
1757 class PlainGatherFloat2DRgb : public GatherBase
1758 {
1759 public:
Init()1760 virtual void Init()
1761 {
1762 CreateTexture2DRgb();
1763 }
1764 };
1765
1766 class PlainGatherFloat2DRg : public GatherBase
1767 {
1768 public:
Init()1769 virtual void Init()
1770 {
1771 CreateTexture2DRg();
1772 }
1773 };
1774
1775 class PlainGatherFloat2DR : public GatherBase
1776 {
1777 public:
Init()1778 virtual void Init()
1779 {
1780 CreateTexture2DR();
1781 }
1782 };
1783
1784 class OffsetGatherFloat2DRgb : public OffsetGatherFloat2D
1785 {
1786 public:
Init()1787 virtual void Init()
1788 {
1789 CreateTexture2DRgb();
1790 }
1791 };
1792
1793 class OffsetGatherFloat2DRg : public OffsetGatherFloat2D
1794 {
1795 public:
Init()1796 virtual void Init()
1797 {
1798 CreateTexture2DRg();
1799 }
1800 };
1801
1802 class OffsetGatherFloat2DR : public OffsetGatherFloat2D
1803 {
1804 public:
Init()1805 virtual void Init()
1806 {
1807 CreateTexture2DR();
1808 }
1809 };
1810
1811 } // anonymous namespace
1812
TextureGatherTests(glcts::Context & context)1813 TextureGatherTests::TextureGatherTests(glcts::Context& context) : TestCaseGroup(context, "texture_gather", "")
1814 {
1815 }
1816
~TextureGatherTests(void)1817 TextureGatherTests::~TextureGatherTests(void)
1818 {
1819 }
1820
init()1821 void TextureGatherTests::init()
1822 {
1823 using namespace glcts;
1824 addChild(new TestSubcase(m_context, "api-enums", TestSubcase::Create<GatherEnumsTest>));
1825 addChild(new TestSubcase(m_context, "gather-glsl-compile", TestSubcase::Create<GatherGLSLCompile>));
1826 addChild(new TestSubcase(m_context, "plain-gather-float-2d", TestSubcase::Create<PlainGatherFloat2D>));
1827 addChild(new TestSubcase(m_context, "plain-gather-int-2d", TestSubcase::Create<PlainGatherInt2D>));
1828 addChild(new TestSubcase(m_context, "plain-gather-uint-2d", TestSubcase::Create<PlainGatherUint2D>));
1829 addChild(new TestSubcase(m_context, "plain-gather-depth-2d", TestSubcase::Create<PlainGatherDepth2D>));
1830 addChild(new TestSubcase(m_context, "plain-gather-float-2darray", TestSubcase::Create<PlainGatherFloat2DArray>));
1831 addChild(new TestSubcase(m_context, "plain-gather-int-2darray", TestSubcase::Create<PlainGatherInt2DArray>));
1832 addChild(new TestSubcase(m_context, "plain-gather-uint-2darray", TestSubcase::Create<PlainGatherUint2DArray>));
1833 addChild(new TestSubcase(m_context, "plain-gather-depth-2darray", TestSubcase::Create<PlainGatherDepth2DArray>));
1834 addChild(new TestSubcase(m_context, "plain-gather-float-cube-rgba", TestSubcase::Create<PlainGatherFloatCube>));
1835 addChild(new TestSubcase(m_context, "plain-gather-int-cube-rgba", TestSubcase::Create<PlainGatherIntCube>));
1836 addChild(new TestSubcase(m_context, "plain-gather-uint-cube", TestSubcase::Create<PlainGatherUintCube>));
1837 addChild(new TestSubcase(m_context, "plain-gather-depth-cube", TestSubcase::Create<PlainGatherDepthCube>));
1838 addChild(new TestSubcase(m_context, "offset-gather-float-2d", TestSubcase::Create<OffsetGatherFloat2D>));
1839 addChild(new TestSubcase(m_context, "offset-gather-int-2d", TestSubcase::Create<OffsetGatherInt2D>));
1840 addChild(new TestSubcase(m_context, "offset-gather-uint-2d", TestSubcase::Create<OffsetGatherUint2D>));
1841 addChild(new TestSubcase(m_context, "offset-gather-depth-2d", TestSubcase::Create<OffsetGatherDepth2D>));
1842 addChild(new TestSubcase(m_context, "offset-gather-float-2darray", TestSubcase::Create<OffsetGatherFloat2DArray>));
1843 addChild(new TestSubcase(m_context, "offset-gather-int-2darray", TestSubcase::Create<OffsetGatherInt2DArray>));
1844 addChild(new TestSubcase(m_context, "offset-gather-uint-2darray", TestSubcase::Create<OffsetGatherUint2DArray>));
1845 addChild(new TestSubcase(m_context, "offset-gather-depth-2darray", TestSubcase::Create<OffsetGatherDepth2DArray>));
1846 addChild(new TestSubcase(m_context, "swizzle", TestSubcase::Create<Swizzle>));
1847 addChild(new TestSubcase(m_context, "base-level", TestSubcase::Create<BaseLevel>));
1848 addChild(new TestSubcase(m_context, "incomplete-texture", TestSubcase::Create<IncompleteTexture>));
1849 addChild(
1850 new TestSubcase(m_context, "incomplete-texture-last-comp", TestSubcase::Create<IncompleteTextureLastComp>));
1851 addChild(new TestSubcase(m_context, "triangle-draw", TestSubcase::Create<TriangleDraw>));
1852 addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb", TestSubcase::Create<PlainGatherFloat2DSrgb>));
1853 addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb-alpha",
1854 TestSubcase::Create<PlainGatherFloat2DSrgbAlpha>));
1855 addChild(new TestSubcase(m_context, "plain-gather-float-2d-rgb", TestSubcase::Create<PlainGatherFloat2DRgb>));
1856 addChild(new TestSubcase(m_context, "plain-gather-float-2d-rg", TestSubcase::Create<PlainGatherFloat2DRg>));
1857 addChild(new TestSubcase(m_context, "plain-gather-float-2d-r", TestSubcase::Create<PlainGatherFloat2DR>));
1858 addChild(new TestSubcase(m_context, "offset-gather-float-2d-rgb", TestSubcase::Create<OffsetGatherFloat2DRgb>));
1859 addChild(new TestSubcase(m_context, "offset-gather-float-2d-rg", TestSubcase::Create<OffsetGatherFloat2DRg>));
1860 addChild(new TestSubcase(m_context, "offset-gather-float-2d-r", TestSubcase::Create<OffsetGatherFloat2DR>));
1861 }
1862 } // glcts namespace
1863