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