1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
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 Basic Layout Binding Tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fLayoutBindingTests.hpp"
25
26 #include "gluShaderProgram.hpp"
27 #include "gluPixelTransfer.hpp"
28 #include "gluTextureUtil.hpp"
29
30 #include "glwFunctions.hpp"
31 #include "glwEnums.hpp"
32
33 #include "tcuSurface.hpp"
34 #include "tcuTestLog.hpp"
35 #include "tcuTexture.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuStringTemplate.hpp"
39 #include "tcuRenderTarget.hpp"
40
41 #include "deString.h"
42 #include "deStringUtil.hpp"
43 #include "deRandom.hpp"
44
45 using tcu::TestLog;
46 using tcu::Vec2;
47 using tcu::Vec3;
48 using tcu::Vec4;
49
50 namespace deqp
51 {
52 namespace gles31
53 {
54 namespace Functional
55 {
56 namespace
57 {
58
59 enum TestType
60 {
61 TESTTYPE_BINDING_SINGLE = 0,
62 TESTTYPE_BINDING_MAX,
63 TESTTYPE_BINDING_MULTIPLE,
64 TESTTYPE_BINDING_ARRAY,
65 TESTTYPE_BINDING_MAX_ARRAY,
66
67 TESTTYPE_BINDING_LAST,
68 };
69
70 enum ShaderType
71 {
72 SHADERTYPE_VERTEX = 0,
73 SHADERTYPE_FRAGMENT,
74 SHADERTYPE_BOTH,
75
76 SHADERTYPE_LAST,
77 };
78
79 enum
80 {
81 MAX_UNIFORM_MULTIPLE_INSTANCES = 7,
82 MAX_UNIFORM_ARRAY_SIZE = 7,
83 };
84
generateVertexShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)85 std::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
86 {
87 static const char* const s_simpleVertexShaderSource = "#version 310 es\n"
88 "in highp vec4 a_position;\n"
89 "void main (void)\n"
90 "{\n"
91 " gl_Position = a_position;\n"
92 "}\n";
93
94 switch (shaderType)
95 {
96 case SHADERTYPE_VERTEX:
97 case SHADERTYPE_BOTH:
98 {
99 std::ostringstream vertexShaderSource;
100 vertexShaderSource << "#version 310 es\n"
101 << "in highp vec4 a_position;\n"
102 << "out highp vec4 v_color;\n"
103 << "uniform highp int u_arrayNdx;\n\n"
104 << shaderUniformDeclarations << "\n"
105 << "void main (void)\n"
106 << "{\n"
107 << " highp vec4 color;\n\n"
108 << shaderBody << "\n"
109 << " v_color = color;\n"
110 << " gl_Position = a_position;\n"
111 << "}\n";
112
113 return vertexShaderSource.str();
114 }
115
116 case SHADERTYPE_FRAGMENT:
117 return s_simpleVertexShaderSource;
118
119 default:
120 DE_ASSERT(false);
121 return "";
122 }
123 }
124
generateFragmentShader(ShaderType shaderType,const std::string & shaderUniformDeclarations,const std::string & shaderBody)125 std::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
126 {
127 static const char* const s_simpleFragmentShaderSource = "#version 310 es\n"
128 "in highp vec4 v_color;\n"
129 "layout(location = 0) out highp vec4 fragColor;\n"
130 "void main (void)\n"
131 "{\n"
132 " fragColor = v_color;\n"
133 "}\n";
134
135 switch (shaderType)
136 {
137 case SHADERTYPE_VERTEX:
138 return s_simpleFragmentShaderSource;
139
140 case SHADERTYPE_FRAGMENT:
141 {
142 std::ostringstream fragmentShaderSource;
143 fragmentShaderSource << "#version 310 es\n"
144 << "layout(location = 0) out highp vec4 fragColor;\n"
145 << "uniform highp int u_arrayNdx;\n\n"
146 << shaderUniformDeclarations << "\n"
147 << "void main (void)\n"
148 << "{\n"
149 << " highp vec4 color;\n\n"
150 << shaderBody << "\n"
151 << " fragColor = color;\n"
152 << "}\n";
153
154 return fragmentShaderSource.str();
155 }
156 case SHADERTYPE_BOTH:
157 {
158 std::ostringstream fragmentShaderSource;
159 fragmentShaderSource << "#version 310 es\n"
160 << "in highp vec4 v_color;\n"
161 << "layout(location = 0) out highp vec4 fragColor;\n"
162 << "uniform highp int u_arrayNdx;\n\n"
163 << shaderUniformDeclarations << "\n"
164 << "void main (void)\n"
165 << "{\n"
166 << " if (v_color.x > 2.0) discard;\n"
167 << " highp vec4 color;\n\n"
168 << shaderBody << "\n"
169 << " fragColor = color;\n"
170 << "}\n";
171
172 return fragmentShaderSource.str();
173 }
174
175 default:
176 DE_ASSERT(false);
177 return "";
178 }
179 }
180
getUniformName(const std::string & name,int declNdx)181 std::string getUniformName (const std::string& name, int declNdx)
182 {
183 return name + de::toString(declNdx);
184 }
185
getUniformName(const std::string & name,int declNdx,int arrNdx)186 std::string getUniformName (const std::string& name, int declNdx, int arrNdx)
187 {
188 return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
189 }
190
getRandomColor(de::Random & rnd)191 Vec4 getRandomColor (de::Random& rnd)
192 {
193 const float r = rnd.getFloat(0.2f, 0.9f);
194 const float g = rnd.getFloat(0.2f, 0.9f);
195 const float b = rnd.getFloat(0.2f, 0.9f);
196 return Vec4(r, g, b, 1.0f);
197 }
198
199 class LayoutBindingRenderCase : public TestCase
200 {
201 public:
202 enum
203 {
204 MAX_TEST_RENDER_WIDTH = 256,
205 MAX_TEST_RENDER_HEIGHT = 256,
206 TEST_TEXTURE_SIZE = 1,
207 };
208
209 LayoutBindingRenderCase (Context& context,
210 const char* name,
211 const char* desc,
212 ShaderType shaderType,
213 TestType testType,
214 glw::GLenum maxBindingPointEnum,
215 glw::GLenum maxVertexUnitsEnum,
216 glw::GLenum maxFragmentUnitsEnum,
217 glw::GLenum maxCombinedUnitsEnum,
218 const std::string& uniformName);
219 virtual ~LayoutBindingRenderCase (void);
220
221 virtual void init (void);
222 virtual void deinit (void);
223
getRenderWidth(void) const224 int getRenderWidth (void) const { return de::min((int)MAX_TEST_RENDER_WIDTH, m_context.getRenderTarget().getWidth()); }
getRenderHeight(void) const225 int getRenderHeight (void) const { return de::min((int)MAX_TEST_RENDER_HEIGHT, m_context.getRenderTarget().getHeight()); }
226 protected:
227 virtual glu::ShaderProgram* generateShaders (void) const = 0;
228
229 void initRenderState (void);
230 bool drawAndVerifyResult (const Vec4& expectedColor);
231 void setTestResult (bool queryTestPassed, bool imageTestPassed);
232
233 const glu::ShaderProgram* m_program;
234 const ShaderType m_shaderType;
235 const TestType m_testType;
236 const std::string m_uniformName;
237
238 const glw::GLenum m_maxBindingPointEnum;
239 const glw::GLenum m_maxVertexUnitsEnum;
240 const glw::GLenum m_maxFragmentUnitsEnum;
241 const glw::GLenum m_maxCombinedUnitsEnum;
242
243 glw::GLuint m_vertexBuffer;
244 glw::GLuint m_indexBuffer;
245 glw::GLint m_shaderProgramLoc;
246 glw::GLint m_shaderProgramPosLoc;
247 glw::GLint m_shaderProgramArrayNdxLoc;
248 glw::GLint m_numBindings;
249
250 std::vector<glw::GLint> m_bindings;
251
252 private:
253 void initBindingPoints (int minBindingPoint, int numBindingPoints);
254 };
255
LayoutBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum maxBindingPointEnum,glw::GLenum maxVertexUnitsEnum,glw::GLenum maxFragmentUnitsEnum,glw::GLenum maxCombinedUnitsEnum,const std::string & uniformName)256 LayoutBindingRenderCase::LayoutBindingRenderCase (Context& context,
257 const char* name,
258 const char* desc,
259 ShaderType shaderType,
260 TestType testType,
261 glw::GLenum maxBindingPointEnum,
262 glw::GLenum maxVertexUnitsEnum,
263 glw::GLenum maxFragmentUnitsEnum,
264 glw::GLenum maxCombinedUnitsEnum,
265 const std::string& uniformName)
266 : TestCase (context, name, desc)
267 , m_program (DE_NULL)
268 , m_shaderType (shaderType)
269 , m_testType (testType)
270 , m_uniformName (uniformName)
271 , m_maxBindingPointEnum (maxBindingPointEnum)
272 , m_maxVertexUnitsEnum (maxVertexUnitsEnum)
273 , m_maxFragmentUnitsEnum (maxFragmentUnitsEnum)
274 , m_maxCombinedUnitsEnum (maxCombinedUnitsEnum)
275 , m_vertexBuffer (0)
276 , m_indexBuffer (0)
277 , m_shaderProgramLoc (0)
278 , m_shaderProgramPosLoc (0)
279 , m_shaderProgramArrayNdxLoc (0)
280 , m_numBindings (0)
281 {
282 }
283
~LayoutBindingRenderCase(void)284 LayoutBindingRenderCase::~LayoutBindingRenderCase (void)
285 {
286 deinit();
287 }
288
init(void)289 void LayoutBindingRenderCase::init (void)
290 {
291 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
292
293 {
294 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
295 glw::GLint numBindingPoints = 0; // Number of available binding points
296 glw::GLint maxVertexUnits = 0; // Available uniforms in the vertex shader
297 glw::GLint maxFragmentUnits = 0; // Available uniforms in the fragment shader
298 glw::GLint maxCombinedUnits = 0; // Available uniforms in all the shader stages combined
299 glw::GLint maxUnits = 0; // Maximum available uniforms for this test
300
301 gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
302 gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
303 gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
304 gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
305 GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
306
307 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
308 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
309 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
310 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
311
312 // Select maximum number of uniforms used for the test
313 switch (m_shaderType)
314 {
315 case SHADERTYPE_VERTEX:
316 maxUnits = maxVertexUnits;
317 break;
318
319 case SHADERTYPE_FRAGMENT:
320 maxUnits = maxFragmentUnits;
321 break;
322
323 case SHADERTYPE_BOTH:
324 maxUnits = maxCombinedUnits/2;
325 break;
326
327 default:
328 DE_ASSERT(false);
329 }
330
331 // Select the number of uniforms (= bindings) used for this test
332 switch (m_testType)
333 {
334 case TESTTYPE_BINDING_SINGLE:
335 case TESTTYPE_BINDING_MAX:
336 m_numBindings = 1;
337 break;
338
339 case TESTTYPE_BINDING_MULTIPLE:
340 if (maxUnits < 2)
341 throw tcu::NotSupportedError("Not enough uniforms available for test");
342 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits));
343 break;
344
345 case TESTTYPE_BINDING_ARRAY:
346 case TESTTYPE_BINDING_MAX_ARRAY:
347 if (maxUnits < 2)
348 throw tcu::NotSupportedError("Not enough uniforms available for test");
349 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
350 break;
351
352 default:
353 DE_ASSERT(false);
354 }
355
356 // Check that we have enough uniforms in different shaders to perform the tests
357 if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
358 throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
359 if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
360 throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
361 if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
362 throw tcu::NotSupportedError("Not enough uniforms available for test");
363
364 // Check that we have enough binding points to perform the tests
365 if (numBindingPoints < m_numBindings)
366 throw tcu::NotSupportedError("Not enough binding points available for test");
367
368 // Initialize the binding points i.e. populate the two binding point vectors
369 initBindingPoints(0, numBindingPoints);
370 }
371
372 // Generate the shader program - note: this must be done after deciding the binding points
373 DE_ASSERT(!m_program);
374 m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
375 m_program = generateShaders();
376 m_testCtx.getLog() << *m_program;
377
378 if (!m_program->isOk())
379 throw tcu::TestError("Shader compile failed");
380
381 // Setup vertex and index buffers
382 {
383 // Get attribute and uniform locations
384 const deUint32 program = m_program->getProgram();
385
386 m_shaderProgramPosLoc = gl.getAttribLocation(program, "a_position");
387 m_shaderProgramArrayNdxLoc = gl.getUniformLocation(program, "u_arrayNdx");
388 m_vertexBuffer = 0;
389 m_indexBuffer = 0;
390
391 // Setup buffers so that we render one quad covering the whole viewport
392 const Vec3 vertices[] =
393 {
394 Vec3(-1.0f, -1.0f, +1.0f),
395 Vec3(+1.0f, -1.0f, +1.0f),
396 Vec3(+1.0f, +1.0f, +1.0f),
397 Vec3(-1.0f, +1.0f, +1.0f),
398 };
399
400 const deUint16 indices[] =
401 {
402 0, 1, 2,
403 0, 2, 3,
404 };
405
406 TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0));
407
408 // Generate and bind index buffer
409 gl.genBuffers(1, &m_indexBuffer);
410 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
411 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(indices)*(glw::GLsizeiptr)sizeof(indices[0])), &indices[0], GL_STATIC_DRAW);
412 GLU_EXPECT_NO_ERROR(gl.getError(), "Index buffer setup failed");
413
414 // Generate and bind vertex buffer
415 gl.genBuffers(1, &m_vertexBuffer);
416 gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
417 gl.bufferData(GL_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(vertices)*(glw::GLsizeiptr)sizeof(vertices[0])), &vertices[0], GL_STATIC_DRAW);
418 gl.enableVertexAttribArray(m_shaderProgramPosLoc);
419 gl.vertexAttribPointer(m_shaderProgramPosLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
420 GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex buffer setup failed");
421 }
422 }
423
deinit(void)424 void LayoutBindingRenderCase::deinit (void)
425 {
426 if (m_program)
427 {
428 delete m_program;
429 m_program = DE_NULL;
430 }
431
432 if (m_shaderProgramPosLoc)
433 m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc);
434
435 if (m_vertexBuffer)
436 {
437 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
438 m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0);
439 }
440
441 if (m_indexBuffer)
442 {
443 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
444 m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
445 }
446 }
447
initBindingPoints(int minBindingPoint,int numBindingPoints)448 void LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
449 {
450 de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
451
452 switch (m_testType)
453 {
454 case TESTTYPE_BINDING_SINGLE:
455 {
456 const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1);
457 m_bindings.push_back(bpoint);
458 break;
459 }
460
461 case TESTTYPE_BINDING_MAX:
462 m_bindings.push_back(numBindingPoints-1);
463 break;
464
465 case TESTTYPE_BINDING_MULTIPLE:
466 {
467 // Choose multiple unique binding points from the low and high end of available binding points
468 std::vector<deUint32> lowBindingPoints;
469 std::vector<deUint32> highBindingPoints;
470
471 for (int bpoint = 0; bpoint < numBindingPoints/2; ++bpoint)
472 lowBindingPoints.push_back(bpoint);
473 for (int bpoint = numBindingPoints/2; bpoint < numBindingPoints; ++bpoint)
474 highBindingPoints.push_back(bpoint);
475
476 rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end());
477 rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end());
478
479 for (int ndx = 0; ndx < m_numBindings; ++ndx)
480 {
481 if (ndx%2 == 0)
482 {
483 const int bpoint = lowBindingPoints.back();
484 lowBindingPoints.pop_back();
485 m_bindings.push_back(bpoint);
486 }
487 else
488 {
489 const int bpoint = highBindingPoints.back();
490 highBindingPoints.pop_back();
491 m_bindings.push_back(bpoint);
492 }
493
494 }
495 break;
496 }
497
498 case TESTTYPE_BINDING_ARRAY:
499 {
500 const glw::GLint binding = rnd.getInt(minBindingPoint, numBindingPoints-m_numBindings);
501 for (int ndx = 0; ndx < m_numBindings; ++ndx)
502 m_bindings.push_back(binding+ndx);
503 break;
504 }
505
506 case TESTTYPE_BINDING_MAX_ARRAY:
507 {
508 const glw::GLint binding = numBindingPoints-m_numBindings;
509 for (int ndx = 0; ndx < m_numBindings; ++ndx)
510 m_bindings.push_back(binding+ndx);
511 break;
512 }
513
514 default:
515 DE_ASSERT(false);
516 }
517 }
518
initRenderState(void)519 void LayoutBindingRenderCase::initRenderState (void)
520 {
521 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
522
523 gl.useProgram(m_program->getProgram());
524 gl.viewport(0, 0, getRenderWidth(), getRenderHeight());
525 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
526 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state");
527 }
528
drawAndVerifyResult(const Vec4 & expectedColor)529 bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
530 {
531 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
532 tcu::Surface reference (getRenderWidth(), getRenderHeight());
533
534 // the point of these test is to check layout_binding. For this purpose, we can use quite
535 // large thresholds.
536 const tcu::RGBA surfaceThreshold = m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold();
537 const tcu::RGBA compareThreshold = tcu::RGBA(de::clamp(2 * surfaceThreshold.getRed(), 0, 255),
538 de::clamp(2 * surfaceThreshold.getGreen(), 0, 255),
539 de::clamp(2 * surfaceThreshold.getBlue(), 0, 255),
540 de::clamp(2 * surfaceThreshold.getAlpha(), 0, 255));
541
542 gl.clear(GL_COLOR_BUFFER_BIT);
543
544 // Draw
545 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
546 GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
547
548 // Verify
549 tcu::Surface result(getRenderWidth(), getRenderHeight());
550 m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
551 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
552 GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
553
554 tcu::clear(reference.getAccess(), expectedColor);
555 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;
556
557 return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
558 }
559
setTestResult(bool queryTestPassed,bool imageTestPassed)560 void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
561 {
562 if (queryTestPassed && imageTestPassed)
563 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
564 else if (!queryTestPassed && !imageTestPassed)
565 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed");
566 else if (!queryTestPassed)
567 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed");
568 else
569 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
570 }
571
572 class LayoutBindingNegativeCase : public TestCase
573 {
574 public:
575 enum ErrorType
576 {
577 ERRORTYPE_OVER_MAX_UNITS = 0,
578 ERRORTYPE_LESS_THAN_ZERO,
579 ERRORTYPE_CONTRADICTORY,
580
581 ERRORTYPE_LAST,
582 };
583
584 LayoutBindingNegativeCase (Context& context,
585 const char* name,
586 const char* desc,
587 ShaderType shaderType,
588 TestType testType,
589 ErrorType errorType,
590 glw::GLenum maxBindingPointEnum,
591 glw::GLenum maxVertexUnitsEnum,
592 glw::GLenum maxFragmentUnitsEnum,
593 glw::GLenum maxCombinedUnitsEnum,
594 const std::string& uniformName);
595 virtual ~LayoutBindingNegativeCase (void);
596
597 virtual void init (void);
598 virtual void deinit (void);
599 virtual IterateResult iterate (void);
600
601 protected:
602 virtual glu::ShaderProgram* generateShaders (void) const = 0;
603
604 const glu::ShaderProgram* m_program;
605 const ShaderType m_shaderType;
606 const TestType m_testType;
607 const ErrorType m_errorType;
608 const glw::GLenum m_maxBindingPointEnum;
609 const glw::GLenum m_maxVertexUnitsEnum;
610 const glw::GLenum m_maxFragmentUnitsEnum;
611 const glw::GLenum m_maxCombinedUnitsEnum;
612 const std::string m_uniformName;
613 glw::GLint m_numBindings;
614 std::vector<glw::GLint> m_vertexShaderBinding;
615 std::vector<glw::GLint> m_fragmentShaderBinding;
616
617 private:
618 void initBindingPoints (int minBindingPoint, int numBindingPoints);
619 };
620
LayoutBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum maxBindingPointEnum,glw::GLenum maxVertexUnitsEnum,glw::GLenum maxFragmentUnitsEnum,glw::GLenum maxCombinedUnitsEnum,const std::string & uniformName)621 LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context& context,
622 const char* name,
623 const char* desc,
624 ShaderType shaderType,
625 TestType testType,
626 ErrorType errorType,
627 glw::GLenum maxBindingPointEnum,
628 glw::GLenum maxVertexUnitsEnum,
629 glw::GLenum maxFragmentUnitsEnum,
630 glw::GLenum maxCombinedUnitsEnum,
631 const std::string& uniformName)
632 : TestCase (context, name, desc)
633 , m_program (DE_NULL)
634 , m_shaderType (shaderType)
635 , m_testType (testType)
636 , m_errorType (errorType)
637 , m_maxBindingPointEnum (maxBindingPointEnum)
638 , m_maxVertexUnitsEnum (maxVertexUnitsEnum)
639 , m_maxFragmentUnitsEnum (maxFragmentUnitsEnum)
640 , m_maxCombinedUnitsEnum (maxCombinedUnitsEnum)
641 , m_uniformName (uniformName)
642 , m_numBindings (0)
643 {
644 }
645
~LayoutBindingNegativeCase(void)646 LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
647 {
648 deinit();
649 }
650
init(void)651 void LayoutBindingNegativeCase::init (void)
652 {
653 // Decide appropriate binding points for the vertex and fragment shaders
654 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
655 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
656 glw::GLint numBindingPoints = 0; // Number of binding points
657 glw::GLint maxVertexUnits = 0; // Available uniforms in the vertex shader
658 glw::GLint maxFragmentUnits = 0; // Available uniforms in the fragment shader
659 glw::GLint maxCombinedUnits = 0; // Available uniforms in all the shader stages combined
660 glw::GLint maxUnits = 0; // Maximum available uniforms for this test
661
662 gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
663 gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
664 gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
665 gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
666 GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
667
668 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
669 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
670 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
671 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
672
673 // Select maximum number of uniforms used for the test
674 switch (m_shaderType)
675 {
676 case SHADERTYPE_VERTEX:
677 maxUnits = maxVertexUnits;
678 break;
679
680 case SHADERTYPE_FRAGMENT:
681 maxUnits = maxFragmentUnits;
682 break;
683
684 case SHADERTYPE_BOTH:
685 maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2);
686 break;
687
688 default:
689 DE_ASSERT(false);
690 }
691
692 // Select the number of uniforms (= bindings) used for this test
693 switch (m_testType)
694 {
695 case TESTTYPE_BINDING_SINGLE:
696 case TESTTYPE_BINDING_MAX:
697 m_numBindings = 1;
698 break;
699
700 case TESTTYPE_BINDING_MULTIPLE:
701 case TESTTYPE_BINDING_ARRAY:
702 case TESTTYPE_BINDING_MAX_ARRAY:
703 if (m_errorType == ERRORTYPE_CONTRADICTORY)
704 {
705 // leave room for contradictory case
706 if (maxUnits < 3)
707 throw tcu::NotSupportedError("Not enough uniforms available for test");
708 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
709 }
710 else
711 {
712 if (maxUnits < 2)
713 throw tcu::NotSupportedError("Not enough uniforms available for test");
714 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
715 }
716 break;
717
718 default:
719 DE_ASSERT(false);
720 }
721
722 // Check that we have enough uniforms in different shaders to perform the tests
723 if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
724 throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
725 if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
726 throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
727 if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
728 throw tcu::NotSupportedError("Not enough uniforms available for test");
729
730 // Check that we have enough binding points to perform the tests
731 if (numBindingPoints < m_numBindings)
732 throw tcu::NotSupportedError("Not enough binding points available for test");
733 if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
734 throw tcu::NotSupportedError("Not enough binding points available for test");
735
736 // Initialize the binding points i.e. populate the two binding point vectors
737 initBindingPoints(0, numBindingPoints);
738
739 // Generate the shader program - note: this must be done after deciding the binding points
740 DE_ASSERT(!m_program);
741 m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
742 m_program = generateShaders();
743 m_testCtx.getLog() << *m_program;
744 }
745
deinit(void)746 void LayoutBindingNegativeCase::deinit (void)
747 {
748 if (m_program)
749 {
750 delete m_program;
751 m_program = DE_NULL;
752 }
753 }
754
iterate(void)755 TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
756 {
757 bool pass = false;
758 std::string failMessage;
759
760 switch (m_errorType)
761 {
762 case ERRORTYPE_CONTRADICTORY: // Contradictory binding points should cause a link-time error
763 if (!(m_program->getProgramInfo()).linkOk)
764 pass = true;
765 failMessage = "Test failed - expected a link-time error";
766 break;
767
768 case ERRORTYPE_LESS_THAN_ZERO: // Out of bounds binding points should cause a compile-time error
769 case ERRORTYPE_OVER_MAX_UNITS:
770 if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk)
771 pass = true;
772 failMessage = "Test failed - expected a compile-time error";
773 break;
774
775 default:
776 DE_ASSERT(false);
777 }
778
779 if (pass)
780 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
781 else
782 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());
783
784 return STOP;
785 }
786
initBindingPoints(int minBindingPoint,int numBindingPoints)787 void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
788 {
789 de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
790
791 switch (m_errorType)
792 {
793 case ERRORTYPE_OVER_MAX_UNITS: // Select a binding point that is 1 over the maximum
794 {
795 m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
796 m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
797 break;
798 }
799
800 case ERRORTYPE_LESS_THAN_ZERO: // Select a random negative binding point
801 {
802 const glw::GLint binding = -rnd.getInt(1, m_numBindings);
803 m_vertexShaderBinding.push_back(binding);
804 m_fragmentShaderBinding.push_back(binding);
805 break;
806 }
807
808 case ERRORTYPE_CONTRADICTORY: // Select two valid, but contradictory binding points
809 {
810 m_vertexShaderBinding.push_back(minBindingPoint);
811 m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
812 DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back());
813 break;
814 }
815
816 default:
817 DE_ASSERT(false);
818 }
819
820 // In case we are testing with multiple uniforms populate the rest of the binding points
821 for (int ndx = 1; ndx < m_numBindings; ++ndx)
822 {
823 m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
824 m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
825 }
826 }
827
828 class SamplerBindingRenderCase : public LayoutBindingRenderCase
829 {
830 public:
831 SamplerBindingRenderCase (Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
832 ~SamplerBindingRenderCase (void);
833
834 void init (void);
835 void deinit (void);
836 IterateResult iterate (void);
837
838 private:
839 glu::ShaderProgram* generateShaders (void) const;
840 glu::DataType getSamplerTexCoordType (void) const;
841 void initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const;
842
843 const glw::GLenum m_samplerType;
844 const glw::GLenum m_textureType;
845
846 std::vector<glw::GLuint> m_textures;
847 std::vector<Vec4> m_textureColors;
848 };
849
850
SamplerBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum samplerType,glw::GLenum textureType)851 SamplerBindingRenderCase::SamplerBindingRenderCase (Context& context,
852 const char* name,
853 const char* desc,
854 ShaderType shaderType,
855 TestType testType,
856 glw::GLenum samplerType,
857 glw::GLenum textureType)
858 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler")
859 , m_samplerType (samplerType)
860 , m_textureType (textureType)
861 {
862 }
863
~SamplerBindingRenderCase(void)864 SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
865 {
866 deinit();
867 }
868
init(void)869 void SamplerBindingRenderCase::init (void)
870 {
871 LayoutBindingRenderCase::init();
872 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
873 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
874
875
876 // Initialize texture resources
877 m_textures = std::vector<glw::GLuint>(m_numBindings, 0);
878
879 // Texture colors
880 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
881 m_textureColors.push_back(getRandomColor(rnd));
882
883 // Textures
884 gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);
885
886 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
887 initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);
888
889 gl.activeTexture(GL_TEXTURE0);
890 }
891
deinit(void)892 void SamplerBindingRenderCase::deinit(void)
893 {
894 LayoutBindingRenderCase::deinit();
895
896 // Clean up texture data
897 for (int i = 0; i < (int)m_textures.size(); ++i)
898 {
899 if (m_textures[i])
900 {
901 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
902 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
903 }
904 }
905 }
906
iterate(void)907 TestCase::IterateResult SamplerBindingRenderCase::iterate (void)
908 {
909 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
910 const int iterations = m_numBindings;
911 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
912 bool imageTestPassed = true;
913 bool queryTestPassed = true;
914
915 // Set the viewport and enable the shader program
916 initRenderState();
917
918 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
919 {
920 // Set the uniform value indicating the current array index
921 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
922
923 // Query binding point
924 const std::string name = arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx);
925 const glw::GLint binding = m_bindings[iterNdx];
926 glw::GLint val = -1;
927
928 gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
929 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
930 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
931
932 // Draw and verify
933 if (val != binding)
934 queryTestPassed = false;
935 if (!drawAndVerifyResult(m_textureColors[iterNdx]))
936 imageTestPassed = false;
937 }
938
939 setTestResult(queryTestPassed, imageTestPassed);
940 return STOP;
941 }
942
generateShaders(void) const943 glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
944 {
945 std::ostringstream shaderUniformDecl;
946 std::ostringstream shaderBody;
947
948 const std::string texCoordType = glu::getDataTypeName(getSamplerTexCoordType());
949 const std::string samplerType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
950 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
951 const int numDeclarations = arrayInstance ? 1 : m_numBindings;
952
953 // Generate the uniform declarations for the vertex and fragment shaders
954 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
955 {
956 shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
957 << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
958 }
959
960 // Generate the shader body for the vertex and fragment shaders
961 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
962 {
963 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
964 << " {\n"
965 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
966 << " }\n";
967 }
968
969 shaderBody << " else\n"
970 << " {\n"
971 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
972 << " }\n";
973
974 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
975 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
976 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
977 }
978
initializeTexture(glw::GLint bindingPoint,glw::GLint textureName,const Vec4 & color) const979 void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
980 {
981 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
982
983 gl.activeTexture(GL_TEXTURE0 + bindingPoint);
984 gl.bindTexture(m_textureType, textureName);
985 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
986
987 switch (m_textureType)
988 {
989 case GL_TEXTURE_2D:
990 {
991 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
992 tcu::clear(level.getAccess(), color);
993 glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
994 break;
995 }
996
997 case GL_TEXTURE_3D:
998 {
999 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1000 tcu::clear(level.getAccess(), color);
1001 glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
1002 break;
1003 }
1004
1005 default:
1006 DE_ASSERT(false);
1007 }
1008
1009 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
1010 }
1011
getSamplerTexCoordType(void) const1012 glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
1013 {
1014 switch (m_samplerType)
1015 {
1016 case GL_SAMPLER_2D:
1017 return glu::TYPE_FLOAT_VEC2;
1018
1019 case GL_SAMPLER_3D:
1020 return glu::TYPE_FLOAT_VEC3;
1021
1022 default:
1023 DE_ASSERT(false);
1024 return glu::TYPE_INVALID;
1025 }
1026 }
1027
1028
1029 class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
1030 {
1031 public:
1032 SamplerBindingNegativeCase (Context& context,
1033 const char* name,
1034 const char* desc,
1035 ShaderType shaderType,
1036 TestType testType,
1037 ErrorType errorType,
1038 glw::GLenum samplerType);
1039 ~SamplerBindingNegativeCase (void);
1040
1041 private:
1042 glu::ShaderProgram* generateShaders (void) const;
1043 glu::DataType getSamplerTexCoordType (void) const;
1044
1045 const glw::GLenum m_samplerType;
1046 };
1047
SamplerBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum samplerType)1048 SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context& context,
1049 const char* name,
1050 const char* desc,
1051 ShaderType shaderType,
1052 TestType testType,
1053 ErrorType errorType,
1054 glw::GLenum samplerType)
1055 : LayoutBindingNegativeCase (context, name, desc, shaderType, testType, errorType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler")
1056 , m_samplerType (samplerType)
1057 {
1058 }
1059
~SamplerBindingNegativeCase(void)1060 SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
1061 {
1062 LayoutBindingNegativeCase::deinit();
1063 }
1064
generateShaders(void) const1065 glu::ShaderProgram* SamplerBindingNegativeCase::generateShaders (void) const
1066 {
1067 std::ostringstream vertexUniformDecl;
1068 std::ostringstream fragmentUniformDecl;
1069 std::ostringstream shaderBody;
1070
1071 const std::string texCoordType = glu::getDataTypeName(getSamplerTexCoordType());
1072 const std::string samplerType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
1073 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1074 const int numDeclarations = arrayInstance ? 1 : m_numBindings;
1075
1076 // Generate the uniform declarations for the vertex and fragment shaders
1077 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1078 {
1079 vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType
1080 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1081 fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
1082 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1083 }
1084
1085 // Generate the shader body for the vertex and fragment shaders
1086 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1087 {
1088 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1089 << " {\n"
1090 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1091 << " }\n";
1092 }
1093
1094 shaderBody << " else\n"
1095 << " {\n"
1096 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1097 << " }\n";
1098
1099 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1100 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1101 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1102 }
1103
getSamplerTexCoordType(void) const1104 glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
1105 {
1106 switch (m_samplerType)
1107 {
1108 case GL_SAMPLER_2D:
1109 return glu::TYPE_FLOAT_VEC2;
1110
1111 case GL_SAMPLER_3D:
1112 return glu::TYPE_FLOAT_VEC3;
1113
1114 default:
1115 DE_ASSERT(false);
1116 return glu::TYPE_INVALID;
1117 }
1118 }
1119
1120 class ImageBindingRenderCase : public LayoutBindingRenderCase
1121 {
1122 public:
1123 ImageBindingRenderCase (Context& context,
1124 const char* name,
1125 const char* desc,
1126 ShaderType shaderType,
1127 TestType testType,
1128 glw::GLenum imageType,
1129 glw::GLenum textureType);
1130 ~ImageBindingRenderCase (void);
1131
1132 void init (void);
1133 void deinit (void);
1134 IterateResult iterate (void);
1135
1136 private:
1137 glu::ShaderProgram* generateShaders (void) const;
1138 void initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const;
1139 glu::DataType getImageTexCoordType (void) const;
1140
1141 const glw::GLenum m_imageType;
1142 const glw::GLenum m_textureType;
1143
1144 std::vector<glw::GLuint> m_textures;
1145 std::vector<Vec4> m_textureColors;
1146 };
1147
1148
ImageBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,glw::GLenum imageType,glw::GLenum textureType)1149 ImageBindingRenderCase::ImageBindingRenderCase (Context& context,
1150 const char* name,
1151 const char* desc,
1152 ShaderType shaderType,
1153 TestType testType,
1154 glw::GLenum imageType,
1155 glw::GLenum textureType)
1156 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image")
1157 , m_imageType (imageType)
1158 , m_textureType (textureType)
1159 {
1160 }
1161
~ImageBindingRenderCase(void)1162 ImageBindingRenderCase::~ImageBindingRenderCase (void)
1163 {
1164 deinit();
1165 }
1166
init(void)1167 void ImageBindingRenderCase::init (void)
1168 {
1169 LayoutBindingRenderCase::init();
1170
1171 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1172 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
1173
1174 // Initialize image / texture resources
1175 m_textures = std::vector<glw::GLuint>(m_numBindings, 0);
1176
1177 // Texture colors
1178 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1179 m_textureColors.push_back(getRandomColor(rnd));
1180
1181 // Image textures
1182 gl.genTextures(m_numBindings, &m_textures[0]);
1183
1184 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1185 initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
1186 }
1187
deinit(void)1188 void ImageBindingRenderCase::deinit (void)
1189 {
1190 LayoutBindingRenderCase::deinit();
1191
1192 // Clean up texture data
1193 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1194 {
1195 if (m_textures[texNdx])
1196 {
1197 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
1198 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1199 }
1200 }
1201 }
1202
iterate(void)1203 TestCase::IterateResult ImageBindingRenderCase::iterate (void)
1204 {
1205 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1206 const int iterations = m_numBindings;
1207 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1208 bool queryTestPassed = true;
1209 bool imageTestPassed = true;
1210
1211 // Set the viewport and enable the shader program
1212 initRenderState();
1213
1214 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1215 {
1216 // Set the uniform value indicating the current array index
1217 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
1218
1219 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1220 const glw::GLint binding = m_bindings[iterNdx];
1221 glw::GLint val = -1;
1222
1223 gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
1224 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1225 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1226
1227 // Draw and verify
1228 if (val != binding)
1229 queryTestPassed = false;
1230 if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1231 imageTestPassed = false;
1232 }
1233
1234 setTestResult(queryTestPassed, imageTestPassed);
1235 return STOP;
1236 }
1237
initializeImage(glw::GLint imageBindingPoint,glw::GLint textureBindingPoint,glw::GLint textureName,const Vec4 & color) const1238 void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
1239 {
1240 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1241
1242 gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
1243 gl.bindTexture(m_textureType, textureName);
1244 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1245
1246 switch (m_textureType)
1247 {
1248 case GL_TEXTURE_2D:
1249 {
1250 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1251 tcu::clear(level.getAccess(), color);
1252 gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1253 gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
1254 break;
1255 }
1256
1257 case GL_TEXTURE_3D:
1258 {
1259 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1260 tcu::clear(level.getAccess(), color);
1261 gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
1262 gl.texSubImage3D(m_textureType, 0, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
1263 break;
1264 }
1265
1266 default:
1267 DE_ASSERT(false);
1268 }
1269
1270 gl.bindTexture(m_textureType, 0);
1271 gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8);
1272 GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed");
1273 }
1274
generateShaders(void) const1275 glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
1276 {
1277 std::ostringstream shaderUniformDecl;
1278 std::ostringstream shaderBody;
1279
1280 const std::string texCoordType = glu::getDataTypeName(getImageTexCoordType());
1281 const std::string imageType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1282 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
1283 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1284
1285 // Generate the uniform declarations for the vertex and fragment shaders
1286 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1287 {
1288 shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType
1289 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1290 }
1291
1292 // Generate the shader body for the vertex and fragment shaders
1293 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1294 {
1295 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1296 << " {\n"
1297 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1298 << " }\n";
1299 }
1300
1301 shaderBody << " else\n"
1302 << " {\n"
1303 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1304 << " }\n";
1305
1306 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1307 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1308 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1309 }
1310
getImageTexCoordType(void) const1311 glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
1312 {
1313 switch (m_imageType)
1314 {
1315 case GL_IMAGE_2D:
1316 return glu::TYPE_INT_VEC2;
1317
1318 case GL_IMAGE_3D:
1319 return glu::TYPE_INT_VEC3;
1320
1321 default:
1322 DE_ASSERT(false);
1323 return glu::TYPE_INVALID;
1324 }
1325 }
1326
1327
1328 class ImageBindingNegativeCase : public LayoutBindingNegativeCase
1329 {
1330 public:
1331 ImageBindingNegativeCase (Context& context,
1332 const char* name,
1333 const char* desc,
1334 ShaderType shaderType,
1335 TestType testType,
1336 ErrorType errorType,
1337 glw::GLenum imageType);
1338 ~ImageBindingNegativeCase (void);
1339
1340 private:
1341 glu::ShaderProgram* generateShaders (void) const;
1342 glu::DataType getImageTexCoordType (void) const;
1343
1344 const glw::GLenum m_imageType;
1345 };
1346
ImageBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType,glw::GLenum imageType)1347 ImageBindingNegativeCase::ImageBindingNegativeCase (Context& context,
1348 const char* name,
1349 const char* desc,
1350 ShaderType shaderType,
1351 TestType testType,
1352 ErrorType errorType,
1353 glw::GLenum imageType)
1354 : LayoutBindingNegativeCase (context, name, desc, shaderType, testType, errorType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image")
1355 , m_imageType (imageType)
1356 {
1357 }
1358
~ImageBindingNegativeCase(void)1359 ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
1360 {
1361 deinit();
1362 }
1363
generateShaders(void) const1364 glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
1365 {
1366 std::ostringstream vertexUniformDecl;
1367 std::ostringstream fragmentUniformDecl;
1368 std::ostringstream shaderBody;
1369
1370 const std::string texCoordType = glu::getDataTypeName(getImageTexCoordType());
1371 const std::string imageType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
1372 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1373 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1374
1375 // Generate the uniform declarations for the vertex and fragment shaders
1376 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1377 {
1378 vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1379 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1380 fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
1381 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1382 }
1383
1384 // Generate the shader body for the vertex and fragment shaders
1385 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1386 {
1387 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1388 << " {\n"
1389 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1390 << " }\n";
1391 }
1392
1393 shaderBody << " else\n"
1394 << " {\n"
1395 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1396 << " }\n";
1397
1398 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1399 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1400 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1401 }
1402
getImageTexCoordType(void) const1403 glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
1404 {
1405 switch (m_imageType)
1406 {
1407 case GL_IMAGE_2D:
1408 return glu::TYPE_INT_VEC2;
1409
1410 case GL_IMAGE_3D:
1411 return glu::TYPE_INT_VEC3;
1412
1413 default:
1414 DE_ASSERT(false);
1415 return glu::TYPE_INVALID;
1416 }
1417 }
1418
1419
1420 class UBOBindingRenderCase : public LayoutBindingRenderCase
1421 {
1422 public:
1423 UBOBindingRenderCase (Context& context,
1424 const char* name,
1425 const char* desc,
1426 ShaderType shaderType,
1427 TestType testType);
1428 ~UBOBindingRenderCase (void);
1429
1430 void init (void);
1431 void deinit (void);
1432 IterateResult iterate (void);
1433
1434 private:
1435 glu::ShaderProgram* generateShaders (void) const;
1436
1437 std::vector<deUint32> m_buffers;
1438 std::vector<Vec4> m_expectedColors;
1439 };
1440
UBOBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType)1441 UBOBindingRenderCase::UBOBindingRenderCase (Context& context,
1442 const char* name,
1443 const char* desc,
1444 ShaderType shaderType,
1445 TestType testType)
1446 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock")
1447 {
1448 }
1449
~UBOBindingRenderCase(void)1450 UBOBindingRenderCase::~UBOBindingRenderCase (void)
1451 {
1452 deinit();
1453 }
1454
init(void)1455 void UBOBindingRenderCase::init (void)
1456 {
1457 LayoutBindingRenderCase::init();
1458
1459 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1460 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
1461
1462 // Initialize UBOs and related data
1463 m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
1464 gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1465
1466 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1467 {
1468 m_expectedColors.push_back(getRandomColor(rnd));
1469 m_expectedColors.push_back(getRandomColor(rnd));
1470 }
1471
1472 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1473 {
1474 gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]);
1475 gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1476 gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1477 }
1478
1479 GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
1480 }
1481
deinit(void)1482 void UBOBindingRenderCase::deinit (void)
1483 {
1484 LayoutBindingRenderCase::deinit();
1485
1486 // Clean up UBO data
1487 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1488 {
1489 if (m_buffers[bufNdx])
1490 {
1491 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1492 m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
1493 }
1494 }
1495 }
1496
iterate(void)1497 TestCase::IterateResult UBOBindingRenderCase::iterate (void)
1498 {
1499 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1500 const int iterations = m_numBindings;
1501 const glw::GLenum prop = GL_BUFFER_BINDING;
1502 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1503 bool queryTestPassed = true;
1504 bool imageTestPassed = true;
1505
1506 // Set the viewport and enable the shader program
1507 initRenderState();
1508
1509 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1510 {
1511 // Query binding point
1512 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1513 const glw::GLint binding = m_bindings[iterNdx];
1514 glw::GLint val = -1;
1515
1516 gl.getProgramResourceiv(m_program->getProgram(), GL_UNIFORM_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_UNIFORM_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val);
1517 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1518 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1519
1520 if (val != binding)
1521 queryTestPassed = false;
1522
1523 // Draw twice to render both colors within the UBO
1524 for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
1525 {
1526 // Set the uniform indicating the array index to be used and set the expected color
1527 const int arrayNdx = iterNdx*2 + drawCycle;
1528 gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
1529
1530 if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1531 imageTestPassed = false;
1532 }
1533 }
1534
1535 setTestResult(queryTestPassed, imageTestPassed);
1536 return STOP;
1537 }
1538
generateShaders(void) const1539 glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
1540 {
1541 std::ostringstream shaderUniformDecl;
1542 std::ostringstream shaderBody;
1543 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1544 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1545
1546 // Generate the uniform declarations for the vertex and fragment shaders
1547 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1548 {
1549 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
1550 << getUniformName(m_uniformName, declNdx) << "\n"
1551 << "{\n"
1552 << " highp vec4 color1;\n"
1553 << " highp vec4 color2;\n"
1554 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1555 }
1556
1557 // Generate the shader body for the vertex and fragment shaders
1558 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO
1559 {
1560 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1561 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1562 << " {\n"
1563 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1564 << " }\n";
1565 }
1566
1567 shaderBody << " else\n"
1568 << " {\n"
1569 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1570 << " }\n";
1571
1572 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1573 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1574 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1575 }
1576
1577
1578 class UBOBindingNegativeCase : public LayoutBindingNegativeCase
1579 {
1580 public:
1581 UBOBindingNegativeCase (Context& context,
1582 const char* name,
1583 const char* desc,
1584 ShaderType shaderType,
1585 TestType testType,
1586 ErrorType errorType);
1587 ~UBOBindingNegativeCase (void);
1588
1589 private:
1590 glu::ShaderProgram* generateShaders (void) const;
1591 };
1592
UBOBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType)1593 UBOBindingNegativeCase::UBOBindingNegativeCase (Context& context,
1594 const char* name,
1595 const char* desc,
1596 ShaderType shaderType,
1597 TestType testType,
1598 ErrorType errorType)
1599 : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock")
1600 {
1601 }
1602
~UBOBindingNegativeCase(void)1603 UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
1604 {
1605 deinit();
1606 }
1607
generateShaders(void) const1608 glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
1609 {
1610 std::ostringstream vertexUniformDecl;
1611 std::ostringstream fragmentUniformDecl;
1612 std::ostringstream shaderBody;
1613 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1614 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1615
1616 // Generate the uniform declarations for the vertex and fragment shaders
1617 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1618 {
1619 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform "
1620 << getUniformName(m_uniformName, declNdx) << "\n"
1621 << "{\n"
1622 << " highp vec4 color1;\n"
1623 << " highp vec4 color2;\n"
1624 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1625
1626 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
1627 << getUniformName(m_uniformName, declNdx) << "\n"
1628 << "{\n"
1629 << " highp vec4 color1;\n"
1630 << " highp vec4 color2;\n"
1631 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1632 }
1633
1634 // Generate the shader body for the vertex and fragment shaders
1635 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO
1636 {
1637 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1638 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1639 << " {\n"
1640 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1641 << " }\n";
1642 }
1643
1644 shaderBody << " else\n"
1645 << " {\n"
1646 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1647 << " }\n";
1648
1649 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1650 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1651 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1652 }
1653
1654
1655 class SSBOBindingRenderCase : public LayoutBindingRenderCase
1656 {
1657 public:
1658 SSBOBindingRenderCase (Context& context,
1659 const char* name,
1660 const char* desc,
1661 ShaderType shaderType,
1662 TestType testType);
1663 ~SSBOBindingRenderCase (void);
1664
1665 void init (void);
1666 void deinit (void);
1667 IterateResult iterate (void);
1668
1669 private:
1670 glu::ShaderProgram* generateShaders (void) const;
1671
1672 std::vector<glw::GLuint> m_buffers;
1673 std::vector<Vec4> m_expectedColors;
1674 };
1675
SSBOBindingRenderCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType)1676 SSBOBindingRenderCase::SSBOBindingRenderCase (Context& context,
1677 const char* name,
1678 const char* desc,
1679 ShaderType shaderType,
1680 TestType testType)
1681 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer")
1682 {
1683 }
1684
~SSBOBindingRenderCase(void)1685 SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
1686 {
1687 deinit();
1688 }
1689
init(void)1690 void SSBOBindingRenderCase::init (void)
1691 {
1692 LayoutBindingRenderCase::init();
1693
1694 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1695 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
1696
1697 // Initialize SSBOs and related data
1698 m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
1699 gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
1700
1701 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1702 {
1703 m_expectedColors.push_back(getRandomColor(rnd));
1704 m_expectedColors.push_back(getRandomColor(rnd));
1705 }
1706
1707 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1708 {
1709 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]);
1710 gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
1711 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
1712 }
1713
1714 GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
1715 }
1716
deinit(void)1717 void SSBOBindingRenderCase::deinit (void)
1718 {
1719 LayoutBindingRenderCase::deinit();
1720
1721 // Clean up SSBO data
1722 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1723 {
1724 if (m_buffers[bufNdx])
1725 {
1726 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1727 m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
1728 m_buffers[bufNdx] = 0;
1729 }
1730 }
1731 }
1732
iterate(void)1733 TestCase::IterateResult SSBOBindingRenderCase::iterate (void)
1734 {
1735 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1736 const int iterations = m_numBindings;
1737 const glw::GLenum prop = GL_BUFFER_BINDING;
1738 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1739 bool queryTestPassed = true;
1740 bool imageTestPassed = true;
1741
1742 initRenderState();
1743
1744 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1745 {
1746 // Query binding point
1747 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
1748 const glw::GLint binding = m_bindings[iterNdx];
1749 glw::GLint val = -1;
1750
1751 gl.getProgramResourceiv(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val);
1752 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
1753 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
1754
1755 if (val != binding)
1756 queryTestPassed = false;
1757
1758 // Draw twice to render both colors within the SSBO
1759 for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
1760 {
1761 // Set the uniform indicating the array index to be used and set the expected color
1762 const int arrayNdx = iterNdx*2 + drawCycle;
1763 gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
1764
1765 if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1766 imageTestPassed = false;
1767 }
1768 }
1769
1770 setTestResult(queryTestPassed, imageTestPassed);
1771 return STOP;
1772 }
1773
generateShaders(void) const1774 glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
1775 {
1776 std::ostringstream shaderUniformDecl;
1777 std::ostringstream shaderBody;
1778 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1779 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1780
1781 // Generate the uniform declarations for the vertex and fragment shaders
1782 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1783 {
1784 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
1785 << getUniformName(m_uniformName, declNdx) << "\n"
1786 << "{\n"
1787 << " highp vec4 color1;\n"
1788 << " highp vec4 color2;\n"
1789 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1790 }
1791
1792 // Generate the shader body for the vertex and fragment shaders
1793 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO
1794 {
1795 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1796 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1797 << " {\n"
1798 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1799 << " }\n";
1800 }
1801
1802 shaderBody << " else\n"
1803 << " {\n"
1804 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1805 << " }\n";
1806
1807 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1808 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
1809 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
1810 }
1811
1812
1813 class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
1814 {
1815 public:
1816 SSBOBindingNegativeCase (Context& context,
1817 const char* name,
1818 const char* desc,
1819 ShaderType shaderType,
1820 TestType testType,
1821 ErrorType errorType);
1822 ~SSBOBindingNegativeCase (void);
1823
1824 private:
1825 glu::ShaderProgram* generateShaders (void) const;
1826 };
1827
SSBOBindingNegativeCase(Context & context,const char * name,const char * desc,ShaderType shaderType,TestType testType,ErrorType errorType)1828 SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
1829 const char* name,
1830 const char* desc,
1831 ShaderType shaderType,
1832 TestType testType,
1833 ErrorType errorType)
1834 : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer")
1835 {
1836 }
1837
~SSBOBindingNegativeCase(void)1838 SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
1839 {
1840 deinit();
1841 }
1842
generateShaders(void) const1843 glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
1844 {
1845 std::ostringstream vertexUniformDecl;
1846 std::ostringstream fragmentUniformDecl;
1847 std::ostringstream shaderBody;
1848 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
1849 const int numDeclarations = (arrayInstance ? 1 : m_numBindings);
1850
1851 // Generate the uniform declarations for the vertex and fragment shaders
1852 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1853 {
1854 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer "
1855 << getUniformName(m_uniformName, declNdx) << "\n"
1856 << "{\n"
1857 << " highp vec4 color1;\n"
1858 << " highp vec4 color2;\n"
1859 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1860
1861 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
1862 << getUniformName(m_uniformName, declNdx) << "\n"
1863 << "{\n"
1864 << " highp vec4 color1;\n"
1865 << " highp vec4 color2;\n"
1866 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1867 }
1868
1869 // Generate the shader body for the vertex and fragment shaders
1870 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO
1871 {
1872 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
1873 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1874 << " {\n"
1875 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1876 << " }\n";
1877 }
1878
1879 shaderBody << " else\n"
1880 << " {\n"
1881 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1882 << " }\n";
1883
1884 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1885 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
1886 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
1887 }
1888
1889
1890 } // Anonymous
1891
LayoutBindingTests(Context & context)1892 LayoutBindingTests::LayoutBindingTests (Context& context)
1893 : TestCaseGroup (context, "layout_binding", "Layout binding tests")
1894 {
1895 }
1896
~LayoutBindingTests(void)1897 LayoutBindingTests::~LayoutBindingTests (void)
1898 {
1899 }
1900
init(void)1901 void LayoutBindingTests::init (void)
1902 {
1903 // Render test groups
1904 tcu::TestCaseGroup* const samplerBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Test sampler layout binding");
1905 tcu::TestCaseGroup* const sampler2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler2d", "Test sampler2d layout binding");
1906 tcu::TestCaseGroup* const sampler3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler3d", "Test sampler3d layout binding");
1907
1908 tcu::TestCaseGroup* const imageBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image", "Test image layout binding");
1909 tcu::TestCaseGroup* const image2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image2d", "Test image2d layout binding");
1910 tcu::TestCaseGroup* const image3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image3d", "Test image3d layout binding");
1911
1912 tcu::TestCaseGroup* const UBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ubo", "Test UBO layout binding");
1913 tcu::TestCaseGroup* const SSBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ssbo", "Test SSBO layout binding");
1914
1915 // Negative test groups
1916 tcu::TestCaseGroup* const negativeBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "negative", "Test layout binding with invalid bindings");
1917
1918 tcu::TestCaseGroup* const negativeSamplerBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Test sampler layout binding with invalid bindings");
1919 tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler2d", "Test sampler2d layout binding with invalid bindings");
1920 tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler3d", "Test sampler3d layout binding with invalid bindings");
1921
1922 tcu::TestCaseGroup* const negativeImageBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image", "Test image layout binding with invalid bindings");
1923 tcu::TestCaseGroup* const negativeImage2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image2d", "Test image2d layout binding with invalid bindings");
1924 tcu::TestCaseGroup* const negativeImage3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image3d", "Test image3d layout binding with invalid bindings");
1925
1926 tcu::TestCaseGroup* const negativeUBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ubo", "Test UBO layout binding with invalid bindings");
1927 tcu::TestCaseGroup* const negativeSSBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ssbo", "Test SSBO layout binding with invalid bindings");
1928
1929 static const struct RenderTestType
1930 {
1931 ShaderType shaderType;
1932 TestType testType;
1933 std::string name;
1934 std::string descPostfix;
1935 } s_renderTestTypes[] =
1936 {
1937 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, "vertex_binding_single", "a single instance" },
1938 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MAX, "vertex_binding_max", "maximum binding point" },
1939 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MULTIPLE, "vertex_binding_multiple", "multiple instances"},
1940 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, "vertex_binding_array", "an array instance" },
1941 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MAX_ARRAY, "vertex_binding_max_array", "an array instance with maximum binding point" },
1942
1943 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, "fragment_binding_single", "a single instance" },
1944 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MAX, "fragment_binding_max", "maximum binding point" },
1945 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MULTIPLE, "fragment_binding_multiple", "multiple instances"},
1946 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, "fragment_binding_array", "an array instance" },
1947 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MAX_ARRAY, "fragment_binding_max_array", "an array instance with maximum binding point" },
1948 };
1949
1950 static const struct NegativeTestType
1951 {
1952 ShaderType shaderType;
1953 TestType testType;
1954 LayoutBindingNegativeCase::ErrorType errorType;
1955 std::string name;
1956 std::string descPostfix;
1957 } s_negativeTestTypes[] =
1958 {
1959 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "vertex_binding_over_max", "over maximum binding point"},
1960 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "fragment_binding_over_max", "over maximum binding point"},
1961 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "vertex_binding_neg", "negative binding point"},
1962 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "fragment_binding_neg", "negative binding point"},
1963
1964 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "vertex_binding_over_max_array", "over maximum binding point"},
1965 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "fragment_binding_over_max_array", "over maximum binding point"},
1966 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "vertex_binding_neg_array", "negative binding point"},
1967 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "fragment_binding_neg_array", "negative binding point"},
1968
1969 { SHADERTYPE_BOTH, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY, "binding_contradictory", "contradictory binding points"},
1970 { SHADERTYPE_BOTH, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY, "binding_contradictory_array", "contradictory binding points"},
1971 };
1972
1973 // Render tests
1974 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
1975 {
1976 const RenderTestType& test = s_renderTestTypes[testNdx];
1977
1978 // Render sampler binding tests
1979 sampler2dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_2D, GL_TEXTURE_2D));
1980 sampler3dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_3D, GL_TEXTURE_3D));
1981
1982 // Render image binding tests
1983 image2dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_2D, GL_TEXTURE_2D));
1984 image3dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_3D, GL_TEXTURE_3D));
1985
1986 // Render UBO binding tests
1987 UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
1988
1989 // Render SSBO binding tests
1990 SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
1991 }
1992
1993 // Negative binding tests
1994 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
1995 {
1996 const NegativeTestType& test = s_negativeTestTypes[testNdx];
1997
1998 // Negative sampler binding tests
1999 negativeSampler2dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_2D));
2000 negativeSampler3dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_3D));
2001
2002 // Negative image binding tests
2003 negativeImage2dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_2D));
2004 negativeImage3dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_3D));
2005
2006 // Negative UBO binding tests
2007 negativeUBOBindingTestGroup->addChild(new UBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid UBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType));
2008
2009 // Negative SSBO binding tests
2010 negativeSSBOBindingTestGroup->addChild(new SSBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid SSBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType));
2011 }
2012
2013 samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
2014 samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);
2015
2016 imageBindingTestGroup->addChild(image2dBindingTestGroup);
2017 imageBindingTestGroup->addChild(image3dBindingTestGroup);
2018
2019 negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
2020 negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);
2021
2022 negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
2023 negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);
2024
2025 negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
2026 negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
2027 negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
2028 negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);
2029
2030 addChild(samplerBindingTestGroup);
2031 addChild(UBOBindingTestGroup);
2032 addChild(SSBOBindingTestGroup);
2033 addChild(imageBindingTestGroup);
2034 addChild(negativeBindingTestGroup);
2035 }
2036
2037 } // Functional
2038 } // gles31
2039 } // deqp
2040