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 };
1316 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 16, props, 16, expected, error);
1317
1318 GLint expected2[] = {
1319 8, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "recolor")
1320 };
1321 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 16, props, 16, expected2, error);
1322
1323 glDeleteProgram(program);
1324 return error;
1325 }
1326 };
1327
1328 class UniformTypes : public PIQBase
1329 {
Title()1330 virtual std::string Title()
1331 {
1332 return "Uniform Types Test";
1333 }
1334
ShadersDesc()1335 virtual std::string ShadersDesc()
1336 {
1337 return "fallthrough fragment and vertex shaders with different uniform types used";
1338 }
1339
PurposeExt()1340 virtual std::string PurposeExt()
1341 {
1342 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1343 }
1344
VertexShader()1345 virtual std::string VertexShader()
1346 {
1347 return "#version 430 \n"
1348 "in vec4 position; \n"
1349 "uniform vec4 a; \n"
1350 "uniform ivec3 b; \n"
1351 "uniform uvec2 c[3]; \n"
1352 "uniform mat2 g[8]; \n"
1353 "uniform mat3x2 i; \n"
1354 "void main(void) \n"
1355 "{ \n"
1356 " float tmp; \n"
1357 " tmp = g[0][1][1] + a.z + b.y + c[0].x; \n"
1358 " tmp += g[1][1][1] + c[1].x; \n"
1359 " tmp += g[2][1][1] + c[2].x; \n"
1360 " for (int i = 3; i < 8; ++i) \n"
1361 " tmp += g[i][1][1]; \n"
1362 " tmp = tmp + i[1][1]; \n"
1363 " gl_Position = position * tmp; \n"
1364 "}";
1365 }
1366
FragmentShader()1367 virtual std::string FragmentShader()
1368 {
1369 return "#version 430 \n"
1370 "struct U { \n"
1371 " bool a[3]; \n"
1372 " vec4 b; \n"
1373 " mat3 c; \n"
1374 " float d[2]; \n"
1375 "}; \n"
1376 "struct UU { \n"
1377 " U a; \n"
1378 " U b[2]; \n"
1379 " uvec2 c; \n"
1380 "}; \n"
1381 "uniform mat4 d; \n"
1382 "uniform mat3 e; \n"
1383 "uniform float h; \n"
1384 "uniform int f; \n"
1385 "uniform U j; \n"
1386 "uniform UU k; \n"
1387 "uniform UU l[3]; \n"
1388 "out vec4 color; \n"
1389 "void main() { \n"
1390 " float tmp; \n"
1391 " tmp = h + f + e[2][2]; \n"
1392 " tmp = tmp + d[0][0] + j.b.x; \n"
1393 " tmp = tmp + k.b[0].c[0][0]; \n"
1394 " tmp = tmp + l[2].a.c[0][1]; \n"
1395 " tmp = tmp + l[2].b[1].d[0]; \n"
1396 " tmp = tmp + l[2].b[1].d[1]; \n"
1397 " tmp = tmp + l[0].c.x; \n"
1398 " color = vec4(0, 1, 0, 1) * tmp; \n"
1399 "}";
1400 }
1401
Run()1402 virtual long Run()
1403 {
1404 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1405 glBindAttribLocation(program, 0, "position");
1406 glBindFragDataLocation(program, 0, "color");
1407 LinkProgram(program);
1408
1409 long error = NO_ERROR;
1410
1411 // only active structure members
1412 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1413 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1414 // l[2].b[1].d[0] and \0
1415 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1416
1417 std::map<std::string, GLuint> indices;
1418 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1419 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1420 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1421 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1422 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1423 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1424 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1425 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1426 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1427 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1428 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1429 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1430 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1431 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1432
1433 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1434 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1435 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1436 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1437 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1438 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1439 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1440 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1441 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1442 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1443 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1444 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1445 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1446 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1447
1448 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1449 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1450 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1451 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1452 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1453 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1454 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1455 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1456 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1457 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1458 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1459 error);
1460 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1461 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1462 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1463 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1464 error);
1465
1466 GLenum props[] = { GL_NAME_LENGTH,
1467 GL_TYPE,
1468 GL_ARRAY_SIZE,
1469 GL_OFFSET,
1470 GL_BLOCK_INDEX,
1471 GL_ARRAY_STRIDE,
1472 GL_MATRIX_STRIDE,
1473 GL_IS_ROW_MAJOR,
1474 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1475 GL_REFERENCED_BY_COMPUTE_SHADER,
1476 GL_REFERENCED_BY_FRAGMENT_SHADER,
1477 GL_REFERENCED_BY_GEOMETRY_SHADER,
1478 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1479 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1480 GL_REFERENCED_BY_VERTEX_SHADER,
1481 GL_LOCATION };
1482 GLint expected[] = {
1483 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a")
1484 };
1485 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 16, props, 16, expected, error);
1486 GLint expected2[] = { 2, GL_INT_VEC3, 1, -1, -1, -1, -1, 0,
1487 -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "b") };
1488 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 16, props, 16, expected2, error);
1489 GLint expected3[] = {
1490 5, GL_UNSIGNED_INT_VEC2, 3, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "c")
1491 };
1492 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 16, props, 16, expected3, error);
1493 GLint expected4[] = {
1494 2, GL_FLOAT_MAT4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "d")
1495 };
1496 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 16, props, 16, expected4, error);
1497 GLint expected5[] = {
1498 2, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "e")
1499 };
1500 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 16, props, 16, expected5, error);
1501 GLint expected6[] = {
1502 2, GL_INT, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "f")
1503 };
1504 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 16, props, 16, expected6, error);
1505 GLint expected7[] = {
1506 5, GL_FLOAT_MAT2, 8, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "g")
1507 };
1508 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 16, props, 16, expected7, error);
1509 GLint expected8[] = { 2, GL_FLOAT, 1, -1, -1, -1, -1, 0,
1510 -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "h") };
1511 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 16, props, 16, expected8, error);
1512 GLint expected9[] = {
1513 2, GL_FLOAT_MAT3x2, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "i")
1514 };
1515 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 16, props, 16, expected9, error);
1516 GLint expected10[] = {
1517 4, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "j.b")
1518 };
1519 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 16, props, 16, expected10, error);
1520 GLint expected11[] = {
1521 9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "k.b[0].c")
1522 };
1523 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 16, props, 16, expected11, error);
1524 GLint expected12[] = { 7, GL_UNSIGNED_INT_VEC2,
1525 1, -1,
1526 -1, -1,
1527 -1, 0,
1528 -1, 0,
1529 1, 0,
1530 0, 0,
1531 0, glGetUniformLocation(program, "l[0].c") };
1532 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 16, props, 16, expected12, error);
1533 GLint expected13[] = { 15, GL_FLOAT, 2, -1, -1, -1, -1, 0,
1534 -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].b[1].d[0]") };
1535 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 16, props, 16, expected13, error);
1536 GLint expected14[] = {
1537 9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].a.c")
1538 };
1539 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 16, props, 16, expected14, error);
1540
1541 glDeleteProgram(program);
1542 return error;
1543 }
1544 };
1545
1546 class UniformBlockTypes : public PIQBase
1547 {
Title()1548 virtual std::string Title()
1549 {
1550 return "Uniform Block Types Test";
1551 }
1552
ShadersDesc()1553 virtual std::string ShadersDesc()
1554 {
1555 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1556 }
1557
PurposeExt()1558 virtual std::string PurposeExt()
1559 {
1560 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1561 }
1562
VertexShader()1563 virtual std::string VertexShader()
1564 {
1565 return "#version 430 \n"
1566 "in vec4 position; \n"
1567 ""
1568 "uniform SimpleBlock { \n"
1569 " mat3x2 a; \n"
1570 " mat4 b; \n"
1571 " vec4 c; \n"
1572 "}; \n"
1573 ""
1574 "uniform NotSoSimpleBlockk { \n"
1575 " ivec2 a[4]; \n"
1576 " mat3 b[2]; \n"
1577 " mat2 c; \n"
1578 "} d; \n"
1579 ""
1580 "void main(void) \n"
1581 "{ \n"
1582 " float tmp; \n"
1583 " tmp = a[0][1] * b[1][2] * c.x; \n"
1584 " tmp = tmp + d.a[2].y + d.b[0][1][1] + d.c[1][1]; \n"
1585 " gl_Position = position * tmp; \n"
1586 "}";
1587 }
1588
FragmentShader()1589 virtual std::string FragmentShader()
1590 {
1591 return "#version 430 \n"
1592 "struct U { \n"
1593 " bool a[3]; \n"
1594 " vec4 b; \n"
1595 " mat3 c; \n"
1596 " float d[2]; \n"
1597 "}; \n"
1598 "struct UU { \n"
1599 " U a; \n"
1600 " U b[2]; \n"
1601 " uvec2 c; \n"
1602 "}; \n"
1603 ""
1604 "uniform TrickyBlock { \n"
1605 " UU a[3]; \n"
1606 " mat4 b; \n"
1607 " uint c; \n"
1608 "} e[2]; \n"
1609 ""
1610 "out vec4 color; \n"
1611 "void main() { \n"
1612 " float tmp; \n"
1613 " tmp = e[0].a[2].b[0].d[1]; \n"
1614 " color = vec4(0, 1, 0, 1) * tmp; \n"
1615 "}";
1616 }
1617
Run()1618 virtual long Run()
1619 {
1620 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1621 glBindAttribLocation(program, 0, "position");
1622 glBindFragDataLocation(program, 0, "color");
1623 LinkProgram(program);
1624
1625 long error = NO_ERROR;
1626
1627 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1628 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1629 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1630 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1631
1632 std::map<std::string, GLuint> indicesUB;
1633 std::map<std::string, GLuint> indicesU;
1634 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1635 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1636 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1637 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1638 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1639 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1640 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1641 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1642 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1643 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1644 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1645
1646 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1647 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1648 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1649 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1650
1651 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1652 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1653 error);
1654 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1655 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1656 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1657 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1658 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1659 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1660 error);
1661 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1662 error);
1663 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1664 error);
1665 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1666 "TrickyBlock.a[2].b[0].d[0]", error);
1667
1668 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1669 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1670 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1671
1672 GLenum props[] = {
1673 GL_NAME_LENGTH,
1674 GL_BUFFER_BINDING,
1675 GL_REFERENCED_BY_COMPUTE_SHADER,
1676 GL_REFERENCED_BY_FRAGMENT_SHADER,
1677 GL_REFERENCED_BY_GEOMETRY_SHADER,
1678 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1679 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1680 GL_REFERENCED_BY_VERTEX_SHADER,
1681 GL_BUFFER_DATA_SIZE,
1682 };
1683 GLint size;
1684 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1685 GLint expected[] = { 12, 0, 0, 0, 0, 0, 0, 1, size };
1686 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 9, props, 9, expected, error);
1687 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1688 GLint expected2[] = { 18, 2, 0, 0, 0, 0, 0, 1, size };
1689 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 9, props, 9, expected2,
1690 error);
1691 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1692 GLint expected3[] = { 15, 3, 0, 1, 0, 0, 0, 0, size };
1693 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 9, props, 9, expected3, error);
1694 GLint expected4[] = { 15, 4, 0, 0, 0, 0, 0, 0, size };
1695 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 9, props, 9, expected4,
1696 error);
1697
1698 GLenum props2[] = { GL_NAME_LENGTH,
1699 GL_TYPE,
1700 GL_ARRAY_SIZE,
1701 GL_BLOCK_INDEX,
1702 GL_ARRAY_STRIDE,
1703 GL_IS_ROW_MAJOR,
1704 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1705 GL_REFERENCED_BY_COMPUTE_SHADER,
1706 GL_REFERENCED_BY_FRAGMENT_SHADER,
1707 GL_REFERENCED_BY_GEOMETRY_SHADER,
1708 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1709 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1710 GL_REFERENCED_BY_VERTEX_SHADER,
1711 GL_LOCATION };
1712 GLint expected5[] = {
1713 2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 0, 0, 0, 1, -1
1714 };
1715 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 14, props2, 14, expected5, error);
1716 GLenum props3[] = { GL_NAME_LENGTH,
1717 GL_TYPE,
1718 GL_ARRAY_SIZE,
1719 GL_BLOCK_INDEX,
1720 GL_MATRIX_STRIDE,
1721 GL_IS_ROW_MAJOR,
1722 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1723 GL_REFERENCED_BY_COMPUTE_SHADER,
1724 GL_REFERENCED_BY_FRAGMENT_SHADER,
1725 GL_REFERENCED_BY_GEOMETRY_SHADER,
1726 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1727 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1728 GL_REFERENCED_BY_VERTEX_SHADER,
1729 GL_LOCATION };
1730 GLint expected6[] = { 27, GL_FLOAT, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, 0,
1731 0, 0, -1 };
1732 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 14, props3, 14, expected6,
1733 error);
1734
1735 GLenum prop = GL_ACTIVE_VARIABLES;
1736 const GLsizei bufSize = 1000;
1737 GLsizei length;
1738 GLint param[bufSize];
1739 std::set<GLuint> exp;
1740 exp.insert(indicesU["a"]);
1741 exp.insert(indicesU["b"]);
1742 exp.insert(indicesU["c"]);
1743 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1744 for (int i = 0; i < length; ++i)
1745 {
1746 if (exp.find(param[i]) == exp.end())
1747 {
1748 m_context.getTestContext().getLog()
1749 << tcu::TestLog::Message
1750 << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1751 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1752 << tcu::TestLog::EndMessage;
1753 glDeleteProgram(program);
1754 return ERROR;
1755 }
1756 else if (length != 3)
1757 {
1758 m_context.getTestContext().getLog()
1759 << tcu::TestLog::Message
1760 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK\n"
1761 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1762 glDeleteProgram(program);
1763 return ERROR;
1764 }
1765 }
1766 std::set<GLuint> exp2;
1767 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1768 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1769 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1770 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1771 param);
1772 for (int i = 0; i < length; ++i)
1773 {
1774 if (exp2.find(param[i]) == exp2.end())
1775 {
1776 m_context.getTestContext().getLog()
1777 << tcu::TestLog::Message
1778 << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1779 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1780 << tcu::TestLog::EndMessage;
1781 glDeleteProgram(program);
1782 return ERROR;
1783 }
1784 else if (length != 3)
1785 {
1786 m_context.getTestContext().getLog()
1787 << tcu::TestLog::Message
1788 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1789 << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1790 glDeleteProgram(program);
1791 return ERROR;
1792 }
1793 }
1794
1795 GLint res;
1796 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1797 if (res < 3)
1798 {
1799 m_context.getTestContext().getLog()
1800 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1801 << tcu::TestLog::EndMessage;
1802 glDeleteProgram(program);
1803 return ERROR;
1804 }
1805
1806 glDeleteProgram(program);
1807 return error;
1808 }
1809 };
1810
1811 class TransformFeedbackTypes : public SimpleShaders
1812 {
Title()1813 virtual std::string Title()
1814 {
1815 return "Transform Feedback Varying Types";
1816 }
1817
ShadersDesc()1818 virtual std::string ShadersDesc()
1819 {
1820 return "fallthrough fragment and vertex shaders with different types of out variables used";
1821 }
1822
PurposeExt()1823 virtual std::string PurposeExt()
1824 {
1825 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1826 }
1827
VertexShader()1828 virtual std::string VertexShader()
1829 {
1830 return "#version 430 \n"
1831 "in vec4 position; \n"
1832 ""
1833 "flat out ivec4 a; \n"
1834 "out float b[2]; \n"
1835 "flat out uvec2 c; \n"
1836 "flat out uint d; \n"
1837 "out vec3 e[2]; \n"
1838 "flat out int f; \n"
1839 ""
1840 "void main(void) \n"
1841 "{ \n"
1842 " vec4 pos; \n"
1843 " a = ivec4(1); \n"
1844 " b[0] = 1.1; \n"
1845 " b[1] = 1.1; \n"
1846 " c = uvec2(1u); \n"
1847 " d = 1u; \n"
1848 " e[0] = vec3(1.1); \n"
1849 " e[1] = vec3(1.1); \n"
1850 " f = 1; \n"
1851 " gl_Position = position; \n"
1852 "}";
1853 }
1854
Run()1855 virtual long Run()
1856 {
1857 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1858 glBindAttribLocation(program, 0, "position");
1859 const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1860 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1861 LinkProgram(program);
1862
1863 long error = NO_ERROR;
1864
1865 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1866 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1867
1868 std::map<std::string, GLuint> indices;
1869 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1870 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1871 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1872 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1873 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1874 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1875
1876 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1877 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1878 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1879 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1880 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1881 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1882
1883 GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1884 GLint expected[] = { 2, GL_INT_VEC4, 1 };
1885 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1886 GLint expected2[] = { 5, GL_FLOAT, 1 };
1887 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1888 error);
1889 GLint expected3[] = { 5, GL_FLOAT, 1 };
1890 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1891 error);
1892 GLint expected4[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1893 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1894 GLint expected5[] = { 2, GL_UNSIGNED_INT, 1 };
1895 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1896 GLint expected6[] = { 2, GL_FLOAT_VEC3, 2 };
1897 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1898
1899 glDeleteProgram(program);
1900 return error;
1901 }
1902 };
1903
1904 class AtomicCounterSimple : public SimpleShaders
1905 {
1906 public:
Title()1907 virtual std::string Title()
1908 {
1909 return "Atomic Counter Buffer Simple Test";
1910 }
1911
ShadersDesc()1912 virtual std::string ShadersDesc()
1913 {
1914 return "fallthrough fragment and vertex shaders with atomic counters used";
1915 }
1916
PurposeExt()1917 virtual std::string PurposeExt()
1918 {
1919 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1920 }
1921
FragmentShader()1922 virtual std::string FragmentShader()
1923 {
1924 return "#version 430 \n"
1925 "out vec4 color; \n"
1926 ""
1927 "layout (binding = 1, offset = 0) uniform atomic_uint a; \n"
1928 "layout (binding = 2, offset = 0) uniform atomic_uint b; \n"
1929 "layout (binding = 2, offset = 4) uniform atomic_uint c; \n"
1930 "layout (binding = 5, offset = 0) uniform atomic_uint d[3]; \n"
1931 "layout (binding = 5, offset = 12) uniform atomic_uint e; \n"
1932 ""
1933 "void main() { \n"
1934 " uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1935 " uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1936 " uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1937 " uint w = atomicCounterIncrement(e); \n"
1938 " color = vec4(float(x), float(y), float(z), float(w)); \n"
1939 "}";
1940 }
1941
Run()1942 virtual long Run()
1943 {
1944 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1945 glBindAttribLocation(program, 0, "position");
1946 glBindFragDataLocation(program, 0, "color");
1947 LinkProgram(program);
1948
1949 long error = NO_ERROR;
1950
1951 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1952 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1953
1954 std::map<std::string, GLuint> indicesU;
1955 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1956 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1957 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1958 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1959 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1960
1961 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1962 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1963 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1964 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1965 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1966
1967 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1968 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1969 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1970 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1971 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1972 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1973 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1974 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1975
1976 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1977 const GLsizei bufSize = 1000;
1978 GLsizei length;
1979 GLint res;
1980 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1981
1982 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1983 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1984 GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1985 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1986
1987 GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1988 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1989 GLint expected2[] = { 2, 8, 2 };
1990 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1991 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1992 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1993
1994 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1995 GLint expected3[] = { 5, 16, 2 };
1996 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1997 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1998 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1999
2000 GLenum prop2 = GL_ACTIVE_VARIABLES;
2001 GLint param[bufSize];
2002 std::set<GLuint> exp;
2003 exp.insert(indicesU["b"]);
2004 exp.insert(indicesU["c"]);
2005 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2006 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2007 for (int i = 0; i < length; ++i)
2008 {
2009 if (exp.find(param[i]) == exp.end() || length != 2)
2010 {
2011 m_context.getTestContext().getLog()
2012 << tcu::TestLog::Message << "Length: " << length
2013 << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2014 << tcu::TestLog::EndMessage;
2015 glDeleteProgram(program);
2016 return ERROR;
2017 }
2018 }
2019 m_context.getTestContext().getLog()
2020 << tcu::TestLog::Message << "GL_ACTIVE_VARIABLES ok for 1st ATOMIC_COUNTER_BUFFER"
2021 << tcu::TestLog::EndMessage;
2022 std::set<GLuint> exp2;
2023 GLint param2[bufSize];
2024 exp2.insert(indicesU["d"]);
2025 exp2.insert(indicesU["e"]);
2026 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
2027 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
2028 for (int i = 0; i < length; ++i)
2029 {
2030 if (exp2.find(param2[i]) == exp2.end() || length != 2)
2031 {
2032 m_context.getTestContext().getLog()
2033 << tcu::TestLog::Message << "Length: " << length
2034 << "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
2035 << tcu::TestLog::EndMessage;
2036 glDeleteProgram(program);
2037 return ERROR;
2038 }
2039 }
2040
2041 glDeleteProgram(program);
2042 return error;
2043 }
2044 };
2045
2046 class SubroutinesBase : public SimpleShaders
2047 {
2048 protected:
ShadersDesc()2049 virtual std::string ShadersDesc()
2050 {
2051 return "fallthrough vertex, geometry, tesselation and fragment shaders with subroutines used";
2052 }
2053
VertexShader()2054 virtual std::string VertexShader()
2055 {
2056 return "#version 430 \n"
2057 "in vec4 position; \n"
2058 ""
2059 "subroutine vec4 a_t(); \n"
2060 "subroutine uniform a_t a; \n"
2061 "subroutine(a_t) vec4 x() { \n"
2062 " return vec4(1); \n"
2063 "} \n"
2064 "subroutine(a_t) vec4 y() { \n"
2065 " return vec4(0); \n"
2066 "} \n"
2067 "void main(void) \n"
2068 "{ \n"
2069 " gl_Position = a(); \n"
2070 "}";
2071 }
2072
TessControlShader()2073 virtual std::string TessControlShader()
2074 {
2075 return "#version 430 \n"
2076 "layout(vertices = 3) out; \n"
2077 ""
2078 "subroutine vec4 a_t(); \n"
2079 "subroutine uniform a_t a; \n"
2080 "subroutine(a_t) vec4 x() { \n"
2081 " return vec4(1); \n"
2082 "} \n"
2083 ""
2084 "void main() { \n"
2085 " gl_out[gl_InvocationID].gl_Position = a(); \n"
2086 " gl_TessLevelInner[0] = 1.0; \n"
2087 " gl_TessLevelInner[1] = 1.0; \n"
2088 " gl_TessLevelOuter[0] = 1.0; \n"
2089 " gl_TessLevelOuter[1] = 1.0; \n"
2090 " gl_TessLevelOuter[2] = 1.0; \n"
2091 "}";
2092 }
2093
TessEvalShader()2094 virtual std::string TessEvalShader()
2095 {
2096 return "#version 430 \n"
2097 "layout(triangles, equal_spacing) in; \n"
2098 ""
2099 "subroutine vec4 a_t(); \n"
2100 "subroutine uniform a_t a; \n"
2101 "subroutine(a_t) vec4 x() { \n"
2102 " return vec4(1); \n"
2103 "} \n"
2104 ""
2105 "void main() { \n"
2106 " vec4 p0 = gl_in[0].gl_Position; \n"
2107 " vec4 p1 = gl_in[1].gl_Position; \n"
2108 " vec4 p2 = gl_in[2].gl_Position; \n"
2109 " vec3 p = gl_TessCoord.xyz; \n"
2110 " gl_Position = a(); \n"
2111 "}";
2112 }
2113
GeometryShader()2114 virtual std::string GeometryShader()
2115 {
2116 return "#version 430 \n"
2117 "layout(triangles) in; \n"
2118 "layout(triangle_strip, max_vertices = 4) out; \n"
2119 ""
2120 "subroutine vec4 a_t(); \n"
2121 "subroutine uniform a_t a; \n"
2122 "subroutine(a_t) vec4 x() { \n"
2123 " return vec4(1); \n"
2124 "} \n"
2125 ""
2126 "void main() { \n"
2127 " gl_Position = vec4(-1, 1, 0, 1); \n"
2128 " EmitVertex(); \n"
2129 " gl_Position = vec4(-1, -1, 0, 1); \n"
2130 " EmitVertex(); \n"
2131 " gl_Position = vec4(1, 1, 0, 1); \n"
2132 " EmitVertex(); \n"
2133 " gl_Position = a(); \n"
2134 " EmitVertex(); \n"
2135 " EndPrimitive(); \n"
2136 "}";
2137 }
2138
FragmentShader()2139 virtual std::string FragmentShader()
2140 {
2141 return "#version 430 \n"
2142 "out vec4 color; \n"
2143 ""
2144 "subroutine vec4 a_t(); \n"
2145 "subroutine uniform a_t a; \n"
2146 "subroutine(a_t) vec4 x() { \n"
2147 " return vec4(1); \n"
2148 "} \n"
2149 ""
2150 "void main() { \n"
2151 " color = a(); \n"
2152 "}";
2153 }
2154
VerifyVS(GLuint program, long& error)2155 virtual void inline VerifyVS(GLuint program, long& error)
2156 {
2157 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, 2, error);
2158 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2159
2160 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2161 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2162 VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 2, error);
2163
2164 std::map<std::string, GLuint> indicesS;
2165 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "x", error);
2166 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "y", error);
2167 std::map<std::string, GLuint> indicesU;
2168 VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU, "a", error);
2169
2170 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["x"], "x", error);
2171 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["y"], "y", error);
2172 VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], "a", error);
2173
2174 VerifyGetProgramResourceLocation(program, GL_VERTEX_SUBROUTINE_UNIFORM, "a",
2175 glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a"), error);
2176
2177 GLenum propsS[] = { GL_NAME_LENGTH };
2178 GLint expectedS[] = { 2 };
2179 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["x"], 1, propsS, 1, expectedS, error);
2180 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["y"], 1, propsS, 1, expectedS, error);
2181
2182 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2183 GLint expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a") };
2184 VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 4, propsU, 4, expectedU,
2185 error);
2186
2187 GLenum prop = GL_COMPATIBLE_SUBROUTINES;
2188 const GLsizei bufSize = 1000;
2189 GLint param[bufSize];
2190 GLsizei length;
2191 std::set<GLuint> exp;
2192 exp.insert(indicesS["x"]);
2193 exp.insert(indicesS["y"]);
2194 glGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, param);
2195 for (int i = 0; i < length; ++i)
2196 {
2197 if (exp.find(param[i]) == exp.end() || length != 2)
2198 {
2199 m_context.getTestContext().getLog()
2200 << tcu::TestLog::Message << "Length: " << length
2201 << "\nUnexpected index/length found in active variables of GL_VERTEX_SUBROUTINE_UNIFORM: "
2202 << param[i] << tcu::TestLog::EndMessage;
2203 error = ERROR;
2204 }
2205 }
2206 }
2207
VerifyTCS(GLuint program, long& error)2208 virtual void inline VerifyTCS(GLuint program, long& error)
2209 {
2210 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2211 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2212
2213 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2214 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2215 VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2216 error);
2217
2218 std::map<std::string, GLuint> indicesTS;
2219 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS, "x", error);
2220 std::map<std::string, GLuint> indicesTU;
2221 VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2222
2223 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS["x"], "x", error);
2224 VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2225
2226 VerifyGetProgramResourceLocation(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, "a",
2227 glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"), error);
2228
2229 GLenum propsS[] = { GL_NAME_LENGTH };
2230 GLint expectedS[] = { 2 };
2231 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE, static_cast<GLint>(indicesTS["x"]), 1, propsS,
2232 1, expectedS, error);
2233
2234 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2235 GL_COMPATIBLE_SUBROUTINES };
2236 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"),
2237 static_cast<GLint>(indicesTS["x"]) };
2238 VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2239 error);
2240 }
2241 };
2242
2243 class SubroutinesVertex : public SubroutinesBase
2244 {
Title()2245 virtual std::string Title()
2246 {
2247 return "Vertex Shader Subroutines Test";
2248 }
2249
PurposeExt()2250 virtual std::string PurposeExt()
2251 {
2252 return "\n\n Purpose is to verify calls using *VERTEX_SUBROUTINE* as an interface params.\n";
2253 }
2254
Run()2255 virtual long Run()
2256 {
2257 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2258 GeometryShader().c_str(), FragmentShader().c_str(), false);
2259 glBindAttribLocation(program, 0, "position");
2260 glBindFragDataLocation(program, 0, "color");
2261 LinkProgram(program);
2262 long error = NO_ERROR;
2263
2264 VerifyVS(program, error);
2265
2266 glDeleteProgram(program);
2267 return error;
2268 }
2269 };
2270
2271 class SubroutinesTessControl : public SubroutinesBase
2272 {
Title()2273 virtual std::string Title()
2274 {
2275 return "Tess Control Subroutines Test";
2276 }
2277
PurposeExt()2278 virtual std::string PurposeExt()
2279 {
2280 return "\n\n Purpose is to verify calls using *TESS_CONTROL_SUBROUTINE* as an interface params.\n";
2281 }
2282
Run()2283 virtual long Run()
2284 {
2285 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2286 GeometryShader().c_str(), FragmentShader().c_str(), false);
2287 glBindAttribLocation(program, 0, "position");
2288 glBindFragDataLocation(program, 0, "color");
2289 LinkProgram(program);
2290 long error = NO_ERROR;
2291
2292 VerifyTCS(program, error);
2293
2294 glDeleteProgram(program);
2295 return error;
2296 }
2297 };
2298
2299 class SubroutinesTessEval : public SubroutinesBase
2300 {
Title()2301 virtual std::string Title()
2302 {
2303 return "Tess Evaluation Subroutines Test";
2304 }
2305
PurposeExt()2306 virtual std::string PurposeExt()
2307 {
2308 return "\n\n Purpose is to verify calls using *TESS_EVALUATION_SUBROUTINE* as an interface params.\n";
2309 }
2310
VerifyTES(GLuint program, long& error)2311 virtual void inline VerifyTES(GLuint program, long& error)
2312 {
2313 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2314 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2315
2316 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2317 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2318 VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
2319 1, error);
2320
2321 std::map<std::string, GLuint> indicesTS;
2322 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS, "x", error);
2323 std::map<std::string, GLuint> indicesTU;
2324 VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2325
2326 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], "x", error);
2327 VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2328
2329 VerifyGetProgramResourceLocation(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, "a",
2330 glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2331 error);
2332
2333 GLenum propsS[] = { GL_NAME_LENGTH };
2334 GLint expectedS[] = { 2 };
2335 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS,
2336 error);
2337
2338 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2339 GL_COMPATIBLE_SUBROUTINES };
2340 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2341 static_cast<GLint>(indicesTS["x"]) };
2342 VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5,
2343 expectedU, error);
2344 }
2345
Run()2346 virtual long Run()
2347 {
2348 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2349 GeometryShader().c_str(), FragmentShader().c_str(), false);
2350 glBindAttribLocation(program, 0, "position");
2351 glBindFragDataLocation(program, 0, "color");
2352 LinkProgram(program);
2353 long error = NO_ERROR;
2354
2355 VerifyTES(program, error);
2356
2357 glDeleteProgram(program);
2358 return error;
2359 }
2360 };
2361
2362 class SubroutinesGeometry : public SubroutinesBase
2363 {
Title()2364 virtual std::string Title()
2365 {
2366 return "Geometry Shader Subroutines Test";
2367 }
2368
PurposeExt()2369 virtual std::string PurposeExt()
2370 {
2371 return "\n\n Purpose is to verify calls using *GEOMETRY_SUBROUTINE* as an interface params.\n";
2372 }
2373
VerifyGEO(GLuint program, long& error)2374 virtual void inline VerifyGEO(GLuint program, long& error)
2375 {
2376 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2377 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2378
2379 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2380 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2381 VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2382 error);
2383
2384 std::map<std::string, GLuint> indicesTS;
2385 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE, indicesTS, "x", error);
2386 std::map<std::string, GLuint> indicesTU;
2387 VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2388
2389 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], "x", error);
2390 VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2391
2392 VerifyGetProgramResourceLocation(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, "a",
2393 glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"), error);
2394
2395 GLenum propsS[] = { GL_NAME_LENGTH };
2396 GLint expectedS[] = { 2 };
2397 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2398
2399 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2400 GL_COMPATIBLE_SUBROUTINES };
2401 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"),
2402 static_cast<GLint>(indicesTS["x"]) };
2403 VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2404 error);
2405 }
2406
Run()2407 virtual long Run()
2408 {
2409 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2410 GeometryShader().c_str(), FragmentShader().c_str(), false);
2411 glBindAttribLocation(program, 0, "position");
2412 glBindFragDataLocation(program, 0, "color");
2413 LinkProgram(program);
2414 long error = NO_ERROR;
2415
2416 VerifyGEO(program, error);
2417
2418 glDeleteProgram(program);
2419 return error;
2420 }
2421 };
2422
2423 class SubroutinesFragment : public SubroutinesBase
2424 {
Title()2425 virtual std::string Title()
2426 {
2427 return "Fragment Shader Subroutines Test";
2428 }
2429
PurposeExt()2430 virtual std::string PurposeExt()
2431 {
2432 return "\n\n Purpose is to verify calls using *FRAGMENT_SUBROUTINE* as an interface params.\n";
2433 }
2434
VerifyFS(GLuint program, long& error)2435 virtual void inline VerifyFS(GLuint program, long& error)
2436 {
2437 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2438 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2439
2440 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2441 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2442 VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2443 error);
2444
2445 std::map<std::string, GLuint> indicesTS;
2446 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE, indicesTS, "x", error);
2447 std::map<std::string, GLuint> indicesTU;
2448 VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2449
2450 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], "x", error);
2451 VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2452
2453 VerifyGetProgramResourceLocation(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, "a",
2454 glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"), error);
2455
2456 GLenum propsS[] = { GL_NAME_LENGTH };
2457 GLint expectedS[] = { 2 };
2458 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2459
2460 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2461 GL_COMPATIBLE_SUBROUTINES };
2462 GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"),
2463 static_cast<GLint>(indicesTS["x"]) };
2464 VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2465 error);
2466 }
2467
Run()2468 virtual long Run()
2469 {
2470 GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2471 GeometryShader().c_str(), FragmentShader().c_str(), false);
2472 glBindAttribLocation(program, 0, "position");
2473 glBindFragDataLocation(program, 0, "color");
2474 LinkProgram(program);
2475 long error = NO_ERROR;
2476
2477 VerifyFS(program, error);
2478
2479 glDeleteProgram(program);
2480 return error;
2481 }
2482 };
2483
2484 class SoubroutinesCompute : public PIQBase
2485 {
Title()2486 virtual std::string Title()
2487 {
2488 return "Compute Shader Subroutines Test";
2489 }
2490
ShadersDesc()2491 virtual std::string ShadersDesc()
2492 {
2493 return "compute shader with subroutines used";
2494 }
2495
PurposeExt()2496 virtual std::string PurposeExt()
2497 {
2498 return "\n\n Purpose is to verify calls using *COMPUTE_SUBROUTINE* as an interface params.\n";
2499 }
2500
ComputeShader()2501 virtual std::string ComputeShader()
2502 {
2503 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2504
2505 "layout(std430) buffer Output { \n"
2506 " vec4 data; \n"
2507 "} g_out; \n"
2508 ""
2509 "subroutine vec4 a_t(); \n"
2510 "subroutine uniform a_t a; \n"
2511 "subroutine(a_t) vec4 ax() { \n"
2512 " return vec4(1); \n"
2513 "} \n"
2514 "subroutine(a_t) vec4 ay() { \n"
2515 " return vec4(0); \n"
2516 "} \n"
2517 ""
2518 "subroutine vec4 b_t(); \n"
2519 "subroutine uniform b_t b[3]; \n"
2520 "subroutine(b_t) vec4 bx() { \n"
2521 " return vec4(1); \n"
2522 "} \n"
2523 "subroutine(b_t) vec4 by() { \n"
2524 " return vec4(0); \n"
2525 "} \n"
2526 "subroutine(b_t) vec4 bz() { \n"
2527 " return vec4(-1); \n"
2528 "} \n"
2529 ""
2530 "void main() { \n"
2531 " g_out.data = a() + b[0]() + b[1]() + b[2](); \n"
2532 "}";
2533 }
2534
CreateComputeProgram(const std::string& cs)2535 GLuint CreateComputeProgram(const std::string& cs)
2536 {
2537 const GLuint p = glCreateProgram();
2538
2539 const char* const kGLSLVer = "#version 430 core\n";
2540
2541 if (!cs.empty())
2542 {
2543 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
2544 glAttachShader(p, sh);
2545 glDeleteShader(sh);
2546 const char* const src[2] = { kGLSLVer, cs.c_str() };
2547 glShaderSource(sh, 2, src, NULL);
2548 glCompileShader(sh);
2549 }
2550
2551 return p;
2552 }
2553
CheckProgram(GLuint program, bool* compile_error = NULL)2554 bool CheckProgram(GLuint program, bool* compile_error = NULL)
2555 {
2556 GLint compile_status = GL_TRUE;
2557 GLint status;
2558 glGetProgramiv(program, GL_LINK_STATUS, &status);
2559
2560 if (status == GL_FALSE)
2561 {
2562 GLint attached_shaders;
2563 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
2564
2565 if (attached_shaders > 0)
2566 {
2567 std::vector<GLuint> shaders(attached_shaders);
2568 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
2569
2570 for (GLint i = 0; i < attached_shaders; ++i)
2571 {
2572 GLenum type;
2573 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
2574 switch (type)
2575 {
2576 case GL_VERTEX_SHADER:
2577 m_context.getTestContext().getLog()
2578 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
2579 break;
2580 case GL_TESS_CONTROL_SHADER:
2581 m_context.getTestContext().getLog()
2582 << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
2583 << tcu::TestLog::EndMessage;
2584 break;
2585 case GL_TESS_EVALUATION_SHADER:
2586 m_context.getTestContext().getLog()
2587 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
2588 << tcu::TestLog::EndMessage;
2589 break;
2590 case GL_GEOMETRY_SHADER:
2591 m_context.getTestContext().getLog()
2592 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
2593 break;
2594 case GL_FRAGMENT_SHADER:
2595 m_context.getTestContext().getLog()
2596 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
2597 break;
2598 case GL_COMPUTE_SHADER:
2599 m_context.getTestContext().getLog()
2600 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
2601 break;
2602 default:
2603 m_context.getTestContext().getLog()
2604 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
2605 }
2606
2607 GLint res;
2608 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
2609 if (res != GL_TRUE)
2610 compile_status = res;
2611
2612 // shader source
2613 GLint length;
2614 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
2615 if (length > 0)
2616 {
2617 std::vector<GLchar> source(length);
2618 glGetShaderSource(shaders[i], length, NULL, &source[0]);
2619 m_context.getTestContext().getLog()
2620 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
2621 }
2622
2623 // shader info log
2624 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
2625 if (length > 0)
2626 {
2627 std::vector<GLchar> log(length);
2628 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
2629 m_context.getTestContext().getLog()
2630 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2631 }
2632 }
2633 }
2634
2635 // program info log
2636 GLint length;
2637 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
2638 if (length > 0)
2639 {
2640 std::vector<GLchar> log(length);
2641 glGetProgramInfoLog(program, length, NULL, &log[0]);
2642 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2643 }
2644 }
2645
2646 if (compile_error)
2647 *compile_error = (compile_status == GL_TRUE ? false : true);
2648 if (compile_status != GL_TRUE)
2649 return false;
2650 return status == GL_TRUE ? true : false;
2651 }
2652
VerifyCompute(GLuint program, long& error)2653 virtual void inline VerifyCompute(GLuint program, long& error)
2654 {
2655 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_ACTIVE_RESOURCES, 5, error);
2656 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_MAX_NAME_LENGTH, 3, error);
2657
2658 GLint res;
2659 glGetProgramStageiv(program, GL_COMPUTE_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &res);
2660 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, res, error);
2661 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 5, error);
2662 VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 3,
2663 error);
2664
2665 std::map<std::string, GLuint> indicesTS;
2666 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ax", error);
2667 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ay", error);
2668 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bx", error);
2669 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "by", error);
2670 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bz", error);
2671 std::map<std::string, GLuint> indicesTU;
2672 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2673 VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "b[0]", error);
2674
2675 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], "ax", error);
2676 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], "ay", error);
2677 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], "bx", error);
2678 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], "by", error);
2679 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], "bz", error);
2680 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2681 VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], "b[0]", error);
2682
2683 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "a",
2684 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a"), error);
2685 VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "b",
2686 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b"), error);
2687
2688 GLenum propsS[] = { GL_NAME_LENGTH };
2689 GLint expectedS[] = { 3 };
2690 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], 1, propsS, 1, expectedS, error);
2691 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], 1, propsS, 1, expectedS, error);
2692 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], 1, propsS, 1, expectedS, error);
2693 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], 1, propsS, 1, expectedS, error);
2694 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], 1, propsS, 1, expectedS, error);
2695
2696 GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2697 GLint expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a") };
2698 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], 4, propsU, 4, expectedU,
2699 error);
2700 GLint expectedU2[] = { 5, 3, 3, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b") };
2701 VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], 4, propsU, 4, expectedU2,
2702 error);
2703 }
2704
Run()2705 virtual long Run()
2706 {
2707 GLuint program = CreateComputeProgram(ComputeShader());
2708 glLinkProgram(program);
2709 if (!CheckProgram(program))
2710 {
2711 glDeleteProgram(program);
2712 return ERROR;
2713 }
2714 glUseProgram(program);
2715
2716 long error = NO_ERROR;
2717
2718 VerifyCompute(program, error);
2719
2720 glDeleteProgram(program);
2721 return error;
2722 }
2723 };
2724
2725 class InvalidValueTest : public SimpleShaders
2726 {
Title()2727 virtual std::string Title()
2728 {
2729 return "Invalid Value Test";
2730 }
2731
PassCriteria()2732 virtual std::string PassCriteria()
2733 {
2734 return "GL_INVALID_VALUE error is generated after every function call.";
2735 }
2736
Purpose()2737 virtual std::string Purpose()
2738 {
2739 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2740 }
2741
Method()2742 virtual std::string Method()
2743 {
2744 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2745 }
2746
Run()2747 virtual long Run()
2748 {
2749 long error = NO_ERROR;
2750
2751 GLint res = 0;
2752 GLsizei len = 0;
2753 GLchar name[100] = { '\0' };
2754 GLenum props[1] = { GL_NAME_LENGTH };
2755
2756 m_context.getTestContext().getLog()
2757 << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2758 << tcu::TestLog::EndMessage;
2759 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2760 ExpectError(GL_INVALID_VALUE, error);
2761 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2762 ExpectError(GL_INVALID_VALUE, error);
2763 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2764 ExpectError(GL_INVALID_VALUE, error);
2765 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2766 ExpectError(GL_INVALID_VALUE, error);
2767 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2768 ExpectError(GL_INVALID_VALUE, error);
2769 glGetProgramResourceLocationIndex(1337u, GL_PROGRAM_OUTPUT, "pie");
2770 ExpectError(GL_INVALID_VALUE, error);
2771 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2772
2773 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2774 glBindAttribLocation(program, 0, "position");
2775 glBindFragDataLocation(program, 0, "color");
2776 LinkProgram(program);
2777
2778 m_context.getTestContext().getLog()
2779 << tcu::TestLog::Message
2780 << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2781 << tcu::TestLog::EndMessage;
2782 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2783 ExpectError(GL_INVALID_VALUE, error);
2784 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2785
2786 m_context.getTestContext().getLog()
2787 << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2788 << tcu::TestLog::EndMessage;
2789 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2790 ExpectError(GL_INVALID_VALUE, error);
2791 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2792
2793 std::string str = "position";
2794 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2795 ExpectError(GL_INVALID_VALUE, error);
2796 GLenum prop = GL_NAME_LENGTH;
2797 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2798 ExpectError(GL_INVALID_VALUE, error);
2799
2800 glDeleteProgram(program);
2801 return error;
2802 }
2803 };
2804
2805 class InvalidEnumTest : public AtomicCounterSimple
2806 {
Title()2807 virtual std::string Title()
2808 {
2809 return "Invalid Enum Test";
2810 }
2811
PassCriteria()2812 virtual std::string PassCriteria()
2813 {
2814 return "GL_INVALID_ENUM error is generated after every function call.";
2815 }
2816
Purpose()2817 virtual std::string Purpose()
2818 {
2819 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2820 }
2821
Method()2822 virtual std::string Method()
2823 {
2824 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2825 }
2826
Run()2827 virtual long Run()
2828 {
2829 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2830 glBindAttribLocation(program, 0, "position");
2831 glBindFragDataLocation(program, 0, "color");
2832 LinkProgram(program);
2833
2834 long error = NO_ERROR;
2835
2836 GLint res = 0;
2837 GLsizei len = 0;
2838 GLchar name[100] = { '\0' };
2839 GLenum props[1] = { GL_TEXTURE_1D };
2840
2841 m_context.getTestContext().getLog()
2842 << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER "
2843 << "in GetProgramResourceIndex or GetProgramResourceName" << tcu::TestLog::EndMessage;
2844 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2845 ExpectError(GL_INVALID_ENUM, error);
2846 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2847 ExpectError(GL_INVALID_ENUM, error);
2848 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2849
2850 m_context.getTestContext().getLog()
2851 << tcu::TestLog::Message << "Case 2: <props> is not a property name supported by "
2852 << "the command GetProgramResourceiv" << tcu::TestLog::EndMessage;
2853 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2854 ExpectError(GL_INVALID_ENUM, error);
2855 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2856
2857 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2858 ExpectError(GL_INVALID_ENUM, error);
2859
2860 glDeleteProgram(program);
2861 return error;
2862 }
2863 };
2864
2865 class InvalidOperationTest : public SimpleShaders
2866 {
Title()2867 virtual std::string Title()
2868 {
2869 return "Invalid Operation Test";
2870 }
2871
PassCriteria()2872 virtual std::string PassCriteria()
2873 {
2874 return "GL_INVALID_OPERATION error is generated after every function call.";
2875 }
2876
Purpose()2877 virtual std::string Purpose()
2878 {
2879 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2880 }
2881
Method()2882 virtual std::string Method()
2883 {
2884 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2885 }
2886
Run()2887 virtual long Run()
2888 {
2889 long error = NO_ERROR;
2890
2891 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2892 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2893 glBindAttribLocation(program, 0, "position");
2894 glBindFragDataLocation(program, 0, "color");
2895 LinkProgram(program);
2896
2897 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2898 GLint res = 0;
2899 GLsizei len = 0;
2900 GLchar name[100] = { '\0' };
2901 GLenum props[1] = { GL_OFFSET };
2902
2903 m_context.getTestContext().getLog()
2904 << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2905 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2906 ExpectError(GL_INVALID_OPERATION, error);
2907 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2908 ExpectError(GL_INVALID_OPERATION, error);
2909 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2910 ExpectError(GL_INVALID_OPERATION, error);
2911 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2912 ExpectError(GL_INVALID_OPERATION, error);
2913 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2914 ExpectError(GL_INVALID_OPERATION, error);
2915 glGetProgramResourceLocationIndex(sh, GL_PROGRAM_OUTPUT, "pie");
2916 ExpectError(GL_INVALID_OPERATION, error);
2917 glDeleteShader(sh);
2918 m_context.getTestContext().getLog()
2919 << tcu::TestLog::Message << "Case 1 finished\n"
2920 << "Case 2: <pname> is not supported in GetProgramInterfacei" << tcu::TestLog::EndMessage;
2921
2922 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2923 ExpectError(GL_INVALID_OPERATION, error);
2924 m_context.getTestContext().getLog()
2925 << tcu::TestLog::Message << "Case 2 finished\n"
2926 << "Case 3: <props> is not supported in GetProgramResourceiv" << tcu::TestLog::EndMessage;
2927
2928 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2929 ExpectError(GL_INVALID_OPERATION, error);
2930 m_context.getTestContext().getLog()
2931 << tcu::TestLog::Message << "Case 3 finished\n"
2932 << "Case 4: <program> has not been linked in GetProgramResourceLocation/GetProgramResourceLocationIndex"
2933 << tcu::TestLog::EndMessage;
2934
2935 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2936 ExpectError(GL_INVALID_OPERATION, error);
2937 glGetProgramResourceLocationIndex(program2, GL_PROGRAM_OUTPUT, "pie");
2938 ExpectError(GL_INVALID_OPERATION, error);
2939 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished\n" << tcu::TestLog::EndMessage;
2940
2941 glDeleteProgram(program);
2942 glDeleteProgram(program2);
2943 return error;
2944 }
2945 };
2946
2947 class ShaderStorageBlock : public SimpleShaders
2948 {
Title()2949 virtual std::string Title()
2950 {
2951 return "Shader Storage Block Test";
2952 }
2953
ShadersDesc()2954 virtual std::string ShadersDesc()
2955 {
2956 return "fallthrough fragment and vertex shaders with different types of storage blocks used";
2957 }
2958
PurposeExt()2959 virtual std::string PurposeExt()
2960 {
2961 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2962 "params.\n";
2963 }
2964
FragmentShader()2965 virtual std::string FragmentShader()
2966 {
2967 return "#version 430 \n"
2968 ""
2969 "struct U { \n"
2970 " bool a[3]; \n"
2971 " mediump vec4 b; \n"
2972 " mediump mat3 c; \n"
2973 " mediump float d[2]; \n"
2974 "}; \n"
2975 ""
2976 "struct UU { \n"
2977 " U a; \n"
2978 " U b[2]; \n"
2979 " uvec2 c; \n"
2980 "}; \n"
2981 ""
2982 "layout(binding=4) buffer TrickyBuffer { \n"
2983 " UU a[3]; \n"
2984 " mediump mat4 b; \n"
2985 " uint c; \n"
2986 "} e[2]; \n"
2987 ""
2988 "layout(binding = 0) buffer SimpleBuffer { \n"
2989 " mediump mat3x2 a; \n"
2990 " mediump mat4 b; \n"
2991 " mediump vec4 c; \n"
2992 "}; \n"
2993 ""
2994 "layout(binding = 1) buffer NotSoSimpleBuffer { \n"
2995 " ivec2 a[4]; \n"
2996 " mediump mat3 b[2]; \n"
2997 " mediump mat2 c; \n"
2998 "} d; \n"
2999 ""
3000 "out mediump vec4 color; \n"
3001 ""
3002 "void main() { \n"
3003 " mediump float tmp; \n"
3004 " mediump float tmp2; \n"
3005 " tmp = e[0].a[0].b[0].d[0] * float(e[1].c); \n"
3006 " tmp2 = a[0][0] * b[0][0] * c.x; \n"
3007 " tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0]; \n"
3008 " color = vec4(0, 1, 0, 1) * tmp * tmp2; \n"
3009 "}";
3010 }
3011
Run()3012 virtual long Run()
3013 {
3014 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3015 glBindAttribLocation(program, 0, "position");
3016 glBindFragDataLocation(program, 0, "color");
3017 LinkProgram(program);
3018
3019 long error = NO_ERROR;
3020
3021 GLint res;
3022 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
3023 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
3024 if (res < 7)
3025 {
3026 m_context.getTestContext().getLog()
3027 << tcu::TestLog::Message
3028 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
3029 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
3030 error = ERROR;
3031 }
3032 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
3033 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
3034
3035 std::map<std::string, GLuint> indicesSSB;
3036 std::map<std::string, GLuint> indicesBV;
3037 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
3038 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
3039 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
3040 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
3041 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
3042 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
3043 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
3044 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
3045 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
3046 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
3047 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
3048 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
3049 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
3050
3051 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
3052 error);
3053 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
3054 "NotSoSimpleBuffer", error);
3055 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
3056 error);
3057 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
3058 error);
3059 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
3060 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
3061 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
3062 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
3063 "NotSoSimpleBuffer.a[0]", error);
3064 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
3065 "NotSoSimpleBuffer.c", error);
3066 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
3067 "NotSoSimpleBuffer.b[0]", error);
3068 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
3069 "TrickyBuffer.a[0].b[0].d[0]", error);
3070 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
3071 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
3072
3073 GLenum props[] = { GL_NAME_LENGTH,
3074 GL_BUFFER_BINDING,
3075 GL_NUM_ACTIVE_VARIABLES,
3076 GL_REFERENCED_BY_COMPUTE_SHADER,
3077 GL_REFERENCED_BY_FRAGMENT_SHADER,
3078 GL_REFERENCED_BY_GEOMETRY_SHADER,
3079 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3080 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3081 GL_REFERENCED_BY_VERTEX_SHADER };
3082 GLint expected[] = { 13, 0, 3, 0, 1, 0, 0, 0, 0 };
3083 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 9, props, 9, expected,
3084 error);
3085
3086 GLenum props2[] = { GL_NAME_LENGTH,
3087 GL_BUFFER_BINDING,
3088 GL_REFERENCED_BY_COMPUTE_SHADER,
3089 GL_REFERENCED_BY_FRAGMENT_SHADER,
3090 GL_REFERENCED_BY_GEOMETRY_SHADER,
3091 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3092 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3093 GL_REFERENCED_BY_VERTEX_SHADER };
3094 GLint expected2[] = { 18, 1, 0, 1, 0, 0, 0, 0 };
3095 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 8, props2, 8,
3096 expected2, error);
3097 GLint expected3[] = { 16, 4, 0, 1, 0, 0, 0, 0 };
3098 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 8, props2, 8,
3099 expected3, error);
3100 GLint expected4[] = { 16, 5, 0, 1, 0, 0, 0, 0 };
3101 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 8, props2, 8,
3102 expected4, error);
3103
3104 GLenum props3[] = { GL_NAME_LENGTH,
3105 GL_TYPE,
3106 GL_ARRAY_SIZE,
3107 GL_BLOCK_INDEX,
3108 GL_ARRAY_STRIDE,
3109 GL_IS_ROW_MAJOR,
3110 GL_REFERENCED_BY_COMPUTE_SHADER,
3111 GL_REFERENCED_BY_FRAGMENT_SHADER,
3112 GL_REFERENCED_BY_GEOMETRY_SHADER,
3113 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3114 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3115 GL_REFERENCED_BY_VERTEX_SHADER,
3116 GL_TOP_LEVEL_ARRAY_SIZE,
3117 GL_TOP_LEVEL_ARRAY_STRIDE };
3118 GLint expected5[] = {
3119 2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
3120 };
3121 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 14, props3, 14, expected5, error);
3122
3123 GLenum props4[] = { GL_NAME_LENGTH,
3124 GL_TYPE,
3125 GL_ARRAY_SIZE,
3126 GL_BLOCK_INDEX,
3127 GL_MATRIX_STRIDE,
3128 GL_IS_ROW_MAJOR,
3129 GL_REFERENCED_BY_COMPUTE_SHADER,
3130 GL_REFERENCED_BY_FRAGMENT_SHADER,
3131 GL_REFERENCED_BY_GEOMETRY_SHADER,
3132 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3133 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3134 GL_REFERENCED_BY_VERTEX_SHADER,
3135 GL_TOP_LEVEL_ARRAY_SIZE };
3136 GLint expected6[] = {
3137 28, GL_FLOAT, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 3
3138 };
3139 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 13, props4, 13,
3140 expected6, error);
3141
3142 GLenum prop = GL_ACTIVE_VARIABLES;
3143 const GLsizei bufSize = 1000;
3144 GLsizei length;
3145 GLint param[bufSize];
3146 std::set<GLuint> exp;
3147 exp.insert(indicesBV["a"]);
3148 exp.insert(indicesBV["b"]);
3149 exp.insert(indicesBV["c"]);
3150 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
3151 param);
3152 for (int i = 0; i < length; ++i)
3153 {
3154 if (exp.find(param[i]) == exp.end())
3155 {
3156 m_context.getTestContext().getLog()
3157 << tcu::TestLog::Message
3158 << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
3159 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3160 "GL_SHADER_STORAGE_BLOCK"
3161 << tcu::TestLog::EndMessage;
3162 glDeleteProgram(program);
3163 return ERROR;
3164 }
3165 else if (length != 3)
3166 {
3167 m_context.getTestContext().getLog()
3168 << tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3169 "interface: GL_SHADER_STORAGE_BLOCK\n"
3170 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3171 glDeleteProgram(program);
3172 return ERROR;
3173 }
3174 }
3175 std::set<GLuint> exp2;
3176 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
3177 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
3178 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
3179 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
3180 &length, param);
3181 for (int i = 0; i < length; ++i)
3182 {
3183 if (exp2.find(param[i]) == exp2.end())
3184 {
3185 m_context.getTestContext().getLog()
3186 << tcu::TestLog::Message
3187 << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
3188 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3189 "GL_SHADER_STORAGE_BLOCK"
3190 << tcu::TestLog::EndMessage;
3191 glDeleteProgram(program);
3192 return ERROR;
3193 }
3194 else if (length != 3)
3195 {
3196 m_context.getTestContext().getLog()
3197 << tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3198 "interface: GL_SHADER_STORAGE_BLOCK\n"
3199 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3200 glDeleteProgram(program);
3201 return ERROR;
3202 }
3203 }
3204
3205 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
3206 if (res < 3)
3207 {
3208 m_context.getTestContext().getLog()
3209 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
3210 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
3211 return ERROR;
3212 }
3213
3214 glDeleteProgram(program);
3215 return error;
3216 }
3217 };
3218
3219 class UniformBlockArray : public SimpleShaders
3220 {
Title()3221 virtual std::string Title()
3222 {
3223 return "Uniform Block Array Test";
3224 }
3225
ShadersDesc()3226 virtual std::string ShadersDesc()
3227 {
3228 return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
3229 }
3230
PurposeExt()3231 virtual std::string PurposeExt()
3232 {
3233 return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
3234 }
3235
VertexShader()3236 virtual std::string VertexShader()
3237 {
3238 return "#version 430 \n"
3239 "void main(void) \n"
3240 "{ \n"
3241 " gl_Position = vec4(1.0); \n"
3242 "}";
3243 }
3244
FragmentShader()3245 virtual std::string FragmentShader()
3246 {
3247 return "#version 430 \n"
3248 "uniform TestBlock { \n"
3249 " mediump vec4 color; \n"
3250 "} blockInstance[4]; \n"
3251 ""
3252 "out mediump vec4 color; \n"
3253 "void main() { \n"
3254 " color = blockInstance[2].color + blockInstance[3].color; \n"
3255 "}";
3256 }
3257
Run()3258 virtual long Run()
3259 {
3260 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3261 LinkProgram(program);
3262
3263 long error = NO_ERROR;
3264
3265 std::map<std::string, GLuint> indicesUB;
3266 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
3267
3268 std::map<std::string, GLuint> indicesU;
3269 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
3270
3271 GLenum props[] = { GL_BLOCK_INDEX };
3272 GLint expected[] = { static_cast<GLint>(indicesUB["TestBlock"]) };
3273 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
3274
3275 glDeleteProgram(program);
3276 return error;
3277 }
3278 };
3279
3280 class TransformFeedbackBuiltin : public SimpleShaders
3281 {
Title()3282 virtual std::string Title()
3283 {
3284 return "Transform Feedback Built-in Variables";
3285 }
3286
ShadersDesc()3287 virtual std::string ShadersDesc()
3288 {
3289 return "fallthrough fragment and vertex shaders with different types of out variables used";
3290 }
3291
PurposeExt()3292 virtual std::string PurposeExt()
3293 {
3294 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param with"
3295 " built-in variables (gl_NextBuffer, gl_SkipComponents) used.\n";
3296 }
3297
VertexShader()3298 virtual std::string VertexShader()
3299 {
3300 return "#version 430 \n"
3301 "in vec4 position; \n"
3302 ""
3303 "out ivec4 a; \n"
3304 "out uvec2 c; \n"
3305 "out uint d; \n"
3306 "out int f; \n"
3307 "out uint e; \n"
3308 "out int g; \n"
3309 ""
3310 "void main(void) \n"
3311 "{ \n"
3312 " vec4 pos; \n"
3313 " a = ivec4(1); \n"
3314 " c = uvec2(1u); \n"
3315 " d = 1u; \n"
3316 " f = 1; \n"
3317 " e = 1u; \n"
3318 " g = 1; \n"
3319 " gl_Position = position; \n"
3320 "}";
3321 }
3322
Run()3323 virtual long Run()
3324 {
3325 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3326 glBindAttribLocation(program, 0, "position");
3327 glBindFragDataLocation(program, 0, "color");
3328 const char* varyings[11] = { "a", "gl_NextBuffer", "c", "gl_SkipComponents1", "d", "gl_SkipComponents2",
3329 "f", "gl_SkipComponents3", "e", "gl_SkipComponents4", "g" };
3330 glTransformFeedbackVaryings(program, 11, varyings, GL_INTERLEAVED_ATTRIBS);
3331 LinkProgram(program);
3332
3333 long error = NO_ERROR;
3334
3335 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 11, error);
3336 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 19, error);
3337
3338 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_NextBuffer", GL_INVALID_INDEX, error);
3339 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents1", GL_INVALID_INDEX,
3340 error);
3341 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents2", GL_INVALID_INDEX,
3342 error);
3343 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents3", GL_INVALID_INDEX,
3344 error);
3345 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents4", GL_INVALID_INDEX,
3346 error);
3347
3348 std::map<std::string, GLuint> indices;
3349 for (int i = 0; i < 11; i++)
3350 {
3351 GLsizei length;
3352 GLchar name[1024] = { '\0' };
3353 glGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, i, 1024, &length, name);
3354 indices[name] = i;
3355 }
3356
3357 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Indices of builtins:\n"
3358 << indices["gl_NextBuffer"] << ", " << indices["gl_SkipComponents1"] << ", "
3359 << indices["gl_SkipComponents2"] << ", " << indices["gl_SkipComponents3"]
3360 << ", " << indices["gl_SkipComponents4"] << tcu::TestLog::EndMessage;
3361
3362 GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
3363 GLint expected[] = { 14, GL_NONE, 0 };
3364 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_NextBuffer"], 3, props, 3,
3365 expected, error);
3366 GLint expected2[] = { 19, GL_NONE, 1 };
3367 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents1"], 3, props, 3,
3368 expected2, error);
3369 GLint expected3[] = { 19, GL_NONE, 2 };
3370 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents2"], 3, props, 3,
3371 expected3, error);
3372 GLint expected4[] = { 19, GL_NONE, 3 };
3373 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents3"], 3, props, 3,
3374 expected4, error);
3375 GLint expected5[] = { 19, GL_NONE, 4 };
3376 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents4"], 3, props, 3,
3377 expected5, error);
3378
3379 glDeleteProgram(program);
3380 return error;
3381 }
3382 };
3383
3384 class NullLength : public SimpleShaders
3385 {
3386
Title()3387 virtual std::string Title()
3388 {
3389 return "NULL Length Test";
3390 }
3391
PurposeExt()3392 virtual std::string PurposeExt()
3393 {
3394 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
3395 "crash).\n";
3396 }
3397
VertexShader()3398 virtual std::string VertexShader()
3399 {
3400 return "#version 430 \n"
3401 "in vec4 position; \n"
3402 "void main(void) \n"
3403 "{ \n"
3404 " gl_Position = position; \n"
3405 "}";
3406 }
3407
FragmentShader()3408 virtual std::string FragmentShader()
3409 {
3410 return "#version 430 \n"
3411 "out vec4 color; \n"
3412 "void main() { \n"
3413 " color = vec4(0, 1, 0, 1); \n"
3414 "}";
3415 }
3416
Run()3417 virtual long Run()
3418 {
3419 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3420 glBindAttribLocation(program, 0, "position");
3421 glBindFragDataLocation(program, 0, "color");
3422 LinkProgram(program);
3423
3424 GLchar name[1024] = { '\0' };
3425 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
3426 GLenum prop = GL_ARRAY_SIZE;
3427 GLint res;
3428 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
3429 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
3430
3431 std::string expected = "color";
3432 if (name != expected)
3433 {
3434 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
3435 << ", got: " << name << tcu::TestLog::EndMessage;
3436 glDeleteProgram(program);
3437 return ERROR;
3438 }
3439 else if (res != 1)
3440 {
3441 m_context.getTestContext().getLog()
3442 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
3443 glDeleteProgram(program);
3444 return ERROR;
3445 }
3446
3447 glDeleteProgram(program);
3448 return NO_ERROR;
3449 }
3450 };
3451
3452 class ArraysOfArrays : public SimpleShaders
3453 {
3454
Title()3455 virtual std::string Title()
3456 {
3457 return "Arrays Of Arrays Test";
3458 }
3459
ShadersDesc()3460 virtual std::string ShadersDesc()
3461 {
3462 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
3463 }
3464
PurposeExt()3465 virtual std::string PurposeExt()
3466 {
3467 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays extension.\n";
3468 }
3469
VertexShader()3470 virtual std::string VertexShader()
3471 {
3472 return "#version 430 \n"
3473 "in vec4 position; \n"
3474 "uniform vec4 a[3][4][5]; \n"
3475 "void main(void) \n"
3476 "{ \n"
3477 " gl_Position = position; \n"
3478 " for (int i = 0; i < 5; ++i) \n"
3479 " gl_Position += a[2][1][i]; \n"
3480 "}";
3481 }
3482
FragmentShader()3483 virtual std::string FragmentShader()
3484 {
3485 return "#version 430 \n"
3486 "out vec4 color; \n"
3487 "void main() { \n"
3488 " color = vec4(0, 1, 0, 1); \n"
3489 "}";
3490 }
3491
Run()3492 virtual long Run()
3493 {
3494 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3495 glBindAttribLocation(program, 0, "position");
3496 glBindFragDataLocation(program, 0, "color");
3497 LinkProgram(program);
3498
3499 long error = NO_ERROR;
3500
3501 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
3502
3503 std::map<std::string, GLuint> indices;
3504 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
3505 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
3506
3507 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
3508
3509 GLenum props[] = { GL_NAME_LENGTH,
3510 GL_TYPE,
3511 GL_ARRAY_SIZE,
3512 GL_OFFSET,
3513 GL_BLOCK_INDEX,
3514 GL_ARRAY_STRIDE,
3515 GL_MATRIX_STRIDE,
3516 GL_IS_ROW_MAJOR,
3517 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3518 GL_REFERENCED_BY_COMPUTE_SHADER,
3519 GL_REFERENCED_BY_FRAGMENT_SHADER,
3520 GL_REFERENCED_BY_GEOMETRY_SHADER,
3521 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3522 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3523 GL_REFERENCED_BY_VERTEX_SHADER,
3524 GL_LOCATION };
3525 GLint expected[] = {
3526 11, GL_FLOAT_VEC4, 5, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a[2][1]")
3527 };
3528 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 16, props, 16, expected, error);
3529
3530 glDeleteProgram(program);
3531 return error;
3532 }
3533 };
3534
3535 class TopLevelArray : public SimpleShaders
3536 {
3537
Title()3538 virtual std::string Title()
3539 {
3540 return "Top Level Array Test";
3541 }
3542
ShadersDesc()3543 virtual std::string ShadersDesc()
3544 {
3545 return "fallthrough fragment and vertex shaders with multi dimensional array used inside storage block";
3546 }
3547
PurposeExt()3548 virtual std::string PurposeExt()
3549 {
3550 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
3551 " and GL_TOP_LEVEL_ARRAY_STRIDE extension.\n";
3552 }
3553
FragmentShader()3554 virtual std::string FragmentShader()
3555 {
3556 return "#version 430 \n"
3557 "buffer Block { \n"
3558 " vec4 a[5][4][3]; \n"
3559 "}; \n"
3560 "out vec4 color; \n"
3561 "void main() { \n"
3562 " color = vec4(0, 1, 0, 1) + a[0][0][0]; \n"
3563 "}";
3564 }
3565
Run()3566 virtual long Run()
3567 {
3568 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3569 glBindAttribLocation(program, 0, "position");
3570 glBindFragDataLocation(program, 0, "color");
3571 LinkProgram(program);
3572
3573 long error = NO_ERROR;
3574
3575 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
3576 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
3577 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
3578
3579 std::map<std::string, GLuint> indicesSSB;
3580 std::map<std::string, GLuint> indicesBV;
3581 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
3582 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
3583
3584 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
3585 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
3586
3587 GLenum props3[] = { GL_NAME_LENGTH,
3588 GL_TYPE,
3589 GL_ARRAY_SIZE,
3590 GL_BLOCK_INDEX,
3591 GL_IS_ROW_MAJOR,
3592 GL_REFERENCED_BY_COMPUTE_SHADER,
3593 GL_REFERENCED_BY_FRAGMENT_SHADER,
3594 GL_REFERENCED_BY_GEOMETRY_SHADER,
3595 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3596 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3597 GL_REFERENCED_BY_VERTEX_SHADER,
3598 GL_TOP_LEVEL_ARRAY_SIZE };
3599 GLint expected5[] = { 11, GL_FLOAT_VEC4, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 0, 1, 0, 0, 0, 0, 5 };
3600 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 12, props3, 12, expected5, error);
3601
3602 GLenum prop = GL_TOP_LEVEL_ARRAY_STRIDE;
3603 GLsizei len;
3604 GLint res;
3605 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
3606 if (res <= 0)
3607 {
3608 m_context.getTestContext().getLog()
3609 << tcu::TestLog::Message
3610 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
3611 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
3612 glDeleteProgram(program);
3613 return ERROR;
3614 }
3615
3616 glDeleteProgram(program);
3617 return error;
3618 }
3619 };
3620
3621 class SeparateProgramsVertex : public SimpleShaders
3622 {
3623 public:
Title()3624 virtual std::string Title()
3625 {
3626 return "Separate Program Vertex Shader Test";
3627 }
3628
ShadersDesc()3629 virtual std::string ShadersDesc()
3630 {
3631 return "vertex shader as separate shader object";
3632 }
3633
PurposeExt()3634 virtual std::string PurposeExt()
3635 {
3636 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3637 "functionality.\n";
3638 }
3639
CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)3640 virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
3641 {
3642 GLuint program = glCreateShaderProgramv(type, count, strings);
3643 GLint status = GL_TRUE;
3644 glGetProgramiv(program, GL_LINK_STATUS, &status);
3645 if (status == GL_FALSE)
3646 {
3647 GLsizei length;
3648 GLchar log[1024];
3649 glGetProgramInfoLog(program, sizeof(log), &length, log);
3650 if (length > 1)
3651 {
3652 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
3653 << log << tcu::TestLog::EndMessage;
3654 }
3655 }
3656 return program;
3657 }
3658
Run()3659 virtual long Run()
3660 {
3661 long error = NO_ERROR;
3662
3663 const char* srcVS = "#version 430 core \n"
3664 "layout(location = 0) in vec4 in_vertex; \n"
3665 ""
3666 "out Color { \n"
3667 " float r, g, b; \n"
3668 " vec4 iLikePie; \n"
3669 "} vs_color; \n"
3670 "out gl_PerVertex { \n"
3671 " vec4 gl_Position; \n"
3672 "}; \n"
3673 ""
3674 "uniform float u; \n"
3675 "uniform vec4 v; \n"
3676 ""
3677 "void main() { \n"
3678 " gl_Position = in_vertex; \n"
3679 " vs_color.r = u; \n"
3680 " vs_color.g = 0.0; \n"
3681 " vs_color.b = 0.0; \n"
3682 " vs_color.iLikePie = v; \n"
3683 "}";
3684
3685 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
3686
3687 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
3688 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
3689 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
3690 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3691 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 15, error);
3692 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
3693
3694 std::map<std::string, GLuint> indicesU;
3695 std::map<std::string, GLuint> indicesI;
3696 std::map<std::string, GLuint> indicesO;
3697 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
3698 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
3699 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
3700 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.r", error);
3701 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.g", error);
3702 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.b", error);
3703 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.iLikePie", error);
3704 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3705
3706 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
3707 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
3708 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
3709 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.r"], "Color.r", error);
3710 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.g"], "Color.g", error);
3711 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.b"], "Color.b", error);
3712 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], "Color.iLikePie", error);
3713 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3714
3715 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
3716 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
3717 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
3718
3719 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.r", -1, error);
3720 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.g", -1, error);
3721 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.b", -1, error);
3722 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.iLikePie", -1, error);
3723 VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "gl_Position", -1, error);
3724
3725 GLenum props[] = { GL_NAME_LENGTH,
3726 GL_TYPE,
3727 GL_ARRAY_SIZE,
3728 GL_OFFSET,
3729 GL_BLOCK_INDEX,
3730 GL_ARRAY_STRIDE,
3731 GL_MATRIX_STRIDE,
3732 GL_IS_ROW_MAJOR,
3733 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3734 GL_REFERENCED_BY_COMPUTE_SHADER,
3735 GL_REFERENCED_BY_FRAGMENT_SHADER,
3736 GL_REFERENCED_BY_GEOMETRY_SHADER,
3737 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3738 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3739 GL_REFERENCED_BY_VERTEX_SHADER,
3740 GL_LOCATION };
3741 GLint expected[] = {
3742 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(vs, "v")
3743 };
3744 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 16, props, 16, expected, error);
3745
3746 GLenum props2[] = { GL_NAME_LENGTH,
3747 GL_TYPE,
3748 GL_ARRAY_SIZE,
3749 GL_REFERENCED_BY_COMPUTE_SHADER,
3750 GL_REFERENCED_BY_FRAGMENT_SHADER,
3751 GL_REFERENCED_BY_GEOMETRY_SHADER,
3752 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3753 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3754 GL_REFERENCED_BY_VERTEX_SHADER,
3755 GL_LOCATION,
3756 GL_IS_PER_PATCH };
3757 GLint expected2[] = { 10, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
3758 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 11, props2, 11, expected2, error);
3759
3760 GLenum props3[] = { GL_NAME_LENGTH,
3761 GL_TYPE,
3762 GL_ARRAY_SIZE,
3763 GL_REFERENCED_BY_COMPUTE_SHADER,
3764 GL_REFERENCED_BY_FRAGMENT_SHADER,
3765 GL_REFERENCED_BY_GEOMETRY_SHADER,
3766 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3767 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3768 GL_REFERENCED_BY_VERTEX_SHADER,
3769 GL_IS_PER_PATCH,
3770 GL_LOCATION_INDEX };
3771 GLint expected3[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, -1 };
3772 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], 11, props3, 11, expected3, error);
3773
3774 glDeleteProgram(vs);
3775 return error;
3776 }
3777 };
3778
3779 class SeparateProgramsTessControl : public SeparateProgramsVertex
3780 {
3781
Title()3782 virtual std::string Title()
3783 {
3784 return "Separate Program Tess Control Shader Test";
3785 }
3786
ShadersDesc()3787 virtual std::string ShadersDesc()
3788 {
3789 return "tess control shader as separate shader object";
3790 }
3791
PurposeExt()3792 virtual std::string PurposeExt()
3793 {
3794 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3795 "functionality.\n";
3796 }
3797
Run()3798 virtual long Run()
3799 {
3800 long error = NO_ERROR;
3801
3802 const char* srcTCS = "#version 430 \n"
3803 "layout(vertices = 3) out; \n"
3804 "layout(location = 0) patch out vec4 data; \n"
3805 "out gl_PerVertex { \n"
3806 " vec4 gl_Position; \n"
3807 " float gl_PointSize; \n"
3808 " float gl_ClipDistance[]; \n"
3809 "} gl_out[]; \n"
3810 ""
3811 "in Color { \n"
3812 " float r, g, b; \n"
3813 " vec4 iLikePie; \n"
3814 "} vs_color[]; \n"
3815 ""
3816 "void main() { \n"
3817 " data = vec4(1); \n"
3818 " gl_out[gl_InvocationID].gl_Position = \n"
3819 " vec4(vs_color[0].r, vs_color[0].g, vs_color[0].b, vs_color[0].iLikePie.x + "
3820 "float(gl_InvocationID)); \n"
3821 " gl_TessLevelInner[0] = 1.0; \n"
3822 " gl_TessLevelInner[1] = 1.0; \n"
3823 " gl_TessLevelOuter[0] = 1.0; \n"
3824 " gl_TessLevelOuter[1] = 1.0; \n"
3825 " gl_TessLevelOuter[2] = 1.0; \n"
3826 "}";
3827
3828 const GLuint tcs = CreateShaderProgram(GL_TESS_CONTROL_SHADER, 1, &srcTCS);
3829
3830 // gl_InvocationID should be included
3831 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 16, error);
3832 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 5, error);
3833
3834 std::map<std::string, GLuint> indicesI;
3835 std::map<std::string, GLuint> indicesO;
3836 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_PerVertex.gl_Position", error);
3837 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "data", error);
3838 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.r", error);
3839 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.g", error);
3840 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.b", error);
3841 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.iLikePie", error);
3842
3843 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_PerVertex.gl_Position"],
3844 "gl_PerVertex.gl_Position", error);
3845 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], "data", error);
3846 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.r"], "Color.r", error);
3847 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.g"], "Color.g", error);
3848 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.b"], "Color.b", error);
3849 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], "Color.iLikePie", error);
3850
3851 GLenum props2[] = { GL_NAME_LENGTH,
3852 GL_TYPE,
3853 GL_ARRAY_SIZE,
3854 GL_REFERENCED_BY_COMPUTE_SHADER,
3855 GL_REFERENCED_BY_FRAGMENT_SHADER,
3856 GL_REFERENCED_BY_GEOMETRY_SHADER,
3857 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3858 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3859 GL_REFERENCED_BY_VERTEX_SHADER,
3860 GL_IS_PER_PATCH };
3861 GLint expected2[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 0 };
3862 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], 10, props2, 10, expected2, error);
3863
3864 GLenum props3[] = { GL_NAME_LENGTH,
3865 GL_TYPE,
3866 GL_ARRAY_SIZE,
3867 GL_REFERENCED_BY_COMPUTE_SHADER,
3868 GL_REFERENCED_BY_FRAGMENT_SHADER,
3869 GL_REFERENCED_BY_GEOMETRY_SHADER,
3870 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3871 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3872 GL_REFERENCED_BY_VERTEX_SHADER,
3873 GL_IS_PER_PATCH,
3874 GL_LOCATION,
3875 GL_LOCATION_INDEX };
3876 GLint expected3[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 1, 0, -1 };
3877 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], 12, props3, 12, expected3, error);
3878
3879 glDeleteProgram(tcs);
3880 return error;
3881 }
3882 };
3883
3884 class SeparateProgramsTessEval : public SeparateProgramsVertex
3885 {
3886
Title()3887 virtual std::string Title()
3888 {
3889 return "Separate Program Tess Eval Shader Test";
3890 }
3891
ShadersDesc()3892 virtual std::string ShadersDesc()
3893 {
3894 return "tess eval shader as separate shader object";
3895 }
3896
Run()3897 virtual long Run()
3898 {
3899 long error = NO_ERROR;
3900
3901 const char* srcTCS = "#version 430 \n"
3902 "layout(quads, equal_spacing, ccw) in; \n"
3903 "out gl_PerVertex { \n"
3904 " vec4 gl_Position; \n"
3905 " float gl_PointSize; \n"
3906 " float gl_ClipDistance[]; \n"
3907 "}; \n"
3908 ""
3909 "in gl_PerVertex { \n"
3910 " vec4 gl_Position; \n"
3911 " float gl_PointSize; \n"
3912 " float gl_ClipDistance[]; \n"
3913 "} gl_in[]; \n"
3914 ""
3915 "void main() { \n"
3916 " vec4 p0 = gl_in[0].gl_Position; \n"
3917 " vec4 p1 = gl_in[1].gl_Position; \n"
3918 " vec4 p2 = gl_in[2].gl_Position; \n"
3919 " gl_Position = vec4(p0.x, p1.y, p2.z, p0.x); \n"
3920 "}";
3921
3922 const GLuint tcs = CreateShaderProgram(GL_TESS_EVALUATION_SHADER, 1, &srcTCS);
3923
3924 std::map<std::string, GLuint> indicesI;
3925 std::map<std::string, GLuint> indicesO;
3926 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
3927 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3928
3929 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
3930 "gl_PerVertex.gl_Position", error);
3931 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3932
3933 GLenum props2[] = { GL_NAME_LENGTH,
3934 GL_TYPE,
3935 GL_ARRAY_SIZE,
3936 GL_REFERENCED_BY_COMPUTE_SHADER,
3937 GL_REFERENCED_BY_FRAGMENT_SHADER,
3938 GL_REFERENCED_BY_GEOMETRY_SHADER,
3939 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3940 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3941 GL_REFERENCED_BY_VERTEX_SHADER,
3942 GL_IS_PER_PATCH };
3943 GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0 };
3944 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
3945 expected2, error);
3946
3947 GLenum props3[] = { GL_NAME_LENGTH,
3948 GL_TYPE,
3949 GL_ARRAY_SIZE,
3950 GL_REFERENCED_BY_COMPUTE_SHADER,
3951 GL_REFERENCED_BY_FRAGMENT_SHADER,
3952 GL_REFERENCED_BY_GEOMETRY_SHADER,
3953 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3954 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3955 GL_REFERENCED_BY_VERTEX_SHADER,
3956 GL_IS_PER_PATCH,
3957 GL_LOCATION_INDEX };
3958 GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0, -1 };
3959 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
3960
3961 glDeleteProgram(tcs);
3962 return error;
3963 }
3964 };
3965
3966 class SeparateProgramsGeometry : public SeparateProgramsVertex
3967 {
3968
Title()3969 virtual std::string Title()
3970 {
3971 return "Separate Program Geometry Shader Test";
3972 }
3973
ShadersDesc()3974 virtual std::string ShadersDesc()
3975 {
3976 return "geometry shader as separate shader object";
3977 }
3978
Run()3979 virtual long Run()
3980 {
3981 long error = NO_ERROR;
3982
3983 const char* srcTCS = "#version 430 \n"
3984 "layout(triangles) in; \n"
3985 "layout(triangle_strip, max_vertices = 4) out; \n"
3986 ""
3987 "out gl_PerVertex { \n"
3988 " vec4 gl_Position; \n"
3989 " float gl_PointSize; \n"
3990 " float gl_ClipDistance[]; \n"
3991 "}; \n"
3992 ""
3993 "in gl_PerVertex { \n"
3994 " vec4 gl_Position; \n"
3995 " float gl_PointSize; \n"
3996 " float gl_ClipDistance[]; \n"
3997 "} gl_in[]; \n"
3998 ""
3999 "void main() { \n"
4000 " gl_Position = vec4(-1, 1, 0, 1); \n"
4001 " EmitVertex(); \n"
4002 " gl_Position = vec4(-1, -1, 0, 1); \n"
4003 " EmitVertex(); \n"
4004 " gl_Position = vec4(1, 1, 0, 1); \n"
4005 " EmitVertex(); \n"
4006 " gl_Position = gl_in[0].gl_Position; \n"
4007 " EmitVertex(); \n"
4008 " EndPrimitive(); \n"
4009 "}";
4010
4011 const GLuint tcs = CreateShaderProgram(GL_GEOMETRY_SHADER, 1, &srcTCS);
4012
4013 std::map<std::string, GLuint> indicesI;
4014 std::map<std::string, GLuint> indicesO;
4015 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
4016 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
4017
4018 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
4019 "gl_PerVertex.gl_Position", error);
4020 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
4021
4022 GLenum props2[] = { GL_NAME_LENGTH,
4023 GL_TYPE,
4024 GL_ARRAY_SIZE,
4025 GL_REFERENCED_BY_COMPUTE_SHADER,
4026 GL_REFERENCED_BY_FRAGMENT_SHADER,
4027 GL_REFERENCED_BY_GEOMETRY_SHADER,
4028 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4029 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4030 GL_REFERENCED_BY_VERTEX_SHADER,
4031 GL_IS_PER_PATCH };
4032 GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0 };
4033 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
4034 expected2, error);
4035
4036 GLenum props3[] = { GL_NAME_LENGTH,
4037 GL_TYPE,
4038 GL_ARRAY_SIZE,
4039 GL_REFERENCED_BY_COMPUTE_SHADER,
4040 GL_REFERENCED_BY_FRAGMENT_SHADER,
4041 GL_REFERENCED_BY_GEOMETRY_SHADER,
4042 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4043 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4044 GL_REFERENCED_BY_VERTEX_SHADER,
4045 GL_IS_PER_PATCH,
4046 GL_LOCATION_INDEX };
4047 GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0, -1 };
4048 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
4049
4050 glDeleteProgram(tcs);
4051 return error;
4052 }
4053 };
4054
4055 class SeparateProgramsFragment : public SeparateProgramsVertex
4056 {
4057
Title()4058 virtual std::string Title()
4059 {
4060 return "Separate Program Fragment Shader Test";
4061 }
4062
ShadersDesc()4063 virtual std::string ShadersDesc()
4064 {
4065 return "fragment shader as separate shader object";
4066 }
4067
Run()4068 virtual long Run()
4069 {
4070 long error = NO_ERROR;
4071
4072 const char* srcTCS = "#version 430 \n"
4073 "out vec4 fs_color; \n"
4074 ""
4075 "layout(location = 1) uniform vec4 x; \n"
4076 ""
4077 "layout(binding = 0) buffer SimpleBuffer { \n"
4078 " vec4 a; \n"
4079 "}; \n"
4080 ""
4081 "in vec4 vs_color; \n"
4082 "void main() { \n"
4083 " fs_color = vs_color + x + a; \n"
4084 "}";
4085
4086 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
4087
4088 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4089 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4090 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
4091 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4092 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
4093 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
4094 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 2, error);
4095 VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4096 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4097 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 13, error);
4098 VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4099
4100 std::map<std::string, GLuint> indicesSSB;
4101 std::map<std::string, GLuint> indicesBV;
4102 std::map<std::string, GLuint> indicesI;
4103 std::map<std::string, GLuint> indicesO;
4104 std::map<std::string, GLuint> indicesU;
4105 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
4106 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
4107 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
4108 VerifyGetProgramResourceIndex(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
4109 VerifyGetProgramResourceIndex(tcs, GL_BUFFER_VARIABLE, indicesBV, "a", error);
4110
4111 VerifyGetProgramResourceName(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer", error);
4112 VerifyGetProgramResourceName(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
4113 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
4114 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
4115 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
4116
4117 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
4118
4119 GLenum props2[] = { GL_NAME_LENGTH,
4120 GL_TYPE,
4121 GL_ARRAY_SIZE,
4122 GL_REFERENCED_BY_COMPUTE_SHADER,
4123 GL_REFERENCED_BY_FRAGMENT_SHADER,
4124 GL_REFERENCED_BY_GEOMETRY_SHADER,
4125 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4126 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4127 GL_REFERENCED_BY_VERTEX_SHADER,
4128 GL_IS_PER_PATCH };
4129 GLint expected2[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0 };
4130 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 10, props2, 10, expected2, error);
4131
4132 GLenum props3[] = { GL_NAME_LENGTH,
4133 GL_TYPE,
4134 GL_ARRAY_SIZE,
4135 GL_REFERENCED_BY_COMPUTE_SHADER,
4136 GL_REFERENCED_BY_FRAGMENT_SHADER,
4137 GL_REFERENCED_BY_GEOMETRY_SHADER,
4138 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4139 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4140 GL_REFERENCED_BY_VERTEX_SHADER,
4141 GL_IS_PER_PATCH,
4142 GL_LOCATION_INDEX };
4143 GLint expected3[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0 };
4144 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 11, props3, 11, expected3, error);
4145
4146 GLenum props5[] = { GL_NAME_LENGTH,
4147 GL_TYPE,
4148 GL_ARRAY_SIZE,
4149 GL_OFFSET,
4150 GL_BLOCK_INDEX,
4151 GL_ARRAY_STRIDE,
4152 GL_MATRIX_STRIDE,
4153 GL_IS_ROW_MAJOR,
4154 GL_ATOMIC_COUNTER_BUFFER_INDEX,
4155 GL_REFERENCED_BY_COMPUTE_SHADER,
4156 GL_REFERENCED_BY_FRAGMENT_SHADER,
4157 GL_REFERENCED_BY_VERTEX_SHADER,
4158 GL_LOCATION };
4159 GLint expected5[] = { 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
4160 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props5, 13, expected5, error);
4161
4162 GLenum props6[] = { GL_NAME_LENGTH,
4163 GL_BUFFER_BINDING,
4164 GL_NUM_ACTIVE_VARIABLES,
4165 GL_REFERENCED_BY_COMPUTE_SHADER,
4166 GL_REFERENCED_BY_FRAGMENT_SHADER,
4167 GL_REFERENCED_BY_VERTEX_SHADER,
4168 GL_ACTIVE_VARIABLES };
4169 GLint expected6[] = { 13, 0, 1, 0, 1, 0, static_cast<GLint>(indicesBV["a"]) };
4170 VerifyGetProgramResourceiv(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 7, props6, 7, expected6,
4171 error);
4172
4173 GLenum props7[] = { GL_NAME_LENGTH,
4174 GL_TYPE,
4175 GL_ARRAY_SIZE,
4176 GL_BLOCK_INDEX,
4177 GL_ARRAY_STRIDE,
4178 GL_IS_ROW_MAJOR,
4179 GL_REFERENCED_BY_COMPUTE_SHADER,
4180 GL_REFERENCED_BY_FRAGMENT_SHADER,
4181 GL_REFERENCED_BY_VERTEX_SHADER,
4182 GL_TOP_LEVEL_ARRAY_SIZE,
4183 GL_TOP_LEVEL_ARRAY_STRIDE };
4184 GLint expected7[] = {
4185 2, GL_FLOAT_VEC4, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 1, 0
4186 };
4187 VerifyGetProgramResourceiv(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props7, 11, expected7, error);
4188
4189 glDeleteProgram(tcs);
4190 return error;
4191 }
4192 };
4193
4194 class UniformBlockAdvanced : public SimpleShaders
4195 {
Title()4196 virtual std::string Title()
4197 {
4198 return "Uniform Block Advanced Test";
4199 }
4200
ShadersDesc()4201 virtual std::string ShadersDesc()
4202 {
4203 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
4204 }
4205
PurposeExt()4206 virtual std::string PurposeExt()
4207 {
4208 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
4209 "verify results of querying offset, strides and row order.\n";
4210 }
4211
VertexShader()4212 virtual std::string VertexShader()
4213 {
4214 return "#version 430 \n"
4215 "in vec4 position; \n"
4216 ""
4217 "layout(row_major) uniform SimpleBlock { \n"
4218 " mat4 a; \n"
4219 " vec4 b[10]; \n"
4220 "}; \n"
4221 "void main(void) \n"
4222 "{ \n"
4223 " float tmp; \n"
4224 " tmp = a[0][0] + b[0].x; \n"
4225 " gl_Position = position * tmp; \n"
4226 "}";
4227 }
4228
Run()4229 virtual long Run()
4230 {
4231 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4232 glBindAttribLocation(program, 0, "position");
4233 glBindFragDataLocation(program, 0, "color");
4234 LinkProgram(program);
4235
4236 long error = NO_ERROR;
4237
4238 std::map<std::string, GLuint> indicesU;
4239 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
4240 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
4241
4242 GLenum props[] = { GL_IS_ROW_MAJOR };
4243 GLint expected[] = { 1 };
4244 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
4245
4246 GLenum prop = GL_MATRIX_STRIDE;
4247 GLsizei len;
4248 GLint res;
4249 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4250 if (res < 1)
4251 {
4252 m_context.getTestContext().getLog()
4253 << tcu::TestLog::Message
4254 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
4255 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4256 }
4257 prop = GL_OFFSET;
4258 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4259 if (res < 0)
4260 {
4261 m_context.getTestContext().getLog()
4262 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
4263 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
4264 }
4265 prop = GL_ARRAY_STRIDE;
4266 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
4267 if (res < 1)
4268 {
4269 m_context.getTestContext().getLog()
4270 << tcu::TestLog::Message
4271 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
4272 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4273 }
4274
4275 glDeleteProgram(program);
4276 return error;
4277 }
4278 };
4279
4280 class ArrayNames : public SimpleShaders
4281 {
4282
Title()4283 virtual std::string Title()
4284 {
4285 return "Array Names Test";
4286 }
4287
ShadersDesc()4288 virtual std::string ShadersDesc()
4289 {
4290 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
4291 }
4292
PurposeExt()4293 virtual std::string PurposeExt()
4294 {
4295 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
4296 "name strings correctly.\n";
4297 }
4298
VertexShader()4299 virtual std::string VertexShader()
4300 {
4301 return "#version 430 \n"
4302 "in vec4 position; \n"
4303 ""
4304 "uniform vec4 a[2]; \n"
4305 ""
4306 "void main(void) \n"
4307 "{ \n"
4308 " gl_Position = position + a[0] + a[1]; \n"
4309 "}";
4310 }
4311
Run()4312 virtual long Run()
4313 {
4314 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4315 glBindAttribLocation(program, 0, "position");
4316 LinkProgram(program);
4317
4318 long error = NO_ERROR;
4319
4320 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
4321 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
4322 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
4323 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
4324 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
4325 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
4326 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
4327 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
4328 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
4329 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
4330 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
4331 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
4332
4333 glDeleteProgram(program);
4334 return error;
4335 }
4336 };
4337
4338 class BuffLength : public SimpleShaders
4339 {
4340
Title()4341 virtual std::string Title()
4342 {
4343 return "Buff Length Test";
4344 }
4345
ShadersDesc()4346 virtual std::string ShadersDesc()
4347 {
4348 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
4349 }
4350
PurposeExt()4351 virtual std::string PurposeExt()
4352 {
4353 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
4354 "GetProgramResourceiv is respected.\n";
4355 }
4356
VertexShader()4357 virtual std::string VertexShader()
4358 {
4359 return "#version 430 \n"
4360 "in vec4 position; \n"
4361 ""
4362 "uniform vec4 someLongName; \n"
4363 ""
4364 "void main(void) \n"
4365 "{ \n"
4366 " gl_Position = position + someLongName; \n"
4367 "}";
4368 }
4369
Run()4370 virtual long Run()
4371 {
4372 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4373 glBindAttribLocation(program, 0, "position");
4374 LinkProgram(program);
4375
4376 long error = NO_ERROR;
4377
4378 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
4379 GLsizei length;
4380 GLchar buff[3] = { 'a', 'b', 'c' };
4381 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
4382 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
4383 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
4384 {
4385 m_context.getTestContext().getLog()
4386 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
4387 error = ERROR;
4388 }
4389 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
4390 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
4391 {
4392 m_context.getTestContext().getLog()
4393 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
4394 error = ERROR;
4395 }
4396 if (length != 1)
4397 {
4398 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
4399 << length << tcu::TestLog::EndMessage;
4400 error = ERROR;
4401 }
4402
4403 GLint params[3] = { 1, 2, 3 };
4404 GLenum props[] = { GL_NAME_LENGTH,
4405 GL_TYPE,
4406 GL_ARRAY_SIZE,
4407 GL_OFFSET,
4408 GL_BLOCK_INDEX,
4409 GL_ARRAY_STRIDE,
4410 GL_MATRIX_STRIDE,
4411 GL_IS_ROW_MAJOR,
4412 GL_ATOMIC_COUNTER_BUFFER_INDEX,
4413 GL_REFERENCED_BY_COMPUTE_SHADER,
4414 GL_REFERENCED_BY_FRAGMENT_SHADER,
4415 GL_REFERENCED_BY_VERTEX_SHADER,
4416 GL_LOCATION };
4417 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
4418 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
4419 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
4420 {
4421 m_context.getTestContext().getLog()
4422 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
4423 error = ERROR;
4424 }
4425 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
4426 if (params[0] != 13 || params[1] != GL_FLOAT_VEC4 || params[2] != 3)
4427 {
4428 m_context.getTestContext().getLog()
4429 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
4430 error = ERROR;
4431 }
4432 if (length != 2)
4433 {
4434 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
4435 << length << tcu::TestLog::EndMessage;
4436 error = ERROR;
4437 }
4438
4439 glDeleteProgram(program);
4440 return error;
4441 }
4442 };
4443
4444 class NoLocations : public SimpleShaders
4445 {
4446
Title()4447 virtual std::string Title()
4448 {
4449 return "No Locations Test";
4450 }
4451
ShadersDesc()4452 virtual std::string ShadersDesc()
4453 {
4454 return "fragment and vertex shaders with no locations set";
4455 }
4456
VertexShader()4457 virtual std::string VertexShader()
4458 {
4459 return "#version 430 \n"
4460 "in vec4 a; \n"
4461 "in vec4 b; \n"
4462 "in vec4 c[1]; \n"
4463 "in vec4 d; \n"
4464 "void main(void) \n"
4465 "{ \n"
4466 " gl_Position = a + b + c[0] + d; \n"
4467 "}";
4468 }
4469
FragmentShader()4470 virtual std::string FragmentShader()
4471 {
4472 return "#version 430 \n"
4473 "out vec4 a; \n"
4474 "out vec4 b; \n"
4475 "out vec4 c; \n"
4476 "out vec4 d[1]; \n"
4477 "void main() { \n"
4478 " a = vec4(0, 1, 0, 1); \n"
4479 " b = vec4(0, 1, 0, 1); \n"
4480 " c = vec4(0, 1, 0, 1); \n"
4481 " d[0] = vec4(0, 1, 0, 1); \n"
4482 "}";
4483 }
4484
Run()4485 virtual long Run()
4486 {
4487 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4488 glBindAttribLocation(program, 0, "position");
4489 glLinkProgram(program);
4490
4491 long error = NO_ERROR;
4492
4493 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
4494 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
4495 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
4496 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
4497
4498 std::map<std::string, GLuint> indicesI;
4499 std::map<std::string, GLuint> indicesO;
4500 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
4501 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
4502 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
4503 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
4504 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
4505 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
4506 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
4507 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
4508
4509 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
4510 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
4511 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c[0]", error);
4512 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
4513 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
4514 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
4515 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
4516 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
4517
4518 std::map<std::string, GLint> locationsI;
4519 std::map<std::string, GLint> locationsO;
4520 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
4521 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
4522 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
4523 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
4524 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
4525 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
4526 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
4527 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
4528
4529 GLenum props[] = { GL_NAME_LENGTH,
4530 GL_TYPE,
4531 GL_ARRAY_SIZE,
4532 GL_REFERENCED_BY_COMPUTE_SHADER,
4533 GL_REFERENCED_BY_FRAGMENT_SHADER,
4534 GL_REFERENCED_BY_VERTEX_SHADER };
4535 GLint expected[] = { 2, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4536 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
4537 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
4538 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
4539 GLint expected2[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4540 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected2, error);
4541 GLint expected3[] = { 2, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4542 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
4543 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
4544 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
4545 GLint expected4[] = { 5, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4546 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
4547
4548 glDeleteProgram(program);
4549 return error;
4550 }
4551 };
4552
4553 class ComputeShaderTest : public PIQBase
4554 {
Title()4555 virtual std::string Title()
4556 {
4557 return "Compute Shader Test";
4558 }
4559
ShadersDesc()4560 virtual std::string ShadersDesc()
4561 {
4562 return "compute shader";
4563 }
4564
ComputeShader()4565 virtual std::string ComputeShader()
4566 {
4567 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
4568 "layout(std430) buffer Output { \n"
4569 " vec4 data[]; \n"
4570 "} g_out; \n"
4571 ""
4572 "void main() { \n"
4573 " g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0); \n"
4574 " g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0); \n"
4575 "}";
4576 }
4577
CreateComputeProgram(const std::string& cs)4578 GLuint CreateComputeProgram(const std::string& cs)
4579 {
4580 const GLuint p = glCreateProgram();
4581
4582 const char* const kGLSLVer = "#version 430 core \n";
4583
4584 if (!cs.empty())
4585 {
4586 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
4587 glAttachShader(p, sh);
4588 glDeleteShader(sh);
4589 const char* const src[2] = { kGLSLVer, cs.c_str() };
4590 glShaderSource(sh, 2, src, NULL);
4591 glCompileShader(sh);
4592 }
4593
4594 return p;
4595 }
4596
CheckProgram(GLuint program, bool* compile_error = NULL)4597 bool CheckProgram(GLuint program, bool* compile_error = NULL)
4598 {
4599 GLint compile_status = GL_TRUE;
4600 GLint status;
4601 glGetProgramiv(program, GL_LINK_STATUS, &status);
4602
4603 if (status == GL_FALSE)
4604 {
4605 GLint attached_shaders;
4606 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
4607
4608 if (attached_shaders > 0)
4609 {
4610 std::vector<GLuint> shaders(attached_shaders);
4611 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
4612
4613 for (GLint i = 0; i < attached_shaders; ++i)
4614 {
4615 GLenum type;
4616 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
4617 switch (type)
4618 {
4619 case GL_VERTEX_SHADER:
4620 m_context.getTestContext().getLog()
4621 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
4622 break;
4623 case GL_TESS_CONTROL_SHADER:
4624 m_context.getTestContext().getLog()
4625 << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
4626 << tcu::TestLog::EndMessage;
4627 break;
4628 case GL_TESS_EVALUATION_SHADER:
4629 m_context.getTestContext().getLog()
4630 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
4631 << tcu::TestLog::EndMessage;
4632 break;
4633 case GL_GEOMETRY_SHADER:
4634 m_context.getTestContext().getLog()
4635 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
4636 break;
4637 case GL_FRAGMENT_SHADER:
4638 m_context.getTestContext().getLog()
4639 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
4640 break;
4641 case GL_COMPUTE_SHADER:
4642 m_context.getTestContext().getLog()
4643 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
4644 break;
4645 default:
4646 m_context.getTestContext().getLog()
4647 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
4648 }
4649
4650 GLint res;
4651 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
4652 if (res != GL_TRUE)
4653 compile_status = res;
4654
4655 // shader source
4656 GLint length;
4657 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
4658 if (length > 0)
4659 {
4660 std::vector<GLchar> source(length);
4661 glGetShaderSource(shaders[i], length, NULL, &source[0]);
4662 m_context.getTestContext().getLog()
4663 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
4664 }
4665
4666 // shader info log
4667 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
4668 if (length > 0)
4669 {
4670 std::vector<GLchar> log(length);
4671 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
4672 m_context.getTestContext().getLog()
4673 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4674 }
4675 }
4676 }
4677
4678 // program info log
4679 GLint length;
4680 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
4681 if (length > 0)
4682 {
4683 std::vector<GLchar> log(length);
4684 glGetProgramInfoLog(program, length, NULL, &log[0]);
4685 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4686 }
4687 }
4688
4689 if (compile_error)
4690 *compile_error = (compile_status == GL_TRUE ? false : true);
4691 if (compile_status != GL_TRUE)
4692 return false;
4693 return status == GL_TRUE ? true : false;
4694 }
4695
VerifyCompute(GLuint program, long& error)4696 virtual void inline VerifyCompute(GLuint program, long& error)
4697 {
4698 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
4699 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4700 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4701 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
4702 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4703
4704 std::map<std::string, GLuint> indicesSSB;
4705 std::map<std::string, GLuint> indicesBV;
4706 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
4707 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
4708
4709 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
4710 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
4711
4712 GLenum props3[] = { GL_NAME_LENGTH,
4713 GL_BUFFER_BINDING,
4714 GL_NUM_ACTIVE_VARIABLES,
4715 GL_REFERENCED_BY_COMPUTE_SHADER,
4716 GL_REFERENCED_BY_FRAGMENT_SHADER,
4717 GL_REFERENCED_BY_VERTEX_SHADER,
4718 GL_ACTIVE_VARIABLES };
4719 GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) };
4720 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
4721 error);
4722
4723 GLenum props4[] = { GL_NAME_LENGTH,
4724 GL_TYPE,
4725 GL_ARRAY_SIZE,
4726 GL_BLOCK_INDEX,
4727 GL_IS_ROW_MAJOR,
4728 GL_REFERENCED_BY_COMPUTE_SHADER,
4729 GL_REFERENCED_BY_FRAGMENT_SHADER,
4730 GL_REFERENCED_BY_VERTEX_SHADER,
4731 GL_TOP_LEVEL_ARRAY_SIZE };
4732 GLint expected4[] = { 15, GL_FLOAT_VEC4, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 };
4733 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
4734 error);
4735 }
4736
Run()4737 virtual long Run()
4738 {
4739 GLuint program = CreateComputeProgram(ComputeShader());
4740 glLinkProgram(program);
4741 if (!CheckProgram(program))
4742 {
4743 glDeleteProgram(program);
4744 return ERROR;
4745 }
4746 glUseProgram(program);
4747
4748 long error = NO_ERROR;
4749
4750 VerifyCompute(program, error);
4751
4752 glDeleteProgram(program);
4753 return error;
4754 }
4755 };
4756
4757 class QueryNotUsed : public SimpleShaders
4758 {
4759
Title()4760 virtual std::string Title()
4761 {
4762 return "Query Not Used Test";
4763 }
4764
PassCriteria()4765 virtual std::string PassCriteria()
4766 {
4767 return "Data from queries matches the not used program.";
4768 }
4769
Purpose()4770 virtual std::string Purpose()
4771 {
4772 return "Verify that program parameter works correctly and proper program is queried when different program is "
4773 "used.";
4774 }
4775
Method()4776 virtual std::string Method()
4777 {
4778 return "Create 2 programs, use one of them and query the other, verify the results.";
4779 }
4780
VertexShader2()4781 virtual std::string VertexShader2()
4782 {
4783 return "#version 430 \n"
4784 "in vec4 p; \n"
4785 "void main(void) \n"
4786 "{ \n"
4787 " gl_Position = p; \n"
4788 "}";
4789 }
4790
FragmentShader2()4791 virtual std::string FragmentShader2()
4792 {
4793 return "#version 430 \n"
4794 "out vec4 c; \n"
4795 "void main() { \n"
4796 " c = vec4(0, 1, 0, 1); \n"
4797 "}";
4798 }
4799
Run()4800 virtual long Run()
4801 {
4802 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4803 glBindAttribLocation(program, 0, "position");
4804 glBindFragDataLocation(program, 0, "color");
4805 LinkProgram(program);
4806
4807 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
4808 glBindAttribLocation(program, 0, "p");
4809 glBindFragDataLocation(program, 0, "c");
4810 LinkProgram(program2);
4811 glUseProgram(program2);
4812
4813 long error = NO_ERROR;
4814
4815 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4816 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4817 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4818 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
4819
4820 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4821 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
4822
4823 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
4824 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
4825
4826 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
4827 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4828
4829 VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4830
4831 GLenum props[] = { GL_NAME_LENGTH,
4832 GL_TYPE,
4833 GL_ARRAY_SIZE,
4834 GL_REFERENCED_BY_COMPUTE_SHADER,
4835 GL_REFERENCED_BY_FRAGMENT_SHADER,
4836 GL_REFERENCED_BY_GEOMETRY_SHADER,
4837 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4838 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4839 GL_REFERENCED_BY_VERTEX_SHADER,
4840 GL_LOCATION,
4841 GL_IS_PER_PATCH };
4842 GLint expected[] = { 9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
4843 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
4844
4845 GLenum props2[] = { GL_NAME_LENGTH,
4846 GL_TYPE,
4847 GL_ARRAY_SIZE,
4848 GL_REFERENCED_BY_COMPUTE_SHADER,
4849 GL_REFERENCED_BY_FRAGMENT_SHADER,
4850 GL_REFERENCED_BY_GEOMETRY_SHADER,
4851 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4852 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4853 GL_REFERENCED_BY_VERTEX_SHADER,
4854 GL_LOCATION,
4855 GL_IS_PER_PATCH,
4856 GL_LOCATION_INDEX };
4857 GLint expected2[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
4858 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
4859
4860 glDeleteProgram(program);
4861 glDeleteProgram(program2);
4862 return error;
4863 }
4864 };
4865
4866 class RelinkFailure : public SimpleShaders
4867 {
4868
Title()4869 virtual std::string Title()
4870 {
4871 return "Relink Failure Test";
4872 }
4873
PassCriteria()4874 virtual std::string PassCriteria()
4875 {
4876 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4877 }
4878
Purpose()4879 virtual std::string Purpose()
4880 {
4881 return "Verify that queries behave correctly after failed relink of a program.";
4882 }
4883
Method()4884 virtual std::string Method()
4885 {
4886 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
4887 "asking for locations.";
4888 }
4889
VertexShader()4890 virtual std::string VertexShader()
4891 {
4892 return "#version 430 \n"
4893 "in vec4 position; \n"
4894 "in vec3 pos; \n"
4895 "void main(void) \n"
4896 "{ \n"
4897 " gl_Position = position + vec4(pos, 1); \n"
4898 "}";
4899 }
4900
Run()4901 virtual long Run()
4902 {
4903 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4904 glBindAttribLocation(program, 0, "position");
4905 glBindAttribLocation(program, 1, "pos");
4906 glBindFragDataLocation(program, 0, "color");
4907 LinkProgram(program);
4908
4909 long error = NO_ERROR;
4910
4911 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
4912 glUseProgram(program);
4913
4914 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
4915 tcu::Vec4(1, -1, 0, 1) };
4916 GLuint vao, vbuf;
4917 glGenVertexArrays(1, &vao);
4918 glBindVertexArray(vao);
4919 glGenBuffers(1, &vbuf);
4920 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
4921 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
4922 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
4923 glEnableVertexAttribArray(0);
4924 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4925
4926 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4927 glDisableVertexAttribArray(0);
4928 glDeleteVertexArrays(1, &vao);
4929 glBindBuffer(GL_ARRAY_BUFFER, 0);
4930 glDeleteBuffers(1, &vbuf);
4931
4932 glBindAttribLocation(program, 0, "pos");
4933 glBindAttribLocation(program, 0, "position");
4934 const char* varyings[2] = { "q", "z" };
4935 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
4936 LinkProgram(program);
4937
4938 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
4939 ExpectError(GL_INVALID_OPERATION, error);
4940 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
4941 ExpectError(GL_INVALID_OPERATION, error);
4942 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
4943 ExpectError(GL_INVALID_OPERATION, error);
4944
4945 glDeleteProgram(program);
4946 return error;
4947 }
4948 };
4949
4950 class LinkFailure : public SimpleShaders
4951 {
4952
Title()4953 virtual std::string Title()
4954 {
4955 return "Link Failure Test";
4956 }
4957
PassCriteria()4958 virtual std::string PassCriteria()
4959 {
4960 return "INVALID_OPERATION is generated when asking for locations after failed link.";
4961 }
4962
Purpose()4963 virtual std::string Purpose()
4964 {
4965 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
4966 }
4967
Method()4968 virtual std::string Method()
4969 {
4970 return "Create a program, use it, relink with failure using different sources and then \n"
4971 "verify that INVALID_OPERATION is returned when asking for locations.";
4972 }
4973
VertexShader_prop()4974 virtual const char* VertexShader_prop()
4975 {
4976 return "#version 430 \n"
4977 "in vec4 posit; \n"
4978 "in vec4 p; \n"
4979 "void main(void) \n"
4980 "{ \n"
4981 " gl_Position = p + posit; \n"
4982 "}";
4983 }
4984
FragmentShader_prop()4985 virtual const char* FragmentShader_prop()
4986 {
4987 return "#version 430 \n"
4988 "out vec4 color; \n"
4989 "void main() { \n"
4990 " color = vec4(0, 1, 0, 1); \n"
4991 "}";
4992 }
4993
VertexShader_fail()4994 virtual const char* VertexShader_fail()
4995 {
4996 return "#version 430 \n"
4997 "in vec4 position; \n"
4998 "void main(void) \n"
4999 "{ \n"
5000 " gl_Position = position; \n"
5001 "}";
5002 }
5003
Run()5004 virtual long Run()
5005 {
5006 const GLuint program = glCreateProgram();
5007 const char* src_vs = VertexShader_prop();
5008 const char* src_fs = FragmentShader_prop();
5009 const char* src_vsh = VertexShader_fail();
5010
5011 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
5012 glAttachShader(program, sh1);
5013 glDeleteShader(sh1);
5014 glShaderSource(sh1, 1, &src_vs, NULL);
5015 glCompileShader(sh1);
5016
5017 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
5018 glAttachShader(program, sh2);
5019 glDeleteShader(sh2);
5020 glShaderSource(sh2, 1, &src_fs, NULL);
5021 glCompileShader(sh2);
5022
5023 glBindAttribLocation(program, 0, "p");
5024 glBindAttribLocation(program, 1, "posit");
5025 glBindFragDataLocation(program, 0, "color");
5026 LinkProgram(program);
5027
5028 long error = NO_ERROR;
5029
5030 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
5031 glUseProgram(program);
5032
5033 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
5034 tcu::Vec4(1, -1, 0, 1) };
5035 GLuint vao, vbuf;
5036 glGenVertexArrays(1, &vao);
5037 glBindVertexArray(vao);
5038 glGenBuffers(1, &vbuf);
5039 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
5040 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
5041 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5042 glEnableVertexAttribArray(0);
5043 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5044
5045 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5046 glDisableVertexAttribArray(0);
5047 glDeleteVertexArrays(1, &vao);
5048 glBindBuffer(GL_ARRAY_BUFFER, 0);
5049 glDeleteBuffers(1, &vbuf);
5050
5051 glDetachShader(program, sh1);
5052 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
5053 glAttachShader(program, vsh);
5054 glDeleteShader(vsh);
5055 glShaderSource(vsh, 1, &src_vsh, NULL);
5056 glCompileShader(vsh);
5057 const char* varyings[2] = { "q", "z" };
5058 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
5059 LinkProgram(program);
5060
5061 GLint res;
5062 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
5063 ExpectError(GL_INVALID_OPERATION, error);
5064 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
5065 if (res != 0 && res != 1)
5066 {
5067 m_context.getTestContext().getLog()
5068 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
5069 << tcu::TestLog::EndMessage;
5070 error = ERROR;
5071 }
5072 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
5073 if (res != 0 && res != 9)
5074 {
5075 m_context.getTestContext().getLog()
5076 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
5077 << tcu::TestLog::EndMessage;
5078 error = ERROR;
5079 }
5080 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
5081 ExpectError(GL_INVALID_OPERATION, error);
5082
5083 glDeleteProgram(program);
5084 return error;
5085 }
5086 };
5087
5088 } // anonymous namespace
5089
ProgramInterfaceQueryTests(deqp::Context& context)5090 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(deqp::Context& context)
5091 : TestCaseGroup(context, "program_interface_query", "")
5092 {
5093 }
5094
~ProgramInterfaceQueryTests(void)5095 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
5096 {
5097 }
5098
init()5099 void ProgramInterfaceQueryTests::init()
5100 {
5101 using namespace deqp;
5102 addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
5103 addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
5104 addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
5105 addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
5106 addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
5107 addChild(new TestSubcase(m_context, "output-types", TestSubcase::Create<OutputTypes>));
5108 addChild(new TestSubcase(m_context, "output-location-index", TestSubcase::Create<OutputLocationIndex>));
5109 addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
5110 addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
5111 addChild(new TestSubcase(m_context, "output-layout-index", TestSubcase::Create<OutputLayoutIndex>));
5112 addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
5113 addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
5114 addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
5115 addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
5116 addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
5117 addChild(new TestSubcase(m_context, "subroutines-vertex", TestSubcase::Create<SubroutinesVertex>));
5118 addChild(new TestSubcase(m_context, "subroutines-tess-control", TestSubcase::Create<SubroutinesTessControl>));
5119 addChild(new TestSubcase(m_context, "subroutines-tess-eval", TestSubcase::Create<SubroutinesTessEval>));
5120 addChild(new TestSubcase(m_context, "subroutines-geometry", TestSubcase::Create<SubroutinesGeometry>));
5121 addChild(new TestSubcase(m_context, "subroutines-fragment", TestSubcase::Create<SubroutinesFragment>));
5122 addChild(new TestSubcase(m_context, "subroutines-compute", TestSubcase::Create<SoubroutinesCompute>));
5123 addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
5124 addChild(new TestSubcase(m_context, "transform-feedback-built-in", TestSubcase::Create<TransformFeedbackBuiltin>));
5125 addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
5126 addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
5127 addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
5128 addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
5129 addChild(
5130 new TestSubcase(m_context, "separate-programs-tess-control", TestSubcase::Create<SeparateProgramsTessControl>));
5131 addChild(new TestSubcase(m_context, "separate-programs-tess-eval", TestSubcase::Create<SeparateProgramsTessEval>));
5132 addChild(new TestSubcase(m_context, "separate-programs-geometry", TestSubcase::Create<SeparateProgramsGeometry>));
5133 addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
5134 addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
5135 addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
5136 addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
5137 addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
5138 addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
5139 addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
5140 addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
5141 addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
5142 addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
5143 addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
5144 addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
5145 addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
5146 }
5147
5148 } // gl4cts namespace
5149