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