13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Basic Layout Binding Tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fLayoutBindingTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexture.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum TestType
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_SINGLE = 0,
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_MAX,
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_MULTIPLE,
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_ARRAY,
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_MAX_ARRAY,
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTTYPE_BINDING_LAST,
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ShaderType
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADERTYPE_VERTEX = 0,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADERTYPE_FRAGMENT,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADERTYPE_BOTH,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADERTYPE_LAST,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_UNIFORM_MULTIPLE_INSTANCES	= 7,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_UNIFORM_ARRAY_SIZE			= 7,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* const s_simpleVertexShaderSource	= 	"#version 310 es\n"
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"in highp vec4 a_position;\n"
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"void main (void)\n"
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"{\n"
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"	gl_Position = a_position;\n"
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"}\n";
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (shaderType)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_VERTEX:
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_BOTH:
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::ostringstream vertexShaderSource;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexShaderSource	<< 	"#version 310 es\n"
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	"in highp vec4 a_position;\n"
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	"out highp vec4 v_color;\n"
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	"uniform highp int u_arrayNdx;\n\n"
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	shaderUniformDeclarations << "\n"
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	"void main (void)\n"
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<<	"{\n"
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<<	"	highp vec4 color;\n\n"
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<< 	shaderBody << "\n"
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<<	"	v_color = color;\n"
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<<	"	gl_Position = a_position;\n"
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								<<	"}\n";
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vertexShaderSource.str();
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_FRAGMENT:
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return s_simpleVertexShaderSource;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* const s_simpleFragmentShaderSource = "#version 310 es\n"
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"in highp vec4 v_color;\n"
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"layout(location = 0) out highp vec4 fragColor;\n"
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"void main (void)\n"
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"{\n"
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"	fragColor = v_color;\n"
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															"}\n";
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (shaderType)
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_VERTEX:
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return s_simpleFragmentShaderSource;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_FRAGMENT:
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::ostringstream fragmentShaderSource;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentShaderSource	<<	"#version 310 es\n"
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"layout(location = 0) out highp vec4 fragColor;\n"
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"uniform highp int u_arrayNdx;\n\n"
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	shaderUniformDeclarations << "\n"
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"void main (void)\n"
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"{\n"
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"	highp vec4 color;\n\n"
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	shaderBody << "\n"
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"	fragColor = color;\n"
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"}\n";
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return fragmentShaderSource.str();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_BOTH:
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::ostringstream fragmentShaderSource;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentShaderSource	<<	"#version 310 es\n"
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"in highp vec4 v_color;\n"
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"layout(location = 0) out highp vec4 fragColor;\n"
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"uniform highp int u_arrayNdx;\n\n"
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	shaderUniformDeclarations << "\n"
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"void main (void)\n"
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"{\n"
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"	if (v_color.x > 2.0) discard;\n"
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"	highp vec4 color;\n\n"
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	shaderBody << "\n"
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"	fragColor = color;\n"
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<<	"}\n";
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return fragmentShaderSource.str();
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string getUniformName (const std::string& name, int declNdx)
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return name + de::toString(declNdx);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string getUniformName (const std::string& name, int declNdx, int arrNdx)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]";
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 getRandomColor (de::Random& rnd)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float r = rnd.getFloat(0.2f, 0.9f);
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float g = rnd.getFloat(0.2f, 0.9f);
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float b = rnd.getFloat(0.2f, 0.9f);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec4(r, g, b, 1.0f);
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LayoutBindingRenderCase : public TestCase
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_RENDER_WIDTH	= 256,
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_RENDER_HEIGHT	= 256,
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TEST_TEXTURE_SIZE	= 1,
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										LayoutBindingRenderCase			(Context&			context,
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*		name,
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*		desc,
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 ShaderType			shaderType,
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 TestType			testType,
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxBindingPointEnum,
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxVertexUnitsEnum,
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxFragmentUnitsEnum,
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxCombinedUnitsEnum,
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const std::string& uniformName);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual								~LayoutBindingRenderCase		(void);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void 						init							(void);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void 						deinit							(void);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								initRenderState					(void);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								drawAndVerifyResult				(const Vec4& expectedColor);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								setTestResult					(bool queryTestPassed, bool imageTestPassed);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*			m_program;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType					m_shaderType;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestType						m_testType;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string					m_uniformName;
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxBindingPointEnum;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxVertexUnitsEnum;
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxFragmentUnitsEnum;
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxCombinedUnitsEnum;
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLuint							m_vertexBuffer;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLuint							m_indexBuffer;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint							m_shaderProgramLoc;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint							m_shaderProgramPosLoc;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint							m_shaderProgramArrayNdxLoc;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint							m_numBindings;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLint>				m_bindings;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingRenderCase::LayoutBindingRenderCase (Context&				context,
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  const char*			name,
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  const char*			desc,
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  ShaderType			shaderType,
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  TestType				testType,
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  glw::GLenum			maxBindingPointEnum,
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  glw::GLenum			maxVertexUnitsEnum,
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  glw::GLenum			maxFragmentUnitsEnum,
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  glw::GLenum			maxCombinedUnitsEnum,
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  const std::string&	uniformName)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase						(context, name, desc)
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program						(DE_NULL)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType					(shaderType)
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testType					(testType)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformName					(uniformName)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxBindingPointEnum			(maxBindingPointEnum)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxVertexUnitsEnum			(maxVertexUnitsEnum)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxFragmentUnitsEnum		(maxFragmentUnitsEnum)
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxCombinedUnitsEnum		(maxCombinedUnitsEnum)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertexBuffer				(0)
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_indexBuffer					(0)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderProgramLoc			(0)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderProgramPosLoc			(0)
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderProgramArrayNdxLoc	(0)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numBindings					(0)
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingRenderCase::~LayoutBindingRenderCase (void)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingRenderCase::init (void)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint				numBindingPoints	= 0;	// Number of available binding points
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select maximum number of uniforms used for the test
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_shaderType)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SHADERTYPE_VERTEX:
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				maxUnits = maxVertexUnits;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SHADERTYPE_FRAGMENT:
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				maxUnits = maxFragmentUnits;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SHADERTYPE_BOTH:
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				maxUnits = maxCombinedUnits/2;
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select the number of uniforms (= bindings) used for this test
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_testType)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TESTTYPE_BINDING_SINGLE:
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TESTTYPE_BINDING_MAX:
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_numBindings = 1;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TESTTYPE_BINDING_MULTIPLE:
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (maxUnits < 2)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					throw tcu::NotSupportedError("Not enough uniforms available for test");
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits));
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TESTTYPE_BINDING_ARRAY:
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TESTTYPE_BINDING_MAX_ARRAY:
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (maxUnits < 2)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					throw tcu::NotSupportedError("Not enough uniforms available for test");
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Check that we have enough uniforms in different shaders to perform the tests
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Not enough uniforms available for test");
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Check that we have enough binding points to perform the tests
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numBindingPoints < m_numBindings)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Not enough binding points available for test");
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Initialize the binding points i.e. populate the two binding point vectors
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		initBindingPoints(0, numBindingPoints);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader program - note: this must be done after deciding the binding points
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = generateShaders();
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Shader compile failed");
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup vertex and index buffers
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Get attribute and uniform locations
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32 	program	= m_program->getProgram();
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_shaderProgramPosLoc		= gl.getAttribLocation(program, "a_position");
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_shaderProgramArrayNdxLoc	= gl.getUniformLocation(program, "u_arrayNdx");
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexBuffer				= 0;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indexBuffer				= 0;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Setup buffers so that we render one quad covering the whole viewport
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec3 vertices[] =
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3(-1.0f, -1.0f, +1.0f),
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3(+1.0f, -1.0f, +1.0f),
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3(+1.0f, +1.0f, +1.0f),
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3(-1.0f, +1.0f, +1.0f),
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint16 indices[] =
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0, 1, 2,
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			0, 2, 3,
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0));
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Generate and bind index buffer
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_indexBuffer);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(indices)*(glw::GLsizeiptr)sizeof(indices[0])), &indices[0], GL_STATIC_DRAW);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Index buffer setup failed");
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Generate and bind vertex buffer
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &m_vertexBuffer);
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(vertices)*(glw::GLsizeiptr)sizeof(vertices[0])), &vertices[0], GL_STATIC_DRAW);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(m_shaderProgramPosLoc);
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(m_shaderProgramPosLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex buffer setup failed");
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingRenderCase::deinit (void)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_program)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = DE_NULL;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_shaderProgramPosLoc)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc);
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertexBuffer)
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_indexBuffer)
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_testType)
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_SINGLE:
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_bindings.push_back(bpoint);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MAX:
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_bindings.push_back(numBindingPoints-1);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MULTIPLE:
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Choose multiple unique binding points from the low and high end of available binding points
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint32> lowBindingPoints;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint32> highBindingPoints;
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int bpoint = 0; bpoint < numBindingPoints/2; ++bpoint)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				lowBindingPoints.push_back(bpoint);
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int bpoint = numBindingPoints/2; bpoint < numBindingPoints; ++bpoint)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				highBindingPoints.push_back(bpoint);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end());
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end());
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < m_numBindings; ++ndx)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (ndx%2 == 0)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int bpoint = lowBindingPoints.back();
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					lowBindingPoints.pop_back();
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_bindings.push_back(bpoint);
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int bpoint = highBindingPoints.back();
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					highBindingPoints.pop_back();
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_bindings.push_back(bpoint);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_ARRAY:
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glw::GLint binding = rnd.getInt(minBindingPoint, numBindingPoints-m_numBindings);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < m_numBindings; ++ndx)
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_bindings.push_back(binding+ndx);
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MAX_ARRAY:
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glw::GLint binding = numBindingPoints-m_numBindings;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < m_numBindings; ++ndx)
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_bindings.push_back(binding+ndx);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingRenderCase::initRenderState (void)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(m_program->getProgram());
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state");
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
529d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
530d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	tcu::Surface			reference			(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
531d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry
532d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	// the point of these test is to check layout_binding. For this purpose, we can use quite
533d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	// large thresholds.
534d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	const tcu::RGBA			surfaceThreshold	= m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold();
535d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	const tcu::RGBA			compareThreshold	= tcu::RGBA(de::clamp(2 * surfaceThreshold.getRed(),   0, 255),
536d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry															de::clamp(2 * surfaceThreshold.getGreen(), 0, 255),
537d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry															de::clamp(2 * surfaceThreshold.getBlue(),  0, 255),
538d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry															de::clamp(2 * surfaceThreshold.getAlpha(), 0, 255));
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed");
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Verify
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface result(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT);
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(reference.getAccess(), expectedColor);
553d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image, fragment output color is " << expectedColor << tcu::TestLog::EndMessage;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
555d55a0267adbac8c78e06ed563aac3003cbc51ad2Jarkko Pöyry	return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, compareThreshold, tcu::COMPARE_LOG_RESULT);
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed)
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (queryTestPassed && imageTestPassed)
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!queryTestPassed && !imageTestPassed)
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed");
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!queryTestPassed)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed");
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed");
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LayoutBindingNegativeCase : public TestCase
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ErrorType
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ERRORTYPE_OVER_MAX_UNITS = 0,
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ERRORTYPE_LESS_THAN_ZERO,
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ERRORTYPE_CONTRADICTORY,
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ERRORTYPE_LAST,
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										LayoutBindingNegativeCase		(Context&			context,
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*		name,
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*		desc,
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 ShaderType			shaderType,
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 TestType			testType,
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 ErrorType			errorType,
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxBindingPointEnum,
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxVertexUnitsEnum,
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxFragmentUnitsEnum,
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 glw::GLenum		maxCombinedUnitsEnum,
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const std::string& uniformName);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual								~LayoutBindingNegativeCase		(void);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						init							(void);
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						deinit							(void);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult				iterate							(void);
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual glu::ShaderProgram*			generateShaders					(void) const = 0;
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*			m_program;
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderType					m_shaderType;
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestType						m_testType;
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ErrorType						m_errorType;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxBindingPointEnum;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxVertexUnitsEnum;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxFragmentUnitsEnum;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum					m_maxCombinedUnitsEnum;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string					m_uniformName;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint							m_numBindings;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLint>				m_vertexShaderBinding;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLint>				m_fragmentShaderBinding;
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								initBindingPoints				(int minBindingPoint, int numBindingPoints);
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&				context,
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  const char*			name,
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  const char*			desc,
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  ShaderType			shaderType,
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  TestType				testType,
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  ErrorType				errorType,
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  glw::GLenum			maxBindingPointEnum,
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  glw::GLenum			maxVertexUnitsEnum,
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  glw::GLenum			maxFragmentUnitsEnum,
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  glw::GLenum			maxCombinedUnitsEnum,
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  const std::string&	uniformName)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(context, name, desc)
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program					(DE_NULL)
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType				(shaderType)
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testType				(testType)
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorType				(errorType)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxBindingPointEnum		(maxBindingPointEnum)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxVertexUnitsEnum		(maxVertexUnitsEnum)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxFragmentUnitsEnum	(maxFragmentUnitsEnum)
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxCombinedUnitsEnum	(maxCombinedUnitsEnum)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformName				(uniformName)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numBindings				(0)
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingNegativeCase::~LayoutBindingNegativeCase (void)
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingNegativeCase::init (void)
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Decide appropriate binding points for the vertex and fragment shaders
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd					(deStringHash(getName()) ^ 0xff23a4);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint				numBindingPoints	= 0;	// Number of binding points
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint				maxVertexUnits		= 0;	// Available uniforms in the vertex shader
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint				maxFragmentUnits	= 0;	// Available uniforms in the fragment shader
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint				maxCombinedUnits	= 0;	// Available uniforms in all the shader stages combined
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLint				maxUnits			= 0;	// Maximum available uniforms for this test
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select maximum number of uniforms used for the test
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_shaderType)
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_VERTEX:
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxUnits = maxVertexUnits;
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_FRAGMENT:
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxUnits = maxFragmentUnits;
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SHADERTYPE_BOTH:
6832acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select the number of uniforms (= bindings) used for this test
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_testType)
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_SINGLE:
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MAX:
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_numBindings = 1;
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MULTIPLE:
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_ARRAY:
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TESTTYPE_BINDING_MAX_ARRAY:
7012acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			if (m_errorType == ERRORTYPE_CONTRADICTORY)
7022acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			{
7032acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry				// leave room for contradictory case
7042acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry				if (maxUnits < 3)
7052acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry					throw tcu::NotSupportedError("Not enough uniforms available for test");
7062acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
7072acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			}
7082acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			else
7092acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			{
7102acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry				if (maxUnits < 2)
7112acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry					throw tcu::NotSupportedError("Not enough uniforms available for test");
7122acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry				m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
7132acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			}
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that we have enough uniforms in different shaders to perform the tests
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Not enough uniforms available for test");
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that we have enough binding points to perform the tests
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numBindingPoints < m_numBindings)
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Not enough binding points available for test");
7312acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry	if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
7322acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry		throw tcu::NotSupportedError("Not enough binding points available for test");
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize the binding points i.e. populate the two binding point vectors
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initBindingPoints(0, numBindingPoints);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader program - note: this must be done after deciding the binding points
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage;
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = generateShaders();
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingNegativeCase::deinit (void)
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_program)
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_program;
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = DE_NULL;
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool pass = false;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string failMessage;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_errorType)
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_CONTRADICTORY:		// Contradictory binding points should cause a link-time error
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!(m_program->getProgramInfo()).linkOk)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				pass = true;
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			failMessage = "Test failed - expected a link-time error";
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_LESS_THAN_ZERO:		// Out of bounds binding points should cause a compile-time error
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_OVER_MAX_UNITS:
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk)
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				pass = true;
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			failMessage = "Test failed - expected a compile-time error";
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (pass)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str());
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints)
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random rnd(deStringHash(getName()) ^ 0xff23a4);
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_errorType)
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_OVER_MAX_UNITS:	// Select a binding point that is 1 over the maximum
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_LESS_THAN_ZERO:	// Select a random negative binding point
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8002acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			const glw::GLint binding = -rnd.getInt(1, m_numBindings);
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_vertexShaderBinding.push_back(binding);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_fragmentShaderBinding.push_back(binding);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ERRORTYPE_CONTRADICTORY:	// Select two valid, but contradictory binding points
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_vertexShaderBinding.push_back(minBindingPoint);
8092acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
8102acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry			DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back());
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// In case we are testing with multiple uniforms populate the rest of the binding points
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 1; ndx < m_numBindings; ++ndx)
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SamplerBindingRenderCase : public LayoutBindingRenderCase
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									SamplerBindingRenderCase		(Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType);
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~SamplerBindingRenderCase		(void);
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 							init							(void);
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 							deinit							(void);
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult 					iterate							(void);
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*				generateShaders					(void) const;
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType					getSamplerTexCoordType			(void) const;
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							initializeTexture				(glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const;
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum				m_samplerType;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum				m_textureType;
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLuint>		m_textures;
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<Vec4>				m_textureColors;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplerBindingRenderCase::SamplerBindingRenderCase (Context&		context,
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													const char*		name,
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													const char*		desc,
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													ShaderType		shaderType,
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													TestType		testType,
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													glw::GLenum		samplerType,
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													glw::GLenum		textureType)
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: 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")
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_samplerType				(samplerType)
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureType				(textureType)
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplerBindingRenderCase::~SamplerBindingRenderCase (void)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SamplerBindingRenderCase::init (void)
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::init();
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize texture resources
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture colors
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureColors.push_back(getRandomColor(rnd));
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Textures
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]);
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0);
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SamplerBindingRenderCase::deinit(void)
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::deinit();
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clean up texture data
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_textures.size(); ++i)
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_textures[i])
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]);
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult SamplerBindingRenderCase::iterate (void)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				iterations		= m_numBindings;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					imageTestPassed	= true;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					queryTestPassed	= true;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set the viewport and enable the shader program
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initRenderState();
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set the uniform value indicating the current array index
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Query binding point
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name	= arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx);
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::GLint	binding = m_bindings[iterNdx];
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint			val		= -1;
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw and verify
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (val != binding)
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			queryTestPassed = false;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			imageTestPassed = false;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setTestResult(queryTestPassed, imageTestPassed);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderUniformDecl;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations =  arrayInstance ? 1 : m_numBindings;
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " "
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0 + bindingPoint);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(m_textureType, textureName);
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_textureType)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(level.getAccess(), color);
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_3D:
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(level.getAccess(), color);
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess());
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed");
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_samplerType)
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER_2D:
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC2;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER_3D:
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC3;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INVALID;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SamplerBindingNegativeCase : public LayoutBindingNegativeCase
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									SamplerBindingNegativeCase		(Context&		context,
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 const char*	name,
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 const char*	desc,
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 ShaderType		shaderType,
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 TestType		testType,
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 ErrorType		errorType,
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	 glw::GLenum	samplerType);
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~SamplerBindingNegativeCase		(void);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*				generateShaders					(void) const;
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType					getSamplerTexCoordType			(void) const;
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum				m_samplerType;
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10463c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplerBindingNegativeCase::SamplerBindingNegativeCase (Context&		context,
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														const char*		name,
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														const char*		desc,
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														ShaderType		shaderType,
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														TestType		testType,
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														ErrorType		errorType,
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														glw::GLenum		samplerType)
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: LayoutBindingNegativeCase		(context, name, desc, shaderType, testType, errorType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler")
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_samplerType					(samplerType)
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySamplerBindingNegativeCase::~SamplerBindingNegativeCase (void)
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingNegativeCase::deinit();
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram*	SamplerBindingNegativeCase::generateShaders	(void) const
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		vertexUniformDecl;
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		fragmentUniformDecl;
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		texCoordType	= glu::getDataTypeName(getSamplerTexCoordType());
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		samplerType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType));
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = arrayInstance ? 1 : m_numBindings;
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n"
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_samplerType)
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER_2D:
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC2;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER_3D:
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC3;
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INVALID;
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ImageBindingRenderCase : public LayoutBindingRenderCase
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											ImageBindingRenderCase			(Context&		context,
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	name,
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	desc,
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ShaderType		shaderType,
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 TestType		testType,
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 glw::GLenum	imageType,
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 glw::GLenum	textureType);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~ImageBindingRenderCase			(void);
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									init							(void);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									deinit							(void);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult 							iterate							(void);
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders					(void) const;
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void									initializeImage					(glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const;
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType							getImageTexCoordType			(void) const;
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum						m_imageType;
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum						m_textureType;
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLuint>				m_textures;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<Vec4>						m_textureColors;
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryImageBindingRenderCase::ImageBindingRenderCase (Context&		context,
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*		name,
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*		desc,
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												ShaderType		shaderType,
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												TestType		testType,
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												glw::GLenum		imageType,
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												glw::GLenum		textureType)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: 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")
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_imageType					(imageType)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureType					(textureType)
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryImageBindingRenderCase::~ImageBindingRenderCase (void)
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ImageBindingRenderCase::init (void)
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::init();
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize image / texture resources
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures = std::vector<glw::GLuint>(m_numBindings,  0);
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture colors
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureColors.push_back(getRandomColor(rnd));
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Image textures
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genTextures(m_numBindings, &m_textures[0]);
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]);
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ImageBindingRenderCase::deinit (void)
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::deinit();
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clean up texture data
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx)
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_textures[texNdx])
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]);
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0);
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult ImageBindingRenderCase::iterate	(void)
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				iterations		= m_numBindings;
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					queryTestPassed	= true;
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					imageTestPassed = true;
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set the viewport and enable the shader program
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initRenderState();
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set the uniform value indicating the current array index
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx);
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::GLint	binding = m_bindings[iterNdx];
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint			val		= -1;
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val);
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw and verify
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (val != binding)
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			queryTestPassed = false;
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!drawAndVerifyResult(m_textureColors[iterNdx]))
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			imageTestPassed = false;
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setTestResult(queryTestPassed, imageTestPassed);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0 + textureBindingPoint);
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(m_textureType, textureName);
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_textureType)
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(level.getAccess(), color);
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr());
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_3D:
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(level.getAccess(), color);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			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());
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(m_textureType, 0);
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8);
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed");
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderUniformDecl;
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false;
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_imageType)
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_IMAGE_2D:
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC2;
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_IMAGE_3D:
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC3;
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INVALID;
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ImageBindingNegativeCase : public LayoutBindingNegativeCase
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											ImageBindingNegativeCase		(Context&		context,
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	name,
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	desc,
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ShaderType		shaderType,
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 TestType		testType,
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ErrorType		errorType,
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 glw::GLenum	imageType);
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~ImageBindingNegativeCase		(void);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders					(void) const;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType							getImageTexCoordType			(void) const;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum						m_imageType;
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryImageBindingNegativeCase::ImageBindingNegativeCase (Context&		context,
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													const char*		name,
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													const char*		desc,
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													ShaderType		shaderType,
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													TestType		testType,
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													ErrorType		errorType,
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													glw::GLenum		imageType)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: LayoutBindingNegativeCase		(context, name, desc, shaderType, testType, errorType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image")
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_imageType					(imageType)
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryImageBindingNegativeCase::~ImageBindingNegativeCase (void)
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		vertexUniformDecl;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		fragmentUniformDecl;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		texCoordType	= glu::getDataTypeName(getImageTexCoordType());
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		imageType		= glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType));
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
13788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx)
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n"
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_imageType)
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_IMAGE_2D:
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC2;
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_IMAGE_3D:
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC3;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INVALID;
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UBOBindingRenderCase : public LayoutBindingRenderCase
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											UBOBindingRenderCase		(Context&		context,
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*	name,
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*	desc,
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 ShaderType		shaderType,
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 TestType		testType);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~UBOBindingRenderCase		(void);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									init						(void);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									deinit						(void);
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult 							iterate						(void);
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders				(void) const;
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint32>					m_buffers;
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<Vec4>						m_expectedColors;
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUBOBindingRenderCase::UBOBindingRenderCase (Context&		context,
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const char*		name,
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const char*		desc,
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											ShaderType		shaderType,
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											TestType		testType)
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: 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")
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUBOBindingRenderCase::~UBOBindingRenderCase (void)
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UBOBindingRenderCase::init (void)
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::init();
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize UBOs and related data
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers = std::vector<glw::GLuint>(m_numBindings,  0);
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_expectedColors.push_back(getRandomColor(rnd));
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_expectedColors.push_back(getRandomColor(rnd));
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]);
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed");
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UBOBindingRenderCase::deinit (void)
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::deinit();
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clean up UBO data
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_buffers[bufNdx])
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0);
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult UBOBindingRenderCase::iterate (void)
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				iterations		= m_numBindings;
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum		prop			= GL_BUFFER_BINDING;
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					queryTestPassed	= true;
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					imageTestPassed = true;
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set the viewport and enable the shader program
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initRenderState();
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Query binding point
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::GLint	binding = m_bindings[iterNdx];
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint			val		= -1;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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);
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (val != binding)
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			queryTestPassed = false;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw twice to render both colors within the UBO
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Set the uniform indicating the array index to be used and set the expected color
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int arrayNdx = iterNdx*2 + drawCycle;
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				imageTestPassed = false;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setTestResult(queryTestPassed, imageTestPassed);
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderUniformDecl;
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform "
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UBOBindingNegativeCase : public LayoutBindingNegativeCase
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											UBOBindingNegativeCase			(Context&		context,
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	name,
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	desc,
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ShaderType		shaderType,
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 TestType		testType,
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ErrorType		errorType);
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~UBOBindingNegativeCase			(void);
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders					(void) const;
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUBOBindingNegativeCase::UBOBindingNegativeCase (Context&		context,
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*		name,
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												const char*		desc,
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												ShaderType		shaderType,
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												TestType		testType,
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												ErrorType		errorType)
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock")
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUBOBindingNegativeCase::~UBOBindingNegativeCase (void)
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		vertexUniformDecl;
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		fragmentUniformDecl;
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform "
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform "
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16352acb6d4631d6d7084ebe4fb762003bcde1aae336Jarkko Pöyry		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SSBOBindingRenderCase : public LayoutBindingRenderCase
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											SSBOBindingRenderCase		(Context&		context,
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*	name,
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*	desc,
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 ShaderType		shaderType,
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 TestType		testType);
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~SSBOBindingRenderCase		(void);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									init						(void);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void 									deinit						(void);
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult 							iterate						(void);
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders				(void) const;
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<glw::GLuint>				m_buffers;
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<Vec4>						m_expectedColors;
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16743c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOBindingRenderCase::SSBOBindingRenderCase (Context&		context,
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  const char*	name,
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  const char*	desc,
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  ShaderType	shaderType,
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  TestType		testType)
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: 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")
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOBindingRenderCase::~SSBOBindingRenderCase (void)
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SSBOBindingRenderCase::init (void)
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::init();
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd		(deStringHash(getName()) ^ 0xff23a4);
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize SSBOs and related data
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers = std::vector<glw::GLuint>(m_numBindings, 0);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_expectedColors.push_back(getRandomColor(rnd));
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_expectedColors.push_back(getRandomColor(rnd));
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]);
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW);
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]);
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed");
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SSBOBindingRenderCase::deinit (void)
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LayoutBindingRenderCase::deinit();
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clean up SSBO data
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_buffers[bufNdx])
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers[bufNdx] = 0;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult SSBOBindingRenderCase::iterate (void)
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				iterations		= m_numBindings;
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum		prop			= GL_BUFFER_BINDING;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					queryTestPassed	= true;
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					imageTestPassed = true;
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initRenderState();
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < iterations; ++iterNdx)
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Query binding point
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name	= (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx));
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::GLint	binding = m_bindings[iterNdx];
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLint			val		= -1;
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage;
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed");
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (val != binding)
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			queryTestPassed = false;
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw twice to render both colors within the SSBO
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int drawCycle = 0; drawCycle < 2; ++drawCycle)
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Set the uniform indicating the array index to be used and set the expected color
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int arrayNdx = iterNdx*2 + drawCycle;
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx);
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!drawAndVerifyResult(m_expectedColors[arrayNdx]))
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				imageTestPassed = false;
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setTestResult(queryTestPassed, imageTestPassed);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderUniformDecl;
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer "
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())));
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SSBOBindingNegativeCase : public LayoutBindingNegativeCase
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											SSBOBindingNegativeCase			(Context&		context,
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	name,
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 const char*	desc,
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ShaderType		shaderType,
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 TestType		testType,
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			 ErrorType		errorType);
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											~SSBOBindingNegativeCase		(void);
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*						generateShaders					(void) const;
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18263c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  const char* name,
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  const char* desc,
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  ShaderType shaderType,
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  TestType testType,
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  ErrorType errorType)
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer")
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18363c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOBindingNegativeCase::~SSBOBindingNegativeCase (void)
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		vertexUniformDecl;
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		fragmentUniformDecl;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		shaderBody;
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				arrayInstance	= (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numDeclarations = (arrayInstance ? 1 : m_numBindings);
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the uniform declarations for the vertex and fragment shaders
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int declNdx = 0; declNdx < numDeclarations; ++declNdx)
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer "
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer "
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< getUniformName(m_uniformName, declNdx) << "\n"
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "{\n"
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color1;\n"
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "	highp vec4 color2;\n"
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate the shader body for the vertex and fragment shaders
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx)	// Multiply by two to cover cases for both colors for each UBO
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2));
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderBody	<< "	" << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n"
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	{\n"
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "		color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n"
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "	}\n";
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shaderBody	<< "	else\n"
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	{\n"
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "		color = vec4(0.0, 0.0, 0.0, 1.0);\n"
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "	}\n";
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Anonymous
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingTests::LayoutBindingTests (Context& context)
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup (context, "layout_binding", "Layout binding tests")
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLayoutBindingTests::~LayoutBindingTests (void)
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LayoutBindingTests::init (void)
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render test groups
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const samplerBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding");
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const sampler2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding");
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const sampler3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding");
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const imageBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding");
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const image2dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding");
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const image3dBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding");
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const UBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding");
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const SSBOBindingTestGroup				= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding");
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Negative test groups
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeBindingTestGroup			= new tcu::TestCaseGroup(m_testCtx, "negative",		"Test layout binding with invalid bindings");
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeSamplerBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler",		"Test sampler layout binding with invalid bindings");
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler2d",	"Test sampler2d layout binding with invalid bindings");
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "sampler3d",	"Test sampler3d layout binding with invalid bindings");
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeImageBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "image",		"Test image layout binding with invalid bindings");
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeImage2dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image2d",		"Test image2d layout binding with invalid bindings");
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeImage3dBindingTestGroup	= new tcu::TestCaseGroup(m_testCtx, "image3d",		"Test image3d layout binding with invalid bindings");
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeUBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ubo",			"Test UBO layout binding with invalid bindings");
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const negativeSSBOBindingTestGroup		= new tcu::TestCaseGroup(m_testCtx, "ssbo",			"Test SSBO layout binding with invalid bindings");
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct RenderTestType
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderType				shaderType;
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestType			 	testType;
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string 			name;
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string 			descPostfix;
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_renderTestTypes[] =
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE, 		"vertex_binding_single",	 	"a single instance" },
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX,			"vertex_binding_max",			"maximum binding point"	},
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MULTIPLE,		"vertex_binding_multiple",		"multiple instances"},
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			"vertex_binding_array",			"an array instance" },
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_MAX_ARRAY,		"vertex_binding_max_array",		"an array instance with maximum binding point" },
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE, 		"fragment_binding_single",	 	"a single instance" },
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX,			"fragment_binding_max",			"maximum binding point"	},
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MULTIPLE,		"fragment_binding_multiple",	"multiple instances"},
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			"fragment_binding_array",		"an array instance" },
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_MAX_ARRAY,		"fragment_binding_max_array",	"an array instance with maximum binding point" },
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct NegativeTestType
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderType								shaderType;
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestType								testType;
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		LayoutBindingNegativeCase::ErrorType	errorType;
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string								name;
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string								descPostfix;
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_negativeTestTypes[] =
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max",			"over maximum binding point"},
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max",		"over maximum binding point"},
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg",				"negative binding point"},
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg",				"negative binding point"},
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"vertex_binding_over_max_array",	"over maximum binding point"},
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,	"fragment_binding_over_max_array",	"over maximum binding point"},
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_VERTEX,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"vertex_binding_neg_array",			"negative binding point"},
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_FRAGMENT,	TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,	"fragment_binding_neg_array",		"negative binding point"},
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_SINGLE,		LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory",			"contradictory binding points"},
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ SHADERTYPE_BOTH,		TESTTYPE_BINDING_ARRAY,			LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,		"binding_contradictory_array",		"contradictory binding points"},
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render tests
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx)
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const RenderTestType& test = s_renderTestTypes[testNdx];
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render sampler binding tests
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render image binding tests
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render UBO binding tests
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Render SSBO binding tests
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType));
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Negative binding tests
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx)
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const NegativeTestType& test = s_negativeTestTypes[testNdx];
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Negative sampler binding tests
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Negative image binding tests
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Negative UBO binding tests
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Negative SSBO binding tests
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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));
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	samplerBindingTestGroup->addChild(sampler2dBindingTestGroup);
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	samplerBindingTestGroup->addChild(sampler3dBindingTestGroup);
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	imageBindingTestGroup->addChild(image2dBindingTestGroup);
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	imageBindingTestGroup->addChild(image3dBindingTestGroup);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup);
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup);
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup);
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup);
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup);
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup);
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup);
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	negativeBindingTestGroup->addChild(negativeImageBindingTestGroup);
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(samplerBindingTestGroup);
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(UBOBindingTestGroup);
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(SSBOBindingTestGroup);
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(imageBindingTestGroup);
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(negativeBindingTestGroup);
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2038