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 "gl4cProgramInterfaceQueryTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include <cstdarg>
28 #include <map>
29 #include <set>
30
31 namespace gl4cts
32 {
33
34 using namespace glw;
35
36 namespace
37 {
38
39 class PIQBase : public deqp::SubcaseBase
40 {
41
42 public:
PassCriteria()43 virtual std::string PassCriteria()
44 {
45 return "All called functions return expected values.";
46 }
47
Purpose()48 virtual std::string Purpose()
49 {
50 return "Verify that the set of tested functions glGetProgram* return\n"
51 "expected results when used to get data from program\n"
52 "made of " +
53 ShadersDesc() + "." + PurposeExt();
54 }
55
Method()56 virtual std::string Method()
57 {
58 return "Create a program using " + ShadersDesc() +
59 "\n"
60 "then use set of tested functions to get an information about it and\n"
61 "verify that information with the expected data" +
62 Expectations();
63 }
64
Cleanup()65 virtual long Cleanup()
66 {
67 glUseProgram(0);
68 return NO_ERROR;
69 }
70
Setup()71 virtual long Setup()
72 {
73 return NO_ERROR;
74 }
75
~PIQBase()76 virtual ~PIQBase()
77 {
78 }
79
80 protected:
LinkProgram(GLuint program)81 void LinkProgram(GLuint program)
82 {
83 glLinkProgram(program);
84 GLsizei length;
85 GLchar log[1024];
86 glGetProgramInfoLog(program, sizeof(log), &length, log);
87 if (length > 1)
88 {
89 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
90 << log << tcu::TestLog::EndMessage;
91 }
92 }
93
CreateProgram(const char * src_vs,const char * src_fs,bool link)94 GLuint CreateProgram(const char *src_vs, const char *src_fs, bool link)
95 {
96 const GLuint p = glCreateProgram();
97
98 if (src_vs)
99 {
100 GLuint sh = glCreateShader(GL_VERTEX_SHADER);
101 glAttachShader(p, sh);
102 glDeleteShader(sh);
103 glShaderSource(sh, 1, &src_vs, NULL);
104 glCompileShader(sh);
105 }
106 if (src_fs)
107 {
108 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
109 glAttachShader(p, sh);
110 glDeleteShader(sh);
111 glShaderSource(sh, 1, &src_fs, NULL);
112 glCompileShader(sh);
113 }
114 if (link)
115 {
116 LinkProgram(p);
117 }
118 return p;
119 }
120
CreateProgram(const char * src_vs,const char * src_tcs,const char * src_tes,const char * src_gs,const char * src_fs,bool link)121 GLuint CreateProgram(const char *src_vs, const char *src_tcs, const char *src_tes, const char *src_gs,
122 const char *src_fs, bool link)
123 {
124 const GLuint p = glCreateProgram();
125
126 if (src_vs)
127 {
128 GLuint sh = glCreateShader(GL_VERTEX_SHADER);
129 glAttachShader(p, sh);
130 glDeleteShader(sh);
131 glShaderSource(sh, 1, &src_vs, NULL);
132 glCompileShader(sh);
133 }
134 if (src_tcs)
135 {
136 GLuint sh = glCreateShader(GL_TESS_CONTROL_SHADER);
137 glAttachShader(p, sh);
138 glDeleteShader(sh);
139 glShaderSource(sh, 1, &src_tcs, NULL);
140 glCompileShader(sh);
141 }
142 if (src_tes)
143 {
144 GLuint sh = glCreateShader(GL_TESS_EVALUATION_SHADER);
145 glAttachShader(p, sh);
146 glDeleteShader(sh);
147 glShaderSource(sh, 1, &src_tes, NULL);
148 glCompileShader(sh);
149 }
150 if (src_gs)
151 {
152 GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
153 glAttachShader(p, sh);
154 glDeleteShader(sh);
155 glShaderSource(sh, 1, &src_gs, NULL);
156 glCompileShader(sh);
157 }
158 if (src_fs)
159 {
160 GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
161 glAttachShader(p, sh);
162 glDeleteShader(sh);
163 glShaderSource(sh, 1, &src_fs, NULL);
164 glCompileShader(sh);
165 }
166 if (link)
167 {
168 LinkProgram(p);
169 }
170 return p;
171 }
172
ShadersDesc()173 virtual std::string ShadersDesc()
174 {
175 return "";
176 }
177
Expectations()178 virtual std::string Expectations()
179 {
180 return ".";
181 }
182
PurposeExt()183 virtual std::string PurposeExt()
184 {
185 return "";
186 }
187
ExpectError(GLenum expected,long & error)188 virtual inline void ExpectError(GLenum expected, long &error)
189 {
190 if (error != NO_ERROR)
191 return;
192 GLenum tmp = glGetError();
193 if (tmp == expected)
194 {
195 m_context.getTestContext().getLog()
196 << tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
197 error = NO_ERROR; // Error is expected
198 }
199 else
200 {
201 error = ERROR;
202 m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
203 << " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
204 }
205 }
206
VerifyGetProgramInterfaceiv(GLuint program,GLenum programInterface,GLenum pname,int expected,long & error)207 virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
208 long &error)
209 {
210 GLint res;
211 glGetProgramInterfaceiv(program, programInterface, pname, &res);
212 if (res != expected)
213 {
214 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
215 << expected << tcu::TestLog::EndMessage;
216 error = ERROR;
217 }
218 }
219
VerifyGetProgramResourceIndex(GLuint program,GLenum programInterface,const std::string & name,GLuint expected,long & error)220 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string &name,
221 GLuint expected, long &error)
222 {
223 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
224 if (res != expected)
225 {
226 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
227 << expected << tcu::TestLog::EndMessage;
228 error = ERROR;
229 }
230 }
231
VerifyGetProgramResourceIndex(GLuint program,GLenum programInterface,std::map<std::string,GLuint> & indices,const std::string & name,long & error)232 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface,
233 std::map<std::string, GLuint> &indices, const std::string &name,
234 long &error)
235 {
236 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
237 if (res == GL_INVALID_INDEX)
238 {
239 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
240 << ", expected number other than -1" << tcu::TestLog::EndMessage;
241 error = ERROR;
242 return;
243 }
244 std::map<std::string, GLuint>::iterator it = indices.begin();
245 while (it != indices.end())
246 {
247 if (it->second == res)
248 {
249 m_context.getTestContext().getLog()
250 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
251 error = ERROR;
252 return;
253 }
254 ++it;
255 }
256 indices[name] = res;
257 }
258
VerifyGetProgramResourceName(GLuint program,GLenum programInterface,GLuint index,const std::string & expected,long & error)259 virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
260 const std::string &expected, long &error)
261 {
262 GLchar name[1024] = {'\0'};
263 GLsizei len;
264 glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
265 if (len <= 0 || len > 1023 || name[len - 1] == '\0')
266 {
267 m_context.getTestContext().getLog()
268 << tcu::TestLog::Message
269 << "ERROR: Length in glGetProgramResourceName should not count null terminator!"
270 << tcu::TestLog::EndMessage;
271 error = ERROR;
272 }
273 else if (name != expected || name[len] != '\0')
274 {
275 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
276 << expected << tcu::TestLog::EndMessage;
277 error = ERROR;
278 }
279 }
280
VerifyGetProgramResourceLocation(GLuint program,GLenum programInterface,const std::string & name,GLint expected,long & error)281 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
282 const std::string &name, GLint expected, long &error)
283 {
284 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
285 if (res != expected)
286 {
287 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
288 << expected << tcu::TestLog::EndMessage;
289 error = ERROR;
290 }
291 }
292
VerifyGetProgramResourceLocation(GLuint program,GLenum programInterface,std::map<std::string,GLint> & locations,const std::string & name,long & error)293 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
294 std::map<std::string, GLint> &locations,
295 const std::string &name, long &error)
296 {
297 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
298 if (res < 0)
299 {
300 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
301 << ", expected not less than 0" << tcu::TestLog::EndMessage;
302 error = ERROR;
303 return;
304 }
305 std::map<std::string, GLint>::iterator it = locations.begin();
306 while (it != locations.end())
307 {
308 if (it->second == res)
309 {
310 m_context.getTestContext().getLog()
311 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
312 error = ERROR;
313 return;
314 }
315 ++it;
316 }
317 locations[name] = res;
318 }
319
VerifyGetProgramResourceiv(GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum props[],GLsizei expectedLength,const GLint expected[],long & error)320 virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
321 GLsizei propCount, const GLenum props[], GLsizei expectedLength,
322 const GLint expected[], long &error)
323 {
324 const GLsizei bufSize = 1000;
325 GLsizei length;
326 GLint params[bufSize];
327 glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
328 if (length != expectedLength || length <= 0)
329 {
330 error = ERROR;
331 m_context.getTestContext().getLog()
332 << tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
333 << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
334 << tcu::TestLog::EndMessage;
335 return;
336 }
337 for (int i = 0; i < length; ++i)
338 {
339 if (params[i] != expected[i])
340 {
341 error = ERROR;
342 m_context.getTestContext().getLog()
343 << tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
344 << " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
345 << tcu::TestLog::EndMessage;
346 }
347 }
348 }
349
VerifyGetProgramResourceLocationIndex(GLuint program,GLenum programInterface,const std::string & name,GLint expected,long & error)350 virtual inline void VerifyGetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
351 const std::string &name, GLint expected, long &error)
352 {
353 GLint res = glGetProgramResourceLocationIndex(program, programInterface, name.c_str());
354 if (res != expected)
355 {
356 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
357 << expected << "\nCALL: glGetProgramResourceLocationIndex, with "
358 << programInterface << ", " << name << tcu::TestLog::EndMessage;
359 error = ERROR;
360 }
361 }
362
GetProgramivRetValue(GLuint program,GLenum pname)363 virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
364 {
365 GLint ret;
366 glGetProgramiv(program, pname, &ret);
367 return ret;
368 }
369
370 static const GLenum interfaces[];
371 };
372
373 const GLenum PIQBase::interfaces[] = {GL_PROGRAM_INPUT,
374 GL_PROGRAM_OUTPUT,
375 GL_UNIFORM,
376 GL_UNIFORM_BLOCK,
377 GL_BUFFER_VARIABLE,
378 GL_SHADER_STORAGE_BLOCK,
379 GL_VERTEX_SUBROUTINE,
380 GL_TESS_CONTROL_SUBROUTINE,
381 GL_TESS_EVALUATION_SUBROUTINE,
382 GL_GEOMETRY_SUBROUTINE,
383 GL_FRAGMENT_SUBROUTINE,
384 GL_COMPUTE_SUBROUTINE,
385 GL_VERTEX_SUBROUTINE_UNIFORM,
386 GL_TESS_CONTROL_SUBROUTINE_UNIFORM,
387 GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,
388 GL_GEOMETRY_SUBROUTINE_UNIFORM,
389 GL_FRAGMENT_SUBROUTINE_UNIFORM,
390 GL_COMPUTE_SUBROUTINE_UNIFORM,
391 GL_TRANSFORM_FEEDBACK_VARYING};
392
393 class NoShaders : public PIQBase
394 {
395
Title()396 virtual std::string Title()
397 {
398 return "No Shaders Test";
399 }
400
ShadersDesc()401 virtual std::string ShadersDesc()
402 {
403 return "no shaders";
404 }
405
Run()406 virtual long Run()
407 {
408 const GLuint program = glCreateProgram();
409
410 long error = NO_ERROR;
411 int size = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
412
413 for (int i = 0; i < size; ++i)
414 {
415 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
416 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
417 continue;
418 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
419 }
420 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
421 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
422 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
423 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
424 error);
425 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
426 error);
427 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
428 error);
429 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
430 0, error);
431 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
432 error);
433 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0, error);
434
435 for (int i = 0; i < size; ++i)
436 {
437 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
438 continue;
439 VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
440 }
441
442 // can't test GetProgramResourceLocation* here since program has to be linked
443 // can't test GetProgramResourceiv, need valid index
444
445 glDeleteProgram(program);
446 return error;
447 }
448 };
449
450 class SimpleShaders : public PIQBase
451 {
452
453 public:
Title()454 virtual std::string Title()
455 {
456 return "Simple Shaders Test";
457 }
458
ShadersDesc()459 virtual std::string ShadersDesc()
460 {
461 return "fallthrough fragment and vertex shaders";
462 }
463
VertexShader()464 virtual std::string VertexShader()
465 {
466 return "#version 430 \n"
467 "in vec4 position; \n"
468 "void main(void) \n"
469 "{ \n"
470 " gl_Position = position; \n"
471 "}";
472 }
473
FragmentShader()474 virtual std::string FragmentShader()
475 {
476 return "#version 430 \n"
477 "out vec4 color; \n"
478 "void main() { \n"
479 " color = vec4(0, 1, 0, 1); \n"
480 "}";
481 }
482
Run()483 virtual long Run()
484 {
485 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
486 glBindAttribLocation(program, 0, "position");
487 glBindFragDataLocation(program, 0, "color");
488 LinkProgram(program);
489
490 long error = NO_ERROR;
491
492 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
493 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
494 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
495 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
496
497 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
498 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
499
500 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
501 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
502
503 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
504 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
505
506 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
507
508 GLenum props[] = {GL_NAME_LENGTH,
509 GL_TYPE,
510 GL_ARRAY_SIZE,
511 GL_REFERENCED_BY_COMPUTE_SHADER,
512 GL_REFERENCED_BY_FRAGMENT_SHADER,
513 GL_REFERENCED_BY_GEOMETRY_SHADER,
514 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
515 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
516 GL_REFERENCED_BY_VERTEX_SHADER,
517 GL_LOCATION,
518 GL_IS_PER_PATCH};
519 GLint expected[] = {9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0};
520 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
521
522 GLenum props2[] = {GL_NAME_LENGTH,
523 GL_TYPE,
524 GL_ARRAY_SIZE,
525 GL_REFERENCED_BY_COMPUTE_SHADER,
526 GL_REFERENCED_BY_FRAGMENT_SHADER,
527 GL_REFERENCED_BY_GEOMETRY_SHADER,
528 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
529 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
530 GL_REFERENCED_BY_VERTEX_SHADER,
531 GL_LOCATION,
532 GL_IS_PER_PATCH,
533 GL_LOCATION_INDEX};
534 GLint expected2[] = {6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0};
535 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
536
537 glDeleteProgram(program);
538 return error;
539 }
540 };
541
542 class InputTypes : public SimpleShaders
543 {
Title()544 virtual std::string Title()
545 {
546 return "Input Types Test";
547 }
548
ShadersDesc()549 virtual std::string ShadersDesc()
550 {
551 return "vertex shader with different `in` types and a fallthrough fragment shader";
552 }
553
VertexShader()554 virtual std::string VertexShader()
555 {
556 return "#version 430 \n"
557 "in mat4 a; \n"
558 "in ivec4 b; \n"
559 "in float c[2]; \n"
560 "in mat2x3 d[2]; \n"
561 "in uvec2 e; \n"
562 "in uint f; \n"
563 "in vec3 g[2]; \n"
564 "in int h; \n"
565 "void main(void) \n"
566 "{ \n"
567 " vec4 pos; \n"
568 " pos.w = h + g[0].x + g[1].y + d[1][1].y; \n"
569 " pos.y = b.x * c[0] + c[1] + d[0][0].x; \n"
570 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n"
571 " pos.z = d[0][1].z + e.x * f + d[1][0].z; \n"
572 " gl_Position = pos; \n"
573 "}";
574 }
575
Run()576 virtual long Run()
577 {
578 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
579 glBindAttribLocation(program, 0, "a");
580 glBindAttribLocation(program, 4, "b");
581 glBindAttribLocation(program, 5, "c");
582 glBindAttribLocation(program, 7, "d");
583 glBindAttribLocation(program, 11, "e");
584 glBindAttribLocation(program, 12, "f");
585 glBindAttribLocation(program, 13, "g");
586 glBindAttribLocation(program, 15, "h");
587 glBindFragDataLocation(program, 0, "color");
588 LinkProgram(program);
589
590 long error = NO_ERROR;
591
592 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
593 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
594
595 std::map<std::string, GLuint> indices;
596 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
597 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
598 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
599 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
600 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
601 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
602 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
603 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
604
605 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
606 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
607 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
608 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
609 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
610 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
611 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
612 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
613
614 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
615 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
616 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
617 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
618 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
619 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
620 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
621 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
622 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
623 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
624 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
625 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
626 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
627
628 GLenum props[] = {GL_NAME_LENGTH,
629 GL_TYPE,
630 GL_ARRAY_SIZE,
631 GL_REFERENCED_BY_COMPUTE_SHADER,
632 GL_REFERENCED_BY_FRAGMENT_SHADER,
633 GL_REFERENCED_BY_GEOMETRY_SHADER,
634 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
635 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
636 GL_REFERENCED_BY_VERTEX_SHADER,
637 GL_LOCATION,
638 GL_IS_PER_PATCH};
639 GLint expected[] = {2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0};
640 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
641 GLint expected2[] = {2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0};
642 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
643 GLint expected3[] = {5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0};
644 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
645 GLint expected4[] = {5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0};
646 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
647 GLint expected5[] = {2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0};
648 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
649 GLint expected6[] = {2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0};
650 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
651 GLint expected7[] = {5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0};
652 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
653 GLint expected8[] = {2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0};
654 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
655
656 glDeleteProgram(program);
657 return error;
658 }
659 };
660
661 class OutputTypes : public SimpleShaders
662 {
Title()663 virtual std::string Title()
664 {
665 return "Output Types Test";
666 }
667
ShadersDesc()668 virtual std::string ShadersDesc()
669 {
670 return "fragment shader with different `out` types and a fallthrough vertex shader";
671 }
672
FragmentShader()673 virtual std::string FragmentShader()
674 {
675 return "#version 430 \n"
676 "out vec3 a[2]; \n"
677 "out uint b; \n"
678 "out float c[2]; \n"
679 "out int d[2]; \n"
680 "out vec2 e; \n"
681 "void main() { \n"
682 " c[1] = -0.6; \n"
683 " d[0] = 0; \n"
684 " b = 12u; \n"
685 " c[0] = 1.1; \n"
686 " e = vec2(0, 1); \n"
687 " d[1] = -19; \n"
688 " a[1] = vec3(0, 1, 0); \n"
689 " a[0] = vec3(0, 1, 0); \n"
690 "}";
691 }
692
Run()693 virtual long Run()
694 {
695 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
696 glBindAttribLocation(program, 0, "position");
697 glBindFragDataLocation(program, 0, "a");
698 glBindFragDataLocation(program, 2, "b");
699 glBindFragDataLocation(program, 3, "c");
700 glBindFragDataLocation(program, 5, "d");
701 glBindFragDataLocation(program, 7, "e");
702 LinkProgram(program);
703
704 long error = NO_ERROR;
705
706 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
707 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
708
709 std::map<std::string, GLuint> indices;
710 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
711 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
712 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
713 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
714 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
715
716 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
717 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
718 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
719 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
720 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
721
722 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
723 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
724 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
725 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
726 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
727 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
728 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
729 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
730 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
731 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
732 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
733
734 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
735 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
736 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
737 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
738 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
739 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
740 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
741 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
742
743 GLenum props[] = {GL_NAME_LENGTH,
744 GL_TYPE,
745 GL_ARRAY_SIZE,
746 GL_REFERENCED_BY_COMPUTE_SHADER,
747 GL_REFERENCED_BY_FRAGMENT_SHADER,
748 GL_REFERENCED_BY_GEOMETRY_SHADER,
749 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
750 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
751 GL_REFERENCED_BY_VERTEX_SHADER,
752 GL_LOCATION,
753 GL_IS_PER_PATCH,
754 GL_LOCATION_INDEX};
755 GLint expected[] = {5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0};
756 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
757 GLint expected2[] = {2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0};
758 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
759 GLint expected3[] = {5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0};
760 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
761 GLint expected4[] = {5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0};
762 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
763 GLint expected5[] = {2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0};
764 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
765
766 glDeleteProgram(program);
767 return error;
768 }
769 };
770
771 class OutputLocationIndex : public SimpleShaders
772 {
Title()773 virtual std::string Title()
774 {
775 return "Output Location Index Test";
776 }
777
ShadersDesc()778 virtual std::string ShadersDesc()
779 {
780 return "fragment shader with `out` location index different from 0 and a fallthrough vertex shader";
781 }
782
Run()783 virtual long Run()
784 {
785 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
786 glBindAttribLocation(program, 0, "position");
787 glBindFragDataLocationIndexed(program, 0, 1, "color");
788 LinkProgram(program);
789
790 long error = NO_ERROR;
791
792 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
793
794 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
795
796 GLenum props[] = {GL_NAME_LENGTH,
797 GL_TYPE,
798 GL_ARRAY_SIZE,
799 GL_REFERENCED_BY_COMPUTE_SHADER,
800 GL_REFERENCED_BY_FRAGMENT_SHADER,
801 GL_REFERENCED_BY_GEOMETRY_SHADER,
802 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
803 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
804 GL_REFERENCED_BY_VERTEX_SHADER,
805 GL_LOCATION,
806 GL_IS_PER_PATCH,
807 GL_LOCATION_INDEX};
808 GLint expected[] = {6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1};
809 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
810
811 glDeleteProgram(program);
812 return error;
813 }
814 };
815
816 class InputBuiltIn : public SimpleShaders
817 {
818
Title()819 virtual std::string Title()
820 {
821 return "Input Built-ins Test";
822 }
823
ShadersDesc()824 virtual std::string ShadersDesc()
825 {
826 return "vertex shader using built-in variables and a fallthrough fragment shader";
827 }
828
Expectations()829 virtual std::string Expectations()
830 {
831 return ".\n\n In this case we ask for information about built-in variables for the input interface.";
832 }
833
VertexShader()834 virtual std::string VertexShader()
835 {
836 return "#version 430 \n"
837 "void main(void) \n"
838 "{ \n"
839 " gl_Position = (gl_VertexID + gl_InstanceID) * vec4(0.1); \n"
840 "}";
841 }
842
Run()843 virtual long Run()
844 {
845 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
846 glBindFragDataLocation(program, 0, "color");
847 LinkProgram(program);
848
849 long error = NO_ERROR;
850
851 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
852 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
853
854 std::map<std::string, GLuint> indices;
855 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
856 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
857
858 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
859 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
860
861 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
862 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
863
864 GLenum props[] = {GL_NAME_LENGTH,
865 GL_TYPE,
866 GL_ARRAY_SIZE,
867 GL_REFERENCED_BY_COMPUTE_SHADER,
868 GL_REFERENCED_BY_FRAGMENT_SHADER,
869 GL_REFERENCED_BY_GEOMETRY_SHADER,
870 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
871 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
872 GL_REFERENCED_BY_VERTEX_SHADER,
873 GL_LOCATION,
874 GL_IS_PER_PATCH};
875 GLint expected[] = {12, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0};
876 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 11, props, 11, expected, error);
877 GLint expected2[] = {14, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0};
878 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 11, props, 11, expected2,
879 error);
880
881 glDeleteProgram(program);
882 return error;
883 }
884 };
885
886 class OutputBuiltIn : public SimpleShaders
887 {
888
Title()889 virtual std::string Title()
890 {
891 return "Output Built-ins Test";
892 }
893
ShadersDesc()894 virtual std::string ShadersDesc()
895 {
896 return "fragment shader using built-in variables and a fallthrough vertex shader";
897 }
898
Expectations()899 virtual std::string Expectations()
900 {
901 return ".\n\n In this case we ask for information about built-in variables for the output interface.";
902 }
903
FragmentShader()904 virtual std::string FragmentShader()
905 {
906 return "#version 430 \n"
907 "void main(void) \n"
908 "{ \n"
909 " gl_FragDepth = 0.1; \n"
910 " gl_SampleMask[0] = 1; \n"
911 "}";
912 }
913
Run()914 virtual long Run()
915 {
916 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
917
918 long error = NO_ERROR;
919
920 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 2, error);
921 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 17, error);
922
923 std::map<std::string, GLuint> indices;
924 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
925 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_SampleMask[0]", error);
926
927 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
928 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], "gl_SampleMask[0]",
929 error);
930
931 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
932 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
933 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
934
935 // spec is not clear what to require here
936 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
937 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
938 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
939
940 GLenum props[] = {GL_NAME_LENGTH,
941 GL_TYPE,
942 GL_ARRAY_SIZE,
943 GL_REFERENCED_BY_COMPUTE_SHADER,
944 GL_REFERENCED_BY_FRAGMENT_SHADER,
945 GL_REFERENCED_BY_GEOMETRY_SHADER,
946 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
947 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
948 GL_REFERENCED_BY_VERTEX_SHADER,
949 GL_LOCATION,
950 GL_IS_PER_PATCH,
951 GL_LOCATION_INDEX};
952 GLint expected[] = {13, GL_FLOAT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1};
953 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], 12, props, 12, expected, error);
954 GLint expected2[] = {17, GL_INT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1};
955 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], 12, props, 12, expected2,
956 error);
957
958 glDeleteProgram(program);
959 return error;
960 }
961 };
962
963 class InputLayout : public SimpleShaders
964 {
Title()965 virtual std::string Title()
966 {
967 return "Input Layout Test";
968 }
969
ShadersDesc()970 virtual std::string ShadersDesc()
971 {
972 return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
973 "shader";
974 }
975
VertexShader()976 virtual std::string VertexShader()
977 {
978 return "#version 430 \n"
979 "layout(location = 4) in ivec4 b; \n"
980 "layout(location = 7) in mat2x3 d[2]; \n"
981 "layout(location = 5) in float c[2]; \n"
982 "layout(location = 12) in uint f; \n"
983 "layout(location = 13) in vec3 g[2]; \n"
984 "layout(location = 0) in mat4 a; \n"
985 "layout(location = 15) in int h; \n"
986 "layout(location = 11) in uvec2 e; \n"
987 "void main(void) \n"
988 "{ \n"
989 " vec4 pos; \n"
990 " pos.w = h + g[0].x + g[1].y + d[1][1].y; \n"
991 " pos.y = b.x * c[0] + c[1] + d[0][0].x; \n"
992 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n"
993 " pos.z = d[0][1].z + e.x * f + d[1][0].z; \n"
994 " gl_Position = pos; \n"
995 "}";
996 }
997
Run()998 virtual long Run()
999 {
1000 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1001 glBindFragDataLocation(program, 0, "color");
1002 LinkProgram(program);
1003
1004 long error = NO_ERROR;
1005
1006 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
1007 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
1008
1009 std::map<std::string, GLuint> indices;
1010 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
1011 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
1012 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
1013 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
1014 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
1015 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
1016 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
1017 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
1018
1019 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
1020 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
1021 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
1022 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
1023 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
1024 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
1025 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
1026 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
1027
1028 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
1029 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
1030 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
1031 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
1032 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
1033 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
1034 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
1035 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
1036 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
1037 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
1038 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
1039 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
1040 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
1041
1042 GLenum props[] = {GL_NAME_LENGTH,
1043 GL_TYPE,
1044 GL_ARRAY_SIZE,
1045 GL_REFERENCED_BY_COMPUTE_SHADER,
1046 GL_REFERENCED_BY_FRAGMENT_SHADER,
1047 GL_REFERENCED_BY_GEOMETRY_SHADER,
1048 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1049 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1050 GL_REFERENCED_BY_VERTEX_SHADER,
1051 GL_LOCATION,
1052 GL_IS_PER_PATCH};
1053 GLint expected[] = {2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0};
1054 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
1055 GLint expected2[] = {2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0};
1056 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
1057 GLint expected3[] = {5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0};
1058 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
1059 GLint expected4[] = {5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0};
1060 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
1061 GLint expected5[] = {2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0};
1062 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
1063 GLint expected6[] = {2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0};
1064 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
1065 GLint expected7[] = {5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0};
1066 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
1067 GLint expected8[] = {2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0};
1068 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
1069
1070 glDeleteProgram(program);
1071 return error;
1072 }
1073 };
1074
1075 class OutputLayout : public SimpleShaders
1076 {
Title()1077 virtual std::string Title()
1078 {
1079 return "Output Layout Test";
1080 }
1081
ShadersDesc()1082 virtual std::string ShadersDesc()
1083 {
1084 return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
1085 "shader";
1086 }
1087
FragmentShader()1088 virtual std::string FragmentShader()
1089 {
1090 return "#version 430 \n"
1091 "layout(location = 2) out uint b; \n"
1092 "layout(location = 7) out vec2 e; \n"
1093 "layout(location = 3) out float c[2]; \n"
1094 "layout(location = 5) out int d[2]; \n"
1095 "layout(location = 0) out vec3 a[2]; \n"
1096 "void main() { \n"
1097 " c[1] = -0.6; \n"
1098 " d[0] = 0; \n"
1099 " b = 12u; \n"
1100 " c[0] = 1.1; \n"
1101 " e = vec2(0, 1); \n"
1102 " d[1] = -19; \n"
1103 " a[1] = vec3(0, 1, 0); \n"
1104 " a[0] = vec3(0, 1, 0); \n"
1105 "}";
1106 }
1107
Run()1108 virtual long Run()
1109 {
1110 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1111 glBindAttribLocation(program, 0, "position");
1112 LinkProgram(program);
1113
1114 long error = NO_ERROR;
1115
1116 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
1117 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
1118
1119 std::map<std::string, GLuint> indices;
1120 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
1121 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
1122 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
1123 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
1124 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
1125
1126 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
1127 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
1128 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
1129 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
1130 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
1131
1132 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1133 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1134 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
1135 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
1136 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
1137 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
1138 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
1139 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
1140 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
1141 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
1142 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
1143
1144 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1145 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1146 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
1147 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
1148 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
1149 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
1150 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
1151 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
1152
1153 GLenum props[] = {GL_NAME_LENGTH,
1154 GL_TYPE,
1155 GL_ARRAY_SIZE,
1156 GL_REFERENCED_BY_COMPUTE_SHADER,
1157 GL_REFERENCED_BY_FRAGMENT_SHADER,
1158 GL_REFERENCED_BY_GEOMETRY_SHADER,
1159 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1160 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1161 GL_REFERENCED_BY_VERTEX_SHADER,
1162 GL_LOCATION,
1163 GL_IS_PER_PATCH,
1164 GL_LOCATION_INDEX};
1165 GLint expected[] = {5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0};
1166 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
1167 GLint expected2[] = {2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0};
1168 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
1169 GLint expected3[] = {5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0};
1170 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
1171 GLint expected4[] = {5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0};
1172 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
1173 GLint expected5[] = {2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0};
1174 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
1175
1176 glDeleteProgram(program);
1177 return error;
1178 }
1179 };
1180
1181 class OutputLayoutIndex : public SimpleShaders
1182 {
Title()1183 virtual std::string Title()
1184 {
1185 return "Output Layout Index Test";
1186 }
1187
ShadersDesc()1188 virtual std::string ShadersDesc()
1189 {
1190 return "fragment shader with different `out` variables fragment color index\n"
1191 "locations set through layout and a fallthrough vertex shader";
1192 }
1193
FragmentShader()1194 virtual std::string FragmentShader()
1195 {
1196 return "#version 430 \n"
1197 "layout(location = 0, index = 1) out vec4 color; \n"
1198 "void main() { \n"
1199 " color = vec4(0, 1, 0, 1); \n"
1200 "}";
1201 }
1202
Run()1203 virtual long Run()
1204 {
1205 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1206 glBindAttribLocation(program, 0, "position");
1207 LinkProgram(program);
1208
1209 long error = NO_ERROR;
1210
1211 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
1212
1213 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
1214
1215 GLenum props[] = {GL_NAME_LENGTH,
1216 GL_TYPE,
1217 GL_ARRAY_SIZE,
1218 GL_REFERENCED_BY_COMPUTE_SHADER,
1219 GL_REFERENCED_BY_FRAGMENT_SHADER,
1220 GL_REFERENCED_BY_GEOMETRY_SHADER,
1221 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1222 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1223 GL_REFERENCED_BY_VERTEX_SHADER,
1224 GL_LOCATION,
1225 GL_IS_PER_PATCH,
1226 GL_LOCATION_INDEX};
1227 GLint expected[] = {6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1};
1228 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
1229
1230 glDeleteProgram(program);
1231 return error;
1232 }
1233 };
1234
1235 class UniformSimple : public PIQBase
1236 {
Title()1237 virtual std::string Title()
1238 {
1239 return "Uniform Simple Test";
1240 }
1241
ShadersDesc()1242 virtual std::string ShadersDesc()
1243 {
1244 return "fallthrough fragment and vertex shaders with uniforms used";
1245 }
1246
PurposeExt()1247 virtual std::string PurposeExt()
1248 {
1249 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1250 }
1251
VertexShader()1252 virtual std::string VertexShader()
1253 {
1254 return "#version 430 \n"
1255 "in vec4 position; \n"
1256 "uniform vec4 repos; \n"
1257 "void main(void) \n"
1258 "{ \n"
1259 " gl_Position = position + repos; \n"
1260 "}";
1261 }
1262
FragmentShader()1263 virtual std::string FragmentShader()
1264 {
1265 return "#version 430 \n"
1266 "uniform vec4 recolor; \n"
1267 "out vec4 color; \n"
1268 "void main() { \n"
1269 " color = vec4(0, 1, 0, 1) + recolor; \n"
1270 "}";
1271 }
1272
Run()1273 virtual long Run()
1274 {
1275 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1276 glBindAttribLocation(program, 0, "position");
1277 glBindFragDataLocation(program, 0, "color");
1278 LinkProgram(program);
1279
1280 long error = NO_ERROR;
1281
1282 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1283 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1284 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1285
1286 std::map<std::string, GLuint> indices;
1287 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1288 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1289
1290 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1291 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1292
1293 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1294 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1295 error);
1296
1297 GLenum props[] = {GL_NAME_LENGTH,
1298 GL_TYPE,
1299 GL_ARRAY_SIZE,
1300 GL_OFFSET,
1301 GL_BLOCK_INDEX,
1302 GL_ARRAY_STRIDE,
1303 GL_MATRIX_STRIDE,
1304 GL_IS_ROW_MAJOR,
1305 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1306 GL_REFERENCED_BY_COMPUTE_SHADER,
1307 GL_REFERENCED_BY_FRAGMENT_SHADER,
1308 GL_REFERENCED_BY_GEOMETRY_SHADER,
1309 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1310 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1311 GL_REFERENCED_BY_VERTEX_SHADER,
1312 GL_LOCATION};
1313 GLint expected[] = {
1314 6, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "repos")};
1315 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 16, props, 16, expected, error);
1316
1317 GLint expected2[] = {
1318 8, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "recolor")};
1319 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 16, props, 16, expected2, error);
1320
1321 glDeleteProgram(program);
1322 return error;
1323 }
1324 };
1325
1326 class UniformTypes : public PIQBase
1327 {
Title()1328 virtual std::string Title()
1329 {
1330 return "Uniform Types Test";
1331 }
1332
ShadersDesc()1333 virtual std::string ShadersDesc()
1334 {
1335 return "fallthrough fragment and vertex shaders with different uniform types used";
1336 }
1337
PurposeExt()1338 virtual std::string PurposeExt()
1339 {
1340 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1341 }
1342
VertexShader()1343 virtual std::string VertexShader()
1344 {
1345 return "#version 430 \n"
1346 "in vec4 position; \n"
1347 "uniform vec4 a; \n"
1348 "uniform ivec3 b; \n"
1349 "uniform uvec2 c[3]; \n"
1350 "uniform mat2 g[8]; \n"
1351 "uniform mat3x2 i; \n"
1352 "void main(void) \n"
1353 "{ \n"
1354 " float tmp; \n"
1355 " tmp = g[0][1][1] + a.z + b.y + c[0].x; \n"
1356 " tmp += g[1][1][1] + c[1].x; \n"
1357 " tmp += g[2][1][1] + c[2].x; \n"
1358 " for (int i = 3; i < 8; ++i) \n"
1359 " tmp += g[i][1][1]; \n"
1360 " tmp = tmp + i[1][1]; \n"
1361 " gl_Position = position * tmp; \n"
1362 "}";
1363 }
1364
FragmentShader()1365 virtual std::string FragmentShader()
1366 {
1367 return "#version 430 \n"
1368 "struct U { \n"
1369 " bool a[3]; \n"
1370 " vec4 b; \n"
1371 " mat3 c; \n"
1372 " float d[2]; \n"
1373 "}; \n"
1374 "struct UU { \n"
1375 " U a; \n"
1376 " U b[2]; \n"
1377 " uvec2 c; \n"
1378 "}; \n"
1379 "uniform mat4 d; \n"
1380 "uniform mat3 e; \n"
1381 "uniform float h; \n"
1382 "uniform int f; \n"
1383 "uniform U j; \n"
1384 "uniform UU k; \n"
1385 "uniform UU l[3]; \n"
1386 "out vec4 color; \n"
1387 "void main() { \n"
1388 " float tmp; \n"
1389 " tmp = h + f + e[2][2]; \n"
1390 " tmp = tmp + d[0][0] + j.b.x; \n"
1391 " tmp = tmp + k.b[0].c[0][0]; \n"
1392 " tmp = tmp + l[2].a.c[0][1]; \n"
1393 " tmp = tmp + l[2].b[1].d[0]; \n"
1394 " tmp = tmp + l[2].b[1].d[1]; \n"
1395 " tmp = tmp + l[0].c.x; \n"
1396 " color = vec4(0, 1, 0, 1) * tmp; \n"
1397 "}";
1398 }
1399
Run()1400 virtual long Run()
1401 {
1402 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1403 glBindAttribLocation(program, 0, "position");
1404 glBindFragDataLocation(program, 0, "color");
1405 LinkProgram(program);
1406
1407 long error = NO_ERROR;
1408
1409 // only active structure members
1410 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1411 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1412 // l[2].b[1].d[0] and \0
1413 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1414
1415 std::map<std::string, GLuint> indices;
1416 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1417 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1418 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1419 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1420 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1421 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1422 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1423 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1424 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1425 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1426 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1427 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1428 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1429 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1430
1431 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1432 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1433 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1434 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1435 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1436 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1437 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1438 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1439 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1440 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1441 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1442 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1443 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1444 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1445
1446 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1447 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1448 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1449 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1450 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1451 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1452 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1453 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1454 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1455 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1456 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1457 error);
1458 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1459 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1460 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1461 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1462 error);
1463
1464 GLenum props[] = {GL_NAME_LENGTH,
1465 GL_TYPE,
1466 GL_ARRAY_SIZE,
1467 GL_OFFSET,
1468 GL_BLOCK_INDEX,
1469 GL_ARRAY_STRIDE,
1470 GL_MATRIX_STRIDE,
1471 GL_IS_ROW_MAJOR,
1472 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1473 GL_REFERENCED_BY_COMPUTE_SHADER,
1474 GL_REFERENCED_BY_FRAGMENT_SHADER,
1475 GL_REFERENCED_BY_GEOMETRY_SHADER,
1476 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1477 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1478 GL_REFERENCED_BY_VERTEX_SHADER,
1479 GL_LOCATION};
1480 GLint expected[] = {
1481 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a")};
1482 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 16, props, 16, expected, error);
1483 GLint expected2[] = {2, GL_INT_VEC3, 1, -1, -1, -1, -1, 0,
1484 -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "b")};
1485 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 16, props, 16, expected2, error);
1486 GLint expected3[] = {
1487 5, GL_UNSIGNED_INT_VEC2, 3, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "c")};
1488 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 16, props, 16, expected3, error);
1489 GLint expected4[] = {
1490 2, GL_FLOAT_MAT4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "d")};
1491 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 16, props, 16, expected4, error);
1492 GLint expected5[] = {
1493 2, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "e")};
1494 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 16, props, 16, expected5, error);
1495 GLint expected6[] = {2, GL_INT, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "f")};
1496 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 16, props, 16, expected6, error);
1497 GLint expected7[] = {
1498 5, GL_FLOAT_MAT2, 8, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "g")};
1499 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 16, props, 16, expected7, error);
1500 GLint expected8[] = {2, GL_FLOAT, 1, -1, -1, -1, -1, 0,
1501 -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "h")};
1502 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 16, props, 16, expected8, error);
1503 GLint expected9[] = {
1504 2, GL_FLOAT_MAT3x2, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "i")};
1505 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 16, props, 16, expected9, error);
1506 GLint expected10[] = {
1507 4, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "j.b")};
1508 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 16, props, 16, expected10, error);
1509 GLint expected11[] = {
1510 9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "k.b[0].c")};
1511 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 16, props, 16, expected11, error);
1512 GLint expected12[] = {7, GL_UNSIGNED_INT_VEC2,
1513 1, -1,
1514 -1, -1,
1515 -1, 0,
1516 -1, 0,
1517 1, 0,
1518 0, 0,
1519 0, glGetUniformLocation(program, "l[0].c")};
1520 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 16, props, 16, expected12, error);
1521 GLint expected13[] = {15, GL_FLOAT, 2, -1, -1, -1, -1, 0,
1522 -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")};
1523 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 16, props, 16, expected13, error);
1524 GLint expected14[] = {
1525 9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].a.c")};
1526 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 16, props, 16, expected14, error);
1527
1528 glDeleteProgram(program);
1529 return error;
1530 }
1531 };
1532
1533 class UniformBlockTypes : public PIQBase
1534 {
Title()1535 virtual std::string Title()
1536 {
1537 return "Uniform Block Types Test";
1538 }
1539
ShadersDesc()1540 virtual std::string ShadersDesc()
1541 {
1542 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1543 }
1544
PurposeExt()1545 virtual std::string PurposeExt()
1546 {
1547 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1548 }
1549
VertexShader()1550 virtual std::string VertexShader()
1551 {
1552 return "#version 430 \n"
1553 "in vec4 position; \n"
1554 ""
1555 "uniform SimpleBlock { \n"
1556 " mat3x2 a; \n"
1557 " mat4 b; \n"
1558 " vec4 c; \n"
1559 "}; \n"
1560 ""
1561 "uniform NotSoSimpleBlockk { \n"
1562 " ivec2 a[4]; \n"
1563 " mat3 b[2]; \n"
1564 " mat2 c; \n"
1565 "} d; \n"
1566 ""
1567 "void main(void) \n"
1568 "{ \n"
1569 " float tmp; \n"
1570 " tmp = a[0][1] * b[1][2] * c.x; \n"
1571 " tmp = tmp + d.a[2].y + d.b[0][1][1] + d.c[1][1]; \n"
1572 " gl_Position = position * tmp; \n"
1573 "}";
1574 }
1575
FragmentShader()1576 virtual std::string FragmentShader()
1577 {
1578 return "#version 430 \n"
1579 "struct U { \n"
1580 " bool a[3]; \n"
1581 " vec4 b; \n"
1582 " mat3 c; \n"
1583 " float d[2]; \n"
1584 "}; \n"
1585 "struct UU { \n"
1586 " U a; \n"
1587 " U b[2]; \n"
1588 " uvec2 c; \n"
1589 "}; \n"
1590 ""
1591 "uniform TrickyBlock { \n"
1592 " UU a[3]; \n"
1593 " mat4 b; \n"
1594 " uint c; \n"
1595 "} e[2]; \n"
1596 ""
1597 "out vec4 color; \n"
1598 "void main() { \n"
1599 " float tmp; \n"
1600 " tmp = e[0].a[2].b[0].d[1]; \n"
1601 " color = vec4(0, 1, 0, 1) * tmp; \n"
1602 "}";
1603 }
1604
Run()1605 virtual long Run()
1606 {
1607 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1608 glBindAttribLocation(program, 0, "position");
1609 glBindFragDataLocation(program, 0, "color");
1610 LinkProgram(program);
1611
1612 long error = NO_ERROR;
1613
1614 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1615 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1616 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1617 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1618
1619 std::map<std::string, GLuint> indicesUB;
1620 std::map<std::string, GLuint> indicesU;
1621 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1622 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1623 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1624 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1625 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1626 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1627 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1628 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1629 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1630 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1631 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1632
1633 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1634 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1635 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1636 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1637
1638 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1639 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1640 error);
1641 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1642 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1643 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1644 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1645 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1646 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1647 error);
1648 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1649 error);
1650 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1651 error);
1652 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1653 "TrickyBlock.a[2].b[0].d[0]", error);
1654
1655 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1656 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1657 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1658
1659 GLenum props[] = {
1660 GL_NAME_LENGTH,
1661 GL_BUFFER_BINDING,
1662 GL_REFERENCED_BY_COMPUTE_SHADER,
1663 GL_REFERENCED_BY_FRAGMENT_SHADER,
1664 GL_REFERENCED_BY_GEOMETRY_SHADER,
1665 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1666 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1667 GL_REFERENCED_BY_VERTEX_SHADER,
1668 GL_BUFFER_DATA_SIZE,
1669 };
1670 GLint size;
1671 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1672 GLint expected[] = {12, 0, 0, 0, 0, 0, 0, 1, size};
1673 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 9, props, 9, expected, error);
1674 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1675 GLint expected2[] = {18, 2, 0, 0, 0, 0, 0, 1, size};
1676 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 9, props, 9, expected2,
1677 error);
1678 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1679 GLint expected3[] = {15, 3, 0, 1, 0, 0, 0, 0, size};
1680 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 9, props, 9, expected3, error);
1681 GLint expected4[] = {15, 4, 0, 0, 0, 0, 0, 0, size};
1682 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 9, props, 9, expected4,
1683 error);
1684
1685 GLenum props2[] = {GL_NAME_LENGTH,
1686 GL_TYPE,
1687 GL_ARRAY_SIZE,
1688 GL_BLOCK_INDEX,
1689 GL_ARRAY_STRIDE,
1690 GL_IS_ROW_MAJOR,
1691 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1692 GL_REFERENCED_BY_COMPUTE_SHADER,
1693 GL_REFERENCED_BY_FRAGMENT_SHADER,
1694 GL_REFERENCED_BY_GEOMETRY_SHADER,
1695 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1696 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1697 GL_REFERENCED_BY_VERTEX_SHADER,
1698 GL_LOCATION};
1699 GLint expected5[] = {
1700 2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 0, 0, 0, 1, -1};
1701 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 14, props2, 14, expected5, error);
1702 GLenum props3[] = {GL_NAME_LENGTH,
1703 GL_TYPE,
1704 GL_ARRAY_SIZE,
1705 GL_BLOCK_INDEX,
1706 GL_MATRIX_STRIDE,
1707 GL_IS_ROW_MAJOR,
1708 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1709 GL_REFERENCED_BY_COMPUTE_SHADER,
1710 GL_REFERENCED_BY_FRAGMENT_SHADER,
1711 GL_REFERENCED_BY_GEOMETRY_SHADER,
1712 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1713 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1714 GL_REFERENCED_BY_VERTEX_SHADER,
1715 GL_LOCATION};
1716 GLint expected6[] = {27, GL_FLOAT, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, 0,
1717 0, 0, -1};
1718 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 14, props3, 14, expected6,
1719 error);
1720
1721 GLenum prop = GL_ACTIVE_VARIABLES;
1722 const GLsizei bufSize = 1000;
1723 GLsizei length;
1724 GLint param[bufSize];
1725 std::set<GLuint> exp;
1726 exp.insert(indicesU["a"]);
1727 exp.insert(indicesU["b"]);
1728 exp.insert(indicesU["c"]);
1729 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1730 for (int i = 0; i < length; ++i)
1731 {
1732 if (exp.find(param[i]) == exp.end())
1733 {
1734 m_context.getTestContext().getLog()
1735 << tcu::TestLog::Message
1736 << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1737 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1738 << tcu::TestLog::EndMessage;
1739 glDeleteProgram(program);
1740 return ERROR;
1741 }
1742 else if (length != 3)
1743 {
1744 m_context.getTestContext().getLog()
1745 << tcu::TestLog::Message
1746 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK\n"
1747 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1748 glDeleteProgram(program);
1749 return ERROR;
1750 }
1751 }
1752 std::set<GLuint> exp2;
1753 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1754 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1755 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1756 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1757 param);
1758 for (int i = 0; i < length; ++i)
1759 {
1760 if (exp2.find(param[i]) == exp2.end())
1761 {
1762 m_context.getTestContext().getLog()
1763 << tcu::TestLog::Message
1764 << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1765 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1766 << tcu::TestLog::EndMessage;
1767 glDeleteProgram(program);
1768 return ERROR;
1769 }
1770 else if (length != 3)
1771 {
1772 m_context.getTestContext().getLog()
1773 << tcu::TestLog::Message
1774 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1775 << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1776 glDeleteProgram(program);
1777 return ERROR;
1778 }
1779 }
1780
1781 GLint res;
1782 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1783 if (res < 3)
1784 {
1785 m_context.getTestContext().getLog()
1786 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1787 << tcu::TestLog::EndMessage;
1788 glDeleteProgram(program);
1789 return ERROR;
1790 }
1791
1792 glDeleteProgram(program);
1793 return error;
1794 }
1795 };
1796
1797 class TransformFeedbackTypes : public SimpleShaders
1798 {
Title()1799 virtual std::string Title()
1800 {
1801 return "Transform Feedback Varying Types";
1802 }
1803
ShadersDesc()1804 virtual std::string ShadersDesc()
1805 {
1806 return "fallthrough fragment and vertex shaders with different types of out variables used";
1807 }
1808
PurposeExt()1809 virtual std::string PurposeExt()
1810 {
1811 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1812 }
1813
VertexShader()1814 virtual std::string VertexShader()
1815 {
1816 return "#version 430 \n"
1817 "in vec4 position; \n"
1818 ""
1819 "flat out ivec4 a; \n"
1820 "out float b[2]; \n"
1821 "flat out uvec2 c; \n"
1822 "flat out uint d; \n"
1823 "out vec3 e[2]; \n"
1824 "flat out int f; \n"
1825 ""
1826 "void main(void) \n"
1827 "{ \n"
1828 " vec4 pos; \n"
1829 " a = ivec4(1); \n"
1830 " b[0] = 1.1; \n"
1831 " b[1] = 1.1; \n"
1832 " c = uvec2(1u); \n"
1833 " d = 1u; \n"
1834 " e[0] = vec3(1.1); \n"
1835 " e[1] = vec3(1.1); \n"
1836 " f = 1; \n"
1837 " gl_Position = position; \n"
1838 "}";
1839 }
1840
Run()1841 virtual long Run()
1842 {
1843 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1844 glBindAttribLocation(program, 0, "position");
1845 const char *varyings[6] = {"a", "b[0]", "b[1]", "c", "d", "e"};
1846 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1847 LinkProgram(program);
1848
1849 long error = NO_ERROR;
1850
1851 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1852 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1853
1854 std::map<std::string, GLuint> indices;
1855 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1856 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1857 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1858 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1859 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1860 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1861
1862 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1863 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1864 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1865 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1866 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1867 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1868
1869 GLenum props[] = {GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE};
1870 GLint expected[] = {2, GL_INT_VEC4, 1};
1871 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1872 GLint expected2[] = {5, GL_FLOAT, 1};
1873 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1874 error);
1875 GLint expected3[] = {5, GL_FLOAT, 1};
1876 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1877 error);
1878 GLint expected4[] = {2, GL_UNSIGNED_INT_VEC2, 1};
1879 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1880 GLint expected5[] = {2, GL_UNSIGNED_INT, 1};
1881 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1882 GLint expected6[] = {2, GL_FLOAT_VEC3, 2};
1883 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1884
1885 glDeleteProgram(program);
1886 return error;
1887 }
1888 };
1889
1890 class AtomicCounterSimple : public SimpleShaders
1891 {
1892 public:
Title()1893 virtual std::string Title()
1894 {
1895 return "Atomic Counter Buffer Simple Test";
1896 }
1897
ShadersDesc()1898 virtual std::string ShadersDesc()
1899 {
1900 return "fallthrough fragment and vertex shaders with atomic counters used";
1901 }
1902
PurposeExt()1903 virtual std::string PurposeExt()
1904 {
1905 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1906 }
1907
FragmentShader()1908 virtual std::string FragmentShader()
1909 {
1910 return "#version 430 \n"
1911 "out vec4 color; \n"
1912 ""
1913 "layout (binding = 1, offset = 0) uniform atomic_uint a; \n"
1914 "layout (binding = 2, offset = 0) uniform atomic_uint b; \n"
1915 "layout (binding = 2, offset = 4) uniform atomic_uint c; \n"
1916 "layout (binding = 5, offset = 0) uniform atomic_uint d[3]; \n"
1917 "layout (binding = 5, offset = 12) uniform atomic_uint e; \n"
1918 ""
1919 "void main() { \n"
1920 " uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1921 " uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1922 " uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1923 " uint w = atomicCounterIncrement(e); \n"
1924 " color = vec4(float(x), float(y), float(z), float(w)); \n"
1925 "}";
1926 }
1927
Run()1928 virtual long Run()
1929 {
1930 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1931 glBindAttribLocation(program, 0, "position");
1932 glBindFragDataLocation(program, 0, "color");
1933 LinkProgram(program);
1934
1935 long error = NO_ERROR;
1936
1937 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1938 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1939
1940 std::map<std::string, GLuint> indicesU;
1941 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1942 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1943 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1944 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1945 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1946
1947 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1948 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1949 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1950 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1951 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1952
1953 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1954 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1955 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1956 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1957 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1958 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1959 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1960 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1961
1962 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1963 const GLsizei bufSize = 1000;
1964 GLsizei length;
1965 GLint res;
1966 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1967
1968 GLenum props[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES};
1969 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1970 GLint expected[] = {1, 4, 1, static_cast<GLint>(indicesU["a"])};
1971 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1972
1973 GLenum props2[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES};
1974 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1975 GLint expected2[] = {2, 8, 2};
1976 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1977 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1978 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1979
1980 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1981 GLint expected3[] = {5, 16, 2};
1982 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1983 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1984 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1985
1986 GLenum prop2 = GL_ACTIVE_VARIABLES;
1987 GLint param[bufSize];
1988 std::set<GLuint> exp;
1989 exp.insert(indicesU["b"]);
1990 exp.insert(indicesU["c"]);
1991 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1992 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1993 for (int i = 0; i < length; ++i)
1994 {
1995 if (exp.find(param[i]) == exp.end() || length != 2)
1996 {
1997 m_context.getTestContext().getLog()
1998 << tcu::TestLog::Message << "Length: " << length
1999 << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2000 << tcu::TestLog::EndMessage;
2001 glDeleteProgram(program);
2002 return ERROR;
2003 }
2004 }
2005 m_context.getTestContext().getLog()
2006 << tcu::TestLog::Message << "GL_ACTIVE_VARIABLES ok for 1st ATOMIC_COUNTER_BUFFER"
2007 << tcu::TestLog::EndMessage;
2008 std::set<GLuint> exp2;
2009 GLint param2[bufSize];
2010 exp2.insert(indicesU["d"]);
2011 exp2.insert(indicesU["e"]);
2012 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
2013 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
2014 for (int i = 0; i < length; ++i)
2015 {
2016 if (exp2.find(param2[i]) == exp2.end() || length != 2)
2017 {
2018 m_context.getTestContext().getLog()
2019 << tcu::TestLog::Message << "Length: " << length
2020 << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
2021 << tcu::TestLog::EndMessage;
2022 glDeleteProgram(program);
2023 return ERROR;
2024 }
2025 }
2026
2027 glDeleteProgram(program);
2028 return error;
2029 }
2030 };
2031
2032 class SubroutinesBase : public SimpleShaders
2033 {
2034 protected:
ShadersDesc()2035 virtual std::string ShadersDesc()
2036 {
2037 return "fallthrough vertex, geometry, tesselation and fragment shaders with subroutines used";
2038 }
2039
VertexShader()2040 virtual std::string VertexShader()
2041 {
2042 return "#version 430 \n"
2043 "in vec4 position; \n"
2044 ""
2045 "subroutine vec4 a_t(); \n"
2046 "subroutine uniform a_t a; \n"
2047 "subroutine(a_t) vec4 x() { \n"
2048 " return vec4(1); \n"
2049 "} \n"
2050 "subroutine(a_t) vec4 y() { \n"
2051 " return vec4(0); \n"
2052 "} \n"
2053 "void main(void) \n"
2054 "{ \n"
2055 " gl_Position = a(); \n"
2056 "}";
2057 }
2058
TessControlShader()2059 virtual std::string TessControlShader()
2060 {
2061 return "#version 430 \n"
2062 "layout(vertices = 3) out; \n"
2063 ""
2064 "subroutine vec4 a_t(); \n"
2065 "subroutine uniform a_t a; \n"
2066 "subroutine(a_t) vec4 x() { \n"
2067 " return vec4(1); \n"
2068 "} \n"
2069 ""
2070 "void main() { \n"
2071 " gl_out[gl_InvocationID].gl_Position = a(); \n"
2072 " gl_TessLevelInner[0] = 1.0; \n"
2073 " gl_TessLevelInner[1] = 1.0; \n"
2074 " gl_TessLevelOuter[0] = 1.0; \n"
2075 " gl_TessLevelOuter[1] = 1.0; \n"
2076 " gl_TessLevelOuter[2] = 1.0; \n"
2077 "}";
2078 }
2079
TessEvalShader()2080 virtual std::string TessEvalShader()
2081 {
2082 return "#version 430 \n"
2083 "layout(triangles, equal_spacing) in; \n"
2084 ""
2085 "subroutine vec4 a_t(); \n"
2086 "subroutine uniform a_t a; \n"
2087 "subroutine(a_t) vec4 x() { \n"
2088 " return vec4(1); \n"
2089 "} \n"
2090 ""
2091 "void main() { \n"
2092 " vec4 p0 = gl_in[0].gl_Position; \n"
2093 " vec4 p1 = gl_in[1].gl_Position; \n"
2094 " vec4 p2 = gl_in[2].gl_Position; \n"
2095 " vec3 p = gl_TessCoord.xyz; \n"
2096 " gl_Position = a(); \n"
2097 "}";
2098 }
2099
GeometryShader()2100 virtual std::string GeometryShader()
2101 {
2102 return "#version 430 \n"
2103 "layout(triangles) in; \n"
2104 "layout(triangle_strip, max_vertices = 4) out; \n"
2105 ""
2106 "subroutine vec4 a_t(); \n"
2107 "subroutine uniform a_t a; \n"
2108 "subroutine(a_t) vec4 x() { \n"
2109 " return vec4(1); \n"
2110 "} \n"
2111 ""
2112 "void main() { \n"
2113 " gl_Position = vec4(-1, 1, 0, 1); \n"
2114 " EmitVertex(); \n"
2115 " gl_Position = vec4(-1, -1, 0, 1); \n"
2116 " EmitVertex(); \n"
2117 " gl_Position = vec4(1, 1, 0, 1); \n"
2118 " EmitVertex(); \n"
2119 " gl_Position = a(); \n"
2120 " EmitVertex(); \n"
2121 " EndPrimitive(); \n"
2122 "}";
2123 }
2124
FragmentShader()2125 virtual std::string FragmentShader()
2126 {
2127 return "#version 430 \n"
2128 "out vec4 color; \n"
2129 ""
2130 "subroutine vec4 a_t(); \n"
2131 "subroutine uniform a_t a; \n"
2132 "subroutine(a_t) vec4 x() { \n"
2133 " return vec4(1); \n"
2134 "} \n"
2135 ""
2136 "void main() { \n"
2137 " color = a(); \n"
2138 "}";
2139 }
2140
VerifyVS(GLuint program,long & error)2141 virtual void inline VerifyVS(GLuint program, long &error)
2142 {
2143 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, 2, error);
2144 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2145
2146 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2147 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2148 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 2, error);
2149
2150 std::map<std::string, GLuint> indicesS;
2151 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "x", error);
2152 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "y", error);
2153 std::map<std::string, GLuint> indicesU;
2154 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU, "a", error);
2155
2156 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["x"], "x", error);
2157 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["y"], "y", error);
2158 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], "a", error);
2159
2160 VerifyGetProgramResourceLocation(program, GL_VERTEX_SUBROUTINE_UNIFORM, "a",
2161 glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a"), error);
2162
2163 GLenum propsS[] = {GL_NAME_LENGTH};
2164 GLint expectedS[] = {2};
2165 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["x"], 1, propsS, 1, expectedS, error);
2166 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["y"], 1, propsS, 1, expectedS, error);
2167
2168 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION};
2169 GLint expectedU[] = {2, 1, 2, glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a")};
2170 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 4, propsU, 4, expectedU,
2171 error);
2172
2173 GLenum prop = GL_COMPATIBLE_SUBROUTINES;
2174 const GLsizei bufSize = 1000;
2175 GLint param[bufSize];
2176 GLsizei length;
2177 std::set<GLuint> exp;
2178 exp.insert(indicesS["x"]);
2179 exp.insert(indicesS["y"]);
2180 glGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, param);
2181 for (int i = 0; i < length; ++i)
2182 {
2183 if (exp.find(param[i]) == exp.end() || length != 2)
2184 {
2185 m_context.getTestContext().getLog()
2186 << tcu::TestLog::Message << "Length: " << length
2187 << "\nUnexpected index/length found in active variables of GL_VERTEX_SUBROUTINE_UNIFORM: "
2188 << param[i] << tcu::TestLog::EndMessage;
2189 error = ERROR;
2190 }
2191 }
2192 }
2193
VerifyTCS(GLuint program,long & error)2194 virtual void inline VerifyTCS(GLuint program, long &error)
2195 {
2196 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2197 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2198
2199 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2200 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2201 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2202 error);
2203
2204 std::map<std::string, GLuint> indicesTS;
2205 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS, "x", error);
2206 std::map<std::string, GLuint> indicesTU;
2207 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2208
2209 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS["x"], "x", error);
2210 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2211
2212 VerifyGetProgramResourceLocation(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, "a",
2213 glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"), error);
2214
2215 GLenum propsS[] = {GL_NAME_LENGTH};
2216 GLint expectedS[] = {2};
2217 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE, static_cast<GLint>(indicesTS["x"]), 1, propsS,
2218 1, expectedS, error);
2219
2220 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2221 GL_COMPATIBLE_SUBROUTINES};
2222 GLint expectedU[] = {2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"),
2223 static_cast<GLint>(indicesTS["x"])};
2224 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2225 error);
2226 }
2227 };
2228
2229 class SubroutinesVertex : public SubroutinesBase
2230 {
Title()2231 virtual std::string Title()
2232 {
2233 return "Vertex Shader Subroutines Test";
2234 }
2235
PurposeExt()2236 virtual std::string PurposeExt()
2237 {
2238 return "\n\n Purpose is to verify calls using *VERTEX_SUBROUTINE* as an interface params.\n";
2239 }
2240
Run()2241 virtual long Run()
2242 {
2243 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2244 GeometryShader().c_str(), FragmentShader().c_str(), false);
2245 glBindAttribLocation(program, 0, "position");
2246 glBindFragDataLocation(program, 0, "color");
2247 LinkProgram(program);
2248 long error = NO_ERROR;
2249
2250 VerifyVS(program, error);
2251
2252 glDeleteProgram(program);
2253 return error;
2254 }
2255 };
2256
2257 class SubroutinesTessControl : public SubroutinesBase
2258 {
Title()2259 virtual std::string Title()
2260 {
2261 return "Tess Control Subroutines Test";
2262 }
2263
PurposeExt()2264 virtual std::string PurposeExt()
2265 {
2266 return "\n\n Purpose is to verify calls using *TESS_CONTROL_SUBROUTINE* as an interface params.\n";
2267 }
2268
Run()2269 virtual long Run()
2270 {
2271 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2272 GeometryShader().c_str(), FragmentShader().c_str(), false);
2273 glBindAttribLocation(program, 0, "position");
2274 glBindFragDataLocation(program, 0, "color");
2275 LinkProgram(program);
2276 long error = NO_ERROR;
2277
2278 VerifyTCS(program, error);
2279
2280 glDeleteProgram(program);
2281 return error;
2282 }
2283 };
2284
2285 class SubroutinesTessEval : public SubroutinesBase
2286 {
Title()2287 virtual std::string Title()
2288 {
2289 return "Tess Evaluation Subroutines Test";
2290 }
2291
PurposeExt()2292 virtual std::string PurposeExt()
2293 {
2294 return "\n\n Purpose is to verify calls using *TESS_EVALUATION_SUBROUTINE* as an interface params.\n";
2295 }
2296
VerifyTES(GLuint program,long & error)2297 virtual void inline VerifyTES(GLuint program, long &error)
2298 {
2299 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2300 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2301
2302 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2303 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2304 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
2305 1, error);
2306
2307 std::map<std::string, GLuint> indicesTS;
2308 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS, "x", error);
2309 std::map<std::string, GLuint> indicesTU;
2310 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2311
2312 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], "x", error);
2313 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2314
2315 VerifyGetProgramResourceLocation(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, "a",
2316 glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2317 error);
2318
2319 GLenum propsS[] = {GL_NAME_LENGTH};
2320 GLint expectedS[] = {2};
2321 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS,
2322 error);
2323
2324 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2325 GL_COMPATIBLE_SUBROUTINES};
2326 GLint expectedU[] = {2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2327 static_cast<GLint>(indicesTS["x"])};
2328 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5,
2329 expectedU, error);
2330 }
2331
Run()2332 virtual long Run()
2333 {
2334 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2335 GeometryShader().c_str(), FragmentShader().c_str(), false);
2336 glBindAttribLocation(program, 0, "position");
2337 glBindFragDataLocation(program, 0, "color");
2338 LinkProgram(program);
2339 long error = NO_ERROR;
2340
2341 VerifyTES(program, error);
2342
2343 glDeleteProgram(program);
2344 return error;
2345 }
2346 };
2347
2348 class SubroutinesGeometry : public SubroutinesBase
2349 {
Title()2350 virtual std::string Title()
2351 {
2352 return "Geometry Shader Subroutines Test";
2353 }
2354
PurposeExt()2355 virtual std::string PurposeExt()
2356 {
2357 return "\n\n Purpose is to verify calls using *GEOMETRY_SUBROUTINE* as an interface params.\n";
2358 }
2359
VerifyGEO(GLuint program,long & error)2360 virtual void inline VerifyGEO(GLuint program, long &error)
2361 {
2362 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2363 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2364
2365 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2366 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2367 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2368 error);
2369
2370 std::map<std::string, GLuint> indicesTS;
2371 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE, indicesTS, "x", error);
2372 std::map<std::string, GLuint> indicesTU;
2373 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2374
2375 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], "x", error);
2376 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2377
2378 VerifyGetProgramResourceLocation(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, "a",
2379 glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"), error);
2380
2381 GLenum propsS[] = {GL_NAME_LENGTH};
2382 GLint expectedS[] = {2};
2383 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2384
2385 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2386 GL_COMPATIBLE_SUBROUTINES};
2387 GLint expectedU[] = {2, 1, 1, glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"),
2388 static_cast<GLint>(indicesTS["x"])};
2389 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2390 error);
2391 }
2392
Run()2393 virtual long Run()
2394 {
2395 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2396 GeometryShader().c_str(), FragmentShader().c_str(), false);
2397 glBindAttribLocation(program, 0, "position");
2398 glBindFragDataLocation(program, 0, "color");
2399 LinkProgram(program);
2400 long error = NO_ERROR;
2401
2402 VerifyGEO(program, error);
2403
2404 glDeleteProgram(program);
2405 return error;
2406 }
2407 };
2408
2409 class SubroutinesFragment : public SubroutinesBase
2410 {
Title()2411 virtual std::string Title()
2412 {
2413 return "Fragment Shader Subroutines Test";
2414 }
2415
PurposeExt()2416 virtual std::string PurposeExt()
2417 {
2418 return "\n\n Purpose is to verify calls using *FRAGMENT_SUBROUTINE* as an interface params.\n";
2419 }
2420
VerifyFS(GLuint program,long & error)2421 virtual void inline VerifyFS(GLuint program, long &error)
2422 {
2423 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2424 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2425
2426 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2427 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2428 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2429 error);
2430
2431 std::map<std::string, GLuint> indicesTS;
2432 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE, indicesTS, "x", error);
2433 std::map<std::string, GLuint> indicesTU;
2434 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2435
2436 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], "x", error);
2437 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2438
2439 VerifyGetProgramResourceLocation(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, "a",
2440 glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"), error);
2441
2442 GLenum propsS[] = {GL_NAME_LENGTH};
2443 GLint expectedS[] = {2};
2444 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2445
2446 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2447 GL_COMPATIBLE_SUBROUTINES};
2448 GLint expectedU[] = {2, 1, 1, glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"),
2449 static_cast<GLint>(indicesTS["x"])};
2450 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2451 error);
2452 }
2453
Run()2454 virtual long Run()
2455 {
2456 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2457 GeometryShader().c_str(), FragmentShader().c_str(), false);
2458 glBindAttribLocation(program, 0, "position");
2459 glBindFragDataLocation(program, 0, "color");
2460 LinkProgram(program);
2461 long error = NO_ERROR;
2462
2463 VerifyFS(program, error);
2464
2465 glDeleteProgram(program);
2466 return error;
2467 }
2468 };
2469
2470 class SoubroutinesCompute : public PIQBase
2471 {
Title()2472 virtual std::string Title()
2473 {
2474 return "Compute Shader Subroutines Test";
2475 }
2476
ShadersDesc()2477 virtual std::string ShadersDesc()
2478 {
2479 return "compute shader with subroutines used";
2480 }
2481
PurposeExt()2482 virtual std::string PurposeExt()
2483 {
2484 return "\n\n Purpose is to verify calls using *COMPUTE_SUBROUTINE* as an interface params.\n";
2485 }
2486
ComputeShader()2487 virtual std::string ComputeShader()
2488 {
2489 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2490
2491 "layout(std430) buffer Output { \n"
2492 " vec4 data; \n"
2493 "} g_out; \n"
2494 ""
2495 "subroutine vec4 a_t(); \n"
2496 "subroutine uniform a_t a; \n"
2497 "subroutine(a_t) vec4 ax() { \n"
2498 " return vec4(1); \n"
2499 "} \n"
2500 "subroutine(a_t) vec4 ay() { \n"
2501 " return vec4(0); \n"
2502 "} \n"
2503 ""
2504 "subroutine vec4 b_t(); \n"
2505 "subroutine uniform b_t b[3]; \n"
2506 "subroutine(b_t) vec4 bx() { \n"
2507 " return vec4(1); \n"
2508 "} \n"
2509 "subroutine(b_t) vec4 by() { \n"
2510 " return vec4(0); \n"
2511 "} \n"
2512 "subroutine(b_t) vec4 bz() { \n"
2513 " return vec4(-1); \n"
2514 "} \n"
2515 ""
2516 "void main() { \n"
2517 " g_out.data = a() + b[0]() + b[1]() + b[2](); \n"
2518 "}";
2519 }
2520
CreateComputeProgram(const std::string & cs)2521 GLuint CreateComputeProgram(const std::string &cs)
2522 {
2523 const GLuint p = glCreateProgram();
2524
2525 const char *const kGLSLVer = "#version 430 core\n";
2526
2527 if (!cs.empty())
2528 {
2529 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
2530 glAttachShader(p, sh);
2531 glDeleteShader(sh);
2532 const char *const src[2] = {kGLSLVer, cs.c_str()};
2533 glShaderSource(sh, 2, src, NULL);
2534 glCompileShader(sh);
2535 }
2536
2537 return p;
2538 }
2539
CheckProgram(GLuint program,bool * compile_error=NULL)2540 bool CheckProgram(GLuint program, bool *compile_error = NULL)
2541 {
2542 GLint compile_status = GL_TRUE;
2543 GLint status;
2544 glGetProgramiv(program, GL_LINK_STATUS, &status);
2545
2546 if (status == GL_FALSE)
2547 {
2548 GLint attached_shaders;
2549 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
2550
2551 if (attached_shaders > 0)
2552 {
2553 std::vector<GLuint> shaders(attached_shaders);
2554 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
2555
2556 for (GLint i = 0; i < attached_shaders; ++i)
2557 {
2558 GLenum type;
2559 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
2560 switch (type)
2561 {
2562 case GL_VERTEX_SHADER:
2563 m_context.getTestContext().getLog()
2564 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
2565 break;
2566 case GL_TESS_CONTROL_SHADER:
2567 m_context.getTestContext().getLog()
2568 << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
2569 << tcu::TestLog::EndMessage;
2570 break;
2571 case GL_TESS_EVALUATION_SHADER:
2572 m_context.getTestContext().getLog()
2573 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
2574 << tcu::TestLog::EndMessage;
2575 break;
2576 case GL_GEOMETRY_SHADER:
2577 m_context.getTestContext().getLog()
2578 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
2579 break;
2580 case GL_FRAGMENT_SHADER:
2581 m_context.getTestContext().getLog()
2582 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
2583 break;
2584 case GL_COMPUTE_SHADER:
2585 m_context.getTestContext().getLog()
2586 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
2587 break;
2588 default:
2589 m_context.getTestContext().getLog()
2590 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
2591 }
2592
2593 GLint res;
2594 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
2595 if (res != GL_TRUE)
2596 compile_status = res;
2597
2598 // shader source
2599 GLint length;
2600 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
2601 if (length > 0)
2602 {
2603 std::vector<GLchar> source(length);
2604 glGetShaderSource(shaders[i], length, NULL, &source[0]);
2605 m_context.getTestContext().getLog()
2606 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
2607 }
2608
2609 // shader info log
2610 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
2611 if (length > 0)
2612 {
2613 std::vector<GLchar> log(length);
2614 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
2615 m_context.getTestContext().getLog()
2616 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2617 }
2618 }
2619 }
2620
2621 // program info log
2622 GLint length;
2623 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
2624 if (length > 0)
2625 {
2626 std::vector<GLchar> log(length);
2627 glGetProgramInfoLog(program, length, NULL, &log[0]);
2628 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2629 }
2630 }
2631
2632 if (compile_error)
2633 *compile_error = (compile_status == GL_TRUE ? false : true);
2634 if (compile_status != GL_TRUE)
2635 return false;
2636 return status == GL_TRUE ? true : false;
2637 }
2638
VerifyCompute(GLuint program,long & error)2639 virtual void inline VerifyCompute(GLuint program, long &error)
2640 {
2641 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_ACTIVE_RESOURCES, 5, error);
2642 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_MAX_NAME_LENGTH, 3, error);
2643
2644 GLint res;
2645 glGetProgramStageiv(program, GL_COMPUTE_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &res);
2646 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, res, error);
2647 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 5, error);
2648 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 3,
2649 error);
2650
2651 std::map<std::string, GLuint> indicesTS;
2652 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ax", error);
2653 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ay", error);
2654 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bx", error);
2655 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "by", error);
2656 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bz", error);
2657 std::map<std::string, GLuint> indicesTU;
2658 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2659 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "b[0]", error);
2660
2661 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], "ax", error);
2662 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], "ay", error);
2663 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], "bx", error);
2664 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], "by", error);
2665 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], "bz", error);
2666 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2667 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], "b[0]", error);
2668
2669 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "a",
2670 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a"), error);
2671 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "b",
2672 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b"), error);
2673
2674 GLenum propsS[] = {GL_NAME_LENGTH};
2675 GLint expectedS[] = {3};
2676 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], 1, propsS, 1, expectedS, error);
2677 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], 1, propsS, 1, expectedS, error);
2678 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], 1, propsS, 1, expectedS, error);
2679 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], 1, propsS, 1, expectedS, error);
2680 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], 1, propsS, 1, expectedS, error);
2681
2682 GLenum propsU[] = {GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION};
2683 GLint expectedU[] = {2, 1, 2, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a")};
2684 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], 4, propsU, 4, expectedU,
2685 error);
2686 GLint expectedU2[] = {5, 3, 3, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b")};
2687 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], 4, propsU, 4, expectedU2,
2688 error);
2689 }
2690
Run()2691 virtual long Run()
2692 {
2693 GLuint program = CreateComputeProgram(ComputeShader());
2694 glLinkProgram(program);
2695 if (!CheckProgram(program))
2696 {
2697 glDeleteProgram(program);
2698 return ERROR;
2699 }
2700 glUseProgram(program);
2701
2702 long error = NO_ERROR;
2703
2704 VerifyCompute(program, error);
2705
2706 glDeleteProgram(program);
2707 return error;
2708 }
2709 };
2710
2711 class InvalidValueTest : public SimpleShaders
2712 {
Title()2713 virtual std::string Title()
2714 {
2715 return "Invalid Value Test";
2716 }
2717
PassCriteria()2718 virtual std::string PassCriteria()
2719 {
2720 return "GL_INVALID_VALUE error is generated after every function call.";
2721 }
2722
Purpose()2723 virtual std::string Purpose()
2724 {
2725 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2726 }
2727
Method()2728 virtual std::string Method()
2729 {
2730 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2731 }
2732
Run()2733 virtual long Run()
2734 {
2735 long error = NO_ERROR;
2736
2737 GLint res = 0;
2738 GLsizei len = 0;
2739 GLchar name[100] = {'\0'};
2740 GLenum props[1] = {GL_NAME_LENGTH};
2741
2742 m_context.getTestContext().getLog()
2743 << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2744 << tcu::TestLog::EndMessage;
2745 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2746 ExpectError(GL_INVALID_VALUE, error);
2747 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2748 ExpectError(GL_INVALID_VALUE, error);
2749 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2750 ExpectError(GL_INVALID_VALUE, error);
2751 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2752 ExpectError(GL_INVALID_VALUE, error);
2753 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2754 ExpectError(GL_INVALID_VALUE, error);
2755 glGetProgramResourceLocationIndex(1337u, GL_PROGRAM_OUTPUT, "pie");
2756 ExpectError(GL_INVALID_VALUE, error);
2757 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2758
2759 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2760 glBindAttribLocation(program, 0, "position");
2761 glBindFragDataLocation(program, 0, "color");
2762 LinkProgram(program);
2763
2764 m_context.getTestContext().getLog()
2765 << tcu::TestLog::Message
2766 << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2767 << tcu::TestLog::EndMessage;
2768 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2769 ExpectError(GL_INVALID_VALUE, error);
2770 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2771
2772 m_context.getTestContext().getLog()
2773 << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2774 << tcu::TestLog::EndMessage;
2775 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2776 ExpectError(GL_INVALID_VALUE, error);
2777 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2778
2779 std::string str = "position";
2780 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char *>(str.c_str()));
2781 ExpectError(GL_INVALID_VALUE, error);
2782 GLenum prop = GL_NAME_LENGTH;
2783 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2784 ExpectError(GL_INVALID_VALUE, error);
2785
2786 glDeleteProgram(program);
2787 return error;
2788 }
2789 };
2790
2791 class InvalidEnumTest : public AtomicCounterSimple
2792 {
Title()2793 virtual std::string Title()
2794 {
2795 return "Invalid Enum Test";
2796 }
2797
PassCriteria()2798 virtual std::string PassCriteria()
2799 {
2800 return "GL_INVALID_ENUM error is generated after every function call.";
2801 }
2802
Purpose()2803 virtual std::string Purpose()
2804 {
2805 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2806 }
2807
Method()2808 virtual std::string Method()
2809 {
2810 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2811 }
2812
Run()2813 virtual long Run()
2814 {
2815 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2816 glBindAttribLocation(program, 0, "position");
2817 glBindFragDataLocation(program, 0, "color");
2818 LinkProgram(program);
2819
2820 long error = NO_ERROR;
2821
2822 GLint res = 0;
2823 GLsizei len = 0;
2824 GLchar name[100] = {'\0'};
2825 GLenum props[1] = {GL_TEXTURE_1D};
2826
2827 m_context.getTestContext().getLog()
2828 << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER "
2829 << "in GetProgramResourceIndex or GetProgramResourceName" << tcu::TestLog::EndMessage;
2830 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2831 ExpectError(GL_INVALID_ENUM, error);
2832 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2833 ExpectError(GL_INVALID_ENUM, error);
2834 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2835
2836 m_context.getTestContext().getLog()
2837 << tcu::TestLog::Message << "Case 2: <props> is not a property name supported by "
2838 << "the command GetProgramResourceiv" << tcu::TestLog::EndMessage;
2839 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2840 ExpectError(GL_INVALID_ENUM, error);
2841 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2842
2843 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2844 ExpectError(GL_INVALID_ENUM, error);
2845
2846 glDeleteProgram(program);
2847 return error;
2848 }
2849 };
2850
2851 class InvalidOperationTest : public SimpleShaders
2852 {
Title()2853 virtual std::string Title()
2854 {
2855 return "Invalid Operation Test";
2856 }
2857
PassCriteria()2858 virtual std::string PassCriteria()
2859 {
2860 return "GL_INVALID_OPERATION error is generated after every function call.";
2861 }
2862
Purpose()2863 virtual std::string Purpose()
2864 {
2865 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2866 }
2867
Method()2868 virtual std::string Method()
2869 {
2870 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2871 }
2872
Run()2873 virtual long Run()
2874 {
2875 long error = NO_ERROR;
2876
2877 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2878 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2879 glBindAttribLocation(program, 0, "position");
2880 glBindFragDataLocation(program, 0, "color");
2881 LinkProgram(program);
2882
2883 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2884 GLint res = 0;
2885 GLsizei len = 0;
2886 GLchar name[100] = {'\0'};
2887 GLenum props[1] = {GL_OFFSET};
2888
2889 m_context.getTestContext().getLog()
2890 << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2891 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2892 ExpectError(GL_INVALID_OPERATION, error);
2893 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2894 ExpectError(GL_INVALID_OPERATION, error);
2895 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2896 ExpectError(GL_INVALID_OPERATION, error);
2897 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2898 ExpectError(GL_INVALID_OPERATION, error);
2899 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2900 ExpectError(GL_INVALID_OPERATION, error);
2901 glGetProgramResourceLocationIndex(sh, GL_PROGRAM_OUTPUT, "pie");
2902 ExpectError(GL_INVALID_OPERATION, error);
2903 glDeleteShader(sh);
2904 m_context.getTestContext().getLog()
2905 << tcu::TestLog::Message << "Case 1 finished\n"
2906 << "Case 2: <pname> is not supported in GetProgramInterfacei" << tcu::TestLog::EndMessage;
2907
2908 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2909 ExpectError(GL_INVALID_OPERATION, error);
2910 m_context.getTestContext().getLog()
2911 << tcu::TestLog::Message << "Case 2 finished\n"
2912 << "Case 3: <props> is not supported in GetProgramResourceiv" << tcu::TestLog::EndMessage;
2913
2914 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2915 ExpectError(GL_INVALID_OPERATION, error);
2916 m_context.getTestContext().getLog()
2917 << tcu::TestLog::Message << "Case 3 finished\n"
2918 << "Case 4: <program> has not been linked in GetProgramResourceLocation/GetProgramResourceLocationIndex"
2919 << tcu::TestLog::EndMessage;
2920
2921 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2922 ExpectError(GL_INVALID_OPERATION, error);
2923 glGetProgramResourceLocationIndex(program2, GL_PROGRAM_OUTPUT, "pie");
2924 ExpectError(GL_INVALID_OPERATION, error);
2925 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished\n" << tcu::TestLog::EndMessage;
2926
2927 glDeleteProgram(program);
2928 glDeleteProgram(program2);
2929 return error;
2930 }
2931 };
2932
2933 class ShaderStorageBlock : public SimpleShaders
2934 {
Title()2935 virtual std::string Title()
2936 {
2937 return "Shader Storage Block Test";
2938 }
2939
ShadersDesc()2940 virtual std::string ShadersDesc()
2941 {
2942 return "fallthrough fragment and vertex shaders with different types of storage blocks used";
2943 }
2944
PurposeExt()2945 virtual std::string PurposeExt()
2946 {
2947 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2948 "params.\n";
2949 }
2950
FragmentShader()2951 virtual std::string FragmentShader()
2952 {
2953 return "#version 430 \n"
2954 ""
2955 "struct U { \n"
2956 " bool a[3]; \n"
2957 " mediump vec4 b; \n"
2958 " mediump mat3 c; \n"
2959 " mediump float d[2]; \n"
2960 "}; \n"
2961 ""
2962 "struct UU { \n"
2963 " U a; \n"
2964 " U b[2]; \n"
2965 " uvec2 c; \n"
2966 "}; \n"
2967 ""
2968 "layout(binding=4) buffer TrickyBuffer { \n"
2969 " UU a[3]; \n"
2970 " mediump mat4 b; \n"
2971 " uint c; \n"
2972 "} e[2]; \n"
2973 ""
2974 "layout(binding = 0) buffer SimpleBuffer { \n"
2975 " mediump mat3x2 a; \n"
2976 " mediump mat4 b; \n"
2977 " mediump vec4 c; \n"
2978 "}; \n"
2979 ""
2980 "layout(binding = 1) buffer NotSoSimpleBuffer { \n"
2981 " ivec2 a[4]; \n"
2982 " mediump mat3 b[2]; \n"
2983 " mediump mat2 c; \n"
2984 "} d; \n"
2985 ""
2986 "out mediump vec4 color; \n"
2987 ""
2988 "void main() { \n"
2989 " mediump float tmp; \n"
2990 " mediump float tmp2; \n"
2991 " tmp = e[0].a[0].b[0].d[0] * float(e[1].c); \n"
2992 " tmp2 = a[0][0] * b[0][0] * c.x; \n"
2993 " tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0]; \n"
2994 " color = vec4(0, 1, 0, 1) * tmp * tmp2; \n"
2995 "}";
2996 }
2997
Run()2998 virtual long Run()
2999 {
3000 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3001 glBindAttribLocation(program, 0, "position");
3002 glBindFragDataLocation(program, 0, "color");
3003 LinkProgram(program);
3004
3005 long error = NO_ERROR;
3006
3007 GLint res;
3008 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
3009 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
3010 if (res < 7)
3011 {
3012 m_context.getTestContext().getLog()
3013 << tcu::TestLog::Message
3014 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
3015 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
3016 error = ERROR;
3017 }
3018 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
3019 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
3020
3021 std::map<std::string, GLuint> indicesSSB;
3022 std::map<std::string, GLuint> indicesBV;
3023 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
3024 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
3025 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
3026 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
3027 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
3028 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
3029 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
3030 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
3031 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
3032 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
3033 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
3034 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
3035 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
3036
3037 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
3038 error);
3039 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
3040 "NotSoSimpleBuffer", error);
3041 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
3042 error);
3043 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
3044 error);
3045 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
3046 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
3047 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
3048 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
3049 "NotSoSimpleBuffer.a[0]", error);
3050 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
3051 "NotSoSimpleBuffer.c", error);
3052 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
3053 "NotSoSimpleBuffer.b[0]", error);
3054 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
3055 "TrickyBuffer.a[0].b[0].d[0]", error);
3056 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
3057 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
3058
3059 GLenum props[] = {GL_NAME_LENGTH,
3060 GL_BUFFER_BINDING,
3061 GL_NUM_ACTIVE_VARIABLES,
3062 GL_REFERENCED_BY_COMPUTE_SHADER,
3063 GL_REFERENCED_BY_FRAGMENT_SHADER,
3064 GL_REFERENCED_BY_GEOMETRY_SHADER,
3065 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3066 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3067 GL_REFERENCED_BY_VERTEX_SHADER};
3068 GLint expected[] = {13, 0, 3, 0, 1, 0, 0, 0, 0};
3069 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 9, props, 9, expected,
3070 error);
3071
3072 GLenum props2[] = {GL_NAME_LENGTH,
3073 GL_BUFFER_BINDING,
3074 GL_REFERENCED_BY_COMPUTE_SHADER,
3075 GL_REFERENCED_BY_FRAGMENT_SHADER,
3076 GL_REFERENCED_BY_GEOMETRY_SHADER,
3077 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3078 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3079 GL_REFERENCED_BY_VERTEX_SHADER};
3080 GLint expected2[] = {18, 1, 0, 1, 0, 0, 0, 0};
3081 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 8, props2, 8,
3082 expected2, error);
3083 GLint expected3[] = {16, 4, 0, 1, 0, 0, 0, 0};
3084 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 8, props2, 8,
3085 expected3, error);
3086 GLint expected4[] = {16, 5, 0, 1, 0, 0, 0, 0};
3087 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 8, props2, 8,
3088 expected4, error);
3089
3090 GLenum props3[] = {GL_NAME_LENGTH,
3091 GL_TYPE,
3092 GL_ARRAY_SIZE,
3093 GL_BLOCK_INDEX,
3094 GL_ARRAY_STRIDE,
3095 GL_IS_ROW_MAJOR,
3096 GL_REFERENCED_BY_COMPUTE_SHADER,
3097 GL_REFERENCED_BY_FRAGMENT_SHADER,
3098 GL_REFERENCED_BY_GEOMETRY_SHADER,
3099 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3100 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3101 GL_REFERENCED_BY_VERTEX_SHADER,
3102 GL_TOP_LEVEL_ARRAY_SIZE,
3103 GL_TOP_LEVEL_ARRAY_STRIDE};
3104 GLint expected5[] = {
3105 2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0};
3106 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 14, props3, 14, expected5, error);
3107
3108 GLenum props4[] = {GL_NAME_LENGTH,
3109 GL_TYPE,
3110 GL_ARRAY_SIZE,
3111 GL_BLOCK_INDEX,
3112 GL_MATRIX_STRIDE,
3113 GL_IS_ROW_MAJOR,
3114 GL_REFERENCED_BY_COMPUTE_SHADER,
3115 GL_REFERENCED_BY_FRAGMENT_SHADER,
3116 GL_REFERENCED_BY_GEOMETRY_SHADER,
3117 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3118 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3119 GL_REFERENCED_BY_VERTEX_SHADER,
3120 GL_TOP_LEVEL_ARRAY_SIZE};
3121 GLint expected6[] = {28, GL_FLOAT, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 0, 1, 0, 0,
3122 0, 0, 3};
3123 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 13, props4, 13,
3124 expected6, error);
3125
3126 GLenum prop = GL_ACTIVE_VARIABLES;
3127 const GLsizei bufSize = 1000;
3128 GLsizei length;
3129 GLint param[bufSize];
3130 std::set<GLuint> exp;
3131 exp.insert(indicesBV["a"]);
3132 exp.insert(indicesBV["b"]);
3133 exp.insert(indicesBV["c"]);
3134 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
3135 param);
3136 for (int i = 0; i < length; ++i)
3137 {
3138 if (exp.find(param[i]) == exp.end())
3139 {
3140 m_context.getTestContext().getLog()
3141 << tcu::TestLog::Message
3142 << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
3143 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3144 "GL_SHADER_STORAGE_BLOCK"
3145 << tcu::TestLog::EndMessage;
3146 glDeleteProgram(program);
3147 return ERROR;
3148 }
3149 else if (length != 3)
3150 {
3151 m_context.getTestContext().getLog()
3152 << tcu::TestLog::Message
3153 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3154 "interface: GL_SHADER_STORAGE_BLOCK\n"
3155 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3156 glDeleteProgram(program);
3157 return ERROR;
3158 }
3159 }
3160 std::set<GLuint> exp2;
3161 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
3162 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
3163 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
3164 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
3165 &length, param);
3166 for (int i = 0; i < length; ++i)
3167 {
3168 if (exp2.find(param[i]) == exp2.end())
3169 {
3170 m_context.getTestContext().getLog()
3171 << tcu::TestLog::Message
3172 << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
3173 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3174 "GL_SHADER_STORAGE_BLOCK"
3175 << tcu::TestLog::EndMessage;
3176 glDeleteProgram(program);
3177 return ERROR;
3178 }
3179 else if (length != 3)
3180 {
3181 m_context.getTestContext().getLog()
3182 << tcu::TestLog::Message
3183 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3184 "interface: GL_SHADER_STORAGE_BLOCK\n"
3185 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3186 glDeleteProgram(program);
3187 return ERROR;
3188 }
3189 }
3190
3191 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
3192 if (res < 3)
3193 {
3194 m_context.getTestContext().getLog()
3195 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
3196 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
3197 return ERROR;
3198 }
3199
3200 glDeleteProgram(program);
3201 return error;
3202 }
3203 };
3204
3205 class UniformBlockArray : public SimpleShaders
3206 {
Title()3207 virtual std::string Title()
3208 {
3209 return "Uniform Block Array Test";
3210 }
3211
ShadersDesc()3212 virtual std::string ShadersDesc()
3213 {
3214 return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
3215 }
3216
PurposeExt()3217 virtual std::string PurposeExt()
3218 {
3219 return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
3220 }
3221
VertexShader()3222 virtual std::string VertexShader()
3223 {
3224 return "#version 430 \n"
3225 "void main(void) \n"
3226 "{ \n"
3227 " gl_Position = vec4(1.0); \n"
3228 "}";
3229 }
3230
FragmentShader()3231 virtual std::string FragmentShader()
3232 {
3233 return "#version 430 \n"
3234 "uniform TestBlock { \n"
3235 " mediump vec4 color; \n"
3236 "} blockInstance[4]; \n"
3237 ""
3238 "out mediump vec4 color; \n"
3239 "void main() { \n"
3240 " color = blockInstance[2].color + blockInstance[3].color; \n"
3241 "}";
3242 }
3243
Run()3244 virtual long Run()
3245 {
3246 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3247 LinkProgram(program);
3248
3249 long error = NO_ERROR;
3250
3251 std::map<std::string, GLuint> indicesUB;
3252 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
3253
3254 std::map<std::string, GLuint> indicesU;
3255 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
3256
3257 GLenum props[] = {GL_BLOCK_INDEX};
3258 GLint expected[] = {static_cast<GLint>(indicesUB["TestBlock"])};
3259 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
3260
3261 glDeleteProgram(program);
3262 return error;
3263 }
3264 };
3265
3266 class TransformFeedbackBuiltin : public SimpleShaders
3267 {
Title()3268 virtual std::string Title()
3269 {
3270 return "Transform Feedback Built-in Variables";
3271 }
3272
ShadersDesc()3273 virtual std::string ShadersDesc()
3274 {
3275 return "fallthrough fragment and vertex shaders with different types of out variables used";
3276 }
3277
PurposeExt()3278 virtual std::string PurposeExt()
3279 {
3280 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param with"
3281 " built-in variables (gl_NextBuffer, gl_SkipComponents) used.\n";
3282 }
3283
VertexShader()3284 virtual std::string VertexShader()
3285 {
3286 return "#version 430 \n"
3287 "in vec4 position; \n"
3288 ""
3289 "out ivec4 a; \n"
3290 "out uvec2 c; \n"
3291 "out uint d; \n"
3292 "out int f; \n"
3293 "out uint e; \n"
3294 "out int g; \n"
3295 ""
3296 "void main(void) \n"
3297 "{ \n"
3298 " vec4 pos; \n"
3299 " a = ivec4(1); \n"
3300 " c = uvec2(1u); \n"
3301 " d = 1u; \n"
3302 " f = 1; \n"
3303 " e = 1u; \n"
3304 " g = 1; \n"
3305 " gl_Position = position; \n"
3306 "}";
3307 }
3308
Run()3309 virtual long Run()
3310 {
3311 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3312 glBindAttribLocation(program, 0, "position");
3313 glBindFragDataLocation(program, 0, "color");
3314 const char *varyings[11] = {"a", "gl_NextBuffer", "c", "gl_SkipComponents1", "d", "gl_SkipComponents2",
3315 "f", "gl_SkipComponents3", "e", "gl_SkipComponents4", "g"};
3316 glTransformFeedbackVaryings(program, 11, varyings, GL_INTERLEAVED_ATTRIBS);
3317 LinkProgram(program);
3318
3319 long error = NO_ERROR;
3320
3321 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 11, error);
3322 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 19, error);
3323
3324 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_NextBuffer", GL_INVALID_INDEX, error);
3325 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents1", GL_INVALID_INDEX,
3326 error);
3327 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents2", GL_INVALID_INDEX,
3328 error);
3329 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents3", GL_INVALID_INDEX,
3330 error);
3331 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents4", GL_INVALID_INDEX,
3332 error);
3333
3334 std::map<std::string, GLuint> indices;
3335 for (int i = 0; i < 11; i++)
3336 {
3337 GLsizei length;
3338 GLchar name[1024] = {'\0'};
3339 glGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, i, 1024, &length, name);
3340 indices[name] = i;
3341 }
3342
3343 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Indices of builtins:\n"
3344 << indices["gl_NextBuffer"] << ", " << indices["gl_SkipComponents1"] << ", "
3345 << indices["gl_SkipComponents2"] << ", " << indices["gl_SkipComponents3"]
3346 << ", " << indices["gl_SkipComponents4"] << tcu::TestLog::EndMessage;
3347
3348 GLenum props[] = {GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE};
3349 GLint expected[] = {14, GL_NONE, 0};
3350 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_NextBuffer"], 3, props, 3,
3351 expected, error);
3352 GLint expected2[] = {19, GL_NONE, 1};
3353 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents1"], 3, props, 3,
3354 expected2, error);
3355 GLint expected3[] = {19, GL_NONE, 2};
3356 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents2"], 3, props, 3,
3357 expected3, error);
3358 GLint expected4[] = {19, GL_NONE, 3};
3359 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents3"], 3, props, 3,
3360 expected4, error);
3361 GLint expected5[] = {19, GL_NONE, 4};
3362 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents4"], 3, props, 3,
3363 expected5, error);
3364
3365 glDeleteProgram(program);
3366 return error;
3367 }
3368 };
3369
3370 class NullLength : public SimpleShaders
3371 {
3372
Title()3373 virtual std::string Title()
3374 {
3375 return "NULL Length Test";
3376 }
3377
PurposeExt()3378 virtual std::string PurposeExt()
3379 {
3380 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
3381 "crash).\n";
3382 }
3383
VertexShader()3384 virtual std::string VertexShader()
3385 {
3386 return "#version 430 \n"
3387 "in vec4 position; \n"
3388 "void main(void) \n"
3389 "{ \n"
3390 " gl_Position = position; \n"
3391 "}";
3392 }
3393
FragmentShader()3394 virtual std::string FragmentShader()
3395 {
3396 return "#version 430 \n"
3397 "out vec4 color; \n"
3398 "void main() { \n"
3399 " color = vec4(0, 1, 0, 1); \n"
3400 "}";
3401 }
3402
Run()3403 virtual long Run()
3404 {
3405 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3406 glBindAttribLocation(program, 0, "position");
3407 glBindFragDataLocation(program, 0, "color");
3408 LinkProgram(program);
3409
3410 GLchar name[1024] = {'\0'};
3411 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
3412 GLenum prop = GL_ARRAY_SIZE;
3413 GLint res;
3414 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
3415 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
3416
3417 std::string expected = "color";
3418 if (name != expected)
3419 {
3420 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
3421 << ", got: " << name << tcu::TestLog::EndMessage;
3422 glDeleteProgram(program);
3423 return ERROR;
3424 }
3425 else if (res != 1)
3426 {
3427 m_context.getTestContext().getLog()
3428 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
3429 glDeleteProgram(program);
3430 return ERROR;
3431 }
3432
3433 glDeleteProgram(program);
3434 return NO_ERROR;
3435 }
3436 };
3437
3438 class ArraysOfArrays : public SimpleShaders
3439 {
3440
Title()3441 virtual std::string Title()
3442 {
3443 return "Arrays Of Arrays Test";
3444 }
3445
ShadersDesc()3446 virtual std::string ShadersDesc()
3447 {
3448 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
3449 }
3450
PurposeExt()3451 virtual std::string PurposeExt()
3452 {
3453 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays extension.\n";
3454 }
3455
VertexShader()3456 virtual std::string VertexShader()
3457 {
3458 return "#version 430 \n"
3459 "in vec4 position; \n"
3460 "uniform vec4 a[3][4][5]; \n"
3461 "void main(void) \n"
3462 "{ \n"
3463 " gl_Position = position; \n"
3464 " for (int i = 0; i < 5; ++i) \n"
3465 " gl_Position += a[2][1][i]; \n"
3466 "}";
3467 }
3468
FragmentShader()3469 virtual std::string FragmentShader()
3470 {
3471 return "#version 430 \n"
3472 "out vec4 color; \n"
3473 "void main() { \n"
3474 " color = vec4(0, 1, 0, 1); \n"
3475 "}";
3476 }
3477
Run()3478 virtual long Run()
3479 {
3480 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3481 glBindAttribLocation(program, 0, "position");
3482 glBindFragDataLocation(program, 0, "color");
3483 LinkProgram(program);
3484
3485 long error = NO_ERROR;
3486
3487 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
3488
3489 std::map<std::string, GLuint> indices;
3490 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
3491 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
3492
3493 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
3494
3495 GLenum props[] = {GL_NAME_LENGTH,
3496 GL_TYPE,
3497 GL_ARRAY_SIZE,
3498 GL_OFFSET,
3499 GL_BLOCK_INDEX,
3500 GL_ARRAY_STRIDE,
3501 GL_MATRIX_STRIDE,
3502 GL_IS_ROW_MAJOR,
3503 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3504 GL_REFERENCED_BY_COMPUTE_SHADER,
3505 GL_REFERENCED_BY_FRAGMENT_SHADER,
3506 GL_REFERENCED_BY_GEOMETRY_SHADER,
3507 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3508 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3509 GL_REFERENCED_BY_VERTEX_SHADER,
3510 GL_LOCATION};
3511 GLint expected[] = {
3512 11, GL_FLOAT_VEC4, 5, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a[2][1]")};
3513 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 16, props, 16, expected, error);
3514
3515 glDeleteProgram(program);
3516 return error;
3517 }
3518 };
3519
3520 class TopLevelArray : public SimpleShaders
3521 {
3522
Title()3523 virtual std::string Title()
3524 {
3525 return "Top Level Array Test";
3526 }
3527
ShadersDesc()3528 virtual std::string ShadersDesc()
3529 {
3530 return "fallthrough fragment and vertex shaders with multi dimensional array used inside storage block";
3531 }
3532
PurposeExt()3533 virtual std::string PurposeExt()
3534 {
3535 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
3536 " and GL_TOP_LEVEL_ARRAY_STRIDE extension.\n";
3537 }
3538
FragmentShader()3539 virtual std::string FragmentShader()
3540 {
3541 return "#version 430 \n"
3542 "buffer Block { \n"
3543 " vec4 a[5][4][3]; \n"
3544 "}; \n"
3545 "out vec4 color; \n"
3546 "void main() { \n"
3547 " color = vec4(0, 1, 0, 1) + a[0][0][0]; \n"
3548 "}";
3549 }
3550
Run()3551 virtual long Run()
3552 {
3553 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3554 glBindAttribLocation(program, 0, "position");
3555 glBindFragDataLocation(program, 0, "color");
3556 LinkProgram(program);
3557
3558 long error = NO_ERROR;
3559
3560 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
3561 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
3562 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
3563
3564 std::map<std::string, GLuint> indicesSSB;
3565 std::map<std::string, GLuint> indicesBV;
3566 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
3567 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
3568
3569 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
3570 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
3571
3572 GLenum props3[] = {GL_NAME_LENGTH,
3573 GL_TYPE,
3574 GL_ARRAY_SIZE,
3575 GL_BLOCK_INDEX,
3576 GL_IS_ROW_MAJOR,
3577 GL_REFERENCED_BY_COMPUTE_SHADER,
3578 GL_REFERENCED_BY_FRAGMENT_SHADER,
3579 GL_REFERENCED_BY_GEOMETRY_SHADER,
3580 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3581 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3582 GL_REFERENCED_BY_VERTEX_SHADER,
3583 GL_TOP_LEVEL_ARRAY_SIZE};
3584 GLint expected5[] = {11, GL_FLOAT_VEC4, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 0, 1, 0, 0, 0, 0, 5};
3585 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 12, props3, 12, expected5, error);
3586
3587 GLenum prop = GL_TOP_LEVEL_ARRAY_STRIDE;
3588 GLsizei len;
3589 GLint res;
3590 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
3591 if (res <= 0)
3592 {
3593 m_context.getTestContext().getLog()
3594 << tcu::TestLog::Message
3595 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
3596 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
3597 glDeleteProgram(program);
3598 return ERROR;
3599 }
3600
3601 glDeleteProgram(program);
3602 return error;
3603 }
3604 };
3605
3606 class SeparateProgramsVertex : public SimpleShaders
3607 {
3608 public:
Title()3609 virtual std::string Title()
3610 {
3611 return "Separate Program Vertex Shader Test";
3612 }
3613
ShadersDesc()3614 virtual std::string ShadersDesc()
3615 {
3616 return "vertex shader as separate shader object";
3617 }
3618
PurposeExt()3619 virtual std::string PurposeExt()
3620 {
3621 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3622 "functionality.\n";
3623 }
3624
CreateShaderProgram(GLenum type,GLsizei count,const GLchar ** strings)3625 virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar **strings)
3626 {
3627 GLuint program = glCreateShaderProgramv(type, count, strings);
3628 GLint status = GL_TRUE;
3629 glGetProgramiv(program, GL_LINK_STATUS, &status);
3630 if (status == GL_FALSE)
3631 {
3632 GLsizei length;
3633 GLchar log[1024];
3634 glGetProgramInfoLog(program, sizeof(log), &length, log);
3635 if (length > 1)
3636 {
3637 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
3638 << log << tcu::TestLog::EndMessage;
3639 }
3640 }
3641 return program;
3642 }
3643
Run()3644 virtual long Run()
3645 {
3646 long error = NO_ERROR;
3647
3648 const char *srcVS = "#version 430 core \n"
3649 "layout(location = 0) in vec4 in_vertex; \n"
3650 ""
3651 "out Color { \n"
3652 " float r, g, b; \n"
3653 " vec4 iLikePie; \n"
3654 "} vs_color; \n"
3655 "out gl_PerVertex { \n"
3656 " vec4 gl_Position; \n"
3657 "}; \n"
3658 ""
3659 "uniform float u; \n"
3660 "uniform vec4 v; \n"
3661 ""
3662 "void main() { \n"
3663 " gl_Position = in_vertex; \n"
3664 " vs_color.r = u; \n"
3665 " vs_color.g = 0.0; \n"
3666 " vs_color.b = 0.0; \n"
3667 " vs_color.iLikePie = v; \n"
3668 "}";
3669
3670 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
3671
3672 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
3673 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
3674 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
3675 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3676 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 15, error);
3677 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
3678
3679 std::map<std::string, GLuint> indicesU;
3680 std::map<std::string, GLuint> indicesI;
3681 std::map<std::string, GLuint> indicesO;
3682 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
3683 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
3684 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
3685 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.r", error);
3686 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.g", error);
3687 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.b", error);
3688 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.iLikePie", error);
3689 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3690
3691 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
3692 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
3693 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
3694 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.r"], "Color.r", error);
3695 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.g"], "Color.g", error);
3696 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.b"], "Color.b", error);
3697 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], "Color.iLikePie", error);
3698 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3699
3700 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
3701 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
3702 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
3703
3704 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.r", -1, error);
3705 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.g", -1, error);
3706 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.b", -1, error);
3707 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.iLikePie", -1, error);
3708 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "gl_Position", -1, error);
3709
3710 GLenum props[] = {GL_NAME_LENGTH,
3711 GL_TYPE,
3712 GL_ARRAY_SIZE,
3713 GL_OFFSET,
3714 GL_BLOCK_INDEX,
3715 GL_ARRAY_STRIDE,
3716 GL_MATRIX_STRIDE,
3717 GL_IS_ROW_MAJOR,
3718 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3719 GL_REFERENCED_BY_COMPUTE_SHADER,
3720 GL_REFERENCED_BY_FRAGMENT_SHADER,
3721 GL_REFERENCED_BY_GEOMETRY_SHADER,
3722 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3723 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3724 GL_REFERENCED_BY_VERTEX_SHADER,
3725 GL_LOCATION};
3726 GLint expected[] = {
3727 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(vs, "v")};
3728 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 16, props, 16, expected, error);
3729
3730 GLenum props2[] = {GL_NAME_LENGTH,
3731 GL_TYPE,
3732 GL_ARRAY_SIZE,
3733 GL_REFERENCED_BY_COMPUTE_SHADER,
3734 GL_REFERENCED_BY_FRAGMENT_SHADER,
3735 GL_REFERENCED_BY_GEOMETRY_SHADER,
3736 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3737 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3738 GL_REFERENCED_BY_VERTEX_SHADER,
3739 GL_LOCATION,
3740 GL_IS_PER_PATCH};
3741 GLint expected2[] = {10, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0};
3742 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 11, props2, 11, expected2, error);
3743
3744 GLenum props3[] = {GL_NAME_LENGTH,
3745 GL_TYPE,
3746 GL_ARRAY_SIZE,
3747 GL_REFERENCED_BY_COMPUTE_SHADER,
3748 GL_REFERENCED_BY_FRAGMENT_SHADER,
3749 GL_REFERENCED_BY_GEOMETRY_SHADER,
3750 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3751 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3752 GL_REFERENCED_BY_VERTEX_SHADER,
3753 GL_IS_PER_PATCH,
3754 GL_LOCATION_INDEX};
3755 GLint expected3[] = {15, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, -1};
3756 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], 11, props3, 11, expected3, error);
3757
3758 glDeleteProgram(vs);
3759 return error;
3760 }
3761 };
3762
3763 class SeparateProgramsTessControl : public SeparateProgramsVertex
3764 {
3765
Title()3766 virtual std::string Title()
3767 {
3768 return "Separate Program Tess Control Shader Test";
3769 }
3770
ShadersDesc()3771 virtual std::string ShadersDesc()
3772 {
3773 return "tess control shader as separate shader object";
3774 }
3775
PurposeExt()3776 virtual std::string PurposeExt()
3777 {
3778 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3779 "functionality.\n";
3780 }
3781
Run()3782 virtual long Run()
3783 {
3784 long error = NO_ERROR;
3785
3786 const char *srcTCS = "#version 430 \n"
3787 "layout(vertices = 3) out; \n"
3788 "layout(location = 0) patch out vec4 data; \n"
3789 "out gl_PerVertex { \n"
3790 " vec4 gl_Position; \n"
3791 " float gl_PointSize; \n"
3792 " float gl_ClipDistance[]; \n"
3793 "} gl_out[]; \n"
3794 ""
3795 "in Color { \n"
3796 " float r, g, b; \n"
3797 " vec4 iLikePie; \n"
3798 "} vs_color[]; \n"
3799 ""
3800 "void main() { \n"
3801 " data = vec4(1); \n"
3802 " gl_out[gl_InvocationID].gl_Position = \n"
3803 " vec4(vs_color[0].r, vs_color[0].g, vs_color[0].b, vs_color[0].iLikePie.x + "
3804 "float(gl_InvocationID)); \n"
3805 " gl_TessLevelInner[0] = 1.0; \n"
3806 " gl_TessLevelInner[1] = 1.0; \n"
3807 " gl_TessLevelOuter[0] = 1.0; \n"
3808 " gl_TessLevelOuter[1] = 1.0; \n"
3809 " gl_TessLevelOuter[2] = 1.0; \n"
3810 "}";
3811
3812 const GLuint tcs = CreateShaderProgram(GL_TESS_CONTROL_SHADER, 1, &srcTCS);
3813
3814 // gl_InvocationID should be included
3815 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 16, error);
3816 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 5, error);
3817
3818 std::map<std::string, GLuint> indicesI;
3819 std::map<std::string, GLuint> indicesO;
3820 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_PerVertex.gl_Position", error);
3821 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "data", error);
3822 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.r", error);
3823 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.g", error);
3824 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.b", error);
3825 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.iLikePie", error);
3826
3827 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_PerVertex.gl_Position"],
3828 "gl_PerVertex.gl_Position", error);
3829 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], "data", error);
3830 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.r"], "Color.r", error);
3831 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.g"], "Color.g", error);
3832 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.b"], "Color.b", error);
3833 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], "Color.iLikePie", error);
3834
3835 GLenum props2[] = {GL_NAME_LENGTH,
3836 GL_TYPE,
3837 GL_ARRAY_SIZE,
3838 GL_REFERENCED_BY_COMPUTE_SHADER,
3839 GL_REFERENCED_BY_FRAGMENT_SHADER,
3840 GL_REFERENCED_BY_GEOMETRY_SHADER,
3841 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3842 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3843 GL_REFERENCED_BY_VERTEX_SHADER,
3844 GL_IS_PER_PATCH};
3845 GLint expected2[] = {15, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 0};
3846 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], 10, props2, 10, expected2, error);
3847
3848 GLenum props3[] = {GL_NAME_LENGTH,
3849 GL_TYPE,
3850 GL_ARRAY_SIZE,
3851 GL_REFERENCED_BY_COMPUTE_SHADER,
3852 GL_REFERENCED_BY_FRAGMENT_SHADER,
3853 GL_REFERENCED_BY_GEOMETRY_SHADER,
3854 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3855 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3856 GL_REFERENCED_BY_VERTEX_SHADER,
3857 GL_IS_PER_PATCH,
3858 GL_LOCATION,
3859 GL_LOCATION_INDEX};
3860 GLint expected3[] = {5, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 1, 0, -1};
3861 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], 12, props3, 12, expected3, error);
3862
3863 glDeleteProgram(tcs);
3864 return error;
3865 }
3866 };
3867
3868 class SeparateProgramsTessEval : public SeparateProgramsVertex
3869 {
3870
Title()3871 virtual std::string Title()
3872 {
3873 return "Separate Program Tess Eval Shader Test";
3874 }
3875
ShadersDesc()3876 virtual std::string ShadersDesc()
3877 {
3878 return "tess eval shader as separate shader object";
3879 }
3880
Run()3881 virtual long Run()
3882 {
3883 long error = NO_ERROR;
3884
3885 const char *srcTCS = "#version 430 \n"
3886 "layout(quads, equal_spacing, ccw) in; \n"
3887 "out gl_PerVertex { \n"
3888 " vec4 gl_Position; \n"
3889 " float gl_PointSize; \n"
3890 " float gl_ClipDistance[]; \n"
3891 "}; \n"
3892 ""
3893 "in gl_PerVertex { \n"
3894 " vec4 gl_Position; \n"
3895 " float gl_PointSize; \n"
3896 " float gl_ClipDistance[]; \n"
3897 "} gl_in[]; \n"
3898 ""
3899 "void main() { \n"
3900 " vec4 p0 = gl_in[0].gl_Position; \n"
3901 " vec4 p1 = gl_in[1].gl_Position; \n"
3902 " vec4 p2 = gl_in[2].gl_Position; \n"
3903 " gl_Position = vec4(p0.x, p1.y, p2.z, p0.x); \n"
3904 "}";
3905
3906 const GLuint tcs = CreateShaderProgram(GL_TESS_EVALUATION_SHADER, 1, &srcTCS);
3907
3908 std::map<std::string, GLuint> indicesI;
3909 std::map<std::string, GLuint> indicesO;
3910 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
3911 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3912
3913 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
3914 "gl_PerVertex.gl_Position", error);
3915 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3916
3917 GLenum props2[] = {GL_NAME_LENGTH,
3918 GL_TYPE,
3919 GL_ARRAY_SIZE,
3920 GL_REFERENCED_BY_COMPUTE_SHADER,
3921 GL_REFERENCED_BY_FRAGMENT_SHADER,
3922 GL_REFERENCED_BY_GEOMETRY_SHADER,
3923 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3924 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3925 GL_REFERENCED_BY_VERTEX_SHADER,
3926 GL_IS_PER_PATCH};
3927 GLint expected2[] = {25, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0};
3928 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
3929 expected2, error);
3930
3931 GLenum props3[] = {GL_NAME_LENGTH,
3932 GL_TYPE,
3933 GL_ARRAY_SIZE,
3934 GL_REFERENCED_BY_COMPUTE_SHADER,
3935 GL_REFERENCED_BY_FRAGMENT_SHADER,
3936 GL_REFERENCED_BY_GEOMETRY_SHADER,
3937 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3938 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3939 GL_REFERENCED_BY_VERTEX_SHADER,
3940 GL_IS_PER_PATCH,
3941 GL_LOCATION_INDEX};
3942 GLint expected3[] = {12, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0, -1};
3943 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
3944
3945 glDeleteProgram(tcs);
3946 return error;
3947 }
3948 };
3949
3950 class SeparateProgramsGeometry : public SeparateProgramsVertex
3951 {
3952
Title()3953 virtual std::string Title()
3954 {
3955 return "Separate Program Geometry Shader Test";
3956 }
3957
ShadersDesc()3958 virtual std::string ShadersDesc()
3959 {
3960 return "geometry shader as separate shader object";
3961 }
3962
Run()3963 virtual long Run()
3964 {
3965 long error = NO_ERROR;
3966
3967 const char *srcTCS = "#version 430 \n"
3968 "layout(triangles) in; \n"
3969 "layout(triangle_strip, max_vertices = 4) out; \n"
3970 ""
3971 "out gl_PerVertex { \n"
3972 " vec4 gl_Position; \n"
3973 " float gl_PointSize; \n"
3974 " float gl_ClipDistance[]; \n"
3975 "}; \n"
3976 ""
3977 "in gl_PerVertex { \n"
3978 " vec4 gl_Position; \n"
3979 " float gl_PointSize; \n"
3980 " float gl_ClipDistance[]; \n"
3981 "} gl_in[]; \n"
3982 ""
3983 "void main() { \n"
3984 " gl_Position = vec4(-1, 1, 0, 1); \n"
3985 " EmitVertex(); \n"
3986 " gl_Position = vec4(-1, -1, 0, 1); \n"
3987 " EmitVertex(); \n"
3988 " gl_Position = vec4(1, 1, 0, 1); \n"
3989 " EmitVertex(); \n"
3990 " gl_Position = gl_in[0].gl_Position; \n"
3991 " EmitVertex(); \n"
3992 " EndPrimitive(); \n"
3993 "}";
3994
3995 const GLuint tcs = CreateShaderProgram(GL_GEOMETRY_SHADER, 1, &srcTCS);
3996
3997 std::map<std::string, GLuint> indicesI;
3998 std::map<std::string, GLuint> indicesO;
3999 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
4000 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
4001
4002 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
4003 "gl_PerVertex.gl_Position", error);
4004 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
4005
4006 GLenum props2[] = {GL_NAME_LENGTH,
4007 GL_TYPE,
4008 GL_ARRAY_SIZE,
4009 GL_REFERENCED_BY_COMPUTE_SHADER,
4010 GL_REFERENCED_BY_FRAGMENT_SHADER,
4011 GL_REFERENCED_BY_GEOMETRY_SHADER,
4012 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4013 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4014 GL_REFERENCED_BY_VERTEX_SHADER,
4015 GL_IS_PER_PATCH};
4016 GLint expected2[] = {25, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0};
4017 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
4018 expected2, error);
4019
4020 GLenum props3[] = {GL_NAME_LENGTH,
4021 GL_TYPE,
4022 GL_ARRAY_SIZE,
4023 GL_REFERENCED_BY_COMPUTE_SHADER,
4024 GL_REFERENCED_BY_FRAGMENT_SHADER,
4025 GL_REFERENCED_BY_GEOMETRY_SHADER,
4026 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4027 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4028 GL_REFERENCED_BY_VERTEX_SHADER,
4029 GL_IS_PER_PATCH,
4030 GL_LOCATION_INDEX};
4031 GLint expected3[] = {12, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0, -1};
4032 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
4033
4034 glDeleteProgram(tcs);
4035 return error;
4036 }
4037 };
4038
4039 class SeparateProgramsFragment : public SeparateProgramsVertex
4040 {
4041
Title()4042 virtual std::string Title()
4043 {
4044 return "Separate Program Fragment Shader Test";
4045 }
4046
ShadersDesc()4047 virtual std::string ShadersDesc()
4048 {
4049 return "fragment shader as separate shader object";
4050 }
4051
Run()4052 virtual long Run()
4053 {
4054 long error = NO_ERROR;
4055
4056 const char *srcTCS = "#version 430 \n"
4057 "out vec4 fs_color; \n"
4058 ""
4059 "layout(location = 1) uniform vec4 x; \n"
4060 ""
4061 "layout(binding = 0) buffer SimpleBuffer { \n"
4062 " vec4 a; \n"
4063 "}; \n"
4064 ""
4065 "in vec4 vs_color; \n"
4066 "void main() { \n"
4067 " fs_color = vs_color + x + a; \n"
4068 "}";
4069
4070 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
4071
4072 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4073 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4074 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
4075 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4076 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
4077 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
4078 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 2, error);
4079 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4080 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4081 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 13, error);
4082 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4083
4084 std::map<std::string, GLuint> indicesSSB;
4085 std::map<std::string, GLuint> indicesBV;
4086 std::map<std::string, GLuint> indicesI;
4087 std::map<std::string, GLuint> indicesO;
4088 std::map<std::string, GLuint> indicesU;
4089 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
4090 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
4091 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
4092 VerifyGetProgramResourceIndex(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
4093 VerifyGetProgramResourceIndex(tcs, GL_BUFFER_VARIABLE, indicesBV, "a", error);
4094
4095 VerifyGetProgramResourceName(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer", error);
4096 VerifyGetProgramResourceName(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
4097 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
4098 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
4099 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
4100
4101 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
4102
4103 GLenum props2[] = {GL_NAME_LENGTH,
4104 GL_TYPE,
4105 GL_ARRAY_SIZE,
4106 GL_REFERENCED_BY_COMPUTE_SHADER,
4107 GL_REFERENCED_BY_FRAGMENT_SHADER,
4108 GL_REFERENCED_BY_GEOMETRY_SHADER,
4109 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4110 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4111 GL_REFERENCED_BY_VERTEX_SHADER,
4112 GL_IS_PER_PATCH};
4113 GLint expected2[] = {9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0};
4114 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 10, props2, 10, expected2, error);
4115
4116 GLenum props3[] = {GL_NAME_LENGTH,
4117 GL_TYPE,
4118 GL_ARRAY_SIZE,
4119 GL_REFERENCED_BY_COMPUTE_SHADER,
4120 GL_REFERENCED_BY_FRAGMENT_SHADER,
4121 GL_REFERENCED_BY_GEOMETRY_SHADER,
4122 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4123 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4124 GL_REFERENCED_BY_VERTEX_SHADER,
4125 GL_IS_PER_PATCH,
4126 GL_LOCATION_INDEX};
4127 GLint expected3[] = {9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0};
4128 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 11, props3, 11, expected3, error);
4129
4130 GLenum props5[] = {GL_NAME_LENGTH,
4131 GL_TYPE,
4132 GL_ARRAY_SIZE,
4133 GL_OFFSET,
4134 GL_BLOCK_INDEX,
4135 GL_ARRAY_STRIDE,
4136 GL_MATRIX_STRIDE,
4137 GL_IS_ROW_MAJOR,
4138 GL_ATOMIC_COUNTER_BUFFER_INDEX,
4139 GL_REFERENCED_BY_COMPUTE_SHADER,
4140 GL_REFERENCED_BY_FRAGMENT_SHADER,
4141 GL_REFERENCED_BY_VERTEX_SHADER,
4142 GL_LOCATION};
4143 GLint expected5[] = {2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1};
4144 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props5, 13, expected5, error);
4145
4146 GLenum props6[] = {GL_NAME_LENGTH,
4147 GL_BUFFER_BINDING,
4148 GL_NUM_ACTIVE_VARIABLES,
4149 GL_REFERENCED_BY_COMPUTE_SHADER,
4150 GL_REFERENCED_BY_FRAGMENT_SHADER,
4151 GL_REFERENCED_BY_VERTEX_SHADER,
4152 GL_ACTIVE_VARIABLES};
4153 GLint expected6[] = {13, 0, 1, 0, 1, 0, static_cast<GLint>(indicesBV["a"])};
4154 VerifyGetProgramResourceiv(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 7, props6, 7, expected6,
4155 error);
4156
4157 GLenum props7[] = {GL_NAME_LENGTH,
4158 GL_TYPE,
4159 GL_ARRAY_SIZE,
4160 GL_BLOCK_INDEX,
4161 GL_ARRAY_STRIDE,
4162 GL_IS_ROW_MAJOR,
4163 GL_REFERENCED_BY_COMPUTE_SHADER,
4164 GL_REFERENCED_BY_FRAGMENT_SHADER,
4165 GL_REFERENCED_BY_VERTEX_SHADER,
4166 GL_TOP_LEVEL_ARRAY_SIZE,
4167 GL_TOP_LEVEL_ARRAY_STRIDE};
4168 GLint expected7[] = {2, GL_FLOAT_VEC4, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 1, 0};
4169 VerifyGetProgramResourceiv(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props7, 11, expected7, error);
4170
4171 glDeleteProgram(tcs);
4172 return error;
4173 }
4174 };
4175
4176 class UniformBlockAdvanced : public SimpleShaders
4177 {
Title()4178 virtual std::string Title()
4179 {
4180 return "Uniform Block Advanced Test";
4181 }
4182
ShadersDesc()4183 virtual std::string ShadersDesc()
4184 {
4185 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
4186 }
4187
PurposeExt()4188 virtual std::string PurposeExt()
4189 {
4190 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
4191 "verify results of querying offset, strides and row order.\n";
4192 }
4193
VertexShader()4194 virtual std::string VertexShader()
4195 {
4196 return "#version 430 \n"
4197 "in vec4 position; \n"
4198 ""
4199 "layout(row_major) uniform SimpleBlock { \n"
4200 " mat4 a; \n"
4201 " vec4 b[10]; \n"
4202 "}; \n"
4203 "void main(void) \n"
4204 "{ \n"
4205 " float tmp; \n"
4206 " tmp = a[0][0] + b[0].x; \n"
4207 " gl_Position = position * tmp; \n"
4208 "}";
4209 }
4210
Run()4211 virtual long Run()
4212 {
4213 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4214 glBindAttribLocation(program, 0, "position");
4215 glBindFragDataLocation(program, 0, "color");
4216 LinkProgram(program);
4217
4218 long error = NO_ERROR;
4219
4220 std::map<std::string, GLuint> indicesU;
4221 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
4222 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
4223
4224 GLenum props[] = {GL_IS_ROW_MAJOR};
4225 GLint expected[] = {1};
4226 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
4227
4228 GLenum prop = GL_MATRIX_STRIDE;
4229 GLsizei len;
4230 GLint res;
4231 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4232 if (res < 1)
4233 {
4234 m_context.getTestContext().getLog()
4235 << tcu::TestLog::Message
4236 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
4237 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4238 }
4239 prop = GL_OFFSET;
4240 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4241 if (res < 0)
4242 {
4243 m_context.getTestContext().getLog()
4244 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
4245 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
4246 }
4247 prop = GL_ARRAY_STRIDE;
4248 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
4249 if (res < 1)
4250 {
4251 m_context.getTestContext().getLog()
4252 << tcu::TestLog::Message
4253 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
4254 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4255 }
4256
4257 glDeleteProgram(program);
4258 return error;
4259 }
4260 };
4261
4262 class ArrayNames : public SimpleShaders
4263 {
4264
Title()4265 virtual std::string Title()
4266 {
4267 return "Array Names Test";
4268 }
4269
ShadersDesc()4270 virtual std::string ShadersDesc()
4271 {
4272 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
4273 }
4274
PurposeExt()4275 virtual std::string PurposeExt()
4276 {
4277 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
4278 "name strings correctly.\n";
4279 }
4280
VertexShader()4281 virtual std::string VertexShader()
4282 {
4283 return "#version 430 \n"
4284 "in vec4 position; \n"
4285 ""
4286 "uniform vec4 a[2]; \n"
4287 ""
4288 "void main(void) \n"
4289 "{ \n"
4290 " gl_Position = position + a[0] + a[1]; \n"
4291 "}";
4292 }
4293
Run()4294 virtual long Run()
4295 {
4296 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4297 glBindAttribLocation(program, 0, "position");
4298 LinkProgram(program);
4299
4300 long error = NO_ERROR;
4301
4302 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
4303 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
4304 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
4305 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
4306 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
4307 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
4308 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
4309 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
4310 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
4311 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
4312 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
4313 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
4314
4315 glDeleteProgram(program);
4316 return error;
4317 }
4318 };
4319
4320 class BuffLength : public SimpleShaders
4321 {
4322
Title()4323 virtual std::string Title()
4324 {
4325 return "Buff Length Test";
4326 }
4327
ShadersDesc()4328 virtual std::string ShadersDesc()
4329 {
4330 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
4331 }
4332
PurposeExt()4333 virtual std::string PurposeExt()
4334 {
4335 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
4336 "GetProgramResourceiv is respected.\n";
4337 }
4338
VertexShader()4339 virtual std::string VertexShader()
4340 {
4341 return "#version 430 \n"
4342 "in vec4 position; \n"
4343 ""
4344 "uniform vec4 someLongName; \n"
4345 ""
4346 "void main(void) \n"
4347 "{ \n"
4348 " gl_Position = position + someLongName; \n"
4349 "}";
4350 }
4351
Run()4352 virtual long Run()
4353 {
4354 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4355 glBindAttribLocation(program, 0, "position");
4356 LinkProgram(program);
4357
4358 long error = NO_ERROR;
4359
4360 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
4361 GLsizei length;
4362 GLchar buff[3] = {'a', 'b', 'c'};
4363 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
4364 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
4365 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
4366 {
4367 m_context.getTestContext().getLog()
4368 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
4369 error = ERROR;
4370 }
4371 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
4372 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
4373 {
4374 m_context.getTestContext().getLog()
4375 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
4376 error = ERROR;
4377 }
4378 if (length != 1)
4379 {
4380 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
4381 << length << tcu::TestLog::EndMessage;
4382 error = ERROR;
4383 }
4384
4385 GLint params[3] = {1, 2, 3};
4386 GLenum props[] = {GL_NAME_LENGTH,
4387 GL_TYPE,
4388 GL_ARRAY_SIZE,
4389 GL_OFFSET,
4390 GL_BLOCK_INDEX,
4391 GL_ARRAY_STRIDE,
4392 GL_MATRIX_STRIDE,
4393 GL_IS_ROW_MAJOR,
4394 GL_ATOMIC_COUNTER_BUFFER_INDEX,
4395 GL_REFERENCED_BY_COMPUTE_SHADER,
4396 GL_REFERENCED_BY_FRAGMENT_SHADER,
4397 GL_REFERENCED_BY_VERTEX_SHADER,
4398 GL_LOCATION};
4399 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
4400 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
4401 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
4402 {
4403 m_context.getTestContext().getLog()
4404 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
4405 error = ERROR;
4406 }
4407 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
4408 if (params[0] != 13 || params[1] != GL_FLOAT_VEC4 || params[2] != 3)
4409 {
4410 m_context.getTestContext().getLog()
4411 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
4412 error = ERROR;
4413 }
4414 if (length != 2)
4415 {
4416 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
4417 << length << tcu::TestLog::EndMessage;
4418 error = ERROR;
4419 }
4420
4421 glDeleteProgram(program);
4422 return error;
4423 }
4424 };
4425
4426 class NoLocations : public SimpleShaders
4427 {
4428
Title()4429 virtual std::string Title()
4430 {
4431 return "No Locations Test";
4432 }
4433
ShadersDesc()4434 virtual std::string ShadersDesc()
4435 {
4436 return "fragment and vertex shaders with no locations set";
4437 }
4438
VertexShader()4439 virtual std::string VertexShader()
4440 {
4441 return "#version 430 \n"
4442 "in vec4 a; \n"
4443 "in vec4 b; \n"
4444 "in vec4 c[1]; \n"
4445 "in vec4 d; \n"
4446 "void main(void) \n"
4447 "{ \n"
4448 " gl_Position = a + b + c[0] + d; \n"
4449 "}";
4450 }
4451
FragmentShader()4452 virtual std::string FragmentShader()
4453 {
4454 return "#version 430 \n"
4455 "out vec4 a; \n"
4456 "out vec4 b; \n"
4457 "out vec4 c; \n"
4458 "out vec4 d[1]; \n"
4459 "void main() { \n"
4460 " a = vec4(0, 1, 0, 1); \n"
4461 " b = vec4(0, 1, 0, 1); \n"
4462 " c = vec4(0, 1, 0, 1); \n"
4463 " d[0] = vec4(0, 1, 0, 1); \n"
4464 "}";
4465 }
4466
Run()4467 virtual long Run()
4468 {
4469 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4470 glBindAttribLocation(program, 0, "position");
4471 glLinkProgram(program);
4472
4473 long error = NO_ERROR;
4474
4475 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
4476 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
4477 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
4478 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
4479
4480 std::map<std::string, GLuint> indicesI;
4481 std::map<std::string, GLuint> indicesO;
4482 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
4483 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
4484 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
4485 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
4486 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
4487 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
4488 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
4489 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
4490
4491 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
4492 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
4493 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c[0]", error);
4494 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
4495 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
4496 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
4497 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
4498 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
4499
4500 std::map<std::string, GLint> locationsI;
4501 std::map<std::string, GLint> locationsO;
4502 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
4503 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
4504 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
4505 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
4506 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
4507 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
4508 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
4509 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
4510
4511 GLenum props[] = {GL_NAME_LENGTH,
4512 GL_TYPE,
4513 GL_ARRAY_SIZE,
4514 GL_REFERENCED_BY_COMPUTE_SHADER,
4515 GL_REFERENCED_BY_FRAGMENT_SHADER,
4516 GL_REFERENCED_BY_VERTEX_SHADER};
4517 GLint expected[] = {2, GL_FLOAT_VEC4, 1, 0, 0, 1};
4518 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
4519 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
4520 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
4521 GLint expected2[] = {5, GL_FLOAT_VEC4, 1, 0, 0, 1};
4522 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected2, error);
4523 GLint expected3[] = {2, GL_FLOAT_VEC4, 1, 0, 1, 0};
4524 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
4525 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
4526 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
4527 GLint expected4[] = {5, GL_FLOAT_VEC4, 1, 0, 1, 0};
4528 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
4529
4530 glDeleteProgram(program);
4531 return error;
4532 }
4533 };
4534
4535 class ComputeShaderTest : public PIQBase
4536 {
Title()4537 virtual std::string Title()
4538 {
4539 return "Compute Shader Test";
4540 }
4541
ShadersDesc()4542 virtual std::string ShadersDesc()
4543 {
4544 return "compute shader";
4545 }
4546
ComputeShader()4547 virtual std::string ComputeShader()
4548 {
4549 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
4550 "layout(std430) buffer Output { \n"
4551 " vec4 data[]; \n"
4552 "} g_out; \n"
4553 ""
4554 "void main() { \n"
4555 " g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0); \n"
4556 " g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0); \n"
4557 "}";
4558 }
4559
CreateComputeProgram(const std::string & cs)4560 GLuint CreateComputeProgram(const std::string &cs)
4561 {
4562 const GLuint p = glCreateProgram();
4563
4564 const char *const kGLSLVer = "#version 430 core \n";
4565
4566 if (!cs.empty())
4567 {
4568 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
4569 glAttachShader(p, sh);
4570 glDeleteShader(sh);
4571 const char *const src[2] = {kGLSLVer, cs.c_str()};
4572 glShaderSource(sh, 2, src, NULL);
4573 glCompileShader(sh);
4574 }
4575
4576 return p;
4577 }
4578
CheckProgram(GLuint program,bool * compile_error=NULL)4579 bool CheckProgram(GLuint program, bool *compile_error = NULL)
4580 {
4581 GLint compile_status = GL_TRUE;
4582 GLint status;
4583 glGetProgramiv(program, GL_LINK_STATUS, &status);
4584
4585 if (status == GL_FALSE)
4586 {
4587 GLint attached_shaders;
4588 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
4589
4590 if (attached_shaders > 0)
4591 {
4592 std::vector<GLuint> shaders(attached_shaders);
4593 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
4594
4595 for (GLint i = 0; i < attached_shaders; ++i)
4596 {
4597 GLenum type;
4598 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
4599 switch (type)
4600 {
4601 case GL_VERTEX_SHADER:
4602 m_context.getTestContext().getLog()
4603 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
4604 break;
4605 case GL_TESS_CONTROL_SHADER:
4606 m_context.getTestContext().getLog()
4607 << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
4608 << tcu::TestLog::EndMessage;
4609 break;
4610 case GL_TESS_EVALUATION_SHADER:
4611 m_context.getTestContext().getLog()
4612 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
4613 << tcu::TestLog::EndMessage;
4614 break;
4615 case GL_GEOMETRY_SHADER:
4616 m_context.getTestContext().getLog()
4617 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
4618 break;
4619 case GL_FRAGMENT_SHADER:
4620 m_context.getTestContext().getLog()
4621 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
4622 break;
4623 case GL_COMPUTE_SHADER:
4624 m_context.getTestContext().getLog()
4625 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
4626 break;
4627 default:
4628 m_context.getTestContext().getLog()
4629 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
4630 }
4631
4632 GLint res;
4633 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
4634 if (res != GL_TRUE)
4635 compile_status = res;
4636
4637 // shader source
4638 GLint length;
4639 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
4640 if (length > 0)
4641 {
4642 std::vector<GLchar> source(length);
4643 glGetShaderSource(shaders[i], length, NULL, &source[0]);
4644 m_context.getTestContext().getLog()
4645 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
4646 }
4647
4648 // shader info log
4649 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
4650 if (length > 0)
4651 {
4652 std::vector<GLchar> log(length);
4653 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
4654 m_context.getTestContext().getLog()
4655 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4656 }
4657 }
4658 }
4659
4660 // program info log
4661 GLint length;
4662 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
4663 if (length > 0)
4664 {
4665 std::vector<GLchar> log(length);
4666 glGetProgramInfoLog(program, length, NULL, &log[0]);
4667 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4668 }
4669 }
4670
4671 if (compile_error)
4672 *compile_error = (compile_status == GL_TRUE ? false : true);
4673 if (compile_status != GL_TRUE)
4674 return false;
4675 return status == GL_TRUE ? true : false;
4676 }
4677
VerifyCompute(GLuint program,long & error)4678 virtual void inline VerifyCompute(GLuint program, long &error)
4679 {
4680 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
4681 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4682 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4683 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
4684 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4685
4686 std::map<std::string, GLuint> indicesSSB;
4687 std::map<std::string, GLuint> indicesBV;
4688 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
4689 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
4690
4691 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
4692 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
4693
4694 GLenum props3[] = {GL_NAME_LENGTH,
4695 GL_BUFFER_BINDING,
4696 GL_NUM_ACTIVE_VARIABLES,
4697 GL_REFERENCED_BY_COMPUTE_SHADER,
4698 GL_REFERENCED_BY_FRAGMENT_SHADER,
4699 GL_REFERENCED_BY_VERTEX_SHADER,
4700 GL_ACTIVE_VARIABLES};
4701 GLint expected3[] = {7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"])};
4702 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
4703 error);
4704
4705 GLenum props4[] = {GL_NAME_LENGTH,
4706 GL_TYPE,
4707 GL_ARRAY_SIZE,
4708 GL_BLOCK_INDEX,
4709 GL_IS_ROW_MAJOR,
4710 GL_REFERENCED_BY_COMPUTE_SHADER,
4711 GL_REFERENCED_BY_FRAGMENT_SHADER,
4712 GL_REFERENCED_BY_VERTEX_SHADER,
4713 GL_TOP_LEVEL_ARRAY_SIZE};
4714 GLint expected4[] = {15, GL_FLOAT_VEC4, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1};
4715 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
4716 error);
4717 }
4718
Run()4719 virtual long Run()
4720 {
4721 GLuint program = CreateComputeProgram(ComputeShader());
4722 glLinkProgram(program);
4723 if (!CheckProgram(program))
4724 {
4725 glDeleteProgram(program);
4726 return ERROR;
4727 }
4728 glUseProgram(program);
4729
4730 long error = NO_ERROR;
4731
4732 VerifyCompute(program, error);
4733
4734 glDeleteProgram(program);
4735 return error;
4736 }
4737 };
4738
4739 class QueryNotUsed : public SimpleShaders
4740 {
4741
Title()4742 virtual std::string Title()
4743 {
4744 return "Query Not Used Test";
4745 }
4746
PassCriteria()4747 virtual std::string PassCriteria()
4748 {
4749 return "Data from queries matches the not used program.";
4750 }
4751
Purpose()4752 virtual std::string Purpose()
4753 {
4754 return "Verify that program parameter works correctly and proper program is queried when different program is "
4755 "used.";
4756 }
4757
Method()4758 virtual std::string Method()
4759 {
4760 return "Create 2 programs, use one of them and query the other, verify the results.";
4761 }
4762
VertexShader2()4763 virtual std::string VertexShader2()
4764 {
4765 return "#version 430 \n"
4766 "in vec4 p; \n"
4767 "void main(void) \n"
4768 "{ \n"
4769 " gl_Position = p; \n"
4770 "}";
4771 }
4772
FragmentShader2()4773 virtual std::string FragmentShader2()
4774 {
4775 return "#version 430 \n"
4776 "out vec4 c; \n"
4777 "void main() { \n"
4778 " c = vec4(0, 1, 0, 1); \n"
4779 "}";
4780 }
4781
Run()4782 virtual long Run()
4783 {
4784 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4785 glBindAttribLocation(program, 0, "position");
4786 glBindFragDataLocation(program, 0, "color");
4787 LinkProgram(program);
4788
4789 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
4790 glBindAttribLocation(program, 0, "p");
4791 glBindFragDataLocation(program, 0, "c");
4792 LinkProgram(program2);
4793 glUseProgram(program2);
4794
4795 long error = NO_ERROR;
4796
4797 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4798 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4799 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4800 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
4801
4802 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4803 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
4804
4805 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
4806 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
4807
4808 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
4809 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4810
4811 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4812
4813 GLenum props[] = {GL_NAME_LENGTH,
4814 GL_TYPE,
4815 GL_ARRAY_SIZE,
4816 GL_REFERENCED_BY_COMPUTE_SHADER,
4817 GL_REFERENCED_BY_FRAGMENT_SHADER,
4818 GL_REFERENCED_BY_GEOMETRY_SHADER,
4819 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4820 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4821 GL_REFERENCED_BY_VERTEX_SHADER,
4822 GL_LOCATION,
4823 GL_IS_PER_PATCH};
4824 GLint expected[] = {9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0};
4825 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
4826
4827 GLenum props2[] = {GL_NAME_LENGTH,
4828 GL_TYPE,
4829 GL_ARRAY_SIZE,
4830 GL_REFERENCED_BY_COMPUTE_SHADER,
4831 GL_REFERENCED_BY_FRAGMENT_SHADER,
4832 GL_REFERENCED_BY_GEOMETRY_SHADER,
4833 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4834 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4835 GL_REFERENCED_BY_VERTEX_SHADER,
4836 GL_LOCATION,
4837 GL_IS_PER_PATCH,
4838 GL_LOCATION_INDEX};
4839 GLint expected2[] = {6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0};
4840 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
4841
4842 glDeleteProgram(program);
4843 glDeleteProgram(program2);
4844 return error;
4845 }
4846 };
4847
4848 class RelinkFailure : public SimpleShaders
4849 {
4850
Title()4851 virtual std::string Title()
4852 {
4853 return "Relink Failure Test";
4854 }
4855
PassCriteria()4856 virtual std::string PassCriteria()
4857 {
4858 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4859 }
4860
Purpose()4861 virtual std::string Purpose()
4862 {
4863 return "Verify that queries behave correctly after failed relink of a program.";
4864 }
4865
Method()4866 virtual std::string Method()
4867 {
4868 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
4869 "asking for locations.";
4870 }
4871
VertexShader()4872 virtual std::string VertexShader()
4873 {
4874 return "#version 430 \n"
4875 "in vec4 position; \n"
4876 "in vec3 pos; \n"
4877 "void main(void) \n"
4878 "{ \n"
4879 " gl_Position = position + vec4(pos, 1); \n"
4880 "}";
4881 }
4882
Run()4883 virtual long Run()
4884 {
4885 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4886 glBindAttribLocation(program, 0, "position");
4887 glBindAttribLocation(program, 1, "pos");
4888 glBindFragDataLocation(program, 0, "color");
4889 LinkProgram(program);
4890
4891 long error = NO_ERROR;
4892
4893 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
4894 glUseProgram(program);
4895
4896 tcu::Vec4 v[4] = {tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
4897 tcu::Vec4(1, -1, 0, 1)};
4898 GLuint vao, vbuf;
4899 glGenVertexArrays(1, &vao);
4900 glBindVertexArray(vao);
4901 glGenBuffers(1, &vbuf);
4902 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
4903 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
4904 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
4905 glEnableVertexAttribArray(0);
4906 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4907
4908 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4909 glDisableVertexAttribArray(0);
4910 glDeleteVertexArrays(1, &vao);
4911 glBindBuffer(GL_ARRAY_BUFFER, 0);
4912 glDeleteBuffers(1, &vbuf);
4913
4914 glBindAttribLocation(program, 0, "pos");
4915 glBindAttribLocation(program, 0, "position");
4916 const char *varyings[2] = {"q", "z"};
4917 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
4918 LinkProgram(program);
4919
4920 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
4921 ExpectError(GL_INVALID_OPERATION, error);
4922 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
4923 ExpectError(GL_INVALID_OPERATION, error);
4924 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
4925 ExpectError(GL_INVALID_OPERATION, error);
4926
4927 glDeleteProgram(program);
4928 return error;
4929 }
4930 };
4931
4932 class LinkFailure : public SimpleShaders
4933 {
4934
Title()4935 virtual std::string Title()
4936 {
4937 return "Link Failure Test";
4938 }
4939
PassCriteria()4940 virtual std::string PassCriteria()
4941 {
4942 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4943 }
4944
Purpose()4945 virtual std::string Purpose()
4946 {
4947 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
4948 }
4949
Method()4950 virtual std::string Method()
4951 {
4952 return "Create a program, use it, relink with failure using different sources and then \n"
4953 "verify that INVALID_OPERATION is returned when asking for locations.";
4954 }
4955
VertexShader_prop()4956 virtual const char *VertexShader_prop()
4957 {
4958 return "#version 430 \n"
4959 "in vec4 posit; \n"
4960 "in vec4 p; \n"
4961 "void main(void) \n"
4962 "{ \n"
4963 " gl_Position = p + posit; \n"
4964 "}";
4965 }
4966
FragmentShader_prop()4967 virtual const char *FragmentShader_prop()
4968 {
4969 return "#version 430 \n"
4970 "out vec4 color; \n"
4971 "void main() { \n"
4972 " color = vec4(0, 1, 0, 1); \n"
4973 "}";
4974 }
4975
VertexShader_fail()4976 virtual const char *VertexShader_fail()
4977 {
4978 return "#version 430 \n"
4979 "in vec4 position; \n"
4980 "void main(void) \n"
4981 "{ \n"
4982 " gl_Position = position; \n"
4983 "}";
4984 }
4985
Run()4986 virtual long Run()
4987 {
4988 const GLuint program = glCreateProgram();
4989 const char *src_vs = VertexShader_prop();
4990 const char *src_fs = FragmentShader_prop();
4991 const char *src_vsh = VertexShader_fail();
4992
4993 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
4994 glAttachShader(program, sh1);
4995 glDeleteShader(sh1);
4996 glShaderSource(sh1, 1, &src_vs, NULL);
4997 glCompileShader(sh1);
4998
4999 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
5000 glAttachShader(program, sh2);
5001 glDeleteShader(sh2);
5002 glShaderSource(sh2, 1, &src_fs, NULL);
5003 glCompileShader(sh2);
5004
5005 glBindAttribLocation(program, 0, "p");
5006 glBindAttribLocation(program, 1, "posit");
5007 glBindFragDataLocation(program, 0, "color");
5008 LinkProgram(program);
5009
5010 long error = NO_ERROR;
5011
5012 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
5013 glUseProgram(program);
5014
5015 tcu::Vec4 v[4] = {tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
5016 tcu::Vec4(1, -1, 0, 1)};
5017 GLuint vao, vbuf;
5018 glGenVertexArrays(1, &vao);
5019 glBindVertexArray(vao);
5020 glGenBuffers(1, &vbuf);
5021 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
5022 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
5023 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5024 glEnableVertexAttribArray(0);
5025 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5026
5027 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5028 glDisableVertexAttribArray(0);
5029 glDeleteVertexArrays(1, &vao);
5030 glBindBuffer(GL_ARRAY_BUFFER, 0);
5031 glDeleteBuffers(1, &vbuf);
5032
5033 glDetachShader(program, sh1);
5034 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
5035 glAttachShader(program, vsh);
5036 glDeleteShader(vsh);
5037 glShaderSource(vsh, 1, &src_vsh, NULL);
5038 glCompileShader(vsh);
5039 const char *varyings[2] = {"q", "z"};
5040 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
5041 LinkProgram(program);
5042
5043 GLint res;
5044 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
5045 ExpectError(GL_INVALID_OPERATION, error);
5046 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
5047 if (res != 0 && res != 1)
5048 {
5049 m_context.getTestContext().getLog()
5050 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
5051 << tcu::TestLog::EndMessage;
5052 error = ERROR;
5053 }
5054 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
5055 if (res != 0 && res != 9)
5056 {
5057 m_context.getTestContext().getLog()
5058 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
5059 << tcu::TestLog::EndMessage;
5060 error = ERROR;
5061 }
5062 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
5063 ExpectError(GL_INVALID_OPERATION, error);
5064
5065 glDeleteProgram(program);
5066 return error;
5067 }
5068 };
5069
5070 } // anonymous namespace
5071
ProgramInterfaceQueryTests(deqp::Context & context)5072 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(deqp::Context &context)
5073 : TestCaseGroup(context, "program_interface_query", "")
5074 {
5075 }
5076
~ProgramInterfaceQueryTests(void)5077 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
5078 {
5079 }
5080
init()5081 void ProgramInterfaceQueryTests::init()
5082 {
5083 using namespace deqp;
5084 addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
5085 addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
5086 addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
5087 addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
5088 addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
5089 addChild(new TestSubcase(m_context, "output-types", TestSubcase::Create<OutputTypes>));
5090 addChild(new TestSubcase(m_context, "output-location-index", TestSubcase::Create<OutputLocationIndex>));
5091 addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
5092 addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
5093 addChild(new TestSubcase(m_context, "output-layout-index", TestSubcase::Create<OutputLayoutIndex>));
5094 addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
5095 addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
5096 addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
5097 addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
5098 addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
5099 addChild(new TestSubcase(m_context, "subroutines-vertex", TestSubcase::Create<SubroutinesVertex>));
5100 addChild(new TestSubcase(m_context, "subroutines-tess-control", TestSubcase::Create<SubroutinesTessControl>));
5101 addChild(new TestSubcase(m_context, "subroutines-tess-eval", TestSubcase::Create<SubroutinesTessEval>));
5102 addChild(new TestSubcase(m_context, "subroutines-geometry", TestSubcase::Create<SubroutinesGeometry>));
5103 addChild(new TestSubcase(m_context, "subroutines-fragment", TestSubcase::Create<SubroutinesFragment>));
5104 addChild(new TestSubcase(m_context, "subroutines-compute", TestSubcase::Create<SoubroutinesCompute>));
5105 addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
5106 addChild(new TestSubcase(m_context, "transform-feedback-built-in", TestSubcase::Create<TransformFeedbackBuiltin>));
5107 addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
5108 addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
5109 addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
5110 addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
5111 addChild(
5112 new TestSubcase(m_context, "separate-programs-tess-control", TestSubcase::Create<SeparateProgramsTessControl>));
5113 addChild(new TestSubcase(m_context, "separate-programs-tess-eval", TestSubcase::Create<SeparateProgramsTessEval>));
5114 addChild(new TestSubcase(m_context, "separate-programs-geometry", TestSubcase::Create<SeparateProgramsGeometry>));
5115 addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
5116 addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
5117 addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
5118 addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
5119 addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
5120 addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
5121 addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
5122 addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
5123 addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
5124 addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
5125 addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
5126 addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
5127 addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
5128 }
5129
5130 } // namespace gl4cts
5131