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 "es31cProgramInterfaceQueryTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include <cstdarg>
28 #include <map>
29 #include <set>
30
31 namespace glcts
32 {
33
34 using namespace glw;
35
36 namespace
37 {
38
39 class PIQBase : public glcts::SubcaseBase
40 {
41
42 public:
~PIQBase()43 virtual ~PIQBase()
44 {
45 }
46
PassCriteria()47 virtual std::string PassCriteria()
48 {
49 return "All called functions return expected values.";
50 }
51
Purpose()52 virtual std::string Purpose()
53 {
54 return "Verify that the set of tested functions glGetProgram* return\n"
55 "expected results when used to get data from program\n"
56 "made of " +
57 ShadersDesc() + "." + PurposeExt();
58 }
59
Method()60 virtual std::string Method()
61 {
62 return "Create a program using " + ShadersDesc() +
63 "\n"
64 "then use set of tested functions to get an information about it and\n"
65 "verify that information with the expected data" +
66 Expectations();
67 }
68
Cleanup()69 virtual long Cleanup()
70 {
71 glUseProgram(0);
72 return NO_ERROR;
73 }
74
Setup()75 virtual long Setup()
76 {
77 return NO_ERROR;
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
ShadersDesc()121 virtual std::string ShadersDesc()
122 {
123 return "";
124 }
125
Expectations()126 virtual std::string Expectations()
127 {
128 return ".";
129 }
130
PurposeExt()131 virtual std::string PurposeExt()
132 {
133 return "";
134 }
135
ExpectError(GLenum expected,long & error)136 virtual inline void ExpectError(GLenum expected, long &error)
137 {
138 if (error != NO_ERROR)
139 return;
140 GLenum tmp = glGetError();
141 if (tmp == expected)
142 {
143 m_context.getTestContext().getLog()
144 << tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
145 error = NO_ERROR; // Error is expected
146 }
147 else
148 {
149 error = ERROR;
150 m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
151 << " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
152 }
153 }
154
VerifyGetProgramInterfaceiv(GLuint program,GLenum programInterface,GLenum pname,int expected,long & error)155 virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
156 long &error)
157 {
158 GLint res;
159 glGetProgramInterfaceiv(program, programInterface, pname, &res);
160 if (res != expected)
161 {
162 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
163 << expected << tcu::TestLog::EndMessage;
164 error = ERROR;
165 }
166 }
167
VerifyGetProgramResourceIndex(GLuint program,GLenum programInterface,const std::string & name,GLuint expected,long & error)168 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string &name,
169 GLuint expected, long &error)
170 {
171 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
172 if (res != expected)
173 {
174 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
175 << expected << tcu::TestLog::EndMessage;
176 error = ERROR;
177 }
178 }
179
VerifyGetProgramResourceIndex(GLuint program,GLenum programInterface,std::map<std::string,GLuint> & indices,const std::string & name,long & error)180 virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface,
181 std::map<std::string, GLuint> &indices, const std::string &name,
182 long &error)
183 {
184 GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
185 if (res == GL_INVALID_INDEX)
186 {
187 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
188 << ", expected number other than -1" << tcu::TestLog::EndMessage;
189 error = ERROR;
190 return;
191 }
192 std::map<std::string, GLuint>::iterator it = indices.begin();
193 while (it != indices.end())
194 {
195 if (it->second == res)
196 {
197 m_context.getTestContext().getLog()
198 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
199 error = ERROR;
200 return;
201 }
202 ++it;
203 }
204 indices[name] = res;
205 }
206
VerifyGetProgramResourceName(GLuint program,GLenum programInterface,GLuint index,const std::string & expected,long & error)207 virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
208 const std::string &expected, long &error)
209 {
210 GLchar name[1024] = {'\0'};
211 GLsizei len;
212 glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
213 if (len <= 0 || len > 1023 || name[len - 1] == '\0')
214 {
215 m_context.getTestContext().getLog()
216 << tcu::TestLog::Message
217 << "ERROR: Length in glGetProgramResourceName should not count null terminator!"
218 << tcu::TestLog::EndMessage;
219 error = ERROR;
220 }
221 else if (name != expected || name[len] != '\0')
222 {
223 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
224 << expected << tcu::TestLog::EndMessage;
225 error = ERROR;
226 }
227 }
228
VerifyGetProgramResourceLocation(GLuint program,GLenum programInterface,const std::string & name,GLint expected,long & error)229 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
230 const std::string &name, GLint expected, long &error)
231 {
232 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
233 if (res != expected)
234 {
235 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
236 << expected << tcu::TestLog::EndMessage;
237 error = ERROR;
238 }
239 }
240
VerifyGetProgramResourceLocation(GLuint program,GLenum programInterface,std::map<std::string,GLint> & locations,const std::string & name,long & error)241 virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
242 std::map<std::string, GLint> &locations,
243 const std::string &name, long &error)
244 {
245 GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
246 if (res < 0)
247 {
248 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
249 << ", expected not less than 0" << tcu::TestLog::EndMessage;
250 error = ERROR;
251 return;
252 }
253 std::map<std::string, GLint>::iterator it = locations.begin();
254 while (it != locations.end())
255 {
256 if (it->second == res)
257 {
258 m_context.getTestContext().getLog()
259 << tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
260 error = ERROR;
261 return;
262 }
263 ++it;
264 }
265 locations[name] = res;
266 }
267
VerifyGetProgramResourceiv(GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum props[],GLsizei expectedLength,const GLint expected[],long & error)268 virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
269 GLsizei propCount, const GLenum props[], GLsizei expectedLength,
270 const GLint expected[], long &error)
271 {
272 const GLsizei bufSize = 1000;
273 GLsizei length;
274 GLint params[bufSize];
275 glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
276 if (length != expectedLength || length <= 0)
277 {
278 error = ERROR;
279 m_context.getTestContext().getLog()
280 << tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
281 << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
282 << tcu::TestLog::EndMessage;
283 return;
284 }
285 for (int i = 0; i < length; ++i)
286 {
287 if (params[i] != expected[i])
288 {
289 error = ERROR;
290 m_context.getTestContext().getLog()
291 << tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
292 << " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
293 << tcu::TestLog::EndMessage;
294 }
295 }
296 }
297
GetProgramivRetValue(GLuint program,GLenum pname)298 virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
299 {
300 GLint ret;
301 glGetProgramiv(program, pname, &ret);
302 return ret;
303 }
304
305 static const GLenum interfaces[];
306 };
307
308 const GLenum PIQBase::interfaces[] = {GL_PROGRAM_INPUT,
309 GL_PROGRAM_OUTPUT,
310 GL_UNIFORM,
311 GL_UNIFORM_BLOCK,
312 GL_BUFFER_VARIABLE,
313 GL_SHADER_STORAGE_BLOCK,
314 GL_ATOMIC_COUNTER_BUFFER,
315 GL_TRANSFORM_FEEDBACK_VARYING};
316
317 class NoShaders : public PIQBase
318 {
319
Title()320 virtual std::string Title()
321 {
322 return "No Shaders Test";
323 }
324
ShadersDesc()325 virtual std::string ShadersDesc()
326 {
327 return "no shaders";
328 }
329
Run()330 virtual long Run()
331 {
332 const GLuint program = glCreateProgram();
333
334 long error = NO_ERROR;
335 int size = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
336
337 for (int i = 0; i < size; ++i)
338 {
339 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
340 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
341 continue;
342 VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
343 }
344 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
345 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
346 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
347
348 for (int i = 0; i < size; ++i)
349 {
350 if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
351 continue;
352 VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
353 }
354
355 // can't test GetProgramResourceLocation* here since program has to be linked
356 // can't test GetProgramResourceiv, need valid index
357
358 glDeleteProgram(program);
359 return error;
360 }
361 };
362
363 class SimpleShaders : public PIQBase
364 {
365
366 public:
Title()367 virtual std::string Title()
368 {
369 return "Simple Shaders Test";
370 }
371
ShadersDesc()372 virtual std::string ShadersDesc()
373 {
374 return "fallthrough fragment and vertex shaders";
375 }
376
VertexShader()377 virtual std::string VertexShader()
378 {
379 return "#version 310 es \n"
380 "in vec4 position; \n"
381 "void main(void) \n"
382 "{ \n"
383 " gl_Position = position; \n"
384 "}";
385 }
386
FragmentShader()387 virtual std::string FragmentShader()
388 {
389 return "#version 310 es \n"
390 "out mediump vec4 color; \n"
391 "void main() { \n"
392 " color = vec4(0, 1, 0, 1); \n"
393 "}";
394 }
395
Run()396 virtual long Run()
397 {
398 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
399 glBindAttribLocation(program, 0, "position");
400 glLinkProgram(program);
401
402 long error = NO_ERROR;
403
404 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
405 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
406 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
407 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
408
409 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
410 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
411
412 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
413 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
414
415 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
416 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
417
418 GLenum props[] = {GL_NAME_LENGTH,
419 GL_TYPE,
420 GL_ARRAY_SIZE,
421 GL_REFERENCED_BY_COMPUTE_SHADER,
422 GL_REFERENCED_BY_FRAGMENT_SHADER,
423 GL_REFERENCED_BY_VERTEX_SHADER,
424 GL_LOCATION};
425 GLint expected[] = {9, 35666, 1, 0, 0, 1, 0};
426 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 7, props, 7, expected, error);
427
428 GLenum props2[] = {GL_NAME_LENGTH,
429 GL_TYPE,
430 GL_ARRAY_SIZE,
431 GL_REFERENCED_BY_COMPUTE_SHADER,
432 GL_REFERENCED_BY_FRAGMENT_SHADER,
433 GL_REFERENCED_BY_VERTEX_SHADER,
434 GL_LOCATION};
435 GLint expected2[] = {6, 35666, 1, 0, 1, 0, 0};
436 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
437
438 glDeleteProgram(program);
439 return error;
440 }
441 };
442
443 class ComputeShaderTest : public PIQBase
444 {
445 public:
Title()446 virtual std::string Title()
447 {
448 return "Compute Shader Test";
449 }
450
ShadersDesc()451 virtual std::string ShadersDesc()
452 {
453 return "compute shader";
454 }
455
ComputeShader()456 virtual std::string ComputeShader()
457 {
458 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
459 "layout(std430) buffer Output { \n"
460 " mediump vec4 data[]; \n"
461 "} g_out; \n"
462 ""
463 "void main() { \n"
464 " g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0); \n"
465 " g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0); \n"
466 "}";
467 }
468
CreateComputeProgram(const std::string & cs)469 GLuint CreateComputeProgram(const std::string &cs)
470 {
471 const GLuint p = glCreateProgram();
472
473 const char *const kGLSLVer = "#version 310 es\n";
474
475 if (!cs.empty())
476 {
477 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
478 glAttachShader(p, sh);
479 glDeleteShader(sh);
480 const char *const src[2] = {kGLSLVer, cs.c_str()};
481 glShaderSource(sh, 2, src, NULL);
482 glCompileShader(sh);
483 }
484
485 return p;
486 }
487
CheckProgram(GLuint program,bool * compile_error=NULL)488 bool CheckProgram(GLuint program, bool *compile_error = NULL)
489 {
490 GLint compile_status = GL_TRUE;
491 GLint status;
492 glGetProgramiv(program, GL_LINK_STATUS, &status);
493
494 if (status == GL_FALSE)
495 {
496 GLint attached_shaders;
497 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
498
499 if (attached_shaders > 0)
500 {
501 std::vector<GLuint> shaders(attached_shaders);
502 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
503
504 for (GLint i = 0; i < attached_shaders; ++i)
505 {
506 GLenum type;
507 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
508 switch (type)
509 {
510 case GL_VERTEX_SHADER:
511 m_context.getTestContext().getLog()
512 << tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
513 break;
514 case GL_TESS_CONTROL_SHADER:
515 m_context.getTestContext().getLog()
516 << tcu::TestLog::Message << "*** Tessellation Control Shader ***"
517 << tcu::TestLog::EndMessage;
518 break;
519 case GL_TESS_EVALUATION_SHADER:
520 m_context.getTestContext().getLog()
521 << tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
522 << tcu::TestLog::EndMessage;
523 break;
524 case GL_GEOMETRY_SHADER:
525 m_context.getTestContext().getLog()
526 << tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
527 break;
528 case GL_FRAGMENT_SHADER:
529 m_context.getTestContext().getLog()
530 << tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
531 break;
532 case GL_COMPUTE_SHADER:
533 m_context.getTestContext().getLog()
534 << tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
535 break;
536 default:
537 m_context.getTestContext().getLog()
538 << tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
539 }
540
541 GLint res;
542 glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
543 if (res != GL_TRUE)
544 compile_status = res;
545
546 // shader source
547 GLint length;
548 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
549 if (length > 0)
550 {
551 std::vector<GLchar> source(length);
552 glGetShaderSource(shaders[i], length, NULL, &source[0]);
553 m_context.getTestContext().getLog()
554 << tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
555 }
556
557 // shader info log
558 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
559 if (length > 0)
560 {
561 std::vector<GLchar> log(length);
562 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
563 m_context.getTestContext().getLog()
564 << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
565 }
566 }
567 }
568
569 // program info log
570 GLint length;
571 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
572 if (length > 0)
573 {
574 std::vector<GLchar> log(length);
575 glGetProgramInfoLog(program, length, NULL, &log[0]);
576 m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
577 }
578 }
579
580 if (compile_error)
581 *compile_error = (compile_status == GL_TRUE ? false : true);
582 if (compile_status != GL_TRUE)
583 return false;
584 return status == GL_TRUE ? true : false;
585 }
586
VerifyCompute(GLuint program,long & error)587 virtual void inline VerifyCompute(GLuint program, long &error)
588 {
589 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
590 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
591 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
592 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
593 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
594
595 std::map<std::string, GLuint> indicesSSB;
596 std::map<std::string, GLuint> indicesBV;
597 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
598 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
599
600 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
601 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
602
603 GLenum props3[] = {GL_NAME_LENGTH,
604 GL_BUFFER_BINDING,
605 GL_NUM_ACTIVE_VARIABLES,
606 GL_REFERENCED_BY_COMPUTE_SHADER,
607 GL_REFERENCED_BY_FRAGMENT_SHADER,
608 GL_REFERENCED_BY_VERTEX_SHADER,
609 GL_ACTIVE_VARIABLES};
610 GLint expected3[] = {7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"])};
611 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
612 error);
613
614 GLenum props4[] = {GL_NAME_LENGTH,
615 GL_TYPE,
616 GL_ARRAY_SIZE,
617 GL_BLOCK_INDEX,
618 GL_IS_ROW_MAJOR,
619 GL_REFERENCED_BY_COMPUTE_SHADER,
620 GL_REFERENCED_BY_FRAGMENT_SHADER,
621 GL_REFERENCED_BY_VERTEX_SHADER,
622 GL_TOP_LEVEL_ARRAY_SIZE};
623 GLint expected4[] = {15, 35666, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1};
624 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
625 error);
626 }
627
Run()628 virtual long Run()
629 {
630 GLuint program = CreateComputeProgram(ComputeShader());
631 glLinkProgram(program);
632 if (!CheckProgram(program))
633 {
634 glDeleteProgram(program);
635 return ERROR;
636 }
637 glUseProgram(program);
638
639 long error = NO_ERROR;
640
641 VerifyCompute(program, error);
642
643 glDeleteProgram(program);
644 return error;
645 }
646 };
647
648 class InputTypes : public SimpleShaders
649 {
Title()650 virtual std::string Title()
651 {
652 return "Input Types Test";
653 }
654
ShadersDesc()655 virtual std::string ShadersDesc()
656 {
657 return "vertex shader with different `in` types and a fallthrough fragment shader";
658 }
659
VertexShader()660 virtual std::string VertexShader()
661 {
662 return "#version 310 es \n"
663 "in mat4 a; \n"
664 "in vec4 b; \n"
665 "in float c; \n"
666 "in mat2x3 d; \n"
667 "in vec2 e; \n"
668 "in uint f; \n"
669 "in vec3 g; \n"
670 "in int h; \n"
671 "void main(void) \n"
672 "{ \n"
673 " vec4 pos; \n"
674 " pos.w = float(h) + g.x + g.y + d[1].y; \n"
675 " pos.y = float(b.x) * c + c + d[0][0]; \n"
676 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n"
677 " pos.z = d[0][1] + float(e.x) * float(f) + d[1][0]; \n"
678 " gl_Position = pos; \n"
679 "}";
680 }
681
Run()682 virtual long Run()
683 {
684 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
685 glBindAttribLocation(program, 0, "a");
686 glBindAttribLocation(program, 4, "b");
687 glBindAttribLocation(program, 5, "c");
688 glBindAttribLocation(program, 7, "d");
689 glBindAttribLocation(program, 11, "e");
690 glBindAttribLocation(program, 12, "f");
691 glBindAttribLocation(program, 13, "g");
692 glBindAttribLocation(program, 15, "h");
693 LinkProgram(program);
694
695 long error = NO_ERROR;
696
697 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
698 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
699
700 std::map<std::string, GLuint> indices;
701 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
702 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
703 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
704 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
705 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
706 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
707 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
708 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
709
710 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
711 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
712 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
713 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
714 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
715 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
716 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
717 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
718
719 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
720 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
721 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
722 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
723 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
724 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
725 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
726 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
727
728 GLenum props[] = {
729 GL_NAME_LENGTH,
730 GL_TYPE,
731 GL_ARRAY_SIZE,
732 GL_REFERENCED_BY_COMPUTE_SHADER,
733 GL_REFERENCED_BY_FRAGMENT_SHADER,
734 GL_REFERENCED_BY_VERTEX_SHADER,
735 GL_LOCATION,
736 };
737 GLint expected[] = {2, 35676, 1, 0, 0, 1, 0};
738 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
739 GLint expected2[] = {2, 35666, 1, 0, 0, 1, 4};
740 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
741 GLint expected3[] = {2, 5126, 1, 0, 0, 1, 5};
742 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
743 GLint expected4[] = {2, 35685, 1, 0, 0, 1, 7};
744 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
745 GLint expected5[] = {2, 35664, 1, 0, 0, 1, 11};
746 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
747 GLint expected6[] = {2, 5125, 1, 0, 0, 1, 12};
748 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
749 GLint expected7[] = {2, 35665, 1, 0, 0, 1, 13};
750 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
751 GLint expected8[] = {2, 5124, 1, 0, 0, 1, 15};
752 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
753
754 glDeleteProgram(program);
755 return error;
756 }
757 };
758
759 class InputBuiltIn : public SimpleShaders
760 {
761
Title()762 virtual std::string Title()
763 {
764 return "Input Built-ins Test";
765 }
766
ShadersDesc()767 virtual std::string ShadersDesc()
768 {
769 return "vertex shader using built-in variables and a fallthrough fragment shader";
770 }
771
Expectations()772 virtual std::string Expectations()
773 {
774 return ".\n\n In this case we ask for information about built-in variables for the input interface.";
775 }
776
VertexShader()777 virtual std::string VertexShader()
778 {
779 return "#version 310 es \n"
780 "void main(void) \n"
781 "{ \n"
782 " gl_Position = (float(gl_VertexID) + float(gl_InstanceID)) * vec4(0.1); \n"
783 "}";
784 }
785
Run()786 virtual long Run()
787 {
788 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
789 LinkProgram(program);
790
791 long error = NO_ERROR;
792
793 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
794 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
795
796 std::map<std::string, GLuint> indices;
797 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
798 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
799
800 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
801 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
802
803 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
804 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
805
806 GLenum props[] = {GL_NAME_LENGTH,
807 GL_TYPE,
808 GL_ARRAY_SIZE,
809 GL_REFERENCED_BY_COMPUTE_SHADER,
810 GL_REFERENCED_BY_FRAGMENT_SHADER,
811 GL_REFERENCED_BY_VERTEX_SHADER,
812 GL_LOCATION};
813 GLint expected[] = {12, 5124, 1, 0, 0, 1, -1};
814 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 7, props, 7, expected, error);
815 GLint expected2[] = {14, 5124, 1, 0, 0, 1, -1};
816 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 7, props, 7, expected2, error);
817
818 glDeleteProgram(program);
819 return error;
820 }
821 };
822
823 class InputLayout : public SimpleShaders
824 {
Title()825 virtual std::string Title()
826 {
827 return "Input Layout Test";
828 }
829
ShadersDesc()830 virtual std::string ShadersDesc()
831 {
832 return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
833 "shader";
834 }
835
VertexShader()836 virtual std::string VertexShader()
837 {
838 return "#version 310 es \n"
839 "layout(location = 4) in vec4 b; \n"
840 "layout(location = 7) in mat2x3 d; \n"
841 "layout(location = 5) in float c; \n"
842 "layout(location = 12) in uint f; \n"
843 "layout(location = 13) in vec3 g; \n"
844 "layout(location = 0) in mat4 a; \n"
845 "layout(location = 15) in int h; \n"
846 "layout(location = 11) in vec2 e; \n"
847 "void main(void) \n"
848 "{ \n"
849 " vec4 pos; \n"
850 " pos.w = float(h) + g.x + g.y + d[1][1]; \n"
851 " pos.y = float(b.x) * c + c + d[0][0]; \n"
852 " pos.x = a[0].x + a[1].y + a[2].z + a[3].w; \n"
853 " pos.z = d[0][1] + float(e.x) * float(f) + d[1][0]; \n"
854 " gl_Position = pos; \n"
855 "}";
856 }
857
Run()858 virtual long Run()
859 {
860 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
861 LinkProgram(program);
862
863 long error = NO_ERROR;
864
865 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
866 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
867
868 std::map<std::string, GLuint> indices;
869 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
870 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
871 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
872 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
873 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
874 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
875 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
876 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
877
878 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
879 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
880 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
881 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
882 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
883 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
884 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
885 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
886
887 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
888 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
889 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
890 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
891 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
892 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
893 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
894 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
895
896 GLenum props[] = {GL_NAME_LENGTH,
897 GL_TYPE,
898 GL_ARRAY_SIZE,
899 GL_REFERENCED_BY_COMPUTE_SHADER,
900 GL_REFERENCED_BY_FRAGMENT_SHADER,
901 GL_REFERENCED_BY_VERTEX_SHADER,
902 GL_LOCATION};
903 GLint expected[] = {2, 35676, 1, 0, 0, 1, 0};
904 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
905 GLint expected2[] = {2, 35666, 1, 0, 0, 1, 4};
906 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
907 GLint expected3[] = {2, 5126, 1, 0, 0, 1, 5};
908 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
909 GLint expected4[] = {2, 35685, 1, 0, 0, 1, 7};
910 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
911 GLint expected5[] = {2, 35664, 1, 0, 0, 1, 11};
912 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
913 GLint expected6[] = {2, 5125, 1, 0, 0, 1, 12};
914 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
915 GLint expected7[] = {2, 35665, 1, 0, 0, 1, 13};
916 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
917 GLint expected8[] = {2, 5124, 1, 0, 0, 1, 15};
918 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
919
920 glDeleteProgram(program);
921 return error;
922 }
923 };
924
925 class OutputLayout : public SimpleShaders
926 {
Title()927 virtual std::string Title()
928 {
929 return "Output Layout Test";
930 }
931
ShadersDesc()932 virtual std::string ShadersDesc()
933 {
934 return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
935 "shader";
936 }
937
FragmentShader()938 virtual std::string FragmentShader()
939 {
940 return "#version 310 es \n"
941 "layout(location = 2) out uint b; \n"
942 "layout(location = 3) out mediump vec2 e; \n"
943 "layout(location = 0) out mediump vec3 a[2]; \n"
944 "void main() { \n"
945 " b = 12u; \n"
946 " e = vec2(0, 1); \n"
947 " a[1] = vec3(0, 1, 0); \n"
948 " a[0] = vec3(0, 1, 0); \n"
949 "}";
950 }
951
Run()952 virtual long Run()
953 {
954 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
955 glBindAttribLocation(program, 0, "position");
956 LinkProgram(program);
957
958 long error = NO_ERROR;
959
960 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 3, error);
961 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
962
963 std::map<std::string, GLuint> indices;
964 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
965 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
966 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
967
968 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
969 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
970 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
971
972 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
973 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
974 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
975 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
976 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 3, error);
977
978 GLenum props[] = {GL_NAME_LENGTH,
979 GL_TYPE,
980 GL_ARRAY_SIZE,
981 GL_REFERENCED_BY_COMPUTE_SHADER,
982 GL_REFERENCED_BY_FRAGMENT_SHADER,
983 GL_REFERENCED_BY_VERTEX_SHADER,
984 GL_LOCATION};
985 GLint expected_a[] = {5, 35665, 2, 0, 1, 0, 0};
986 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 7, props, 7, expected_a, error);
987 GLint expected_b[] = {2, 5125, 1, 0, 1, 0, 2};
988 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 7, props, 7, expected_b, error);
989 GLint expected_e[] = {2, 35664, 1, 0, 1, 0, 3};
990 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 7, props, 7, expected_e, error);
991
992 glDeleteProgram(program);
993 return error;
994 }
995 };
996
997 class UniformSimple : public PIQBase
998 {
Title()999 virtual std::string Title()
1000 {
1001 return "Uniform Simple Test";
1002 }
1003
ShadersDesc()1004 virtual std::string ShadersDesc()
1005 {
1006 return "fallthrough fragment and vertex shaders with uniforms used";
1007 }
1008
PurposeExt()1009 virtual std::string PurposeExt()
1010 {
1011 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1012 }
1013
VertexShader()1014 virtual std::string VertexShader()
1015 {
1016 return "#version 310 es \n"
1017 "in vec4 position; \n"
1018 "uniform mediump vec4 repos; \n"
1019 "void main(void) \n"
1020 "{ \n"
1021 " gl_Position = position + repos; \n"
1022 "}";
1023 }
1024
FragmentShader()1025 virtual std::string FragmentShader()
1026 {
1027 return "#version 310 es \n"
1028 "uniform mediump vec4 recolor; \n"
1029 "out mediump vec4 color; \n"
1030 "void main() { \n"
1031 " color = vec4(0, 1, 0, 1) + recolor; \n"
1032 "}";
1033 }
1034
Run()1035 virtual long Run()
1036 {
1037 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1038 glBindAttribLocation(program, 0, "position");
1039 LinkProgram(program);
1040
1041 long error = NO_ERROR;
1042
1043 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1044 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1045 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1046
1047 std::map<std::string, GLuint> indices;
1048 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1049 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1050
1051 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1052 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1053
1054 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1055 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1056 error);
1057
1058 GLenum props[] = {GL_NAME_LENGTH,
1059 GL_TYPE,
1060 GL_ARRAY_SIZE,
1061 GL_OFFSET,
1062 GL_BLOCK_INDEX,
1063 GL_ARRAY_STRIDE,
1064 GL_MATRIX_STRIDE,
1065 GL_IS_ROW_MAJOR,
1066 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1067 GL_REFERENCED_BY_COMPUTE_SHADER,
1068 GL_REFERENCED_BY_FRAGMENT_SHADER,
1069 GL_REFERENCED_BY_VERTEX_SHADER,
1070 GL_LOCATION};
1071 GLint expected[] = {6, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "repos")};
1072 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 13, props, 13, expected, error);
1073
1074 GLint expected2[] = {8, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "recolor")};
1075 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 13, props, 13, expected2, error);
1076
1077 glDeleteProgram(program);
1078 return error;
1079 }
1080 };
1081
1082 class UniformTypes : public PIQBase
1083 {
Title()1084 virtual std::string Title()
1085 {
1086 return "Uniform Types Test";
1087 }
1088
ShadersDesc()1089 virtual std::string ShadersDesc()
1090 {
1091 return "fallthrough fragment and vertex shaders with different uniform types used";
1092 }
1093
PurposeExt()1094 virtual std::string PurposeExt()
1095 {
1096 return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1097 }
1098
VertexShader()1099 virtual std::string VertexShader()
1100 {
1101 return "#version 310 es \n"
1102 "in vec4 position; \n"
1103 "uniform mediump vec4 a; \n"
1104 "uniform ivec3 b; \n"
1105 "uniform uvec2 c[3]; \n"
1106 "uniform mediump mat2 g[8]; \n"
1107 "uniform mediump mat3x2 i; \n"
1108 "void main(void) \n"
1109 "{ \n"
1110 " float tmp; \n"
1111 " tmp = g[0][1][1] * g[1][0][0] + g[2][1][0] - g[3][0][1]; \n"
1112 " tmp = tmp + g[4][0][0] * g[5][1][0] - g[6][1][1] + g[7][0][1]; \n"
1113 " tmp = tmp + a.z + +float(b.y) + float(c[0].x) - float(c[1].x) * float(c[2].y); \n"
1114 " tmp = tmp + i[1][1]; \n"
1115 " gl_Position = position * tmp; \n"
1116 "}";
1117 }
1118
FragmentShader()1119 virtual std::string FragmentShader()
1120 {
1121 return "#version 310 es \n"
1122 "struct U { \n"
1123 " bool a[3]; \n"
1124 " mediump vec4 b; \n"
1125 " mediump mat3 c; \n"
1126 " mediump float d[2]; \n"
1127 "}; \n"
1128 "struct UU { \n"
1129 " U a; \n"
1130 " U b[2]; \n"
1131 " uvec2 c; \n"
1132 "}; \n"
1133 "uniform mediump mat4 d; \n"
1134 "uniform mediump mat3 e; \n"
1135 "uniform mediump float h; \n"
1136 "uniform int f; \n"
1137 "uniform U j; \n"
1138 "uniform UU k; \n"
1139 "uniform UU l[3]; \n"
1140 "out mediump vec4 color; \n"
1141 "void main() { \n"
1142 " mediump float tmp; \n"
1143 " tmp = h + float(f) + e[2][2]; \n"
1144 " tmp = tmp + d[0][0] + j.b.x; \n"
1145 " tmp = tmp + k.b[0].c[0][0]; \n"
1146 " tmp = tmp + l[2].a.c[0][1]; \n"
1147 " int i = int(tmp); \n"
1148 " if (i < 2) \n"
1149 " tmp = tmp + l[2].b[1].d[i]; \n"
1150 " else \n"
1151 " tmp = tmp + l[2].b[1].d[0]; \n"
1152 " tmp = tmp + float(l[0].c.x); \n"
1153 " color = vec4(0, 1, 0, 1) * tmp; \n"
1154 "}";
1155 }
1156
Run()1157 virtual long Run()
1158 {
1159 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1160 glBindAttribLocation(program, 0, "position");
1161 LinkProgram(program);
1162
1163 long error = NO_ERROR;
1164
1165 // only active structure members
1166 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1167 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1168 // l[2].b[1].d[0] and \0
1169 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1170
1171 std::map<std::string, GLuint> indices;
1172 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1173 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1174 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1175 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1176 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1177 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1178 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1179 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1180 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1181 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1182 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1183 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1184 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1185 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1186
1187 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1188 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1189 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1190 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1191 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1192 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1193 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1194 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1195 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1196 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1197 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1198 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1199 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1200 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1201
1202 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1203 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1204 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1205 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1206 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1207 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1208 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1209 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1210 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1211 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1212 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1213 error);
1214 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1215 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1216 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1217 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1218 error);
1219
1220 GLenum props[] = {GL_NAME_LENGTH,
1221 GL_TYPE,
1222 GL_ARRAY_SIZE,
1223 GL_OFFSET,
1224 GL_BLOCK_INDEX,
1225 GL_ARRAY_STRIDE,
1226 GL_MATRIX_STRIDE,
1227 GL_IS_ROW_MAJOR,
1228 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1229 GL_REFERENCED_BY_COMPUTE_SHADER,
1230 GL_REFERENCED_BY_FRAGMENT_SHADER,
1231 GL_REFERENCED_BY_VERTEX_SHADER,
1232 GL_LOCATION};
1233 GLint expected[] = {2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a")};
1234 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error);
1235 GLint expected2[] = {2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b")};
1236 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error);
1237 GLint expected3[] = {5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c")};
1238 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error);
1239 GLint expected4[] = {2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d")};
1240 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error);
1241 GLint expected5[] = {2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e")};
1242 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error);
1243 GLint expected6[] = {2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f")};
1244 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error);
1245 GLint expected7[] = {5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g")};
1246 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error);
1247 GLint expected8[] = {2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h")};
1248 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error);
1249 GLint expected9[] = {2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i")};
1250 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error);
1251 GLint expected10[] = {4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b")};
1252 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error);
1253 GLint expected11[] = {9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c")};
1254 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error);
1255 GLint expected12[] = {7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c")};
1256 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error);
1257 GLint expected13[] = {
1258 15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")};
1259 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error);
1260 GLint expected14[] = {9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c")};
1261 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error);
1262
1263 glDeleteProgram(program);
1264 return error;
1265 }
1266 };
1267
1268 class UniformBlockTypes : public PIQBase
1269 {
Title()1270 virtual std::string Title()
1271 {
1272 return "Uniform Block Types Test";
1273 }
1274
ShadersDesc()1275 virtual std::string ShadersDesc()
1276 {
1277 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1278 }
1279
PurposeExt()1280 virtual std::string PurposeExt()
1281 {
1282 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1283 }
1284
VertexShader()1285 virtual std::string VertexShader()
1286 {
1287 return "#version 310 es \n"
1288 "in vec4 position; \n"
1289 ""
1290 "uniform SimpleBlock { \n"
1291 " mediump mat3x2 a; \n"
1292 " mediump mat4 b; \n"
1293 " vec4 c; \n"
1294 "}; \n"
1295 ""
1296 "uniform NotSoSimpleBlockk { \n"
1297 " ivec2 a[4]; \n"
1298 " mediump mat3 b[2]; \n"
1299 " mediump mat2 c; \n"
1300 "} d; \n"
1301 ""
1302 "void main(void) \n"
1303 "{ \n"
1304 " mediump float tmp; \n"
1305 " tmp = a[0][1] * b[1][2] * c.x; \n"
1306 " tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1]; \n"
1307 " gl_Position = position * tmp; \n"
1308 "}";
1309 }
1310
FragmentShader()1311 virtual std::string FragmentShader()
1312 {
1313 return "#version 310 es \n"
1314 "struct U { \n"
1315 " bool a[3]; \n"
1316 " mediump vec4 b; \n"
1317 " mediump mat3 c; \n"
1318 " mediump float d[2]; \n"
1319 "}; \n"
1320 "struct UU { \n"
1321 " U a; \n"
1322 " U b[2]; \n"
1323 " uvec2 c; \n"
1324 "}; \n"
1325 ""
1326 "uniform TrickyBlock { \n"
1327 " UU a[3]; \n"
1328 " mediump mat4 b; \n"
1329 " uint c; \n"
1330 "} e[2]; \n"
1331 ""
1332 "out mediump vec4 color; \n"
1333 "void main() { \n"
1334 " mediump float tmp; \n"
1335 " tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n"
1336 " color = vec4(0, 1, 0, 1) * tmp; \n"
1337 "}";
1338 }
1339
Run()1340 virtual long Run()
1341 {
1342 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1343 glBindAttribLocation(program, 0, "position");
1344 LinkProgram(program);
1345
1346 long error = NO_ERROR;
1347
1348 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1349 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1350 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1351 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1352
1353 std::map<std::string, GLuint> indicesUB;
1354 std::map<std::string, GLuint> indicesU;
1355 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1356 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1357 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1358 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1359 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1360 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1361 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1362 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1363 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1364 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1365 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1366
1367 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1368 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1369 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1370 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1371
1372 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1373 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1374 error);
1375 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1376 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1377 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1378 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1379 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1380 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1381 error);
1382 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1383 error);
1384 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1385 error);
1386 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1387 "TrickyBlock.a[2].b[0].d[0]", error);
1388
1389 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1390 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1391 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1392
1393 GLenum props[] = {
1394 GL_NAME_LENGTH,
1395 GL_BUFFER_BINDING,
1396 GL_REFERENCED_BY_COMPUTE_SHADER,
1397 GL_REFERENCED_BY_FRAGMENT_SHADER,
1398 GL_REFERENCED_BY_VERTEX_SHADER,
1399 GL_BUFFER_DATA_SIZE,
1400 };
1401 GLint size;
1402 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1403 GLint expected[] = {12, 0, 0, 0, 1, size};
1404 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error);
1405 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1406 GLint expected2[] = {18, 2, 0, 0, 1, size};
1407 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2,
1408 error);
1409 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1410 GLint expected3[] = {15, 3, 0, 1, 0, size};
1411 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error);
1412 GLint expected4[] = {15, 4, 0, 1, 0, size};
1413 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4,
1414 error);
1415
1416 GLenum props2[] = {GL_NAME_LENGTH,
1417 GL_TYPE,
1418 GL_ARRAY_SIZE,
1419 GL_BLOCK_INDEX,
1420 GL_ARRAY_STRIDE,
1421 GL_IS_ROW_MAJOR,
1422 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1423 GL_REFERENCED_BY_COMPUTE_SHADER,
1424 GL_REFERENCED_BY_FRAGMENT_SHADER,
1425 GL_REFERENCED_BY_VERTEX_SHADER,
1426 GL_LOCATION};
1427 GLint expected5[] = {2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1};
1428 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error);
1429 GLenum props3[] = {GL_NAME_LENGTH,
1430 GL_TYPE,
1431 GL_ARRAY_SIZE,
1432 GL_BLOCK_INDEX,
1433 GL_MATRIX_STRIDE,
1434 GL_IS_ROW_MAJOR,
1435 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1436 GL_REFERENCED_BY_COMPUTE_SHADER,
1437 GL_REFERENCED_BY_FRAGMENT_SHADER,
1438 GL_REFERENCED_BY_VERTEX_SHADER,
1439 GL_LOCATION};
1440 GLint expected6[] = {27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1};
1441 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6,
1442 error);
1443
1444 GLenum prop = GL_ACTIVE_VARIABLES;
1445 const GLsizei bufSize = 1000;
1446 GLsizei length;
1447 GLint param[bufSize];
1448 std::set<GLuint> exp;
1449 exp.insert(indicesU["a"]);
1450 exp.insert(indicesU["b"]);
1451 exp.insert(indicesU["c"]);
1452 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1453 for (int i = 0; i < length; ++i)
1454 {
1455 if (exp.find(param[i]) == exp.end())
1456 {
1457 m_context.getTestContext().getLog()
1458 << tcu::TestLog::Message
1459 << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1460 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1461 << tcu::TestLog::EndMessage;
1462 glDeleteProgram(program);
1463 return ERROR;
1464 }
1465 else if (length != 3)
1466 {
1467 m_context.getTestContext().getLog()
1468 << tcu::TestLog::Message
1469 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1470 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1471 glDeleteProgram(program);
1472 return ERROR;
1473 }
1474 }
1475 std::set<GLuint> exp2;
1476 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1477 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1478 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1479 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1480 param);
1481 for (int i = 0; i < length; ++i)
1482 {
1483 if (exp2.find(param[i]) == exp2.end())
1484 {
1485 m_context.getTestContext().getLog()
1486 << tcu::TestLog::Message
1487 << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1488 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1489 << tcu::TestLog::EndMessage;
1490 glDeleteProgram(program);
1491 return ERROR;
1492 }
1493 else if (length != 3)
1494 {
1495 m_context.getTestContext().getLog()
1496 << tcu::TestLog::Message
1497 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1498 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1499 glDeleteProgram(program);
1500 return ERROR;
1501 }
1502 }
1503
1504 GLint res;
1505 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1506 if (res < 3)
1507 {
1508 m_context.getTestContext().getLog()
1509 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1510 << tcu::TestLog::EndMessage;
1511 glDeleteProgram(program);
1512 return ERROR;
1513 }
1514
1515 glDeleteProgram(program);
1516 return error;
1517 }
1518 };
1519
1520 class UniformBlockArray : public PIQBase
1521 {
Title()1522 virtual std::string Title()
1523 {
1524 return "Uniform Block Array Test";
1525 }
1526
ShadersDesc()1527 virtual std::string ShadersDesc()
1528 {
1529 return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
1530 }
1531
PurposeExt()1532 virtual std::string PurposeExt()
1533 {
1534 return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
1535 }
1536
VertexShader()1537 virtual std::string VertexShader()
1538 {
1539 return "#version 310 es \n"
1540 "void main(void) \n"
1541 "{ \n"
1542 " gl_Position = vec4(1.0); \n"
1543 "}";
1544 }
1545
FragmentShader()1546 virtual std::string FragmentShader()
1547 {
1548 return "#version 310 es \n"
1549 "uniform TestBlock { \n"
1550 " mediump vec4 color; \n"
1551 "} blockInstance[4]; \n"
1552 ""
1553 "out mediump vec4 color; \n"
1554 "void main() { \n"
1555 " color = blockInstance[2].color + blockInstance[3].color; \n"
1556 "}";
1557 }
1558
Run()1559 virtual long Run()
1560 {
1561 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1562 LinkProgram(program);
1563
1564 long error = NO_ERROR;
1565
1566 std::map<std::string, GLuint> indicesUB;
1567 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
1568
1569 std::map<std::string, GLuint> indicesU;
1570 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
1571
1572 GLenum props[] = {GL_BLOCK_INDEX};
1573 GLint expected[] = {static_cast<GLint>(indicesUB["TestBlock"])};
1574 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
1575
1576 glDeleteProgram(program);
1577 return error;
1578 }
1579 };
1580
1581 class TransformFeedbackTypes : public SimpleShaders
1582 {
Title()1583 virtual std::string Title()
1584 {
1585 return "Transform Feedback Varying Types";
1586 }
1587
ShadersDesc()1588 virtual std::string ShadersDesc()
1589 {
1590 return "fallthrough fragment and vertex shaders with different types of out variables used";
1591 }
1592
PurposeExt()1593 virtual std::string PurposeExt()
1594 {
1595 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1596 }
1597
VertexShader()1598 virtual std::string VertexShader()
1599 {
1600 return "#version 310 es \n"
1601 "in vec4 position; \n"
1602 ""
1603 "flat out highp vec4 a; \n"
1604 "out mediump float b[2]; \n"
1605 "flat out highp uvec2 c; \n"
1606 "flat out highp uint d; \n"
1607 "out mediump vec3 e[2]; \n"
1608 "flat out int f; \n"
1609 ""
1610 "void main(void) \n"
1611 "{ \n"
1612 " vec4 pos; \n"
1613 " a = vec4(1); \n"
1614 " b[0] = 1.1; \n"
1615 " b[1] = 1.1; \n"
1616 " c = uvec2(1u); \n"
1617 " d = 1u; \n"
1618 " e[0] = vec3(1.1); \n"
1619 " e[1] = vec3(1.1); \n"
1620 " f = 1; \n"
1621 " gl_Position = position; \n"
1622 "}";
1623 }
1624
Run()1625 virtual long Run()
1626 {
1627 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1628 glBindAttribLocation(program, 0, "position");
1629 const char *varyings[6] = {"a", "b[0]", "b[1]", "c", "d", "e"};
1630 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1631 LinkProgram(program);
1632
1633 long error = NO_ERROR;
1634
1635 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1636 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1637
1638 std::map<std::string, GLuint> indices;
1639 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1640 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1641 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1642 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1643 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1644 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1645
1646 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1647 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1648 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1649 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1650 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1651 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1652
1653 GLenum props[] = {GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE};
1654 GLint expected[] = {2, 35666, 1};
1655 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1656 GLint expected2[] = {5, 5126, 1};
1657 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1658 error);
1659 GLint expected3[] = {5, 5126, 1};
1660 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1661 error);
1662 GLint expected4[] = {2, 36294, 1};
1663 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1664 GLint expected5[] = {2, 5125, 1};
1665 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1666 GLint expected6[] = {2, 35665, 2};
1667 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1668
1669 glDeleteProgram(program);
1670 return error;
1671 }
1672 };
1673
1674 class TransformFeedbackTypesFullArrayCapture : public SimpleShaders
1675 {
Title()1676 virtual std::string Title()
1677 {
1678 return "Transform Feedback Varying Types Without Element Capture";
1679 }
1680
ShadersDesc()1681 virtual std::string ShadersDesc()
1682 {
1683 return "fallthrough fragment and vertex shaders with different types of out variables used";
1684 }
1685
PurposeExt()1686 virtual std::string PurposeExt()
1687 {
1688 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1689 }
1690
VertexShader()1691 virtual std::string VertexShader()
1692 {
1693 return "#version 310 es \n"
1694 "in vec4 position; \n"
1695 ""
1696 "flat out highp vec4 a; \n"
1697 "out mediump float b[2]; \n"
1698 "flat out highp uvec2 c; \n"
1699 "flat out highp uint d; \n"
1700 "out mediump vec3 e[2]; \n"
1701 "flat out int f; \n"
1702 ""
1703 "void main(void) \n"
1704 "{ \n"
1705 " vec4 pos; \n"
1706 " a = vec4(1); \n"
1707 " b[0] = 1.1; \n"
1708 " b[1] = 1.1; \n"
1709 " c = uvec2(1u); \n"
1710 " d = 1u; \n"
1711 " e[0] = vec3(1.1); \n"
1712 " e[1] = vec3(1.1); \n"
1713 " f = 1; \n"
1714 " gl_Position = position; \n"
1715 "}";
1716 }
1717
Run()1718 virtual long Run()
1719 {
1720 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1721 glBindAttribLocation(program, 0, "position");
1722 const char *varyings[5] = {"a", "b", "c", "d", "e"};
1723 glTransformFeedbackVaryings(program, 5, varyings, GL_INTERLEAVED_ATTRIBS);
1724 LinkProgram(program);
1725
1726 long error = NO_ERROR;
1727
1728 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 5, error);
1729 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 2, error);
1730
1731 std::map<std::string, GLuint> indices;
1732 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1733 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b", error);
1734 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1735 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1736 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1737
1738 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1739 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], "b", error);
1740 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1741 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1742 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1743
1744 GLenum props[] = {GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE};
1745 GLint expected[] = {2, GL_FLOAT_VEC4, 1};
1746 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1747 GLint expected2[] = {2, GL_FLOAT, 2};
1748 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], 3, props, 3, expected2, error);
1749 GLint expected3[] = {2, GL_UNSIGNED_INT_VEC2, 1};
1750 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected3, error);
1751 GLint expected4[] = {2, GL_UNSIGNED_INT, 1};
1752 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected4, error);
1753 GLint expected5[] = {2, GL_FLOAT_VEC3, 2};
1754 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected5, error);
1755
1756 glDeleteProgram(program);
1757 return error;
1758 }
1759 };
1760
1761 class AtomicCounterSimple : public ComputeShaderTest
1762 {
1763 public:
Title()1764 virtual std::string Title()
1765 {
1766 return "Atomic Counter Buffer Simple Test";
1767 }
1768
ShadersDesc()1769 virtual std::string ShadersDesc()
1770 {
1771 return "compute shader with atomic counters used";
1772 }
1773
PurposeExt()1774 virtual std::string PurposeExt()
1775 {
1776 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1777 }
1778
Run()1779 virtual long Run()
1780 {
1781
1782 GLint max_buffer_bindings = 0;
1783 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1784 if (max_buffer_bindings < 6)
1785 {
1786 OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
1787 return NOT_SUPPORTED;
1788 }
1789
1790 const char *const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n"
1791 "layout(std430) buffer Output { \n"
1792 " mediump vec4 data; \n"
1793 "} g_out; \n"
1794 ""
1795 "layout (binding = 1, offset = 0) uniform highp atomic_uint a; \n"
1796 "layout (binding = 2, offset = 0) uniform highp atomic_uint b; \n"
1797 "layout (binding = 2, offset = 4) uniform highp atomic_uint c; \n"
1798 "layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
1799 "layout (binding = 5, offset = 12) uniform highp atomic_uint e; \n"
1800 ""
1801 "void main() { \n"
1802 " uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1803 " uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1804 " uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1805 " uint w = atomicCounterIncrement(e); \n"
1806 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n"
1807 "}";
1808
1809 GLuint program = CreateComputeProgram(glsl_cs);
1810 glLinkProgram(program);
1811 if (!CheckProgram(program))
1812 {
1813 glDeleteProgram(program);
1814 return ERROR;
1815 }
1816 glUseProgram(program);
1817
1818 long error = NO_ERROR;
1819
1820 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1821 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1822
1823 std::map<std::string, GLuint> indicesU;
1824 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1825 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1826 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1827 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1828 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1829
1830 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1831 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1832 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1833 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1834 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1835
1836 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1837 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1838 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1839 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1840 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1841 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1842 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1843 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1844
1845 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1846 const GLsizei bufSize = 1000;
1847 GLsizei length;
1848 GLint res;
1849 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1850
1851 GLenum props[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES};
1852 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1853 GLint expected[] = {1, 4, 1, static_cast<GLint>(indicesU["a"])};
1854 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1855
1856 GLenum props2[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES};
1857 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1858 GLint expected2[] = {2, 8, 2};
1859 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1860 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1861 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1862
1863 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1864 GLint expected3[] = {5, 16, 2};
1865 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1866 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1867 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1868
1869 GLenum prop2 = GL_ACTIVE_VARIABLES;
1870 GLint param[bufSize];
1871 std::set<GLuint> exp;
1872 exp.insert(indicesU["b"]);
1873 exp.insert(indicesU["c"]);
1874 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1875 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1876 for (int i = 0; i < length; ++i)
1877 {
1878 if (exp.find(param[i]) == exp.end() || length != 2)
1879 {
1880 m_context.getTestContext().getLog()
1881 << tcu::TestLog::Message << "Length: " << length
1882 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1883 << tcu::TestLog::EndMessage;
1884 glDeleteProgram(program);
1885 return ERROR;
1886 }
1887 }
1888 std::set<GLuint> exp2;
1889 GLint param2[bufSize];
1890 exp2.insert(indicesU["d"]);
1891 exp2.insert(indicesU["e"]);
1892 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1893 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
1894 for (int i = 0; i < length; ++i)
1895 {
1896 if (exp2.find(param2[i]) == exp2.end() || length != 2)
1897 {
1898 m_context.getTestContext().getLog()
1899 << tcu::TestLog::Message << "Length: " << length
1900 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
1901 << tcu::TestLog::EndMessage;
1902 glDeleteProgram(program);
1903 return ERROR;
1904 }
1905 }
1906
1907 glDeleteProgram(program);
1908 return error;
1909 }
1910 };
1911
1912 class AtomicCounterSimpleOneBuffer : public ComputeShaderTest
1913 {
1914 public:
Title()1915 virtual std::string Title()
1916 {
1917 return "Atomic Counter Buffer Simple One Buffer Test";
1918 }
1919
ShadersDesc()1920 virtual std::string ShadersDesc()
1921 {
1922 return "compute shader with atomic counters used";
1923 }
1924
PurposeExt()1925 virtual std::string PurposeExt()
1926 {
1927 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1928 }
1929
Run()1930 virtual long Run()
1931 {
1932
1933 GLint max_buffer_bindings = 0;
1934 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1935 if (max_buffer_bindings < 3)
1936 {
1937 OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
1938 return NOT_SUPPORTED;
1939 }
1940
1941 const char *const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n"
1942 "layout(std430) buffer Output { \n"
1943 " mediump vec4 data; \n"
1944 "} g_out; \n"
1945 ""
1946 "layout (binding = 0, offset = 0) uniform highp atomic_uint a; \n"
1947 "layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
1948 "layout (binding = 0, offset = 16) uniform highp atomic_uint c; \n"
1949 ""
1950 "void main() { \n"
1951 " uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
1952 " uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
1953 " uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
1954 " uint w = atomicCounterIncrement(c); \n"
1955 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n"
1956 "}";
1957
1958 GLuint program = CreateComputeProgram(glsl_cs);
1959 glLinkProgram(program);
1960 if (!CheckProgram(program))
1961 {
1962 glDeleteProgram(program);
1963 return ERROR;
1964 }
1965 glUseProgram(program);
1966
1967 long error = NO_ERROR;
1968
1969 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
1970 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
1971
1972 std::map<std::string, GLuint> indicesU;
1973 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1974 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1975 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1976
1977 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1978 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
1979 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1980
1981 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1982 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1983 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1984 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
1985 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
1986 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
1987
1988 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1989 const GLsizei bufSize = 1000;
1990 GLsizei length;
1991 GLint res;
1992
1993 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1994 if (res != 0)
1995 {
1996 m_context.getTestContext().getLog()
1997 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1998 glDeleteProgram(program);
1999 return ERROR;
2000 }
2001
2002 GLenum props[] = {GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES};
2003 GLint expected[] = {0, 20, 3};
2004 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
2005
2006 GLenum prop2 = GL_ACTIVE_VARIABLES;
2007 GLint param[bufSize];
2008 std::set<GLuint> exp;
2009 exp.insert(indicesU["a"]);
2010 exp.insert(indicesU["b"]);
2011 exp.insert(indicesU["c"]);
2012
2013 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2014 if (res != 0)
2015 {
2016 m_context.getTestContext().getLog()
2017 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
2018 glDeleteProgram(program);
2019 return ERROR;
2020 }
2021
2022 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2023 for (int i = 0; i < length; ++i)
2024 {
2025 if (exp.find(param[i]) == exp.end() || length != 3)
2026 {
2027 m_context.getTestContext().getLog()
2028 << tcu::TestLog::Message << "Length: " << length
2029 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2030 << tcu::TestLog::EndMessage;
2031 glDeleteProgram(program);
2032 return ERROR;
2033 }
2034 }
2035
2036 glDeleteProgram(program);
2037 return error;
2038 }
2039 };
2040
2041 class InvalidValueTest : public SimpleShaders
2042 {
Title()2043 virtual std::string Title()
2044 {
2045 return "Invalid Value Test";
2046 }
2047
PassCriteria()2048 virtual std::string PassCriteria()
2049 {
2050 return "GL_INVALID_VALUE error is generated after every function call.";
2051 }
2052
Purpose()2053 virtual std::string Purpose()
2054 {
2055 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2056 }
2057
Method()2058 virtual std::string Method()
2059 {
2060 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2061 }
2062
Run()2063 virtual long Run()
2064 {
2065 long error = NO_ERROR;
2066
2067 GLint res;
2068 GLsizei len = 0;
2069 GLchar name[100] = {'\0'};
2070 GLenum props[1] = {GL_NAME_LENGTH};
2071
2072 m_context.getTestContext().getLog()
2073 << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2074 << tcu::TestLog::EndMessage;
2075 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2076 ExpectError(GL_INVALID_VALUE, error);
2077 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2078 ExpectError(GL_INVALID_VALUE, error);
2079 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2080 ExpectError(GL_INVALID_VALUE, error);
2081 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2082 ExpectError(GL_INVALID_VALUE, error);
2083 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2084 ExpectError(GL_INVALID_VALUE, error);
2085 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2086
2087 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2088 glBindAttribLocation(program, 0, "position");
2089 LinkProgram(program);
2090
2091 m_context.getTestContext().getLog()
2092 << tcu::TestLog::Message
2093 << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2094 << tcu::TestLog::EndMessage;
2095 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2096 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2097 ExpectError(GL_INVALID_VALUE, error);
2098 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
2099
2100 m_context.getTestContext().getLog()
2101 << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2102 << tcu::TestLog::EndMessage;
2103 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2104 ExpectError(GL_INVALID_VALUE, error);
2105 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
2106
2107 std::string str = "position";
2108 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char *>(str.c_str()));
2109 ExpectError(GL_INVALID_VALUE, error);
2110 GLenum prop = GL_NAME_LENGTH;
2111 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2112 ExpectError(GL_INVALID_VALUE, error);
2113
2114 glDeleteProgram(program);
2115 return error;
2116 }
2117 };
2118
2119 class InvalidEnumTest : public SimpleShaders
2120 {
Title()2121 virtual std::string Title()
2122 {
2123 return "Invalid Enum Test";
2124 }
2125
PassCriteria()2126 virtual std::string PassCriteria()
2127 {
2128 return "GL_INVALID_ENUM error is generated after every function call.";
2129 }
2130
Purpose()2131 virtual std::string Purpose()
2132 {
2133 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2134 }
2135
Method()2136 virtual std::string Method()
2137 {
2138 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2139 }
2140
2141 // make sure at least one atomic counter resource is active
FragmentShader()2142 virtual std::string FragmentShader()
2143 {
2144 return "#version 310 es \n"
2145 "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
2146 "out mediump vec4 outColor; \n"
2147 "void main(void) { \n"
2148 " uint b = atomicCounterIncrement(a); \n"
2149 " outColor = vec4(float(b)); \n"
2150 "} \n";
2151 }
2152
Run()2153 virtual long Run()
2154 {
2155 GLint max_buffers = 0, max_counters = 0;
2156 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
2157 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
2158 if (max_buffers < 1 || max_counters < 1)
2159 {
2160 OutputNotSupported("Test requires at least 1 atomic counter.");
2161 return NOT_SUPPORTED;
2162 }
2163
2164 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2165 glBindAttribLocation(program, 0, "position");
2166 LinkProgram(program);
2167
2168 long error = NO_ERROR;
2169
2170 GLint res;
2171 GLsizei len = 0;
2172 GLchar name[100] = {'\0'};
2173 GLenum props[1] = {GL_TEXTURE_1D};
2174
2175 m_context.getTestContext().getLog() << tcu::TestLog::Message
2176 << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
2177 "GetProgramResourceIndex or GetProgramResourceName"
2178 << tcu::TestLog::EndMessage;
2179 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2180 ExpectError(GL_INVALID_ENUM, error);
2181 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2182 ExpectError(GL_INVALID_ENUM, error);
2183 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2184
2185 m_context.getTestContext().getLog()
2186 << tcu::TestLog::Message
2187 << "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
2188 << tcu::TestLog::EndMessage;
2189 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2190 ExpectError(GL_INVALID_ENUM, error);
2191 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2192
2193 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2194 ExpectError(GL_INVALID_ENUM, error);
2195
2196 glDeleteProgram(program);
2197 return error;
2198 }
2199 };
2200
2201 class InvalidOperationTest : public SimpleShaders
2202 {
Title()2203 virtual std::string Title()
2204 {
2205 return "Invalid Operation Test";
2206 }
2207
PassCriteria()2208 virtual std::string PassCriteria()
2209 {
2210 return "GL_INVALID_OPERATION error is generated after every function call.";
2211 }
2212
Purpose()2213 virtual std::string Purpose()
2214 {
2215 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2216 }
2217
Method()2218 virtual std::string Method()
2219 {
2220 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2221 }
2222
Run()2223 virtual long Run()
2224 {
2225 long error = NO_ERROR;
2226
2227 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2228 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2229 glBindAttribLocation(program, 0, "position");
2230 LinkProgram(program);
2231
2232 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2233 GLint res;
2234 GLsizei len = 0;
2235 GLchar name[100] = {'\0'};
2236 GLenum props[1] = {GL_OFFSET};
2237
2238 m_context.getTestContext().getLog()
2239 << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2240 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2241 ExpectError(GL_INVALID_OPERATION, error);
2242 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2243 ExpectError(GL_INVALID_OPERATION, error);
2244 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2245 ExpectError(GL_INVALID_OPERATION, error);
2246 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2247 ExpectError(GL_INVALID_OPERATION, error);
2248 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2249 ExpectError(GL_INVALID_OPERATION, error);
2250 glDeleteShader(sh);
2251 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2252
2253 m_context.getTestContext().getLog()
2254 << tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
2255 << tcu::TestLog::EndMessage;
2256 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2257 ExpectError(GL_INVALID_OPERATION, error);
2258 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2259
2260 m_context.getTestContext().getLog()
2261 << tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
2262 << tcu::TestLog::EndMessage;
2263 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2264 ExpectError(GL_INVALID_OPERATION, error);
2265 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2266
2267 m_context.getTestContext().getLog()
2268 << tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
2269 << tcu::TestLog::EndMessage;
2270 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2271 ExpectError(GL_INVALID_OPERATION, error);
2272 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
2273
2274 glDeleteProgram(program);
2275 glDeleteProgram(program2);
2276 return error;
2277 }
2278 };
2279
2280 class ShaderStorageBlock : public ComputeShaderTest
2281 {
Title()2282 virtual std::string Title()
2283 {
2284 return "Shader Storage Block Test";
2285 }
2286
ShadersDesc()2287 virtual std::string ShadersDesc()
2288 {
2289 return "compute shader different types of storage blocks used";
2290 }
2291
PurposeExt()2292 virtual std::string PurposeExt()
2293 {
2294 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2295 "params.\n";
2296 }
2297
ComputeShader()2298 virtual std::string ComputeShader()
2299 {
2300 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2301 "layout(std430) buffer Output { \n"
2302 " mediump vec4 data; \n"
2303 "} g_out; \n"
2304 ""
2305 "struct U { \n"
2306 " bool a[3]; \n"
2307 " mediump vec4 b; \n"
2308 " mediump mat3 c; \n"
2309 " mediump float d[2]; \n"
2310 "}; \n"
2311 "struct UU { \n"
2312 " U a; \n"
2313 " U b[2]; \n"
2314 " uvec2 c; \n"
2315 "}; \n"
2316 ""
2317 "layout(binding=4) buffer TrickyBuffer { \n"
2318 " UU a[3]; \n"
2319 " mediump mat4 b; \n"
2320 " uint c; \n"
2321 "} e[2]; \n"
2322 ""
2323 "layout(binding = 0) buffer SimpleBuffer { \n"
2324 " mediump mat3x2 a; \n"
2325 " mediump mat4 b; \n"
2326 " mediump vec4 c; \n"
2327 "}; \n"
2328 ""
2329 "layout(binding = 1) buffer NotSoSimpleBuffer { \n"
2330 " ivec2 a[4]; \n"
2331 " mediump mat3 b[2]; \n"
2332 " mediump mat2 c; \n"
2333 "} d; \n"
2334 ""
2335 "void main() { \n"
2336 " mediump float tmp; \n"
2337 " mediump float tmp2; \n"
2338 " tmp = e[0].a[0].b[0].d[0] * float(e[1].c); \n"
2339 " tmp2 = a[0][0] * b[0][0] * c.x; \n"
2340 " tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0]; \n"
2341 " g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2; \n"
2342 "}";
2343 }
2344
Run()2345 virtual long Run()
2346 {
2347 GLuint program = CreateComputeProgram(ComputeShader());
2348 glLinkProgram(program);
2349 if (!CheckProgram(program))
2350 {
2351 glDeleteProgram(program);
2352 return ERROR;
2353 }
2354 glUseProgram(program);
2355
2356 long error = NO_ERROR;
2357
2358 GLint res;
2359 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
2360 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
2361 if (res < 7)
2362 {
2363 m_context.getTestContext().getLog()
2364 << tcu::TestLog::Message
2365 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
2366 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
2367 glDeleteProgram(program);
2368 return ERROR;
2369 }
2370 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
2371 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
2372
2373 std::map<std::string, GLuint> indicesSSB;
2374 std::map<std::string, GLuint> indicesBV;
2375 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
2376 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
2377 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
2378 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
2379 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
2380 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
2381 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
2382 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
2383 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
2384 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
2385 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
2386 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
2387 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
2388
2389 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
2390 error);
2391 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
2392 "NotSoSimpleBuffer", error);
2393 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
2394 error);
2395 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
2396 error);
2397 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
2398 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
2399 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
2400 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
2401 "NotSoSimpleBuffer.a[0]", error);
2402 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
2403 "NotSoSimpleBuffer.c", error);
2404 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
2405 "NotSoSimpleBuffer.b[0]", error);
2406 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
2407 "TrickyBuffer.a[0].b[0].d[0]", error);
2408 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
2409 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
2410
2411 GLenum props[] = {GL_NAME_LENGTH,
2412 GL_BUFFER_BINDING,
2413 GL_NUM_ACTIVE_VARIABLES,
2414 GL_REFERENCED_BY_COMPUTE_SHADER,
2415 GL_REFERENCED_BY_FRAGMENT_SHADER,
2416 GL_REFERENCED_BY_VERTEX_SHADER};
2417 GLint expected[] = {13, 0, 3, 1, 0, 0};
2418 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
2419 error);
2420 GLenum props2[] = {GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
2421 GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER};
2422 GLint expected2[] = {18, 1, 1, 0, 0};
2423 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
2424 expected2, error);
2425 GLint expected3[] = {16, 4, 1, 0, 0};
2426 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
2427 expected3, error);
2428 GLint expected4[] = {16, 5, 1, 0, 0};
2429 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
2430 expected4, error);
2431
2432 GLenum props3[] = {GL_NAME_LENGTH,
2433 GL_TYPE,
2434 GL_ARRAY_SIZE,
2435 GL_BLOCK_INDEX,
2436 GL_ARRAY_STRIDE,
2437 GL_IS_ROW_MAJOR,
2438 GL_REFERENCED_BY_COMPUTE_SHADER,
2439 GL_REFERENCED_BY_FRAGMENT_SHADER,
2440 GL_REFERENCED_BY_VERTEX_SHADER,
2441 GL_TOP_LEVEL_ARRAY_SIZE,
2442 GL_TOP_LEVEL_ARRAY_STRIDE};
2443 GLint expected5[] = {2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0};
2444 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
2445 GLenum props4[] = {GL_NAME_LENGTH,
2446 GL_TYPE,
2447 GL_ARRAY_SIZE,
2448 GL_BLOCK_INDEX,
2449 GL_MATRIX_STRIDE,
2450 GL_IS_ROW_MAJOR,
2451 GL_REFERENCED_BY_COMPUTE_SHADER,
2452 GL_REFERENCED_BY_FRAGMENT_SHADER,
2453 GL_REFERENCED_BY_VERTEX_SHADER,
2454 GL_TOP_LEVEL_ARRAY_SIZE};
2455 GLint expected6[] = {28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3};
2456 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
2457 expected6, error);
2458
2459 GLenum prop = GL_ACTIVE_VARIABLES;
2460 const GLsizei bufSize = 1000;
2461 GLsizei length;
2462 GLint param[bufSize];
2463 std::set<GLuint> exp;
2464 exp.insert(indicesBV["a"]);
2465 exp.insert(indicesBV["b"]);
2466 exp.insert(indicesBV["c"]);
2467 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
2468 param);
2469 for (int i = 0; i < length; ++i)
2470 {
2471 if (exp.find(param[i]) == exp.end())
2472 {
2473 m_context.getTestContext().getLog()
2474 << tcu::TestLog::Message
2475 << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
2476 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2477 "GL_SHADER_STORAGE_BLOCK"
2478 << tcu::TestLog::EndMessage;
2479 glDeleteProgram(program);
2480 return ERROR;
2481 }
2482 else if (length != 3)
2483 {
2484 m_context.getTestContext().getLog()
2485 << tcu::TestLog::Message
2486 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2487 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2488 glDeleteProgram(program);
2489 return ERROR;
2490 }
2491 }
2492 std::set<GLuint> exp2;
2493 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
2494 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
2495 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
2496 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
2497 &length, param);
2498 for (int i = 0; i < length; ++i)
2499 {
2500 if (exp2.find(param[i]) == exp2.end())
2501 {
2502 m_context.getTestContext().getLog()
2503 << tcu::TestLog::Message
2504 << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
2505 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2506 "GL_SHADER_STORAGE_BLOCK"
2507 << tcu::TestLog::EndMessage;
2508 glDeleteProgram(program);
2509 return ERROR;
2510 }
2511 else if (length != 3)
2512 {
2513 m_context.getTestContext().getLog()
2514 << tcu::TestLog::Message
2515 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2516 << param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2517 glDeleteProgram(program);
2518 return ERROR;
2519 }
2520 }
2521
2522 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2523 if (res < 3)
2524 {
2525 m_context.getTestContext().getLog()
2526 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
2527 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
2528 return ERROR;
2529 }
2530
2531 glDeleteProgram(program);
2532 return error;
2533 }
2534 };
2535
2536 class NullLength : public SimpleShaders
2537 {
2538
Title()2539 virtual std::string Title()
2540 {
2541 return "NULL Length Test";
2542 }
2543
PurposeExt()2544 virtual std::string PurposeExt()
2545 {
2546 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
2547 "crash).\n";
2548 }
2549
VertexShader()2550 virtual std::string VertexShader()
2551 {
2552 return "#version 310 es \n"
2553 "in vec4 position; \n"
2554 "void main(void) \n"
2555 "{ \n"
2556 " gl_Position = position; \n"
2557 "}";
2558 }
2559
FragmentShader()2560 virtual std::string FragmentShader()
2561 {
2562 return "#version 310 es \n"
2563 "out mediump vec4 color; \n"
2564 "void main() { \n"
2565 " color = vec4(0, 1, 0, 1); \n"
2566 "}";
2567 }
2568
Run()2569 virtual long Run()
2570 {
2571 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2572 glBindAttribLocation(program, 0, "position");
2573 LinkProgram(program);
2574
2575 GLchar name[1024] = {'\0'};
2576 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
2577 GLenum prop = GL_ARRAY_SIZE;
2578 GLint res;
2579 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
2580 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
2581
2582 std::string expected = "color";
2583 if (name != expected)
2584 {
2585 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
2586 << ", got: " << name << tcu::TestLog::EndMessage;
2587 glDeleteProgram(program);
2588 return ERROR;
2589 }
2590 else if (res != 1)
2591 {
2592 m_context.getTestContext().getLog()
2593 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
2594 glDeleteProgram(program);
2595 return ERROR;
2596 }
2597
2598 glDeleteProgram(program);
2599 return NO_ERROR;
2600 }
2601 };
2602
2603 class ArraysOfArrays : public SimpleShaders
2604 {
2605
Title()2606 virtual std::string Title()
2607 {
2608 return "Arrays Of Arrays Test";
2609 }
2610
ShadersDesc()2611 virtual std::string ShadersDesc()
2612 {
2613 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
2614 }
2615
PurposeExt()2616 virtual std::string PurposeExt()
2617 {
2618 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
2619 }
2620
VertexShader()2621 virtual std::string VertexShader()
2622 {
2623 return "#version 310 es \n"
2624 "in vec4 position; \n"
2625 "uniform mediump vec4 a[3][4][5]; \n"
2626 "void main(void) \n"
2627 "{ \n"
2628 " int i = int(position.x); \n"
2629 " if (i < 5) \n"
2630 " gl_Position = position + a[2][1][i]; \n"
2631 " else \n"
2632 " gl_Position = position + a[2][1][0]; \n"
2633 "}";
2634 }
2635
FragmentShader()2636 virtual std::string FragmentShader()
2637 {
2638 return "#version 310 es \n"
2639 "out mediump vec4 color; \n"
2640 "void main() { \n"
2641 " color = vec4(0, 1, 0, 1); \n"
2642 "}";
2643 }
2644
Run()2645 virtual long Run()
2646 {
2647 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2648 glBindAttribLocation(program, 0, "position");
2649 LinkProgram(program);
2650
2651 long error = NO_ERROR;
2652
2653 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
2654
2655 std::map<std::string, GLuint> indices;
2656 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
2657 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
2658
2659 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
2660
2661 GLenum props[] = {GL_NAME_LENGTH,
2662 GL_TYPE,
2663 GL_ARRAY_SIZE,
2664 GL_OFFSET,
2665 GL_BLOCK_INDEX,
2666 GL_ARRAY_STRIDE,
2667 GL_MATRIX_STRIDE,
2668 GL_IS_ROW_MAJOR,
2669 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2670 GL_REFERENCED_BY_COMPUTE_SHADER,
2671 GL_REFERENCED_BY_FRAGMENT_SHADER,
2672 GL_REFERENCED_BY_VERTEX_SHADER,
2673 GL_LOCATION};
2674 GLint expected[] = {11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]")};
2675 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
2676
2677 glDeleteProgram(program);
2678 return error;
2679 }
2680 };
2681
2682 class TopLevelArray : public ComputeShaderTest
2683 {
2684
Title()2685 virtual std::string Title()
2686 {
2687 return "Top Level Array Test";
2688 }
2689
ShadersDesc()2690 virtual std::string ShadersDesc()
2691 {
2692 return "compute shader with multi dimensional array used inside storage block";
2693 }
2694
PurposeExt()2695 virtual std::string PurposeExt()
2696 {
2697 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
2698 " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
2699 }
2700
ComputeShader()2701 virtual std::string ComputeShader()
2702 {
2703 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2704 "layout(std430) buffer Outp { \n"
2705 " mediump vec4 d; \n"
2706 "} g_out; \n"
2707 ""
2708 "buffer Block { \n"
2709 " mediump vec4 a[5][4][3]; \n"
2710 "}; \n"
2711 ""
2712 "void main(void) \n"
2713 "{ \n"
2714 " g_out.d = a[0][0][0]; \n"
2715 "}";
2716 }
2717
Run()2718 virtual long Run()
2719 {
2720 GLuint program = CreateComputeProgram(ComputeShader());
2721 glLinkProgram(program);
2722 if (!CheckProgram(program))
2723 {
2724 glDeleteProgram(program);
2725 return ERROR;
2726 }
2727 glUseProgram(program);
2728
2729 long error = NO_ERROR;
2730
2731 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
2732 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
2733 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
2734
2735 std::map<std::string, GLuint> indicesSSB;
2736 std::map<std::string, GLuint> indicesBV;
2737 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
2738 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
2739
2740 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
2741 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
2742
2743 GLenum props3[] = {GL_NAME_LENGTH,
2744 GL_TYPE,
2745 GL_ARRAY_SIZE,
2746 GL_BLOCK_INDEX,
2747 GL_IS_ROW_MAJOR,
2748 GL_REFERENCED_BY_COMPUTE_SHADER,
2749 GL_REFERENCED_BY_FRAGMENT_SHADER,
2750 GL_REFERENCED_BY_VERTEX_SHADER,
2751 GL_TOP_LEVEL_ARRAY_SIZE};
2752 GLint expected5[] = {11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5};
2753 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
2754
2755 GLenum prop = GL_TOP_LEVEL_ARRAY_STRIDE;
2756 GLsizei len;
2757 GLint res;
2758 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
2759 if (res <= 0)
2760 {
2761 m_context.getTestContext().getLog()
2762 << tcu::TestLog::Message
2763 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
2764 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
2765 glDeleteProgram(program);
2766 return ERROR;
2767 }
2768
2769 glDeleteProgram(program);
2770 return error;
2771 }
2772 };
2773
2774 class SeparateProgramsVertex : public SimpleShaders
2775 {
2776 public:
Title()2777 virtual std::string Title()
2778 {
2779 return "Separate Program Vertex Shader Test";
2780 }
2781
ShadersDesc()2782 virtual std::string ShadersDesc()
2783 {
2784 return "vertex shader as separate shader object";
2785 }
2786
PurposeExt()2787 virtual std::string PurposeExt()
2788 {
2789 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
2790 "functionality.\n";
2791 }
2792
CreateShaderProgram(GLenum type,GLsizei count,const GLchar ** strings)2793 virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar **strings)
2794 {
2795 GLuint program = glCreateShaderProgramv(type, count, strings);
2796 GLint status = GL_TRUE;
2797 glGetProgramiv(program, GL_LINK_STATUS, &status);
2798 if (status == GL_FALSE)
2799 {
2800 GLsizei length;
2801 GLchar log[1024];
2802 glGetProgramInfoLog(program, sizeof(log), &length, log);
2803 if (length > 1)
2804 {
2805 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
2806 << log << tcu::TestLog::EndMessage;
2807 }
2808 }
2809 return program;
2810 }
2811
Run()2812 virtual long Run()
2813 {
2814 long error = NO_ERROR;
2815
2816 const char *srcVS = "#version 310 es \n"
2817 "layout(location = 0) in vec4 in_vertex; \n"
2818 ""
2819 "out mediump float r, g, b; \n"
2820 "out mediump vec4 iLikePie; \n"
2821 ""
2822 "uniform mediump float u; \n"
2823 "uniform mediump vec4 v; \n"
2824 ""
2825 "void main() { \n"
2826 " gl_Position = in_vertex; \n"
2827 " r = u; \n"
2828 " g = 0.0; \n"
2829 " b = 0.0; \n"
2830 " iLikePie = v; \n"
2831 "}";
2832
2833 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
2834
2835 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2836 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
2837 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
2838 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2839 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
2840 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
2841
2842 std::map<std::string, GLuint> indicesU;
2843 std::map<std::string, GLuint> indicesI;
2844 std::map<std::string, GLuint> indicesO;
2845 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
2846 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
2847 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
2848 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
2849 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
2850 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
2851 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
2852 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
2853
2854 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
2855 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
2856 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
2857 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
2858 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
2859 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
2860 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
2861 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
2862
2863 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
2864 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
2865 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
2866
2867 GLenum props[] = {GL_NAME_LENGTH,
2868 GL_TYPE,
2869 GL_ARRAY_SIZE,
2870 GL_OFFSET,
2871 GL_BLOCK_INDEX,
2872 GL_ARRAY_STRIDE,
2873 GL_MATRIX_STRIDE,
2874 GL_IS_ROW_MAJOR,
2875 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2876 GL_REFERENCED_BY_COMPUTE_SHADER,
2877 GL_REFERENCED_BY_FRAGMENT_SHADER,
2878 GL_REFERENCED_BY_VERTEX_SHADER,
2879 GL_LOCATION};
2880 GLint expected[] = {2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v")};
2881 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
2882
2883 GLenum props2[] = {GL_NAME_LENGTH,
2884 GL_TYPE,
2885 GL_ARRAY_SIZE,
2886 GL_REFERENCED_BY_COMPUTE_SHADER,
2887 GL_REFERENCED_BY_FRAGMENT_SHADER,
2888 GL_REFERENCED_BY_VERTEX_SHADER,
2889 GL_LOCATION};
2890 GLint expected2[] = {10, 35666, 1, 0, 0, 1, 0};
2891 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
2892
2893 GLenum props3[] = {GL_NAME_LENGTH,
2894 GL_TYPE,
2895 GL_ARRAY_SIZE,
2896 GL_REFERENCED_BY_COMPUTE_SHADER,
2897 GL_REFERENCED_BY_FRAGMENT_SHADER,
2898 GL_REFERENCED_BY_VERTEX_SHADER};
2899 GLint expected3[] = {9, 35666, 1, 0, 0, 1};
2900 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
2901
2902 glDeleteProgram(vs);
2903 return error;
2904 }
2905 };
2906
2907 class SeparateProgramsFragment : public SeparateProgramsVertex
2908 {
2909
Title()2910 virtual std::string Title()
2911 {
2912 return "Separate Program Fragment Shader Test";
2913 }
2914
ShadersDesc()2915 virtual std::string ShadersDesc()
2916 {
2917 return "fragment shader as separate shader object";
2918 }
2919
Run()2920 virtual long Run()
2921 {
2922 long error = NO_ERROR;
2923
2924 const char *srcTCS = "#version 310 es \n"
2925 "out mediump vec4 fs_color; \n"
2926 ""
2927 "layout(location = 1) uniform mediump vec4 x; \n"
2928 ""
2929 "in mediump vec4 vs_color; \n"
2930 "void main() { \n"
2931 " fs_color = vs_color + x; \n"
2932 "}";
2933
2934 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
2935
2936 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
2937 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2938 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
2939 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
2940 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2941 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2942
2943 std::map<std::string, GLuint> indicesI;
2944 std::map<std::string, GLuint> indicesO;
2945 std::map<std::string, GLuint> indicesU;
2946 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
2947 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
2948 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
2949
2950 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
2951 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
2952 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
2953
2954 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
2955
2956 GLenum props2[] = {GL_NAME_LENGTH,
2957 GL_TYPE,
2958 GL_ARRAY_SIZE,
2959 GL_REFERENCED_BY_COMPUTE_SHADER,
2960 GL_REFERENCED_BY_FRAGMENT_SHADER,
2961 GL_REFERENCED_BY_VERTEX_SHADER};
2962 GLint expected2[] = {9, 35666, 1, 0, 1, 0};
2963 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
2964 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
2965
2966 GLenum props[] = {GL_NAME_LENGTH,
2967 GL_TYPE,
2968 GL_ARRAY_SIZE,
2969 GL_OFFSET,
2970 GL_BLOCK_INDEX,
2971 GL_ARRAY_STRIDE,
2972 GL_MATRIX_STRIDE,
2973 GL_IS_ROW_MAJOR,
2974 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2975 GL_REFERENCED_BY_COMPUTE_SHADER,
2976 GL_REFERENCED_BY_FRAGMENT_SHADER,
2977 GL_REFERENCED_BY_VERTEX_SHADER,
2978 GL_LOCATION};
2979 GLint expected[] = {2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1};
2980 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
2981
2982 glDeleteProgram(tcs);
2983 return error;
2984 }
2985 };
2986
2987 class UniformBlockAdvanced : public SimpleShaders
2988 {
Title()2989 virtual std::string Title()
2990 {
2991 return "Uniform Block Advanced Test";
2992 }
2993
ShadersDesc()2994 virtual std::string ShadersDesc()
2995 {
2996 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
2997 }
2998
PurposeExt()2999 virtual std::string PurposeExt()
3000 {
3001 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
3002 "verify results of querying offset, strides and row order.\n";
3003 }
3004
VertexShader()3005 virtual std::string VertexShader()
3006 {
3007 return "#version 310 es \n"
3008 "in vec4 position; \n"
3009 ""
3010 "layout(row_major) uniform SimpleBlock { \n"
3011 " mat4 a; \n"
3012 " vec4 b[10]; \n"
3013 "}; \n"
3014 ""
3015 "void main(void) \n"
3016 "{ \n"
3017 " float tmp; \n"
3018 " tmp = a[0][0] + b[0].x; \n"
3019 " gl_Position = position * tmp; \n"
3020 "}";
3021 }
3022
Run()3023 virtual long Run()
3024 {
3025 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3026 glBindAttribLocation(program, 0, "position");
3027 LinkProgram(program);
3028
3029 long error = NO_ERROR;
3030
3031 std::map<std::string, GLuint> indicesU;
3032 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
3033 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
3034
3035 GLenum props[] = {GL_IS_ROW_MAJOR};
3036 GLint expected[] = {1};
3037 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
3038
3039 GLenum prop = GL_MATRIX_STRIDE;
3040 GLsizei len;
3041 GLint res;
3042 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3043 if (res < 1)
3044 {
3045 m_context.getTestContext().getLog()
3046 << tcu::TestLog::Message
3047 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
3048 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3049 }
3050 prop = GL_OFFSET;
3051 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3052 if (res < 0)
3053 {
3054 m_context.getTestContext().getLog()
3055 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
3056 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
3057 }
3058 prop = GL_ARRAY_STRIDE;
3059 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
3060 if (res < 1)
3061 {
3062 m_context.getTestContext().getLog()
3063 << tcu::TestLog::Message
3064 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
3065 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3066 }
3067
3068 glDeleteProgram(program);
3069 return error;
3070 }
3071 };
3072
3073 class ArrayNames : public SimpleShaders
3074 {
3075
Title()3076 virtual std::string Title()
3077 {
3078 return "Array Names Test";
3079 }
3080
ShadersDesc()3081 virtual std::string ShadersDesc()
3082 {
3083 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
3084 }
3085
PurposeExt()3086 virtual std::string PurposeExt()
3087 {
3088 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
3089 "name strings correctly.\n";
3090 }
3091
VertexShader()3092 virtual std::string VertexShader()
3093 {
3094 return "#version 310 es \n"
3095 "in vec4 position; \n"
3096 ""
3097 "uniform mediump vec4 a[2]; \n"
3098 ""
3099 "void main(void) \n"
3100 "{ \n"
3101 " gl_Position = position + a[0] + a[1]; \n"
3102 "}";
3103 }
3104
Run()3105 virtual long Run()
3106 {
3107 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3108 glBindAttribLocation(program, 0, "position");
3109 LinkProgram(program);
3110
3111 long error = NO_ERROR;
3112
3113 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
3114 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
3115 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
3116 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
3117 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
3118 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
3119 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
3120 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
3121 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
3122 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
3123 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
3124 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
3125
3126 glDeleteProgram(program);
3127 return error;
3128 }
3129 };
3130
3131 class BuffLength : public SimpleShaders
3132 {
3133
Title()3134 virtual std::string Title()
3135 {
3136 return "Buff Length Test";
3137 }
3138
ShadersDesc()3139 virtual std::string ShadersDesc()
3140 {
3141 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
3142 }
3143
PurposeExt()3144 virtual std::string PurposeExt()
3145 {
3146 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
3147 "GetProgramResourceiv is respected.\n";
3148 }
3149
VertexShader()3150 virtual std::string VertexShader()
3151 {
3152 return "#version 310 es \n"
3153 "in vec4 position; \n"
3154 ""
3155 "uniform mediump vec4 someLongName; \n"
3156 ""
3157 "void main(void) \n"
3158 "{ \n"
3159 " gl_Position = position + someLongName; \n"
3160 "}";
3161 }
3162
Run()3163 virtual long Run()
3164 {
3165 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3166 glBindAttribLocation(program, 0, "position");
3167 LinkProgram(program);
3168
3169 long error = NO_ERROR;
3170
3171 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
3172 GLsizei length;
3173 GLchar buff[3] = {'a', 'b', 'c'};
3174 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
3175 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
3176 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
3177 {
3178 m_context.getTestContext().getLog()
3179 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
3180 error = ERROR;
3181 }
3182 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
3183 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
3184 {
3185 m_context.getTestContext().getLog()
3186 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
3187 error = ERROR;
3188 }
3189 if (length != 1)
3190 {
3191 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
3192 << length << tcu::TestLog::EndMessage;
3193 error = ERROR;
3194 }
3195
3196 GLint params[3] = {1, 2, 3};
3197 GLenum props[] = {GL_NAME_LENGTH,
3198 GL_TYPE,
3199 GL_ARRAY_SIZE,
3200 GL_OFFSET,
3201 GL_BLOCK_INDEX,
3202 GL_ARRAY_STRIDE,
3203 GL_MATRIX_STRIDE,
3204 GL_IS_ROW_MAJOR,
3205 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3206 GL_REFERENCED_BY_COMPUTE_SHADER,
3207 GL_REFERENCED_BY_FRAGMENT_SHADER,
3208 GL_REFERENCED_BY_VERTEX_SHADER,
3209 GL_LOCATION};
3210 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
3211 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
3212 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
3213 {
3214 m_context.getTestContext().getLog()
3215 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
3216 error = ERROR;
3217 }
3218 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
3219 if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
3220 {
3221 m_context.getTestContext().getLog()
3222 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
3223 error = ERROR;
3224 }
3225 if (length != 2)
3226 {
3227 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
3228 << length << tcu::TestLog::EndMessage;
3229 error = ERROR;
3230 }
3231
3232 glDeleteProgram(program);
3233 return error;
3234 }
3235 };
3236
3237 class NoLocations : public SimpleShaders
3238 {
3239
Title()3240 virtual std::string Title()
3241 {
3242 return "No Locations Test";
3243 }
3244
ShadersDesc()3245 virtual std::string ShadersDesc()
3246 {
3247 return "fragment and vertex shaders with no locations set";
3248 }
3249
VertexShader()3250 virtual std::string VertexShader()
3251 {
3252 return "#version 310 es \n"
3253 "in vec4 a; \n"
3254 "in vec4 b; \n"
3255 "in vec4 c; \n"
3256 "in vec4 d; \n"
3257 "void main(void) \n"
3258 "{ \n"
3259 " gl_Position = a + b + c + d; \n"
3260 "}";
3261 }
3262
3263 // fragment shader outputs need an explicit location per spec
FragmentShader()3264 virtual std::string FragmentShader()
3265 {
3266 return "#version 310 es \n"
3267 "layout (location=0) out mediump vec4 a; \n"
3268 "layout (location=1) out mediump vec4 b; \n"
3269 "layout (location=2) out mediump vec4 c; \n"
3270 "layout (location=3) out mediump vec4 d[1]; \n"
3271 "void main() { \n"
3272 " a = vec4(0, 1, 0, 1); \n"
3273 " b = vec4(0, 1, 0, 1); \n"
3274 " c = vec4(0, 1, 0, 1); \n"
3275 " d[0] = vec4(0, 1, 0, 1); \n"
3276 "}";
3277 }
3278
Run()3279 virtual long Run()
3280 {
3281 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3282 glBindAttribLocation(program, 0, "position");
3283 glLinkProgram(program);
3284
3285 long error = NO_ERROR;
3286
3287 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
3288 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
3289 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
3290 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
3291
3292 std::map<std::string, GLuint> indicesI;
3293 std::map<std::string, GLuint> indicesO;
3294 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
3295 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
3296 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
3297 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
3298 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
3299 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
3300 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
3301 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
3302
3303 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
3304 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
3305 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
3306 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
3307 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
3308 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
3309 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
3310 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
3311
3312 std::map<std::string, GLint> locationsI;
3313 std::map<std::string, GLint> locationsO;
3314 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
3315 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
3316 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
3317 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
3318 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
3319 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
3320 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
3321 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
3322
3323 GLenum props[] = {GL_NAME_LENGTH,
3324 GL_TYPE,
3325 GL_ARRAY_SIZE,
3326 GL_REFERENCED_BY_COMPUTE_SHADER,
3327 GL_REFERENCED_BY_FRAGMENT_SHADER,
3328 GL_REFERENCED_BY_VERTEX_SHADER};
3329 GLint expected[] = {2, 35666, 1, 0, 0, 1};
3330 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
3331 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
3332 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
3333 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
3334 GLint expected3[] = {2, 35666, 1, 0, 1, 0};
3335 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
3336 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
3337 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
3338 GLint expected4[] = {5, 35666, 1, 0, 1, 0};
3339 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
3340
3341 glDeleteProgram(program);
3342 return error;
3343 }
3344 };
3345
3346 class OutputBuiltIn : public SimpleShaders
3347 {
3348
Title()3349 virtual std::string Title()
3350 {
3351 return "Output Built-ins Test";
3352 }
3353
ShadersDesc()3354 virtual std::string ShadersDesc()
3355 {
3356 return "fragment shader using built-in variables and a fallthrough vertex shader";
3357 }
3358
Expectations()3359 virtual std::string Expectations()
3360 {
3361 return ".\n\n In this case we ask for information about built-in variables for the output interface.";
3362 }
3363
FragmentShader()3364 virtual std::string FragmentShader()
3365 {
3366 return "#version 310 es \n"
3367 "void main(void) \n"
3368 "{ \n"
3369 " gl_FragDepth = 0.1; \n"
3370 "}";
3371 }
3372
Run()3373 virtual long Run()
3374 {
3375 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
3376
3377 long error = NO_ERROR;
3378
3379 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3380 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
3381
3382 std::map<std::string, GLuint> indices;
3383 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
3384
3385 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
3386
3387 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
3388
3389 GLenum props[] = {GL_NAME_LENGTH,
3390 GL_TYPE,
3391 GL_ARRAY_SIZE,
3392 GL_REFERENCED_BY_COMPUTE_SHADER,
3393 GL_REFERENCED_BY_FRAGMENT_SHADER,
3394 GL_REFERENCED_BY_VERTEX_SHADER,
3395 GL_LOCATION};
3396 GLint expected[] = {13, 5126, 1, 0, 1, 0, -1};
3397 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
3398 props, DE_LENGTH_OF_ARRAY(expected), expected, error);
3399
3400 glDeleteProgram(program);
3401 return error;
3402 }
3403 };
3404
3405 class QueryNotUsed : public SimpleShaders
3406 {
3407
Title()3408 virtual std::string Title()
3409 {
3410 return "Query Not Used Test";
3411 }
3412
PassCriteria()3413 virtual std::string PassCriteria()
3414 {
3415 return "Data from queries matches the not used program.";
3416 }
3417
Purpose()3418 virtual std::string Purpose()
3419 {
3420 return "Verify that program parameter works correctly and proper program is queried when different program is "
3421 "used.";
3422 }
3423
Method()3424 virtual std::string Method()
3425 {
3426 return "Create 2 programs, use one of them and query the other, verify the results.";
3427 }
3428
VertexShader2()3429 virtual std::string VertexShader2()
3430 {
3431 return "#version 310 es \n"
3432 "in mediump vec4 p; \n"
3433 "void main(void) \n"
3434 "{ \n"
3435 " gl_Position = p; \n"
3436 "}";
3437 }
3438
FragmentShader2()3439 virtual std::string FragmentShader2()
3440 {
3441 return "#version 310 es \n"
3442 "out mediump vec4 c; \n"
3443 "void main() { \n"
3444 " c = vec4(0., 1., 0., 1.); \n"
3445 "}";
3446 }
3447
Run()3448 virtual long Run()
3449 {
3450 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3451 LinkProgram(program);
3452
3453 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
3454 LinkProgram(program2);
3455 glUseProgram(program2);
3456
3457 long error = NO_ERROR;
3458
3459 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3460 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
3461 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3462 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
3463
3464 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3465 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
3466
3467 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
3468 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
3469
3470 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
3471 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3472
3473 GLenum props[] = {GL_NAME_LENGTH,
3474 GL_TYPE,
3475 GL_ARRAY_SIZE,
3476 GL_REFERENCED_BY_COMPUTE_SHADER,
3477 GL_REFERENCED_BY_FRAGMENT_SHADER,
3478 GL_REFERENCED_BY_VERTEX_SHADER,
3479 GL_LOCATION};
3480 GLint expected[] = {9, 35666, 1, 0, 0, 1, 0};
3481 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
3482 DE_LENGTH_OF_ARRAY(expected), expected, error);
3483
3484 GLenum props2[] = {GL_NAME_LENGTH,
3485 GL_TYPE,
3486 GL_ARRAY_SIZE,
3487 GL_REFERENCED_BY_COMPUTE_SHADER,
3488 GL_REFERENCED_BY_FRAGMENT_SHADER,
3489 GL_REFERENCED_BY_VERTEX_SHADER,
3490 GL_LOCATION};
3491 GLint expected2[] = {6, 35666, 1, 0, 1, 0, 0};
3492 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
3493
3494 glDeleteProgram(program);
3495 glDeleteProgram(program2);
3496 return error;
3497 }
3498 };
3499
3500 class RelinkFailure : public SimpleShaders
3501 {
3502
Title()3503 virtual std::string Title()
3504 {
3505 return "Relink Failure Test";
3506 }
3507
PassCriteria()3508 virtual std::string PassCriteria()
3509 {
3510 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3511 }
3512
Purpose()3513 virtual std::string Purpose()
3514 {
3515 return "Verify that queries behave correctly after failed relink of a program.";
3516 }
3517
Method()3518 virtual std::string Method()
3519 {
3520 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
3521 "asking for locations.";
3522 }
3523
VertexShader()3524 virtual std::string VertexShader()
3525 {
3526 return "#version 310 es \n"
3527 "in mediump vec4 position; \n"
3528 "in mediump vec3 pos; \n"
3529 "void main(void) \n"
3530 "{ \n"
3531 " gl_Position = position + vec4(pos, 1.); \n"
3532 "}";
3533 }
3534
Run()3535 virtual long Run()
3536 {
3537 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3538 glBindAttribLocation(program, 0, "position");
3539 glBindAttribLocation(program, 1, "pos");
3540 LinkProgram(program);
3541
3542 long error = NO_ERROR;
3543
3544 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
3545 glUseProgram(program);
3546
3547 tcu::Vec4 v[4] = {tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3548 tcu::Vec4(1, -1, 0, 1)};
3549 GLuint vao, vbuf;
3550 glGenVertexArrays(1, &vao);
3551 glBindVertexArray(vao);
3552 glGenBuffers(1, &vbuf);
3553 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3554 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3555 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3556 glEnableVertexAttribArray(0);
3557 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3558
3559 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3560 glDisableVertexAttribArray(0);
3561 glDeleteVertexArrays(1, &vao);
3562 glBindBuffer(GL_ARRAY_BUFFER, 0);
3563 glDeleteBuffers(1, &vbuf);
3564
3565 glBindAttribLocation(program, 0, "pos");
3566 glBindAttribLocation(program, 0, "position");
3567 const char *varyings[2] = {"q", "z"};
3568 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3569 LinkProgram(program);
3570
3571 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3572 ExpectError(GL_INVALID_OPERATION, error);
3573 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
3574 ExpectError(GL_INVALID_OPERATION, error);
3575 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3576 ExpectError(GL_INVALID_OPERATION, error);
3577
3578 glDeleteProgram(program);
3579 return error;
3580 }
3581 };
3582
3583 class LinkFailure : public SimpleShaders
3584 {
3585
Title()3586 virtual std::string Title()
3587 {
3588 return "Link Failure Test";
3589 }
3590
PassCriteria()3591 virtual std::string PassCriteria()
3592 {
3593 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3594 }
3595
Purpose()3596 virtual std::string Purpose()
3597 {
3598 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
3599 }
3600
Method()3601 virtual std::string Method()
3602 {
3603 return "Create a program, use it, relink with failure using different sources and then \n"
3604 "verify that INVALID_OPERATION is returned when asking for locations.";
3605 }
3606
VertexShader_prop()3607 virtual const char *VertexShader_prop()
3608 {
3609 return "#version 310 es \n"
3610 "in mediump vec4 posit; \n"
3611 "in mediump vec4 p; \n"
3612 "void main(void) \n"
3613 "{ \n"
3614 " gl_Position = p + posit; \n"
3615 "}";
3616 }
3617
FragmentShader_prop()3618 virtual const char *FragmentShader_prop()
3619 {
3620 return "#version 310 es \n"
3621 "out mediump vec4 color; \n"
3622 "void main() { \n"
3623 " color = vec4(0., 1., 0., 1.); \n"
3624 "}";
3625 }
3626
VertexShader_fail()3627 virtual const char *VertexShader_fail()
3628 {
3629 return "#version 310 es \n"
3630 "in mediump vec4 position; \n"
3631 "void main(void) \n"
3632 "{ \n"
3633 " gl_Position = position; \n"
3634 "}";
3635 }
3636
Run()3637 virtual long Run()
3638 {
3639 const GLuint program = glCreateProgram();
3640 const char *src_vs = VertexShader_prop();
3641 const char *src_fs = FragmentShader_prop();
3642 const char *src_vsh = VertexShader_fail();
3643
3644 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
3645 glAttachShader(program, sh1);
3646 glDeleteShader(sh1);
3647 glShaderSource(sh1, 1, &src_vs, NULL);
3648 glCompileShader(sh1);
3649
3650 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
3651 glAttachShader(program, sh2);
3652 glDeleteShader(sh2);
3653 glShaderSource(sh2, 1, &src_fs, NULL);
3654 glCompileShader(sh2);
3655
3656 glBindAttribLocation(program, 0, "p");
3657 glBindAttribLocation(program, 1, "posit");
3658 LinkProgram(program);
3659
3660 long error = NO_ERROR;
3661
3662 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
3663 glUseProgram(program);
3664
3665 tcu::Vec4 v[4] = {tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3666 tcu::Vec4(1, -1, 0, 1)};
3667 GLuint vao, vbuf;
3668 glGenVertexArrays(1, &vao);
3669 glBindVertexArray(vao);
3670 glGenBuffers(1, &vbuf);
3671 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3672 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3673 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3674 glEnableVertexAttribArray(0);
3675 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3676
3677 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3678 glDisableVertexAttribArray(0);
3679 glDeleteVertexArrays(1, &vao);
3680 glBindBuffer(GL_ARRAY_BUFFER, 0);
3681 glDeleteBuffers(1, &vbuf);
3682
3683 glDetachShader(program, sh1);
3684 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
3685 glAttachShader(program, vsh);
3686 glDeleteShader(vsh);
3687 glShaderSource(vsh, 1, &src_vsh, NULL);
3688 glCompileShader(vsh);
3689 const char *varyings[2] = {"q", "z"};
3690 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3691 LinkProgram(program);
3692
3693 GLint res;
3694 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3695 ExpectError(GL_INVALID_OPERATION, error);
3696 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
3697 if (res != 0 && res != 1)
3698 {
3699 m_context.getTestContext().getLog()
3700 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
3701 << tcu::TestLog::EndMessage;
3702 error = ERROR;
3703 }
3704 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
3705 if (res != 0 && res != 9)
3706 {
3707 m_context.getTestContext().getLog()
3708 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
3709 << tcu::TestLog::EndMessage;
3710 error = ERROR;
3711 }
3712 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3713 ExpectError(GL_INVALID_OPERATION, error);
3714
3715 glDeleteProgram(program);
3716 return error;
3717 }
3718 };
3719 } // namespace
3720
ProgramInterfaceQueryTests(glcts::Context & context)3721 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context &context)
3722 : TestCaseGroup(context, "program_interface_query", "")
3723 {
3724 }
3725
~ProgramInterfaceQueryTests(void)3726 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
3727 {
3728 }
3729
init()3730 void ProgramInterfaceQueryTests::init()
3731 {
3732 using namespace glcts;
3733 addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
3734 addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
3735 addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
3736 addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
3737 addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
3738 addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
3739 addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
3740 addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
3741 addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
3742 addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
3743 addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
3744 addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
3745 addChild(new TestSubcase(m_context, "transform-feedback-types-full-array-capture",
3746 TestSubcase::Create<TransformFeedbackTypesFullArrayCapture>));
3747 addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
3748 addChild(
3749 new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
3750 addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
3751 addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
3752 addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
3753 addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
3754 addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
3755 addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
3756 addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
3757 addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
3758 addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
3759 addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
3760 addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
3761 addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
3762 addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
3763 addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
3764 addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
3765 addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
3766 addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
3767 }
3768 } // namespace glcts
3769