1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Basic Layout Binding Tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fLayoutBindingTests.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "gluPixelTransfer.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "gluContextInfo.hpp"
31 #include "glwFunctions.hpp"
32 #include "glwEnums.hpp"
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"
43 #include "deStringUtil.hpp"
44 #include "deRandom.hpp"
62 TESTTYPE_BINDING_SINGLE = 0,
64 TESTTYPE_BINDING_MULTIPLE,
65 TESTTYPE_BINDING_ARRAY,
66 TESTTYPE_BINDING_MAX_ARRAY,
68 TESTTYPE_BINDING_LAST,
73 SHADERTYPE_VERTEX = 0,
75 SHADERTYPE_TESS_CONTROL,
76 SHADERTYPE_TESS_EVALUATION,
84 MAX_UNIFORM_MULTIPLE_INSTANCES = 7,
85 MAX_UNIFORM_ARRAY_SIZE = 7,
88 std::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
90 static const char* const s_simpleVertexShaderSource = "#version 310 es\n"
91 "in highp vec4 a_position;\n"
94 " gl_Position = a_position;\n"
99 case SHADERTYPE_VERTEX:
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"
110 << " highp vec4 color;\n\n"
111 << shaderBody << "\n"
112 << " v_color = color;\n"
113 << " gl_Position = a_position;\n"
116 return vertexShaderSource.str();
119 case SHADERTYPE_FRAGMENT:
120 case SHADERTYPE_TESS_CONTROL:
121 case SHADERTYPE_TESS_EVALUATION:
122 return s_simpleVertexShaderSource;
130 std::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
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"
137 " fragColor = v_color;\n"
142 case SHADERTYPE_VERTEX:
143 case SHADERTYPE_TESS_CONTROL:
144 case SHADERTYPE_TESS_EVALUATION:
145 return s_simpleFragmentShaderSource;
147 case SHADERTYPE_FRAGMENT:
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"
156 << " highp vec4 color;\n\n"
157 << shaderBody << "\n"
158 << " fragColor = color;\n"
161 return fragmentShaderSource.str();
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"
173 << " if (v_color.x > 2.0) discard;\n"
174 << " highp vec4 color;\n\n"
175 << shaderBody << "\n"
176 << " fragColor = color;\n"
179 return fragmentShaderSource.str();
188 std::string generateTessControlShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
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"
196 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
201 case SHADERTYPE_VERTEX:
202 case SHADERTYPE_FRAGMENT:
203 case SHADERTYPE_TESS_EVALUATION:
204 return s_simpleTessContorlShaderSource;
206 case SHADERTYPE_TESS_CONTROL:
209 std::ostringstream tessControlShaderSource;
210 tessControlShaderSource << "#version 310 es\n"
211 << "#extension GL_EXT_tessellation_shader : require\n"
212 << "layout (vertices=3) out;\n"
214 << "uniform highp int u_arrayNdx;\n\n"
215 << shaderUniformDeclarations << "\n"
216 << "void main (void)\n"
218 << " highp vec4 color;\n\n"
219 << shaderBody << "\n"
220 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
223 return tessControlShaderSource.str();
232 std::string generateTessEvaluationShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
234 static const char* const s_simpleTessEvaluationShaderSource = "#version 310 es\n"
235 "#extension GL_EXT_tessellation_shader : require\n"
236 "layout (triangles) in;\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"
245 case SHADERTYPE_VERTEX:
246 case SHADERTYPE_FRAGMENT:
247 case SHADERTYPE_TESS_CONTROL:
248 return s_simpleTessEvaluationShaderSource;
250 case SHADERTYPE_TESS_EVALUATION:
253 std::ostringstream tessEvaluationShaderSource;
254 tessEvaluationShaderSource << "#version 310 es\n"
255 << "#extension GL_EXT_tessellation_shader : require\n"
256 << "layout (triangles) in;\n"
258 << "uniform highp int u_arrayNdx;\n\n"
259 << shaderUniformDeclarations << "\n"
260 << "out mediump vec4 v_color;\n"
261 << "void main (void)\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"
269 return tessEvaluationShaderSource.str();
278 std::string getUniformName (const std::string& name, int declNdx)
280 return name + de::toString(declNdx);
283 std::string getUniformName (const std::string& name, int declNdx, int arrNdx)
285 return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
288 Vec4 getRandomColor (de::Random& rnd)
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);
296 class LayoutBindingRenderCase : public TestCase
301 MAX_TEST_RENDER_WIDTH = 256,
302 MAX_TEST_RENDER_HEIGHT = 256,
303 TEST_TEXTURE_SIZE = 1,
306 LayoutBindingRenderCase (Context& context,
309 ShaderType shaderType,
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);
318 virtual void init (void);
319 virtual void deinit (void);
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()); }
324 virtual glu::ShaderProgram* generateShaders (void) const = 0;
326 void initRenderState (void);
327 bool drawAndVerifyResult (const Vec4& expectedColor);
328 void setTestResult (bool queryTestPassed, bool imageTestPassed);
330 const glu::ShaderProgram* m_program;
331 const ShaderType m_shaderType;
332 const TestType m_testType;
333 const std::string m_uniformName;
335 const glw::GLenum m_maxBindingPointEnum;
336 const glw::GLenum m_maxVertexUnitsEnum;
337 const glw::GLenum m_maxFragmentUnitsEnum;
338 const glw::GLenum m_maxCombinedUnitsEnum;
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;
347 std::vector<glw::GLint> m_bindings;
350 void initBindingPoints (int minBindingPoint, int numBindingPoints);
353 LayoutBindingRenderCase::LayoutBindingRenderCase (Context& context,
356 ShaderType shaderType,
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)
374 , m_shaderProgramLoc (0)
375 , m_shaderProgramPosLoc (0)
376 , m_shaderProgramArrayNdxLoc (0)
381 LayoutBindingRenderCase::~LayoutBindingRenderCase (void)
386 void LayoutBindingRenderCase::init (void)
388 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
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
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");
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;
409 // Select maximum number of uniforms used for the test
410 switch (m_shaderType)
412 case SHADERTYPE_VERTEX:
413 maxUnits = maxVertexUnits;
416 case SHADERTYPE_FRAGMENT:
417 maxUnits = maxFragmentUnits;
421 maxUnits = maxCombinedUnits/2;
428 // Select the number of uniforms (= bindings) used for this test
431 case TESTTYPE_BINDING_SINGLE:
432 case TESTTYPE_BINDING_MAX:
436 case TESTTYPE_BINDING_MULTIPLE:
438 throw tcu::NotSupportedError("Not enough uniforms available for test");
439 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits));
442 case TESTTYPE_BINDING_ARRAY:
443 case TESTTYPE_BINDING_MAX_ARRAY:
445 throw tcu::NotSupportedError("Not enough uniforms available for test");
446 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
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");
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");
465 // Initialize the binding points i.e. populate the two binding point vectors
466 initBindingPoints(0, numBindingPoints);
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;
475 if (!m_program->isOk())
476 throw tcu::TestError("Shader compile failed");
478 // Setup vertex and index buffers
480 // Get attribute and uniform locations
481 const deUint32 program = m_program->getProgram();
483 m_shaderProgramPosLoc = gl.getAttribLocation(program, "a_position");
484 m_shaderProgramArrayNdxLoc = gl.getUniformLocation(program, "u_arrayNdx");
488 // Setup buffers so that we render one quad covering the whole viewport
489 const Vec3 vertices[] =
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),
497 const deUint16 indices[] =
503 TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0));
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");
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");
521 void LayoutBindingRenderCase::deinit (void)
529 if (m_shaderProgramPosLoc)
530 m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc);
534 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
535 m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0);
540 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
541 m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
545 void LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
547 de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
551 case TESTTYPE_BINDING_SINGLE:
553 const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1);
554 m_bindings.push_back(bpoint);
558 case TESTTYPE_BINDING_MAX:
559 m_bindings.push_back(numBindingPoints-1);
562 case TESTTYPE_BINDING_MULTIPLE:
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;
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);
573 rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end());
574 rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end());
576 for (int ndx = 0; ndx < m_numBindings; ++ndx)
580 const int bpoint = lowBindingPoints.back();
581 lowBindingPoints.pop_back();
582 m_bindings.push_back(bpoint);
586 const int bpoint = highBindingPoints.back();
587 highBindingPoints.pop_back();
588 m_bindings.push_back(bpoint);
595 case TESTTYPE_BINDING_ARRAY:
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);
603 case TESTTYPE_BINDING_MAX_ARRAY:
605 const glw::GLint binding = numBindingPoints-m_numBindings;
606 for (int ndx = 0; ndx < m_numBindings; ++ndx)
607 m_bindings.push_back(binding+ndx);
616 void LayoutBindingRenderCase::initRenderState (void)
618 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
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");
626 bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
628 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
629 tcu::Surface reference (getRenderWidth(), getRenderHeight());
631 // the point of these test is to check layout_binding. For this purpose, we can use quite
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));
639 gl.clear(GL_COLOR_BUFFER_BIT);
642 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
643 GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
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");
651 tcu::clear(reference.getAccess(), expectedColor);
652 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;
654 return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
657 void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
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");
666 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
669 class LayoutBindingNegativeCase : public TestCase
674 ERRORTYPE_OVER_MAX_UNITS = 0,
675 ERRORTYPE_LESS_THAN_ZERO,
676 ERRORTYPE_CONTRADICTORY,
681 LayoutBindingNegativeCase (Context& context,
684 ShaderType shaderType,
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);
696 virtual void init (void);
697 virtual void deinit (void);
698 virtual IterateResult iterate (void);
701 virtual glu::ShaderProgram* generateShaders (void) const = 0;
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;
722 void initBindingPoints (int minBindingPoint, int numBindingPoints);
725 LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context& context,
728 ShaderType shaderType,
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)
751 , m_tessSupport (false)
755 LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
760 void LayoutBindingNegativeCase::init (void)
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
773 m_tessSupport = m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader")
774 || contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
776 if (!m_tessSupport && (m_shaderType == SHADERTYPE_TESS_EVALUATION || m_shaderType == SHADERTYPE_TESS_CONTROL))
777 TCU_THROW(NotSupportedError, "Tesselation shaders not supported");
779 int numShaderStages = m_tessSupport ? 4 : 2;
781 gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
782 gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
786 gl.getIntegerv(m_maxTessCtrlUnitsEnum, &maxTessCtrlUnits);
787 gl.getIntegerv(m_maxTessEvalUnitsEnum, &maxTessEvalUnits);
790 gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
791 gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
792 GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
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;
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;
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;
806 // Select maximum number of uniforms used for the test
807 switch (m_shaderType)
809 case SHADERTYPE_VERTEX:
810 maxUnits = maxVertexUnits;
813 case SHADERTYPE_FRAGMENT:
814 maxUnits = maxFragmentUnits;
818 maxUnits = de::min(de::min(de::min(maxVertexUnits, maxFragmentUnits), de::min(maxTessCtrlUnits, maxTessEvalUnits)), maxCombinedUnits/numShaderStages);
821 case SHADERTYPE_TESS_CONTROL:
822 maxUnits = maxTessCtrlUnits;
825 case SHADERTYPE_TESS_EVALUATION:
826 maxUnits = maxTessEvalUnits;
833 // Select the number of uniforms (= bindings) used for this test
836 case TESTTYPE_BINDING_SINGLE:
837 case TESTTYPE_BINDING_MAX:
841 case TESTTYPE_BINDING_MULTIPLE:
842 case TESTTYPE_BINDING_ARRAY:
843 case TESTTYPE_BINDING_MAX_ARRAY:
844 if (m_errorType == ERRORTYPE_CONTRADICTORY)
846 // leave room for contradictory case
848 TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
849 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
854 TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
855 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
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");
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");
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");
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");
876 if ((m_shaderType == SHADERTYPE_ALL) && (maxCombinedUnits < m_numBindings*numShaderStages) )
877 TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
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");
883 if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
884 TCU_THROW(NotSupportedError, "Not enough binding points available for test");
886 // Initialize the binding points i.e. populate the two binding point vectors
887 initBindingPoints(0, numBindingPoints);
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;
896 void LayoutBindingNegativeCase::deinit (void)
905 TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
908 std::string failMessage;
912 case ERRORTYPE_CONTRADICTORY: // Contradictory binding points should cause a link-time error
913 if (!(m_program->getProgramInfo()).linkOk)
915 failMessage = "Test failed - expected a link-time error";
918 case ERRORTYPE_LESS_THAN_ZERO: // Out of bounds binding points should cause a compile-time error
919 case ERRORTYPE_OVER_MAX_UNITS:
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)
930 if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk
931 || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk))
935 failMessage = "Test failed - expected a compile-time error";
943 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
945 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());
950 void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
952 de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
956 case ERRORTYPE_OVER_MAX_UNITS: // Select a binding point that is 1 over the maximum
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);
965 case ERRORTYPE_LESS_THAN_ZERO: // Select a random negative binding point
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);
975 case ERRORTYPE_CONTRADICTORY: // Select two valid, but contradictory binding points
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);
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());
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)
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);
1005 class SamplerBindingRenderCase : public LayoutBindingRenderCase
1008 SamplerBindingRenderCase (Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
1009 ~SamplerBindingRenderCase (void);
1013 IterateResult iterate (void);
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;
1020 const glw::GLenum m_samplerType;
1021 const glw::GLenum m_textureType;
1023 std::vector<glw::GLuint> m_textures;
1024 std::vector<Vec4> m_textureColors;
1028 SamplerBindingRenderCase::SamplerBindingRenderCase (Context& context,
1031 ShaderType shaderType,
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)
1041 SamplerBindingRenderCase::~SamplerBindingRenderCase (void)
1046 void SamplerBindingRenderCase::init (void)
1048 LayoutBindingRenderCase::init();
1049 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1050 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
1053 // Initialize texture resources
1054 m_textures = std::vector<glw::GLuint>(m_numBindings, 0);
1057 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1058 m_textureColors.push_back(getRandomColor(rnd));
1061 gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);
1063 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1064 initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);
1066 gl.activeTexture(GL_TEXTURE0);
1069 void SamplerBindingRenderCase::deinit(void)
1071 LayoutBindingRenderCase::deinit();
1073 // Clean up texture data
1074 for (int i = 0; i < (int)m_textures.size(); ++i)
1078 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
1079 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1084 TestCase::IterateResult SamplerBindingRenderCase::iterate (void)
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;
1092 // Set the viewport and enable the shader program
1095 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1097 // Set the uniform value indicating the current array index
1098 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
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;
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");
1111 queryTestPassed = false;
1112 if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1113 imageTestPassed = false;
1116 setTestResult(queryTestPassed, imageTestPassed);
1120 glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
1122 std::ostringstream shaderUniformDecl;
1123 std::ostringstream shaderBody;
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;
1130 // Generate the uniform declarations for the vertex and fragment shaders
1131 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1133 shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
1134 << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
1137 // Generate the shader body for the vertex and fragment shaders
1138 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1140 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1142 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1146 shaderBody << " else\n"
1148 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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())));
1156 void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
1158 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1160 gl.activeTexture(GL_TEXTURE0 + bindingPoint);
1161 gl.bindTexture(m_textureType, textureName);
1162 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1164 switch (m_textureType)
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());
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());
1186 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
1189 glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
1191 switch (m_samplerType)
1194 return glu::TYPE_FLOAT_VEC2;
1197 return glu::TYPE_FLOAT_VEC3;
1201 return glu::TYPE_INVALID;
1206 class SamplerBindingNegativeCase : public LayoutBindingNegativeCase
1209 SamplerBindingNegativeCase (Context& context,
1212 ShaderType shaderType,
1214 ErrorType errorType,
1215 glw::GLenum samplerType);
1216 ~SamplerBindingNegativeCase (void);
1219 glu::ShaderProgram* generateShaders (void) const;
1220 glu::DataType getSamplerTexCoordType (void) const;
1222 const glw::GLenum m_samplerType;
1225 SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context& context,
1228 ShaderType shaderType,
1230 ErrorType errorType,
1231 glw::GLenum samplerType)
1232 : LayoutBindingNegativeCase (context,
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,
1245 , m_samplerType (samplerType)
1249 SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
1251 LayoutBindingNegativeCase::deinit();
1254 glu::ShaderProgram* SamplerBindingNegativeCase::generateShaders (void) const
1256 std::ostringstream vertexUniformDecl;
1257 std::ostringstream fragmentUniformDecl;
1258 std::ostringstream tessCtrlUniformDecl;
1259 std::ostringstream tessEvalUniformDecl;
1260 std::ostringstream shaderBody;
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;
1267 // Generate the uniform declarations for the vertex and fragment shaders
1268 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
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";
1280 // Generate the shader body for the vertex and fragment shaders
1281 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1283 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1285 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
1289 shaderBody << " else\n"
1291 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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()));
1299 sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1300 << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1302 return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1306 glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
1308 switch (m_samplerType)
1311 return glu::TYPE_FLOAT_VEC2;
1314 return glu::TYPE_FLOAT_VEC3;
1318 return glu::TYPE_INVALID;
1322 class ImageBindingRenderCase : public LayoutBindingRenderCase
1325 ImageBindingRenderCase (Context& context,
1328 ShaderType shaderType,
1330 glw::GLenum imageType,
1331 glw::GLenum textureType);
1332 ~ImageBindingRenderCase (void);
1336 IterateResult iterate (void);
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;
1343 const glw::GLenum m_imageType;
1344 const glw::GLenum m_textureType;
1346 std::vector<glw::GLuint> m_textures;
1347 std::vector<Vec4> m_textureColors;
1351 ImageBindingRenderCase::ImageBindingRenderCase (Context& context,
1354 ShaderType shaderType,
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)
1364 ImageBindingRenderCase::~ImageBindingRenderCase (void)
1369 void ImageBindingRenderCase::init (void)
1371 LayoutBindingRenderCase::init();
1373 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1374 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
1376 // Initialize image / texture resources
1377 m_textures = std::vector<glw::GLuint>(m_numBindings, 0);
1380 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1381 m_textureColors.push_back(getRandomColor(rnd));
1384 gl.genTextures(m_numBindings, &m_textures[0]);
1386 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1387 initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
1390 void ImageBindingRenderCase::deinit (void)
1392 LayoutBindingRenderCase::deinit();
1394 // Clean up texture data
1395 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
1397 if (m_textures[texNdx])
1399 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
1400 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
1405 TestCase::IterateResult ImageBindingRenderCase::iterate (void)
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;
1413 // Set the viewport and enable the shader program
1416 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
1418 // Set the uniform value indicating the current array index
1419 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
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;
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");
1431 queryTestPassed = false;
1432 if (!drawAndVerifyResult(m_textureColors[iterNdx]))
1433 imageTestPassed = false;
1436 setTestResult(queryTestPassed, imageTestPassed);
1440 void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
1442 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1444 gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
1445 gl.bindTexture(m_textureType, textureName);
1446 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1448 switch (m_textureType)
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());
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());
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");
1477 glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
1479 std::ostringstream shaderUniformDecl;
1480 std::ostringstream shaderBody;
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);
1487 // Generate the uniform declarations for the vertex and fragment shaders
1488 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
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";
1494 // Generate the shader body for the vertex and fragment shaders
1495 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1497 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1499 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1503 shaderBody << " else\n"
1505 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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())));
1513 glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
1515 switch (m_imageType)
1518 return glu::TYPE_INT_VEC2;
1521 return glu::TYPE_INT_VEC3;
1525 return glu::TYPE_INVALID;
1530 class ImageBindingNegativeCase : public LayoutBindingNegativeCase
1533 ImageBindingNegativeCase (Context& context,
1536 ShaderType shaderType,
1538 ErrorType errorType,
1539 glw::GLenum imageType);
1540 ~ImageBindingNegativeCase (void);
1543 glu::ShaderProgram* generateShaders (void) const;
1544 glu::DataType getImageTexCoordType (void) const;
1546 const glw::GLenum m_imageType;
1549 ImageBindingNegativeCase::ImageBindingNegativeCase (Context& context,
1552 ShaderType shaderType,
1554 ErrorType errorType,
1555 glw::GLenum imageType)
1556 : LayoutBindingNegativeCase (context,
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,
1569 , m_imageType (imageType)
1573 ImageBindingNegativeCase::~ImageBindingNegativeCase (void)
1578 glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
1580 std::ostringstream vertexUniformDecl;
1581 std::ostringstream fragmentUniformDecl;
1582 std::ostringstream tessCtrlUniformDecl;
1583 std::ostringstream tessEvalUniformDecl;
1584 std::ostringstream shaderBody;
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);
1591 // Generate the uniform declarations for the vertex and fragment shaders
1592 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
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";
1604 // Generate the shader body for the vertex and fragment shaders
1605 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
1607 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
1609 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
1613 shaderBody << " else\n"
1615 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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()));
1623 sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1624 << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1626 return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1629 glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
1631 switch (m_imageType)
1634 return glu::TYPE_INT_VEC2;
1637 return glu::TYPE_INT_VEC3;
1641 return glu::TYPE_INVALID;
1646 class UBOBindingRenderCase : public LayoutBindingRenderCase
1649 UBOBindingRenderCase (Context& context,
1652 ShaderType shaderType,
1654 ~UBOBindingRenderCase (void);
1658 IterateResult iterate (void);
1661 glu::ShaderProgram* generateShaders (void) const;
1663 std::vector<deUint32> m_buffers;
1664 std::vector<Vec4> m_expectedColors;
1667 UBOBindingRenderCase::UBOBindingRenderCase (Context& context,
1670 ShaderType shaderType,
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")
1676 UBOBindingRenderCase::~UBOBindingRenderCase (void)
1681 void UBOBindingRenderCase::init (void)
1683 LayoutBindingRenderCase::init();
1685 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1686 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
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]);
1692 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1694 m_expectedColors.push_back(getRandomColor(rnd));
1695 m_expectedColors.push_back(getRandomColor(rnd));
1698 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
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]);
1705 GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
1708 void UBOBindingRenderCase::deinit (void)
1710 LayoutBindingRenderCase::deinit();
1712 // Clean up UBO data
1713 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1715 if (m_buffers[bufNdx])
1717 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
1718 m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
1723 TestCase::IterateResult UBOBindingRenderCase::iterate (void)
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;
1732 // Set the viewport and enable the shader program
1735 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
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;
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");
1747 queryTestPassed = false;
1749 // Draw twice to render both colors within the UBO
1750 for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
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);
1756 if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
1757 imageTestPassed = false;
1761 setTestResult(queryTestPassed, imageTestPassed);
1765 glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
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);
1772 // Generate the uniform declarations for the vertex and fragment shaders
1773 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1775 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
1776 << getUniformName(m_uniformName, declNdx) << "\n"
1778 << " highp vec4 color1;\n"
1779 << " highp vec4 color2;\n"
1780 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
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
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"
1789 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1793 shaderBody << " else\n"
1795 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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())));
1804 class UBOBindingNegativeCase : public LayoutBindingNegativeCase
1807 UBOBindingNegativeCase (Context& context,
1810 ShaderType shaderType,
1812 ErrorType errorType);
1813 ~UBOBindingNegativeCase (void);
1816 glu::ShaderProgram* generateShaders (void) const;
1819 UBOBindingNegativeCase::UBOBindingNegativeCase (Context& context,
1822 ShaderType shaderType,
1824 ErrorType errorType)
1825 : LayoutBindingNegativeCase(context,
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,
1841 UBOBindingNegativeCase::~UBOBindingNegativeCase (void)
1846 glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
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);
1856 // Generate the uniform declarations for the vertex and fragment shaders
1857 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
1859 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform "
1860 << getUniformName(m_uniformName, declNdx) << "\n"
1862 << " highp vec4 color1;\n"
1863 << " highp vec4 color2;\n"
1864 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1866 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
1867 << getUniformName(m_uniformName, declNdx) << "\n"
1869 << " highp vec4 color1;\n"
1870 << " highp vec4 color2;\n"
1871 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1873 tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
1874 << getUniformName(m_uniformName, declNdx) << "\n"
1876 << " highp vec4 color1;\n"
1877 << " highp vec4 color2;\n"
1878 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
1880 tessEvalUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
1881 << getUniformName(m_uniformName, declNdx) << "\n"
1883 << " highp vec4 color1;\n"
1884 << " highp vec4 color2;\n"
1885 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
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
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"
1894 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
1898 shaderBody << " else\n"
1900 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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()));
1908 sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
1909 << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
1911 return new glu::ShaderProgram(m_context.getRenderContext(), sources);
1915 class SSBOBindingRenderCase : public LayoutBindingRenderCase
1918 SSBOBindingRenderCase (Context& context,
1921 ShaderType shaderType,
1923 ~SSBOBindingRenderCase (void);
1927 IterateResult iterate (void);
1930 glu::ShaderProgram* generateShaders (void) const;
1932 std::vector<glw::GLuint> m_buffers;
1933 std::vector<Vec4> m_expectedColors;
1936 SSBOBindingRenderCase::SSBOBindingRenderCase (Context& context,
1939 ShaderType shaderType,
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")
1945 SSBOBindingRenderCase::~SSBOBindingRenderCase (void)
1950 void SSBOBindingRenderCase::init (void)
1952 LayoutBindingRenderCase::init();
1954 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1955 de::Random rnd (deStringHash(getName()) ^ 0xff23a4);
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]);
1961 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1963 m_expectedColors.push_back(getRandomColor(rnd));
1964 m_expectedColors.push_back(getRandomColor(rnd));
1967 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
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]);
1974 GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
1977 void SSBOBindingRenderCase::deinit (void)
1979 LayoutBindingRenderCase::deinit();
1981 // Clean up SSBO data
1982 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1984 if (m_buffers[bufNdx])
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;
1993 TestCase::IterateResult SSBOBindingRenderCase::iterate (void)
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;
2004 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
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;
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");
2016 queryTestPassed = false;
2018 // Draw twice to render both colors within the SSBO
2019 for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
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);
2025 if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
2026 imageTestPassed = false;
2030 setTestResult(queryTestPassed, imageTestPassed);
2034 glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
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);
2041 // Generate the uniform declarations for the vertex and fragment shaders
2042 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
2044 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
2045 << getUniformName(m_uniformName, declNdx) << "\n"
2047 << " highp vec4 color1;\n"
2048 << " highp vec4 color2;\n"
2049 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
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
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"
2058 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
2062 shaderBody << " else\n"
2064 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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())));
2073 class SSBOBindingNegativeCase : public LayoutBindingNegativeCase
2076 SSBOBindingNegativeCase (Context& context,
2079 ShaderType shaderType,
2081 ErrorType errorType);
2082 ~SSBOBindingNegativeCase (void);
2085 glu::ShaderProgram* generateShaders (void) const;
2088 SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
2091 ShaderType shaderType,
2093 ErrorType errorType)
2094 : LayoutBindingNegativeCase(context,
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,
2110 SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
2115 glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
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);
2125 // Generate the uniform declarations for the vertex and fragment shaders
2126 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
2128 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer "
2129 << getUniformName(m_uniformName, declNdx) << "\n"
2131 << " highp vec4 color1;\n"
2132 << " highp vec4 color2;\n"
2133 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2135 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
2136 << getUniformName(m_uniformName, declNdx) << "\n"
2138 << " highp vec4 color1;\n"
2139 << " highp vec4 color2;\n"
2140 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2142 tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") buffer "
2143 << getUniformName(m_uniformName, declNdx) << "\n"
2145 << " highp vec4 color1;\n"
2146 << " highp vec4 color2;\n"
2147 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
2149 tessEvalUniformDecl << "layout(std140, binding = " << m_tessEvalShaderBinding[declNdx] << ") buffer "
2150 << getUniformName(m_uniformName, declNdx) << "\n"
2152 << " highp vec4 color1;\n"
2153 << " highp vec4 color2;\n"
2154 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
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
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"
2163 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
2167 shaderBody << " else\n"
2169 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n"
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()));
2177 sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
2178 << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
2180 return new glu::ShaderProgram(m_context.getRenderContext(), sources);
2186 LayoutBindingTests::LayoutBindingTests (Context& context)
2187 : TestCaseGroup (context, "layout_binding", "Layout binding tests")
2191 LayoutBindingTests::~LayoutBindingTests (void)
2195 void LayoutBindingTests::init (void)
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");
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");
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");
2209 // Negative test groups
2210 tcu::TestCaseGroup* const negativeBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "negative", "Test layout binding with invalid bindings");
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");
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");
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");
2223 static const struct RenderTestType
2225 ShaderType shaderType;
2228 std::string descPostfix;
2229 } s_renderTestTypes[] =
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" },
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" },
2244 static const struct NegativeTestType
2246 ShaderType shaderType;
2248 LayoutBindingNegativeCase::ErrorType errorType;
2250 std::string descPostfix;
2251 } s_negativeTestTypes[] =
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" },
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" },
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" },
2276 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
2278 const RenderTestType& test = s_renderTestTypes[testNdx];
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));
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));
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));
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));
2295 // Negative binding tests
2296 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
2298 const NegativeTestType& test = s_negativeTestTypes[testNdx];
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));
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));
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));
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));
2315 samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
2316 samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);
2318 imageBindingTestGroup->addChild(image2dBindingTestGroup);
2319 imageBindingTestGroup->addChild(image3dBindingTestGroup);
2321 negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
2322 negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);
2324 negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
2325 negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);
2327 negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
2328 negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
2329 negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
2330 negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);
2332 addChild(samplerBindingTestGroup);
2333 addChild(UBOBindingTestGroup);
2334 addChild(SSBOBindingTestGroup);
2335 addChild(imageBindingTestGroup);
2336 addChild(negativeBindingTestGroup);