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