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 " tmp = tmp + l[2].b[1].d[0]; \n"
1148 " tmp = tmp + float(l[0].c.x); \n"
1149 " color = vec4(0, 1, 0, 1) * tmp; \n"
1150 "}";
1151 }
1152
Run()1153 virtual long Run()
1154 {
1155 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1156 glBindAttribLocation(program, 0, "position");
1157 LinkProgram(program);
1158
1159 long error = NO_ERROR;
1160
1161 // only active structure members
1162 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1163 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1164 // l[2].b[1].d[0] and \0
1165 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1166
1167 std::map<std::string, GLuint> indices;
1168 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1169 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1170 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1171 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1172 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1173 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1174 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1175 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1176 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1177 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1178 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1179 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1180 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1181 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1182
1183 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1184 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1185 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1186 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1187 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1188 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1189 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1190 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1191 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1192 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1193 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1194 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1195 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1196 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1197
1198 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1199 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1200 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1201 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1202 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1203 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1204 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1205 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1206 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1207 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1208 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1209 error);
1210 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1211 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1212 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1213 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1214 error);
1215
1216 GLenum props[] = { GL_NAME_LENGTH,
1217 GL_TYPE,
1218 GL_ARRAY_SIZE,
1219 GL_OFFSET,
1220 GL_BLOCK_INDEX,
1221 GL_ARRAY_STRIDE,
1222 GL_MATRIX_STRIDE,
1223 GL_IS_ROW_MAJOR,
1224 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1225 GL_REFERENCED_BY_COMPUTE_SHADER,
1226 GL_REFERENCED_BY_FRAGMENT_SHADER,
1227 GL_REFERENCED_BY_VERTEX_SHADER,
1228 GL_LOCATION };
1229 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a") };
1230 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error);
1231 GLint expected2[] = { 2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b") };
1232 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error);
1233 GLint expected3[] = { 5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c") };
1234 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error);
1235 GLint expected4[] = { 2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d") };
1236 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error);
1237 GLint expected5[] = { 2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e") };
1238 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error);
1239 GLint expected6[] = { 2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f") };
1240 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error);
1241 GLint expected7[] = { 5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g") };
1242 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error);
1243 GLint expected8[] = { 2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h") };
1244 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error);
1245 GLint expected9[] = { 2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i") };
1246 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error);
1247 GLint expected10[] = { 4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b") };
1248 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error);
1249 GLint expected11[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c") };
1250 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error);
1251 GLint expected12[] = { 7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c") };
1252 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error);
1253 GLint expected13[] = {
1254 15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")
1255 };
1256 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error);
1257 GLint expected14[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c") };
1258 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error);
1259
1260 glDeleteProgram(program);
1261 return error;
1262 }
1263 };
1264
1265 class UniformBlockTypes : public PIQBase
1266 {
Title()1267 virtual std::string Title()
1268 {
1269 return "Uniform Block Types Test";
1270 }
1271
ShadersDesc()1272 virtual std::string ShadersDesc()
1273 {
1274 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1275 }
1276
PurposeExt()1277 virtual std::string PurposeExt()
1278 {
1279 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1280 }
1281
VertexShader()1282 virtual std::string VertexShader()
1283 {
1284 return "#version 310 es \n"
1285 "in vec4 position; \n"
1286 ""
1287 "uniform SimpleBlock { \n"
1288 " mediump mat3x2 a; \n"
1289 " mediump mat4 b; \n"
1290 " vec4 c; \n"
1291 "}; \n"
1292 ""
1293 "uniform NotSoSimpleBlockk { \n"
1294 " ivec2 a[4]; \n"
1295 " mediump mat3 b[2]; \n"
1296 " mediump mat2 c; \n"
1297 "} d; \n"
1298 ""
1299 "void main(void) \n"
1300 "{ \n"
1301 " mediump float tmp; \n"
1302 " tmp = a[0][1] * b[1][2] * c.x; \n"
1303 " tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1]; \n"
1304 " gl_Position = position * tmp; \n"
1305 "}";
1306 }
1307
FragmentShader()1308 virtual std::string FragmentShader()
1309 {
1310 return "#version 310 es \n"
1311 "struct U { \n"
1312 " bool a[3]; \n"
1313 " mediump vec4 b; \n"
1314 " mediump mat3 c; \n"
1315 " mediump float d[2]; \n"
1316 "}; \n"
1317 "struct UU { \n"
1318 " U a; \n"
1319 " U b[2]; \n"
1320 " uvec2 c; \n"
1321 "}; \n"
1322 ""
1323 "uniform TrickyBlock { \n"
1324 " UU a[3]; \n"
1325 " mediump mat4 b; \n"
1326 " uint c; \n"
1327 "} e[2]; \n"
1328 ""
1329 "out mediump vec4 color; \n"
1330 "void main() { \n"
1331 " mediump float tmp; \n"
1332 " tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n"
1333 " color = vec4(0, 1, 0, 1) * tmp; \n"
1334 "}";
1335 }
1336
Run()1337 virtual long Run()
1338 {
1339 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1340 glBindAttribLocation(program, 0, "position");
1341 LinkProgram(program);
1342
1343 long error = NO_ERROR;
1344
1345 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1346 GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1347 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1348 VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1349
1350 std::map<std::string, GLuint> indicesUB;
1351 std::map<std::string, GLuint> indicesU;
1352 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1353 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1354 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1355 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1356 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1357 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1358 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1359 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1360 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1361 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1362 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1363
1364 glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1365 glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1366 glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1367 glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1368
1369 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1370 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1371 error);
1372 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1373 VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1374 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1375 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1376 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1377 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1378 error);
1379 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1380 error);
1381 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1382 error);
1383 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1384 "TrickyBlock.a[2].b[0].d[0]", error);
1385
1386 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1387 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1388 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1389
1390 GLenum props[] = {
1391 GL_NAME_LENGTH,
1392 GL_BUFFER_BINDING,
1393 GL_REFERENCED_BY_COMPUTE_SHADER,
1394 GL_REFERENCED_BY_FRAGMENT_SHADER,
1395 GL_REFERENCED_BY_VERTEX_SHADER,
1396 GL_BUFFER_DATA_SIZE,
1397 };
1398 GLint size;
1399 glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1400 GLint expected[] = { 12, 0, 0, 0, 1, size };
1401 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error);
1402 glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1403 GLint expected2[] = { 18, 2, 0, 0, 1, size };
1404 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2,
1405 error);
1406 glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1407 GLint expected3[] = { 15, 3, 0, 1, 0, size };
1408 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error);
1409 GLint expected4[] = { 15, 4, 0, 1, 0, size };
1410 VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4,
1411 error);
1412
1413 GLenum props2[] = { GL_NAME_LENGTH,
1414 GL_TYPE,
1415 GL_ARRAY_SIZE,
1416 GL_BLOCK_INDEX,
1417 GL_ARRAY_STRIDE,
1418 GL_IS_ROW_MAJOR,
1419 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1420 GL_REFERENCED_BY_COMPUTE_SHADER,
1421 GL_REFERENCED_BY_FRAGMENT_SHADER,
1422 GL_REFERENCED_BY_VERTEX_SHADER,
1423 GL_LOCATION };
1424 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1 };
1425 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error);
1426 GLenum props3[] = { GL_NAME_LENGTH,
1427 GL_TYPE,
1428 GL_ARRAY_SIZE,
1429 GL_BLOCK_INDEX,
1430 GL_MATRIX_STRIDE,
1431 GL_IS_ROW_MAJOR,
1432 GL_ATOMIC_COUNTER_BUFFER_INDEX,
1433 GL_REFERENCED_BY_COMPUTE_SHADER,
1434 GL_REFERENCED_BY_FRAGMENT_SHADER,
1435 GL_REFERENCED_BY_VERTEX_SHADER,
1436 GL_LOCATION };
1437 GLint expected6[] = { 27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1 };
1438 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6,
1439 error);
1440
1441 GLenum prop = GL_ACTIVE_VARIABLES;
1442 const GLsizei bufSize = 1000;
1443 GLsizei length;
1444 GLint param[bufSize];
1445 std::set<GLuint> exp;
1446 exp.insert(indicesU["a"]);
1447 exp.insert(indicesU["b"]);
1448 exp.insert(indicesU["c"]);
1449 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1450 for (int i = 0; i < length; ++i)
1451 {
1452 if (exp.find(param[i]) == exp.end())
1453 {
1454 m_context.getTestContext().getLog()
1455 << tcu::TestLog::Message
1456 << "Unexpected index found in active variables of SimpleBlock: " << param[i]
1457 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1458 << tcu::TestLog::EndMessage;
1459 glDeleteProgram(program);
1460 return ERROR;
1461 }
1462 else if (length != 3)
1463 {
1464 m_context.getTestContext().getLog()
1465 << tcu::TestLog::Message
1466 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1467 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1468 glDeleteProgram(program);
1469 return ERROR;
1470 }
1471 }
1472 std::set<GLuint> exp2;
1473 exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1474 exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1475 exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1476 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1477 param);
1478 for (int i = 0; i < length; ++i)
1479 {
1480 if (exp2.find(param[i]) == exp2.end())
1481 {
1482 m_context.getTestContext().getLog()
1483 << tcu::TestLog::Message
1484 << "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1485 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1486 << tcu::TestLog::EndMessage;
1487 glDeleteProgram(program);
1488 return ERROR;
1489 }
1490 else if (length != 3)
1491 {
1492 m_context.getTestContext().getLog()
1493 << tcu::TestLog::Message
1494 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1495 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1496 glDeleteProgram(program);
1497 return ERROR;
1498 }
1499 }
1500
1501 GLint res;
1502 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1503 if (res < 3)
1504 {
1505 m_context.getTestContext().getLog()
1506 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1507 << tcu::TestLog::EndMessage;
1508 glDeleteProgram(program);
1509 return ERROR;
1510 }
1511
1512 glDeleteProgram(program);
1513 return error;
1514 }
1515 };
1516
1517 class UniformBlockArray : public PIQBase
1518 {
Title()1519 virtual std::string Title()
1520 {
1521 return "Uniform Block Array Test";
1522 }
1523
ShadersDesc()1524 virtual std::string ShadersDesc()
1525 {
1526 return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
1527 }
1528
PurposeExt()1529 virtual std::string PurposeExt()
1530 {
1531 return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
1532 }
1533
VertexShader()1534 virtual std::string VertexShader()
1535 {
1536 return "#version 310 es \n"
1537 "void main(void) \n"
1538 "{ \n"
1539 " gl_Position = vec4(1.0); \n"
1540 "}";
1541 }
1542
FragmentShader()1543 virtual std::string FragmentShader()
1544 {
1545 return "#version 310 es \n"
1546 "uniform TestBlock { \n"
1547 " mediump vec4 color; \n"
1548 "} blockInstance[4]; \n"
1549 ""
1550 "out mediump vec4 color; \n"
1551 "void main() { \n"
1552 " color = blockInstance[2].color + blockInstance[3].color; \n"
1553 "}";
1554 }
1555
Run()1556 virtual long Run()
1557 {
1558 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1559 LinkProgram(program);
1560
1561 long error = NO_ERROR;
1562
1563 std::map<std::string, GLuint> indicesUB;
1564 VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
1565
1566 std::map<std::string, GLuint> indicesU;
1567 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
1568
1569 GLenum props[] = { GL_BLOCK_INDEX };
1570 GLint expected[] = { static_cast<GLint>(indicesUB["TestBlock"]) };
1571 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
1572
1573 glDeleteProgram(program);
1574 return error;
1575 }
1576 };
1577
1578 class TransformFeedbackTypes : public SimpleShaders
1579 {
Title()1580 virtual std::string Title()
1581 {
1582 return "Transform Feedback Varying Types";
1583 }
1584
ShadersDesc()1585 virtual std::string ShadersDesc()
1586 {
1587 return "fallthrough fragment and vertex shaders with different types of out variables used";
1588 }
1589
PurposeExt()1590 virtual std::string PurposeExt()
1591 {
1592 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1593 }
1594
VertexShader()1595 virtual std::string VertexShader()
1596 {
1597 return "#version 310 es \n"
1598 "in vec4 position; \n"
1599 ""
1600 "flat out highp vec4 a; \n"
1601 "out mediump float b[2]; \n"
1602 "flat out highp uvec2 c; \n"
1603 "flat out highp uint d; \n"
1604 "out mediump vec3 e[2]; \n"
1605 "flat out int f; \n"
1606 ""
1607 "void main(void) \n"
1608 "{ \n"
1609 " vec4 pos; \n"
1610 " a = vec4(1); \n"
1611 " b[0] = 1.1; \n"
1612 " b[1] = 1.1; \n"
1613 " c = uvec2(1u); \n"
1614 " d = 1u; \n"
1615 " e[0] = vec3(1.1); \n"
1616 " e[1] = vec3(1.1); \n"
1617 " f = 1; \n"
1618 " gl_Position = position; \n"
1619 "}";
1620 }
1621
Run()1622 virtual long Run()
1623 {
1624 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1625 glBindAttribLocation(program, 0, "position");
1626 const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1627 glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1628 LinkProgram(program);
1629
1630 long error = NO_ERROR;
1631
1632 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1633 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1634
1635 std::map<std::string, GLuint> indices;
1636 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1637 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1638 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1639 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1640 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1641 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1642
1643 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1644 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1645 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1646 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1647 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1648 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1649
1650 GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1651 GLint expected[] = { 2, 35666, 1 };
1652 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1653 GLint expected2[] = { 5, 5126, 1 };
1654 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1655 error);
1656 GLint expected3[] = { 5, 5126, 1 };
1657 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1658 error);
1659 GLint expected4[] = { 2, 36294, 1 };
1660 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1661 GLint expected5[] = { 2, 5125, 1 };
1662 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1663 GLint expected6[] = { 2, 35665, 2 };
1664 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1665
1666 glDeleteProgram(program);
1667 return error;
1668 }
1669 };
1670
1671 class TransformFeedbackTypesFullArrayCapture : public SimpleShaders
1672 {
Title()1673 virtual std::string Title()
1674 {
1675 return "Transform Feedback Varying Types Without Element Capture";
1676 }
1677
ShadersDesc()1678 virtual std::string ShadersDesc()
1679 {
1680 return "fallthrough fragment and vertex shaders with different types of out variables used";
1681 }
1682
PurposeExt()1683 virtual std::string PurposeExt()
1684 {
1685 return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1686 }
1687
VertexShader()1688 virtual std::string VertexShader()
1689 {
1690 return "#version 310 es \n"
1691 "in vec4 position; \n"
1692 ""
1693 "flat out highp vec4 a; \n"
1694 "out mediump float b[2]; \n"
1695 "flat out highp uvec2 c; \n"
1696 "flat out highp uint d; \n"
1697 "out mediump vec3 e[2]; \n"
1698 "flat out int f; \n"
1699 ""
1700 "void main(void) \n"
1701 "{ \n"
1702 " vec4 pos; \n"
1703 " a = vec4(1); \n"
1704 " b[0] = 1.1; \n"
1705 " b[1] = 1.1; \n"
1706 " c = uvec2(1u); \n"
1707 " d = 1u; \n"
1708 " e[0] = vec3(1.1); \n"
1709 " e[1] = vec3(1.1); \n"
1710 " f = 1; \n"
1711 " gl_Position = position; \n"
1712 "}";
1713 }
1714
Run()1715 virtual long Run()
1716 {
1717 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1718 glBindAttribLocation(program, 0, "position");
1719 const char* varyings[5] = { "a", "b", "c", "d", "e" };
1720 glTransformFeedbackVaryings(program, 5, varyings, GL_INTERLEAVED_ATTRIBS);
1721 LinkProgram(program);
1722
1723 long error = NO_ERROR;
1724
1725 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 5, error);
1726 VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 2, error);
1727
1728 std::map<std::string, GLuint> indices;
1729 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1730 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b", error);
1731 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1732 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1733 VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1734
1735 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1736 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], "b", error);
1737 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1738 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1739 VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1740
1741 GLenum props[] = { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1742 GLint expected[] = { 2, GL_FLOAT_VEC4, 1 };
1743 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1744 GLint expected2[] = { 2, GL_FLOAT, 2 };
1745 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], 3, props, 3, expected2, error);
1746 GLint expected3[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1747 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected3, error);
1748 GLint expected4[] = { 2, GL_UNSIGNED_INT, 1 };
1749 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected4, error);
1750 GLint expected5[] = { 2, GL_FLOAT_VEC3, 2 };
1751 VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected5, error);
1752
1753 glDeleteProgram(program);
1754 return error;
1755 }
1756 };
1757
1758 class AtomicCounterSimple : public ComputeShaderTest
1759 {
1760 public:
Title()1761 virtual std::string Title()
1762 {
1763 return "Atomic Counter Buffer Simple Test";
1764 }
1765
ShadersDesc()1766 virtual std::string ShadersDesc()
1767 {
1768 return "compute shader with atomic counters used";
1769 }
1770
PurposeExt()1771 virtual std::string PurposeExt()
1772 {
1773 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1774 }
1775
Run()1776 virtual long Run()
1777 {
1778
1779 GLint max_buffer_bindings = 0;
1780 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1781 if (max_buffer_bindings < 6)
1782 {
1783 OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
1784 return NOT_SUPPORTED;
1785 }
1786
1787 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n"
1788 "layout(std430) buffer Output { \n"
1789 " mediump vec4 data; \n"
1790 "} g_out; \n"
1791 ""
1792 "layout (binding = 1, offset = 0) uniform highp atomic_uint a; \n"
1793 "layout (binding = 2, offset = 0) uniform highp atomic_uint b; \n"
1794 "layout (binding = 2, offset = 4) uniform highp atomic_uint c; \n"
1795 "layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
1796 "layout (binding = 5, offset = 12) uniform highp atomic_uint e; \n"
1797 ""
1798 "void main() { \n"
1799 " uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1800 " uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1801 " uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1802 " uint w = atomicCounterIncrement(e); \n"
1803 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n"
1804 "}";
1805
1806 GLuint program = CreateComputeProgram(glsl_cs);
1807 glLinkProgram(program);
1808 if (!CheckProgram(program))
1809 {
1810 glDeleteProgram(program);
1811 return ERROR;
1812 }
1813 glUseProgram(program);
1814
1815 long error = NO_ERROR;
1816
1817 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1818 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1819
1820 std::map<std::string, GLuint> indicesU;
1821 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1822 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1823 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1824 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1825 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1826
1827 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1828 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1829 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1830 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1831 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1832
1833 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1834 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1835 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1836 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1837 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1838 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1839 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1840 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1841
1842 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1843 const GLsizei bufSize = 1000;
1844 GLsizei length;
1845 GLint res;
1846 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1847
1848 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1849 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1850 GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1851 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1852
1853 GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1854 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1855 GLint expected2[] = { 2, 8, 2 };
1856 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1857 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1858 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1859
1860 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1861 GLint expected3[] = { 5, 16, 2 };
1862 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1863 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1864 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1865
1866 GLenum prop2 = GL_ACTIVE_VARIABLES;
1867 GLint param[bufSize];
1868 std::set<GLuint> exp;
1869 exp.insert(indicesU["b"]);
1870 exp.insert(indicesU["c"]);
1871 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1872 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1873 for (int i = 0; i < length; ++i)
1874 {
1875 if (exp.find(param[i]) == exp.end() || length != 2)
1876 {
1877 m_context.getTestContext().getLog()
1878 << tcu::TestLog::Message << "Length: " << length
1879 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1880 << tcu::TestLog::EndMessage;
1881 glDeleteProgram(program);
1882 return ERROR;
1883 }
1884 }
1885 std::set<GLuint> exp2;
1886 GLint param2[bufSize];
1887 exp2.insert(indicesU["d"]);
1888 exp2.insert(indicesU["e"]);
1889 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1890 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
1891 for (int i = 0; i < length; ++i)
1892 {
1893 if (exp2.find(param2[i]) == exp2.end() || length != 2)
1894 {
1895 m_context.getTestContext().getLog()
1896 << tcu::TestLog::Message << "Length: " << length
1897 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
1898 << tcu::TestLog::EndMessage;
1899 glDeleteProgram(program);
1900 return ERROR;
1901 }
1902 }
1903
1904 glDeleteProgram(program);
1905 return error;
1906 }
1907 };
1908
1909 class AtomicCounterSimpleOneBuffer : public ComputeShaderTest
1910 {
1911 public:
Title()1912 virtual std::string Title()
1913 {
1914 return "Atomic Counter Buffer Simple One Buffer Test";
1915 }
1916
ShadersDesc()1917 virtual std::string ShadersDesc()
1918 {
1919 return "compute shader with atomic counters used";
1920 }
1921
PurposeExt()1922 virtual std::string PurposeExt()
1923 {
1924 return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1925 }
1926
Run()1927 virtual long Run()
1928 {
1929
1930 GLint max_buffer_bindings = 0;
1931 glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1932 if (max_buffer_bindings < 3)
1933 {
1934 OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
1935 return NOT_SUPPORTED;
1936 }
1937
1938 const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in; \n"
1939 "layout(std430) buffer Output { \n"
1940 " mediump vec4 data; \n"
1941 "} g_out; \n"
1942 ""
1943 "layout (binding = 0, offset = 0) uniform highp atomic_uint a; \n"
1944 "layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
1945 "layout (binding = 0, offset = 16) uniform highp atomic_uint c; \n"
1946 ""
1947 "void main() { \n"
1948 " uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
1949 " uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
1950 " uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
1951 " uint w = atomicCounterIncrement(c); \n"
1952 " g_out.data = vec4(float(x), float(y), float(z), float(w)); \n"
1953 "}";
1954
1955 GLuint program = CreateComputeProgram(glsl_cs);
1956 glLinkProgram(program);
1957 if (!CheckProgram(program))
1958 {
1959 glDeleteProgram(program);
1960 return ERROR;
1961 }
1962 glUseProgram(program);
1963
1964 long error = NO_ERROR;
1965
1966 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
1967 VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
1968
1969 std::map<std::string, GLuint> indicesU;
1970 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1971 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1972 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1973
1974 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1975 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
1976 VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1977
1978 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1979 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1980 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1981 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
1982 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
1983 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
1984
1985 GLenum prop = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1986 const GLsizei bufSize = 1000;
1987 GLsizei length;
1988 GLint res;
1989
1990 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1991 if (res != 0)
1992 {
1993 m_context.getTestContext().getLog()
1994 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1995 glDeleteProgram(program);
1996 return ERROR;
1997 }
1998
1999 GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
2000 GLint expected[] = { 0, 20, 3 };
2001 VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
2002
2003 GLenum prop2 = GL_ACTIVE_VARIABLES;
2004 GLint param[bufSize];
2005 std::set<GLuint> exp;
2006 exp.insert(indicesU["a"]);
2007 exp.insert(indicesU["b"]);
2008 exp.insert(indicesU["c"]);
2009
2010 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2011 if (res != 0)
2012 {
2013 m_context.getTestContext().getLog()
2014 << tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
2015 glDeleteProgram(program);
2016 return ERROR;
2017 }
2018
2019 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2020 for (int i = 0; i < length; ++i)
2021 {
2022 if (exp.find(param[i]) == exp.end() || length != 3)
2023 {
2024 m_context.getTestContext().getLog()
2025 << tcu::TestLog::Message << "Length: " << length
2026 << "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2027 << tcu::TestLog::EndMessage;
2028 glDeleteProgram(program);
2029 return ERROR;
2030 }
2031 }
2032
2033 glDeleteProgram(program);
2034 return error;
2035 }
2036 };
2037
2038 class InvalidValueTest : public SimpleShaders
2039 {
Title()2040 virtual std::string Title()
2041 {
2042 return "Invalid Value Test";
2043 }
2044
PassCriteria()2045 virtual std::string PassCriteria()
2046 {
2047 return "GL_INVALID_VALUE error is generated after every function call.";
2048 }
2049
Purpose()2050 virtual std::string Purpose()
2051 {
2052 return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2053 }
2054
Method()2055 virtual std::string Method()
2056 {
2057 return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2058 }
2059
Run()2060 virtual long Run()
2061 {
2062 long error = NO_ERROR;
2063
2064 GLint res;
2065 GLsizei len = 0;
2066 GLchar name[100] = { '\0' };
2067 GLenum props[1] = { GL_NAME_LENGTH };
2068
2069 m_context.getTestContext().getLog()
2070 << tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2071 << tcu::TestLog::EndMessage;
2072 glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2073 ExpectError(GL_INVALID_VALUE, error);
2074 glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2075 ExpectError(GL_INVALID_VALUE, error);
2076 glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2077 ExpectError(GL_INVALID_VALUE, error);
2078 glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2079 ExpectError(GL_INVALID_VALUE, error);
2080 glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2081 ExpectError(GL_INVALID_VALUE, error);
2082 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2083
2084 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2085 glBindAttribLocation(program, 0, "position");
2086 LinkProgram(program);
2087
2088 m_context.getTestContext().getLog()
2089 << tcu::TestLog::Message
2090 << "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2091 << tcu::TestLog::EndMessage;
2092 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2093 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2094 ExpectError(GL_INVALID_VALUE, error);
2095 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
2096
2097 m_context.getTestContext().getLog()
2098 << tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2099 << tcu::TestLog::EndMessage;
2100 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2101 ExpectError(GL_INVALID_VALUE, error);
2102 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
2103
2104 std::string str = "position";
2105 glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2106 ExpectError(GL_INVALID_VALUE, error);
2107 GLenum prop = GL_NAME_LENGTH;
2108 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2109 ExpectError(GL_INVALID_VALUE, error);
2110
2111 glDeleteProgram(program);
2112 return error;
2113 }
2114 };
2115
2116 class InvalidEnumTest : public SimpleShaders
2117 {
Title()2118 virtual std::string Title()
2119 {
2120 return "Invalid Enum Test";
2121 }
2122
PassCriteria()2123 virtual std::string PassCriteria()
2124 {
2125 return "GL_INVALID_ENUM error is generated after every function call.";
2126 }
2127
Purpose()2128 virtual std::string Purpose()
2129 {
2130 return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2131 }
2132
Method()2133 virtual std::string Method()
2134 {
2135 return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2136 }
2137
2138 // make sure at least one atomic counter resource is active
FragmentShader()2139 virtual std::string FragmentShader()
2140 {
2141 return "#version 310 es \n"
2142 "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
2143 "out mediump vec4 outColor; \n"
2144 "void main(void) { \n"
2145 " uint b = atomicCounterIncrement(a); \n"
2146 " outColor = vec4(float(b)); \n"
2147 "} \n";
2148 }
2149
Run()2150 virtual long Run()
2151 {
2152 GLint max_buffers = 0, max_counters = 0;
2153 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
2154 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
2155 if (max_buffers < 1 || max_counters < 1)
2156 {
2157 OutputNotSupported("Test requires at least 1 atomic counter.");
2158 return NOT_SUPPORTED;
2159 }
2160
2161 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2162 glBindAttribLocation(program, 0, "position");
2163 LinkProgram(program);
2164
2165 long error = NO_ERROR;
2166
2167 GLint res;
2168 GLsizei len = 0;
2169 GLchar name[100] = { '\0' };
2170 GLenum props[1] = { GL_TEXTURE_1D };
2171
2172 m_context.getTestContext().getLog()
2173 << tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
2174 "GetProgramResourceIndex or GetProgramResourceName"
2175 << tcu::TestLog::EndMessage;
2176 glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2177 ExpectError(GL_INVALID_ENUM, error);
2178 glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2179 ExpectError(GL_INVALID_ENUM, error);
2180 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2181
2182 m_context.getTestContext().getLog()
2183 << tcu::TestLog::Message
2184 << "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
2185 << tcu::TestLog::EndMessage;
2186 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2187 ExpectError(GL_INVALID_ENUM, error);
2188 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2189
2190 glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2191 ExpectError(GL_INVALID_ENUM, error);
2192
2193 glDeleteProgram(program);
2194 return error;
2195 }
2196 };
2197
2198 class InvalidOperationTest : public SimpleShaders
2199 {
Title()2200 virtual std::string Title()
2201 {
2202 return "Invalid Operation Test";
2203 }
2204
PassCriteria()2205 virtual std::string PassCriteria()
2206 {
2207 return "GL_INVALID_OPERATION error is generated after every function call.";
2208 }
2209
Purpose()2210 virtual std::string Purpose()
2211 {
2212 return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2213 }
2214
Method()2215 virtual std::string Method()
2216 {
2217 return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2218 }
2219
Run()2220 virtual long Run()
2221 {
2222 long error = NO_ERROR;
2223
2224 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2225 GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2226 glBindAttribLocation(program, 0, "position");
2227 LinkProgram(program);
2228
2229 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2230 GLint res;
2231 GLsizei len = 0;
2232 GLchar name[100] = { '\0' };
2233 GLenum props[1] = { GL_OFFSET };
2234
2235 m_context.getTestContext().getLog()
2236 << tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2237 glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2238 ExpectError(GL_INVALID_OPERATION, error);
2239 glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2240 ExpectError(GL_INVALID_OPERATION, error);
2241 glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2242 ExpectError(GL_INVALID_OPERATION, error);
2243 glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2244 ExpectError(GL_INVALID_OPERATION, error);
2245 glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2246 ExpectError(GL_INVALID_OPERATION, error);
2247 glDeleteShader(sh);
2248 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2249
2250 m_context.getTestContext().getLog()
2251 << tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
2252 << tcu::TestLog::EndMessage;
2253 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2254 ExpectError(GL_INVALID_OPERATION, error);
2255 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2256
2257 m_context.getTestContext().getLog()
2258 << tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
2259 << tcu::TestLog::EndMessage;
2260 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2261 ExpectError(GL_INVALID_OPERATION, error);
2262 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2263
2264 m_context.getTestContext().getLog()
2265 << tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
2266 << tcu::TestLog::EndMessage;
2267 glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2268 ExpectError(GL_INVALID_OPERATION, error);
2269 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
2270
2271 glDeleteProgram(program);
2272 glDeleteProgram(program2);
2273 return error;
2274 }
2275 };
2276
2277 class ShaderStorageBlock : public ComputeShaderTest
2278 {
Title()2279 virtual std::string Title()
2280 {
2281 return "Shader Storage Block Test";
2282 }
2283
ShadersDesc()2284 virtual std::string ShadersDesc()
2285 {
2286 return "compute shader different types of storage blocks used";
2287 }
2288
PurposeExt()2289 virtual std::string PurposeExt()
2290 {
2291 return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2292 "params.\n";
2293 }
2294
ComputeShader()2295 virtual std::string ComputeShader()
2296 {
2297 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2298 "layout(std430) buffer Output { \n"
2299 " mediump vec4 data; \n"
2300 "} g_out; \n"
2301 ""
2302 "struct U { \n"
2303 " bool a[3]; \n"
2304 " mediump vec4 b; \n"
2305 " mediump mat3 c; \n"
2306 " mediump float d[2]; \n"
2307 "}; \n"
2308 "struct UU { \n"
2309 " U a; \n"
2310 " U b[2]; \n"
2311 " uvec2 c; \n"
2312 "}; \n"
2313 ""
2314 "layout(binding=4) buffer TrickyBuffer { \n"
2315 " UU a[3]; \n"
2316 " mediump mat4 b; \n"
2317 " uint c; \n"
2318 "} e[2]; \n"
2319 ""
2320 "layout(binding = 0) buffer SimpleBuffer { \n"
2321 " mediump mat3x2 a; \n"
2322 " mediump mat4 b; \n"
2323 " mediump vec4 c; \n"
2324 "}; \n"
2325 ""
2326 "layout(binding = 1) buffer NotSoSimpleBuffer { \n"
2327 " ivec2 a[4]; \n"
2328 " mediump mat3 b[2]; \n"
2329 " mediump mat2 c; \n"
2330 "} d; \n"
2331 ""
2332 "void main() { \n"
2333 " mediump float tmp; \n"
2334 " mediump float tmp2; \n"
2335 " tmp = e[0].a[0].b[0].d[0] * float(e[1].c); \n"
2336 " tmp2 = a[0][0] * b[0][0] * c.x; \n"
2337 " tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0]; \n"
2338 " g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2; \n"
2339 "}";
2340 }
2341
Run()2342 virtual long Run()
2343 {
2344 GLuint program = CreateComputeProgram(ComputeShader());
2345 glLinkProgram(program);
2346 if (!CheckProgram(program))
2347 {
2348 glDeleteProgram(program);
2349 return ERROR;
2350 }
2351 glUseProgram(program);
2352
2353 long error = NO_ERROR;
2354
2355 GLint res;
2356 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
2357 glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
2358 if (res < 7)
2359 {
2360 m_context.getTestContext().getLog()
2361 << tcu::TestLog::Message
2362 << "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
2363 << "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
2364 glDeleteProgram(program);
2365 return ERROR;
2366 }
2367 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
2368 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
2369
2370 std::map<std::string, GLuint> indicesSSB;
2371 std::map<std::string, GLuint> indicesBV;
2372 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
2373 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
2374 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
2375 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
2376 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
2377 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
2378 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
2379 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
2380 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
2381 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
2382 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
2383 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
2384 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
2385
2386 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
2387 error);
2388 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
2389 "NotSoSimpleBuffer", error);
2390 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
2391 error);
2392 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
2393 error);
2394 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
2395 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
2396 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
2397 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
2398 "NotSoSimpleBuffer.a[0]", error);
2399 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
2400 "NotSoSimpleBuffer.c", error);
2401 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
2402 "NotSoSimpleBuffer.b[0]", error);
2403 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
2404 "TrickyBuffer.a[0].b[0].d[0]", error);
2405 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
2406 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
2407
2408 GLenum props[] = { GL_NAME_LENGTH,
2409 GL_BUFFER_BINDING,
2410 GL_NUM_ACTIVE_VARIABLES,
2411 GL_REFERENCED_BY_COMPUTE_SHADER,
2412 GL_REFERENCED_BY_FRAGMENT_SHADER,
2413 GL_REFERENCED_BY_VERTEX_SHADER };
2414 GLint expected[] = { 13, 0, 3, 1, 0, 0 };
2415 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
2416 error);
2417 GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
2418 GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER };
2419 GLint expected2[] = { 18, 1, 1, 0, 0 };
2420 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
2421 expected2, error);
2422 GLint expected3[] = { 16, 4, 1, 0, 0 };
2423 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
2424 expected3, error);
2425 GLint expected4[] = { 16, 5, 1, 0, 0 };
2426 VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
2427 expected4, error);
2428
2429 GLenum props3[] = { GL_NAME_LENGTH,
2430 GL_TYPE,
2431 GL_ARRAY_SIZE,
2432 GL_BLOCK_INDEX,
2433 GL_ARRAY_STRIDE,
2434 GL_IS_ROW_MAJOR,
2435 GL_REFERENCED_BY_COMPUTE_SHADER,
2436 GL_REFERENCED_BY_FRAGMENT_SHADER,
2437 GL_REFERENCED_BY_VERTEX_SHADER,
2438 GL_TOP_LEVEL_ARRAY_SIZE,
2439 GL_TOP_LEVEL_ARRAY_STRIDE };
2440 GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 };
2441 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
2442 GLenum props4[] = { GL_NAME_LENGTH,
2443 GL_TYPE,
2444 GL_ARRAY_SIZE,
2445 GL_BLOCK_INDEX,
2446 GL_MATRIX_STRIDE,
2447 GL_IS_ROW_MAJOR,
2448 GL_REFERENCED_BY_COMPUTE_SHADER,
2449 GL_REFERENCED_BY_FRAGMENT_SHADER,
2450 GL_REFERENCED_BY_VERTEX_SHADER,
2451 GL_TOP_LEVEL_ARRAY_SIZE };
2452 GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 };
2453 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
2454 expected6, error);
2455
2456 GLenum prop = GL_ACTIVE_VARIABLES;
2457 const GLsizei bufSize = 1000;
2458 GLsizei length;
2459 GLint param[bufSize];
2460 std::set<GLuint> exp;
2461 exp.insert(indicesBV["a"]);
2462 exp.insert(indicesBV["b"]);
2463 exp.insert(indicesBV["c"]);
2464 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
2465 param);
2466 for (int i = 0; i < length; ++i)
2467 {
2468 if (exp.find(param[i]) == exp.end())
2469 {
2470 m_context.getTestContext().getLog()
2471 << tcu::TestLog::Message
2472 << "Unexpected index found in active variables of SimpleBuffer: " << param[i]
2473 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2474 "GL_SHADER_STORAGE_BLOCK"
2475 << tcu::TestLog::EndMessage;
2476 glDeleteProgram(program);
2477 return ERROR;
2478 }
2479 else if (length != 3)
2480 {
2481 m_context.getTestContext().getLog()
2482 << tcu::TestLog::Message
2483 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2484 << "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2485 glDeleteProgram(program);
2486 return ERROR;
2487 }
2488 }
2489 std::set<GLuint> exp2;
2490 exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
2491 exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
2492 exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
2493 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
2494 &length, param);
2495 for (int i = 0; i < length; ++i)
2496 {
2497 if (exp2.find(param[i]) == exp2.end())
2498 {
2499 m_context.getTestContext().getLog()
2500 << tcu::TestLog::Message
2501 << "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
2502 << "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2503 "GL_SHADER_STORAGE_BLOCK"
2504 << tcu::TestLog::EndMessage;
2505 glDeleteProgram(program);
2506 return ERROR;
2507 }
2508 else if (length != 3)
2509 {
2510 m_context.getTestContext().getLog()
2511 << tcu::TestLog::Message
2512 << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2513 << param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2514 glDeleteProgram(program);
2515 return ERROR;
2516 }
2517 }
2518
2519 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2520 if (res < 3)
2521 {
2522 m_context.getTestContext().getLog()
2523 << tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
2524 << "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
2525 return ERROR;
2526 }
2527
2528 glDeleteProgram(program);
2529 return error;
2530 }
2531 };
2532
2533 class NullLength : public SimpleShaders
2534 {
2535
Title()2536 virtual std::string Title()
2537 {
2538 return "NULL Length Test";
2539 }
2540
PurposeExt()2541 virtual std::string PurposeExt()
2542 {
2543 return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
2544 "crash).\n";
2545 }
2546
VertexShader()2547 virtual std::string VertexShader()
2548 {
2549 return "#version 310 es \n"
2550 "in vec4 position; \n"
2551 "void main(void) \n"
2552 "{ \n"
2553 " gl_Position = position; \n"
2554 "}";
2555 }
2556
FragmentShader()2557 virtual std::string FragmentShader()
2558 {
2559 return "#version 310 es \n"
2560 "out mediump vec4 color; \n"
2561 "void main() { \n"
2562 " color = vec4(0, 1, 0, 1); \n"
2563 "}";
2564 }
2565
Run()2566 virtual long Run()
2567 {
2568 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2569 glBindAttribLocation(program, 0, "position");
2570 LinkProgram(program);
2571
2572 GLchar name[1024] = { '\0' };
2573 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
2574 GLenum prop = GL_ARRAY_SIZE;
2575 GLint res;
2576 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
2577 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
2578
2579 std::string expected = "color";
2580 if (name != expected)
2581 {
2582 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
2583 << ", got: " << name << tcu::TestLog::EndMessage;
2584 glDeleteProgram(program);
2585 return ERROR;
2586 }
2587 else if (res != 1)
2588 {
2589 m_context.getTestContext().getLog()
2590 << tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
2591 glDeleteProgram(program);
2592 return ERROR;
2593 }
2594
2595 glDeleteProgram(program);
2596 return NO_ERROR;
2597 }
2598 };
2599
2600 class ArraysOfArrays : public SimpleShaders
2601 {
2602
Title()2603 virtual std::string Title()
2604 {
2605 return "Arrays Of Arrays Test";
2606 }
2607
ShadersDesc()2608 virtual std::string ShadersDesc()
2609 {
2610 return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
2611 }
2612
PurposeExt()2613 virtual std::string PurposeExt()
2614 {
2615 return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
2616 }
2617
VertexShader()2618 virtual std::string VertexShader()
2619 {
2620 return "#version 310 es \n"
2621 "in vec4 position; \n"
2622 "uniform mediump vec4 a[3][4][5]; \n"
2623 "void main(void) \n"
2624 "{ \n"
2625 " gl_Position = position + a[2][1][0]; \n"
2626 "}";
2627 }
2628
FragmentShader()2629 virtual std::string FragmentShader()
2630 {
2631 return "#version 310 es \n"
2632 "out mediump vec4 color; \n"
2633 "void main() { \n"
2634 " color = vec4(0, 1, 0, 1); \n"
2635 "}";
2636 }
2637
Run()2638 virtual long Run()
2639 {
2640 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2641 glBindAttribLocation(program, 0, "position");
2642 LinkProgram(program);
2643
2644 long error = NO_ERROR;
2645
2646 VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
2647
2648 std::map<std::string, GLuint> indices;
2649 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
2650 VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
2651
2652 VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
2653
2654 GLenum props[] = { GL_NAME_LENGTH,
2655 GL_TYPE,
2656 GL_ARRAY_SIZE,
2657 GL_OFFSET,
2658 GL_BLOCK_INDEX,
2659 GL_ARRAY_STRIDE,
2660 GL_MATRIX_STRIDE,
2661 GL_IS_ROW_MAJOR,
2662 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2663 GL_REFERENCED_BY_COMPUTE_SHADER,
2664 GL_REFERENCED_BY_FRAGMENT_SHADER,
2665 GL_REFERENCED_BY_VERTEX_SHADER,
2666 GL_LOCATION };
2667 GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") };
2668 VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
2669
2670 glDeleteProgram(program);
2671 return error;
2672 }
2673 };
2674
2675 class TopLevelArray : public ComputeShaderTest
2676 {
2677
Title()2678 virtual std::string Title()
2679 {
2680 return "Top Level Array Test";
2681 }
2682
ShadersDesc()2683 virtual std::string ShadersDesc()
2684 {
2685 return "compute shader with multi dimensional array used inside storage block";
2686 }
2687
PurposeExt()2688 virtual std::string PurposeExt()
2689 {
2690 return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
2691 " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
2692 }
2693
ComputeShader()2694 virtual std::string ComputeShader()
2695 {
2696 return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2697 "layout(std430) buffer Outp { \n"
2698 " mediump vec4 d; \n"
2699 "} g_out; \n"
2700 ""
2701 "buffer Block { \n"
2702 " mediump vec4 a[5][4][3]; \n"
2703 "}; \n"
2704 ""
2705 "void main(void) \n"
2706 "{ \n"
2707 " g_out.d = a[0][0][0]; \n"
2708 "}";
2709 }
2710
Run()2711 virtual long Run()
2712 {
2713 GLuint program = CreateComputeProgram(ComputeShader());
2714 glLinkProgram(program);
2715 if (!CheckProgram(program))
2716 {
2717 glDeleteProgram(program);
2718 return ERROR;
2719 }
2720 glUseProgram(program);
2721
2722 long error = NO_ERROR;
2723
2724 VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
2725 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
2726 VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
2727
2728 std::map<std::string, GLuint> indicesSSB;
2729 std::map<std::string, GLuint> indicesBV;
2730 VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
2731 VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
2732
2733 VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
2734 VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
2735
2736 GLenum props3[] = { GL_NAME_LENGTH,
2737 GL_TYPE,
2738 GL_ARRAY_SIZE,
2739 GL_BLOCK_INDEX,
2740 GL_IS_ROW_MAJOR,
2741 GL_REFERENCED_BY_COMPUTE_SHADER,
2742 GL_REFERENCED_BY_FRAGMENT_SHADER,
2743 GL_REFERENCED_BY_VERTEX_SHADER,
2744 GL_TOP_LEVEL_ARRAY_SIZE };
2745 GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 };
2746 VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
2747
2748 GLenum prop = GL_TOP_LEVEL_ARRAY_STRIDE;
2749 GLsizei len;
2750 GLint res;
2751 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
2752 if (res <= 0)
2753 {
2754 m_context.getTestContext().getLog()
2755 << tcu::TestLog::Message
2756 << "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
2757 << "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
2758 glDeleteProgram(program);
2759 return ERROR;
2760 }
2761
2762 glDeleteProgram(program);
2763 return error;
2764 }
2765 };
2766
2767 class SeparateProgramsVertex : public SimpleShaders
2768 {
2769 public:
Title()2770 virtual std::string Title()
2771 {
2772 return "Separate Program Vertex Shader Test";
2773 }
2774
ShadersDesc()2775 virtual std::string ShadersDesc()
2776 {
2777 return "vertex shader as separate shader object";
2778 }
2779
PurposeExt()2780 virtual std::string PurposeExt()
2781 {
2782 return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
2783 "functionality.\n";
2784 }
2785
CreateShaderProgram(GLenum type,GLsizei count,const GLchar ** strings)2786 virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
2787 {
2788 GLuint program = glCreateShaderProgramv(type, count, strings);
2789 GLint status = GL_TRUE;
2790 glGetProgramiv(program, GL_LINK_STATUS, &status);
2791 if (status == GL_FALSE)
2792 {
2793 GLsizei length;
2794 GLchar log[1024];
2795 glGetProgramInfoLog(program, sizeof(log), &length, log);
2796 if (length > 1)
2797 {
2798 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
2799 << log << tcu::TestLog::EndMessage;
2800 }
2801 }
2802 return program;
2803 }
2804
Run()2805 virtual long Run()
2806 {
2807 long error = NO_ERROR;
2808
2809 const char* srcVS = "#version 310 es \n"
2810 "layout(location = 0) in vec4 in_vertex; \n"
2811 ""
2812 "out mediump float r, g, b; \n"
2813 "out mediump vec4 iLikePie; \n"
2814 ""
2815 "uniform mediump float u; \n"
2816 "uniform mediump vec4 v; \n"
2817 ""
2818 "void main() { \n"
2819 " gl_Position = in_vertex; \n"
2820 " r = u; \n"
2821 " g = 0.0; \n"
2822 " b = 0.0; \n"
2823 " iLikePie = v; \n"
2824 "}";
2825
2826 const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
2827
2828 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2829 VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
2830 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
2831 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2832 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
2833 VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
2834
2835 std::map<std::string, GLuint> indicesU;
2836 std::map<std::string, GLuint> indicesI;
2837 std::map<std::string, GLuint> indicesO;
2838 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
2839 VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
2840 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
2841 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
2842 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
2843 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
2844 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
2845 VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
2846
2847 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
2848 VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
2849 VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
2850 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
2851 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
2852 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
2853 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
2854 VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
2855
2856 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
2857 VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
2858 VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
2859
2860 GLenum props[] = { GL_NAME_LENGTH,
2861 GL_TYPE,
2862 GL_ARRAY_SIZE,
2863 GL_OFFSET,
2864 GL_BLOCK_INDEX,
2865 GL_ARRAY_STRIDE,
2866 GL_MATRIX_STRIDE,
2867 GL_IS_ROW_MAJOR,
2868 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2869 GL_REFERENCED_BY_COMPUTE_SHADER,
2870 GL_REFERENCED_BY_FRAGMENT_SHADER,
2871 GL_REFERENCED_BY_VERTEX_SHADER,
2872 GL_LOCATION };
2873 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") };
2874 VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
2875
2876 GLenum props2[] = { GL_NAME_LENGTH,
2877 GL_TYPE,
2878 GL_ARRAY_SIZE,
2879 GL_REFERENCED_BY_COMPUTE_SHADER,
2880 GL_REFERENCED_BY_FRAGMENT_SHADER,
2881 GL_REFERENCED_BY_VERTEX_SHADER,
2882 GL_LOCATION };
2883 GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 };
2884 VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
2885
2886 GLenum props3[] = { GL_NAME_LENGTH,
2887 GL_TYPE,
2888 GL_ARRAY_SIZE,
2889 GL_REFERENCED_BY_COMPUTE_SHADER,
2890 GL_REFERENCED_BY_FRAGMENT_SHADER,
2891 GL_REFERENCED_BY_VERTEX_SHADER };
2892 GLint expected3[] = { 9, 35666, 1, 0, 0, 1 };
2893 VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
2894
2895 glDeleteProgram(vs);
2896 return error;
2897 }
2898 };
2899
2900 class SeparateProgramsFragment : public SeparateProgramsVertex
2901 {
2902
Title()2903 virtual std::string Title()
2904 {
2905 return "Separate Program Fragment Shader Test";
2906 }
2907
ShadersDesc()2908 virtual std::string ShadersDesc()
2909 {
2910 return "fragment shader as separate shader object";
2911 }
2912
Run()2913 virtual long Run()
2914 {
2915 long error = NO_ERROR;
2916
2917 const char* srcTCS = "#version 310 es \n"
2918 "out mediump vec4 fs_color; \n"
2919 ""
2920 "layout(location = 1) uniform mediump vec4 x; \n"
2921 ""
2922 "in mediump vec4 vs_color; \n"
2923 "void main() { \n"
2924 " fs_color = vs_color + x; \n"
2925 "}";
2926
2927 const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
2928
2929 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
2930 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2931 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
2932 VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
2933 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2934 VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2935
2936 std::map<std::string, GLuint> indicesI;
2937 std::map<std::string, GLuint> indicesO;
2938 std::map<std::string, GLuint> indicesU;
2939 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
2940 VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
2941 VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
2942
2943 VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
2944 VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
2945 VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
2946
2947 VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
2948
2949 GLenum props2[] = { GL_NAME_LENGTH,
2950 GL_TYPE,
2951 GL_ARRAY_SIZE,
2952 GL_REFERENCED_BY_COMPUTE_SHADER,
2953 GL_REFERENCED_BY_FRAGMENT_SHADER,
2954 GL_REFERENCED_BY_VERTEX_SHADER };
2955 GLint expected2[] = { 9, 35666, 1, 0, 1, 0 };
2956 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
2957 VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
2958
2959 GLenum props[] = { GL_NAME_LENGTH,
2960 GL_TYPE,
2961 GL_ARRAY_SIZE,
2962 GL_OFFSET,
2963 GL_BLOCK_INDEX,
2964 GL_ARRAY_STRIDE,
2965 GL_MATRIX_STRIDE,
2966 GL_IS_ROW_MAJOR,
2967 GL_ATOMIC_COUNTER_BUFFER_INDEX,
2968 GL_REFERENCED_BY_COMPUTE_SHADER,
2969 GL_REFERENCED_BY_FRAGMENT_SHADER,
2970 GL_REFERENCED_BY_VERTEX_SHADER,
2971 GL_LOCATION };
2972 GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
2973 VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
2974
2975 glDeleteProgram(tcs);
2976 return error;
2977 }
2978 };
2979
2980 class UniformBlockAdvanced : public SimpleShaders
2981 {
Title()2982 virtual std::string Title()
2983 {
2984 return "Uniform Block Advanced Test";
2985 }
2986
ShadersDesc()2987 virtual std::string ShadersDesc()
2988 {
2989 return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
2990 }
2991
PurposeExt()2992 virtual std::string PurposeExt()
2993 {
2994 return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
2995 "verify results of querying offset, strides and row order.\n";
2996 }
2997
VertexShader()2998 virtual std::string VertexShader()
2999 {
3000 return "#version 310 es \n"
3001 "in vec4 position; \n"
3002 ""
3003 "layout(row_major) uniform SimpleBlock { \n"
3004 " mat4 a; \n"
3005 " vec4 b[10]; \n"
3006 "}; \n"
3007 ""
3008 "void main(void) \n"
3009 "{ \n"
3010 " float tmp; \n"
3011 " tmp = a[0][0] + b[0].x; \n"
3012 " gl_Position = position * tmp; \n"
3013 "}";
3014 }
3015
Run()3016 virtual long Run()
3017 {
3018 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3019 glBindAttribLocation(program, 0, "position");
3020 LinkProgram(program);
3021
3022 long error = NO_ERROR;
3023
3024 std::map<std::string, GLuint> indicesU;
3025 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
3026 VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
3027
3028 GLenum props[] = { GL_IS_ROW_MAJOR };
3029 GLint expected[] = { 1 };
3030 VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
3031
3032 GLenum prop = GL_MATRIX_STRIDE;
3033 GLsizei len;
3034 GLint res;
3035 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3036 if (res < 1)
3037 {
3038 m_context.getTestContext().getLog()
3039 << tcu::TestLog::Message
3040 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
3041 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3042 }
3043 prop = GL_OFFSET;
3044 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3045 if (res < 0)
3046 {
3047 m_context.getTestContext().getLog()
3048 << tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
3049 << "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
3050 }
3051 prop = GL_ARRAY_STRIDE;
3052 glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
3053 if (res < 1)
3054 {
3055 m_context.getTestContext().getLog()
3056 << tcu::TestLog::Message
3057 << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
3058 << "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3059 }
3060
3061 glDeleteProgram(program);
3062 return error;
3063 }
3064 };
3065
3066 class ArrayNames : public SimpleShaders
3067 {
3068
Title()3069 virtual std::string Title()
3070 {
3071 return "Array Names Test";
3072 }
3073
ShadersDesc()3074 virtual std::string ShadersDesc()
3075 {
3076 return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
3077 }
3078
PurposeExt()3079 virtual std::string PurposeExt()
3080 {
3081 return "\n\n Purpose is to verify that GetProgramResourceLocation match "
3082 "name strings correctly.\n";
3083 }
3084
VertexShader()3085 virtual std::string VertexShader()
3086 {
3087 return "#version 310 es \n"
3088 "in vec4 position; \n"
3089 ""
3090 "uniform mediump vec4 a[2]; \n"
3091 ""
3092 "void main(void) \n"
3093 "{ \n"
3094 " gl_Position = position + a[0] + a[1]; \n"
3095 "}";
3096 }
3097
Run()3098 virtual long Run()
3099 {
3100 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3101 glBindAttribLocation(program, 0, "position");
3102 LinkProgram(program);
3103
3104 long error = NO_ERROR;
3105
3106 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
3107 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
3108 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
3109 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
3110 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
3111 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
3112 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
3113 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
3114 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
3115 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
3116 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
3117 VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
3118
3119 glDeleteProgram(program);
3120 return error;
3121 }
3122 };
3123
3124 class BuffLength : public SimpleShaders
3125 {
3126
Title()3127 virtual std::string Title()
3128 {
3129 return "Buff Length Test";
3130 }
3131
ShadersDesc()3132 virtual std::string ShadersDesc()
3133 {
3134 return "fallthrough fragment shader and vertex with uniform of vec4 type used";
3135 }
3136
PurposeExt()3137 virtual std::string PurposeExt()
3138 {
3139 return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
3140 "GetProgramResourceiv is respected.\n";
3141 }
3142
VertexShader()3143 virtual std::string VertexShader()
3144 {
3145 return "#version 310 es \n"
3146 "in vec4 position; \n"
3147 ""
3148 "uniform mediump vec4 someLongName; \n"
3149 ""
3150 "void main(void) \n"
3151 "{ \n"
3152 " gl_Position = position + someLongName; \n"
3153 "}";
3154 }
3155
Run()3156 virtual long Run()
3157 {
3158 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3159 glBindAttribLocation(program, 0, "position");
3160 LinkProgram(program);
3161
3162 long error = NO_ERROR;
3163
3164 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
3165 GLsizei length;
3166 GLchar buff[3] = { 'a', 'b', 'c' };
3167 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
3168 glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
3169 if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
3170 {
3171 m_context.getTestContext().getLog()
3172 << tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
3173 error = ERROR;
3174 }
3175 glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
3176 if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
3177 {
3178 m_context.getTestContext().getLog()
3179 << tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
3180 error = ERROR;
3181 }
3182 if (length != 1)
3183 {
3184 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
3185 << length << tcu::TestLog::EndMessage;
3186 error = ERROR;
3187 }
3188
3189 GLint params[3] = { 1, 2, 3 };
3190 GLenum props[] = { GL_NAME_LENGTH,
3191 GL_TYPE,
3192 GL_ARRAY_SIZE,
3193 GL_OFFSET,
3194 GL_BLOCK_INDEX,
3195 GL_ARRAY_STRIDE,
3196 GL_MATRIX_STRIDE,
3197 GL_IS_ROW_MAJOR,
3198 GL_ATOMIC_COUNTER_BUFFER_INDEX,
3199 GL_REFERENCED_BY_COMPUTE_SHADER,
3200 GL_REFERENCED_BY_FRAGMENT_SHADER,
3201 GL_REFERENCED_BY_VERTEX_SHADER,
3202 GL_LOCATION };
3203 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
3204 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
3205 if (params[0] != 1 || params[1] != 2 || params[2] != 3)
3206 {
3207 m_context.getTestContext().getLog()
3208 << tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
3209 error = ERROR;
3210 }
3211 glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
3212 if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
3213 {
3214 m_context.getTestContext().getLog()
3215 << tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
3216 error = ERROR;
3217 }
3218 if (length != 2)
3219 {
3220 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
3221 << length << tcu::TestLog::EndMessage;
3222 error = ERROR;
3223 }
3224
3225 glDeleteProgram(program);
3226 return error;
3227 }
3228 };
3229
3230 class NoLocations : public SimpleShaders
3231 {
3232
Title()3233 virtual std::string Title()
3234 {
3235 return "No Locations Test";
3236 }
3237
ShadersDesc()3238 virtual std::string ShadersDesc()
3239 {
3240 return "fragment and vertex shaders with no locations set";
3241 }
3242
VertexShader()3243 virtual std::string VertexShader()
3244 {
3245 return "#version 310 es \n"
3246 "in vec4 a; \n"
3247 "in vec4 b; \n"
3248 "in vec4 c; \n"
3249 "in vec4 d; \n"
3250 "void main(void) \n"
3251 "{ \n"
3252 " gl_Position = a + b + c + d; \n"
3253 "}";
3254 }
3255
3256 // fragment shader outputs need an explicit location per spec
FragmentShader()3257 virtual std::string FragmentShader()
3258 {
3259 return "#version 310 es \n"
3260 "layout (location=0) out mediump vec4 a; \n"
3261 "layout (location=1) out mediump vec4 b; \n"
3262 "layout (location=2) out mediump vec4 c; \n"
3263 "layout (location=3) out mediump vec4 d[1]; \n"
3264 "void main() { \n"
3265 " a = vec4(0, 1, 0, 1); \n"
3266 " b = vec4(0, 1, 0, 1); \n"
3267 " c = vec4(0, 1, 0, 1); \n"
3268 " d[0] = vec4(0, 1, 0, 1); \n"
3269 "}";
3270 }
3271
Run()3272 virtual long Run()
3273 {
3274 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3275 glBindAttribLocation(program, 0, "position");
3276 glLinkProgram(program);
3277
3278 long error = NO_ERROR;
3279
3280 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
3281 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
3282 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
3283 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
3284
3285 std::map<std::string, GLuint> indicesI;
3286 std::map<std::string, GLuint> indicesO;
3287 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
3288 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
3289 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
3290 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
3291 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
3292 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
3293 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
3294 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
3295
3296 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
3297 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
3298 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
3299 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
3300 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
3301 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
3302 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
3303 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
3304
3305 std::map<std::string, GLint> locationsI;
3306 std::map<std::string, GLint> locationsO;
3307 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
3308 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
3309 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
3310 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
3311 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
3312 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
3313 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
3314 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
3315
3316 GLenum props[] = { GL_NAME_LENGTH,
3317 GL_TYPE,
3318 GL_ARRAY_SIZE,
3319 GL_REFERENCED_BY_COMPUTE_SHADER,
3320 GL_REFERENCED_BY_FRAGMENT_SHADER,
3321 GL_REFERENCED_BY_VERTEX_SHADER };
3322 GLint expected[] = { 2, 35666, 1, 0, 0, 1 };
3323 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
3324 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
3325 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
3326 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
3327 GLint expected3[] = { 2, 35666, 1, 0, 1, 0 };
3328 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
3329 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
3330 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
3331 GLint expected4[] = { 5, 35666, 1, 0, 1, 0 };
3332 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
3333
3334 glDeleteProgram(program);
3335 return error;
3336 }
3337 };
3338
3339 class OutputBuiltIn : public SimpleShaders
3340 {
3341
Title()3342 virtual std::string Title()
3343 {
3344 return "Output Built-ins Test";
3345 }
3346
ShadersDesc()3347 virtual std::string ShadersDesc()
3348 {
3349 return "fragment shader using built-in variables and a fallthrough vertex shader";
3350 }
3351
Expectations()3352 virtual std::string Expectations()
3353 {
3354 return ".\n\n In this case we ask for information about built-in variables for the output interface.";
3355 }
3356
FragmentShader()3357 virtual std::string FragmentShader()
3358 {
3359 return "#version 310 es \n"
3360 "void main(void) \n"
3361 "{ \n"
3362 " gl_FragDepth = 0.1; \n"
3363 "}";
3364 }
3365
Run()3366 virtual long Run()
3367 {
3368 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
3369
3370 long error = NO_ERROR;
3371
3372 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3373 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
3374
3375 std::map<std::string, GLuint> indices;
3376 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
3377
3378 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
3379
3380 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
3381
3382 GLenum props[] = { GL_NAME_LENGTH,
3383 GL_TYPE,
3384 GL_ARRAY_SIZE,
3385 GL_REFERENCED_BY_COMPUTE_SHADER,
3386 GL_REFERENCED_BY_FRAGMENT_SHADER,
3387 GL_REFERENCED_BY_VERTEX_SHADER,
3388 GL_LOCATION };
3389 GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 };
3390 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
3391 props, DE_LENGTH_OF_ARRAY(expected), expected, error);
3392
3393 glDeleteProgram(program);
3394 return error;
3395 }
3396 };
3397
3398 class QueryNotUsed : public SimpleShaders
3399 {
3400
Title()3401 virtual std::string Title()
3402 {
3403 return "Query Not Used Test";
3404 }
3405
PassCriteria()3406 virtual std::string PassCriteria()
3407 {
3408 return "Data from queries matches the not used program.";
3409 }
3410
Purpose()3411 virtual std::string Purpose()
3412 {
3413 return "Verify that program parameter works correctly and proper program is queried when different program is "
3414 "used.";
3415 }
3416
Method()3417 virtual std::string Method()
3418 {
3419 return "Create 2 programs, use one of them and query the other, verify the results.";
3420 }
3421
VertexShader2()3422 virtual std::string VertexShader2()
3423 {
3424 return "#version 310 es \n"
3425 "in mediump vec4 p; \n"
3426 "void main(void) \n"
3427 "{ \n"
3428 " gl_Position = p; \n"
3429 "}";
3430 }
3431
FragmentShader2()3432 virtual std::string FragmentShader2()
3433 {
3434 return "#version 310 es \n"
3435 "out mediump vec4 c; \n"
3436 "void main() { \n"
3437 " c = vec4(0., 1., 0., 1.); \n"
3438 "}";
3439 }
3440
Run()3441 virtual long Run()
3442 {
3443 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3444 LinkProgram(program);
3445
3446 GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
3447 LinkProgram(program2);
3448 glUseProgram(program2);
3449
3450 long error = NO_ERROR;
3451
3452 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3453 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
3454 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3455 VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
3456
3457 VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3458 VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
3459
3460 VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
3461 VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
3462
3463 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
3464 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3465
3466 GLenum props[] = { GL_NAME_LENGTH,
3467 GL_TYPE,
3468 GL_ARRAY_SIZE,
3469 GL_REFERENCED_BY_COMPUTE_SHADER,
3470 GL_REFERENCED_BY_FRAGMENT_SHADER,
3471 GL_REFERENCED_BY_VERTEX_SHADER,
3472 GL_LOCATION };
3473 GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
3474 VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
3475 DE_LENGTH_OF_ARRAY(expected), expected, error);
3476
3477 GLenum props2[] = { GL_NAME_LENGTH,
3478 GL_TYPE,
3479 GL_ARRAY_SIZE,
3480 GL_REFERENCED_BY_COMPUTE_SHADER,
3481 GL_REFERENCED_BY_FRAGMENT_SHADER,
3482 GL_REFERENCED_BY_VERTEX_SHADER,
3483 GL_LOCATION };
3484 GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
3485 VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
3486
3487 glDeleteProgram(program);
3488 glDeleteProgram(program2);
3489 return error;
3490 }
3491 };
3492
3493 class RelinkFailure : public SimpleShaders
3494 {
3495
Title()3496 virtual std::string Title()
3497 {
3498 return "Relink Failure Test";
3499 }
3500
PassCriteria()3501 virtual std::string PassCriteria()
3502 {
3503 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3504 }
3505
Purpose()3506 virtual std::string Purpose()
3507 {
3508 return "Verify that queries behave correctly after failed relink of a program.";
3509 }
3510
Method()3511 virtual std::string Method()
3512 {
3513 return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
3514 "asking for locations.";
3515 }
3516
VertexShader()3517 virtual std::string VertexShader()
3518 {
3519 return "#version 310 es \n"
3520 "in mediump vec4 position; \n"
3521 "in mediump vec3 pos; \n"
3522 "void main(void) \n"
3523 "{ \n"
3524 " gl_Position = position + vec4(pos, 1.); \n"
3525 "}";
3526 }
3527
Run()3528 virtual long Run()
3529 {
3530 GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3531 glBindAttribLocation(program, 0, "position");
3532 glBindAttribLocation(program, 1, "pos");
3533 LinkProgram(program);
3534
3535 long error = NO_ERROR;
3536
3537 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
3538 glUseProgram(program);
3539
3540 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3541 tcu::Vec4(1, -1, 0, 1) };
3542 GLuint vao, vbuf;
3543 glGenVertexArrays(1, &vao);
3544 glBindVertexArray(vao);
3545 glGenBuffers(1, &vbuf);
3546 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3547 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3548 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3549 glEnableVertexAttribArray(0);
3550 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3551
3552 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3553 glDisableVertexAttribArray(0);
3554 glDeleteVertexArrays(1, &vao);
3555 glBindBuffer(GL_ARRAY_BUFFER, 0);
3556 glDeleteBuffers(1, &vbuf);
3557
3558 glBindAttribLocation(program, 0, "pos");
3559 glBindAttribLocation(program, 0, "position");
3560 const char* varyings[2] = { "q", "z" };
3561 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3562 LinkProgram(program);
3563
3564 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3565 ExpectError(GL_INVALID_OPERATION, error);
3566 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
3567 ExpectError(GL_INVALID_OPERATION, error);
3568 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3569 ExpectError(GL_INVALID_OPERATION, error);
3570
3571 glDeleteProgram(program);
3572 return error;
3573 }
3574 };
3575
3576 class LinkFailure : public SimpleShaders
3577 {
3578
Title()3579 virtual std::string Title()
3580 {
3581 return "Link Failure Test";
3582 }
3583
PassCriteria()3584 virtual std::string PassCriteria()
3585 {
3586 return "INVALID_OPERATION is generated when asking for locations after failed link.";
3587 }
3588
Purpose()3589 virtual std::string Purpose()
3590 {
3591 return "Verify that queries behave correctly after failed relink of a program with changed sources.";
3592 }
3593
Method()3594 virtual std::string Method()
3595 {
3596 return "Create a program, use it, relink with failure using different sources and then \n"
3597 "verify that INVALID_OPERATION is returned when asking for locations.";
3598 }
3599
VertexShader_prop()3600 virtual const char* VertexShader_prop()
3601 {
3602 return "#version 310 es \n"
3603 "in mediump vec4 posit; \n"
3604 "in mediump vec4 p; \n"
3605 "void main(void) \n"
3606 "{ \n"
3607 " gl_Position = p + posit; \n"
3608 "}";
3609 }
3610
FragmentShader_prop()3611 virtual const char* FragmentShader_prop()
3612 {
3613 return "#version 310 es \n"
3614 "out mediump vec4 color; \n"
3615 "void main() { \n"
3616 " color = vec4(0., 1., 0., 1.); \n"
3617 "}";
3618 }
3619
VertexShader_fail()3620 virtual const char* VertexShader_fail()
3621 {
3622 return "#version 310 es \n"
3623 "in mediump vec4 position; \n"
3624 "void main(void) \n"
3625 "{ \n"
3626 " gl_Position = position; \n"
3627 "}";
3628 }
3629
Run()3630 virtual long Run()
3631 {
3632 const GLuint program = glCreateProgram();
3633 const char* src_vs = VertexShader_prop();
3634 const char* src_fs = FragmentShader_prop();
3635 const char* src_vsh = VertexShader_fail();
3636
3637 GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
3638 glAttachShader(program, sh1);
3639 glDeleteShader(sh1);
3640 glShaderSource(sh1, 1, &src_vs, NULL);
3641 glCompileShader(sh1);
3642
3643 GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
3644 glAttachShader(program, sh2);
3645 glDeleteShader(sh2);
3646 glShaderSource(sh2, 1, &src_fs, NULL);
3647 glCompileShader(sh2);
3648
3649 glBindAttribLocation(program, 0, "p");
3650 glBindAttribLocation(program, 1, "posit");
3651 LinkProgram(program);
3652
3653 long error = NO_ERROR;
3654
3655 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
3656 glUseProgram(program);
3657
3658 tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3659 tcu::Vec4(1, -1, 0, 1) };
3660 GLuint vao, vbuf;
3661 glGenVertexArrays(1, &vao);
3662 glBindVertexArray(vao);
3663 glGenBuffers(1, &vbuf);
3664 glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3665 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3666 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3667 glEnableVertexAttribArray(0);
3668 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3669
3670 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3671 glDisableVertexAttribArray(0);
3672 glDeleteVertexArrays(1, &vao);
3673 glBindBuffer(GL_ARRAY_BUFFER, 0);
3674 glDeleteBuffers(1, &vbuf);
3675
3676 glDetachShader(program, sh1);
3677 GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
3678 glAttachShader(program, vsh);
3679 glDeleteShader(vsh);
3680 glShaderSource(vsh, 1, &src_vsh, NULL);
3681 glCompileShader(vsh);
3682 const char* varyings[2] = { "q", "z" };
3683 glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3684 LinkProgram(program);
3685
3686 GLint res;
3687 VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3688 ExpectError(GL_INVALID_OPERATION, error);
3689 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
3690 if (res != 0 && res != 1)
3691 {
3692 m_context.getTestContext().getLog()
3693 << tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
3694 << tcu::TestLog::EndMessage;
3695 error = ERROR;
3696 }
3697 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
3698 if (res != 0 && res != 9)
3699 {
3700 m_context.getTestContext().getLog()
3701 << tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
3702 << tcu::TestLog::EndMessage;
3703 error = ERROR;
3704 }
3705 VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3706 ExpectError(GL_INVALID_OPERATION, error);
3707
3708 glDeleteProgram(program);
3709 return error;
3710 }
3711 };
3712 }
3713
ProgramInterfaceQueryTests(glcts::Context & context)3714 ProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context)
3715 : TestCaseGroup(context, "program_interface_query", "")
3716 {
3717 }
3718
~ProgramInterfaceQueryTests(void)3719 ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
3720 {
3721 }
3722
init()3723 void ProgramInterfaceQueryTests::init()
3724 {
3725 using namespace glcts;
3726 addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
3727 addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
3728 addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
3729 addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
3730 addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
3731 addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
3732 addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
3733 addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
3734 addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
3735 addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
3736 addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
3737 addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
3738 addChild(new TestSubcase(m_context, "transform-feedback-types-full-array-capture",
3739 TestSubcase::Create<TransformFeedbackTypesFullArrayCapture>));
3740 addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
3741 addChild(
3742 new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
3743 addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
3744 addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
3745 addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
3746 addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
3747 addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
3748 addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
3749 addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
3750 addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
3751 addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
3752 addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
3753 addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
3754 addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
3755 addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
3756 addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
3757 addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
3758 addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
3759 addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
3760 }
3761 }
3762