13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 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 Shader API tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderApiTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fApiCase.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwDefs.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; // GL types
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ShaderSourceCaseFlags
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASE_EXPLICIT_SOURCE_LENGTHS	= 1,
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASE_RANDOM_NULL_TERMINATED		= 2
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ShaderSources
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<std::string>	strings;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<int>			lengths;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Simple shaders
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* getSimpleShaderSource (const glu::ShaderType shaderType)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* simpleVertexShaderSource =
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(0.0);\n"
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* simpleFragmentShaderSource =
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 o_fragColor;\n"
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	o_fragColor = vec4(0.0);\n"
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (shaderType)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::SHADERTYPE_VERTEX:
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return simpleVertexShaderSource;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::SHADERTYPE_FRAGMENT:
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return simpleFragmentShaderSource;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setShaderSources (glu::Shader& shader, const ShaderSources& sources)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<const char*> cStrings (sources.strings.size(), 0);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < sources.strings.size(); ndx++)
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cStrings[ndx] = sources.strings[ndx].c_str();
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sources.lengths.size() > 0)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shader.setSources((int)cStrings.size(), &cStrings[0], &sources.lengths[0]);
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shader.setSources((int)cStrings.size(), &cStrings[0], 0);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid sliceSourceString (const std::string& in, ShaderSources& out, const int numSlices, const size_t paddingLength = 0)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numSlices > 0);
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const size_t		sliceSize			= in.length() / numSlices;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const size_t		sliceSizeRemainder	= in.length() - (sliceSize * numSlices);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string	padding				(paddingLength, 'E');
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numSlices; ndx++)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.strings.push_back(in.substr(ndx * sliceSize, sliceSize) + padding);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (paddingLength > 0)
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			out.lengths.push_back((int)sliceSize);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sliceSizeRemainder > 0)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	lastString			= in.substr(numSlices * sliceSize);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			lastStringLength	= (int)lastString.length();
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.strings.push_back(lastString + padding);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (paddingLength > 0)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			out.lengths.push_back(lastStringLength);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid queryShaderInfo (glu::RenderContext& renderCtx, deUint32 shader, glu::ShaderInfo& info)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = renderCtx.getFunctions();
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	info.compileOk		= false;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	info.compileTimeUs	= 0;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	info.infoLog.clear();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query source, status & log.
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int	compileStatus	= 0;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sourceLen		= 0;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int	infoLogLen		= 0;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int	unusedLen;
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getShaderiv(shader, GL_COMPILE_STATUS,			&compileStatus);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getShaderiv(shader, GL_SHADER_SOURCE_LENGTH,	&sourceLen);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getShaderiv(shader, GL_INFO_LOG_LENGTH,		&infoLogLen);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		info.compileOk = compileStatus != GL_FALSE;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (sourceLen > 0)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<char> source(sourceLen);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.getShaderSource(shader, (int)source.size(), &unusedLen, &source[0]);
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			info.source = std::string(&source[0], sourceLen);
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (infoLogLen > 0)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<char> infoLog(infoLogLen);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.getShaderInfoLog(shader, (int)infoLog.size(), &unusedLen, &infoLog[0]);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			info.infoLog = std::string(&infoLog[0], infoLogLen);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Draw test quad
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawWithProgram (glu::RenderContext& renderCtx, deUint32 program)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = renderCtx.getFunctions();
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float position[] =
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.0f, -1.0f,  0.0f, 1.0f,
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.0f, +1.0f,  0.0f, 1.0f,
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		+1.0f, -1.0f,  0.0f, 1.0f,
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		+1.0f, +1.0f,  0.0f, 1.0f
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(program);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::VertexArrayBinding vertexArrays[] =
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::va::Float("a_position",	4, 4, 0, &position[0])
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::draw(renderCtx, program, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0], glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Shader source generator
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SourceGenerator
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual				~SourceGenerator	(void)	{}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual std::string	next				(const glu::ShaderType shaderType)			= 0;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool		finished			(const glu::ShaderType shaderType) const	= 0;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConstantShaderGenerator : public SourceGenerator
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ConstantShaderGenerator		(de::Random& rnd)	: m_rnd(rnd)	{}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				~ConstantShaderGenerator	(void)								{}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		finished					(const glu::ShaderType shaderType) const	{ DE_UNREF(shaderType); return false; }
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string	next						(const glu::ShaderType shaderType);
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	m_rnd;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ConstantShaderGenerator::next (const glu::ShaderType shaderType)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderType == glu::SHADERTYPE_VERTEX || shaderType == glu::SHADERTYPE_FRAGMENT);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float			value		= m_rnd.getFloat(0.0f, 1.0f);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string	valueString	= de::toString(value);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string	outputName	= (shaderType == glu::SHADERTYPE_VERTEX) ? "gl_Position" : "o_fragColor";
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	out;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "#version 300 es\n";
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (shaderType == glu::SHADERTYPE_FRAGMENT)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "layout(location = 0) out mediump vec4 o_fragColor;\n";
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "void main (void)\n";
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "{\n";
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "	" << outputName << " = vec4(" << valueString << ");\n";
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out << "}\n";
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return out.str();
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Shader allocation utility
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderAllocator
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderAllocator		(glu::RenderContext& context, SourceGenerator& generator);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~ShaderAllocator	(void);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			hasShader			(const glu::ShaderType shaderType);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			setSource			(const glu::ShaderType shaderType);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	createShader		(const glu::ShaderType shaderType);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			deleteShader		(const glu::ShaderType shaderType);
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	get					(const glu::ShaderType shaderType)	{ DE_ASSERT(hasShader(shaderType)); return *m_shaders[shaderType]; }
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&				m_context;
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SourceGenerator&						m_srcGen;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::map<glu::ShaderType, glu::Shader*>	m_shaders;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAllocator::ShaderAllocator (glu::RenderContext& context, SourceGenerator& generator)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_context	(context)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_srcGen	(generator)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderAllocator::~ShaderAllocator (void)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::map<glu::ShaderType, glu::Shader*>::iterator shaderIter = m_shaders.begin(); shaderIter != m_shaders.end(); shaderIter++)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete shaderIter->second;
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders.clear();
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderAllocator::hasShader (const glu::ShaderType shaderType)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_shaders.find(shaderType) != m_shaders.end())
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::Shader& ShaderAllocator::createShader (const glu::ShaderType shaderType)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!this->hasShader(shaderType));
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader* const	shader	= new glu::Shader(m_context, shaderType);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders[shaderType] = shader;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->setSource(shaderType);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *shader;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAllocator::deleteShader (const glu::ShaderType shaderType)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(this->hasShader(shaderType));
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_shaders[shaderType];
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders.erase(shaderType);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderAllocator::setSource (const glu::ShaderType shaderType)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(this->hasShader(shaderType));
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_srcGen.finished(shaderType));
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string	source	= m_srcGen.next(shaderType);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const	cSource	= source.c_str();
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders[shaderType]->setSources(1, &cSource, 0);
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Logging utilities
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid logShader (TestLog& log, glu::RenderContext& renderCtx, glu::Shader& shader)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderInfo info;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	queryShaderInfo(renderCtx, shader.getShader(), info);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Shader(getLogShaderType(shader.getType()), info.source, info.compileOk, info.infoLog);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid logProgram (TestLog& log, glu::RenderContext& renderCtx, glu::Program& program, ShaderAllocator& shaders)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::ShaderProgram(program.getLinkStatus(), program.getInfoLog());
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderTypeInt = 0; shaderTypeInt < glu::SHADERTYPE_LAST; shaderTypeInt++)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderType shaderType = (glu::ShaderType)shaderTypeInt;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (shaders.hasShader(shaderType))
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logShader(log, renderCtx, shaders.get(shaderType));
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::EndShaderProgram;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid logVertexFragmentProgram (TestLog& log, glu::RenderContext& renderCtx, glu::Program& program, glu::Shader& vertShader, glu::Shader& fragShader)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(vertShader.getType() == glu::SHADERTYPE_VERTEX && fragShader.getType() == glu::SHADERTYPE_FRAGMENT);
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::ShaderProgram(program.getLinkStatus(), program.getInfoLog());
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	logShader(log, renderCtx, vertShader);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	logShader(log, renderCtx, fragShader);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::EndShaderProgram;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Simple glCreateShader() case
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CreateShaderCase : public ApiCase
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CreateShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ApiCase		(context, name, desc)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_shaderType	(shaderType)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint shaderObject = glCreateShader(glu::getGLShaderType(m_shaderType));
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(shaderObject != 0);
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(shaderObject);
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType m_shaderType;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Simple glCompileShader() case
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CompileShaderCase : public ApiCase
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CompileShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ApiCase		(context, name, desc)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_shaderType	(shaderType)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool checkCompileStatus (const GLuint shaderObject)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint compileStatus = -1;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &compileStatus);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (compileStatus == GL_TRUE);
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		shaderSource	= getSimpleShaderSource(m_shaderType);
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint	shaderObject	= glCreateShader(glu::getGLShaderType(m_shaderType));
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(shaderObject != 0);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glShaderSource(shaderObject, 1, &shaderSource, 0);
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glCompileShader(shaderObject);
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(checkCompileStatus(shaderObject));
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(shaderObject);
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType m_shaderType;
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class for simple program API tests
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SimpleProgramCase : public ApiCase
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SimpleProgramCase (Context& context, const char* name, const char* desc)
446653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		: ApiCase		(context, name, desc)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_vertShader	(0)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_fragShader	(0)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_program		(0)
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~SimpleProgramCase (void)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void compileShaders (void)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		vertSource	= getSimpleShaderSource(glu::SHADERTYPE_VERTEX);
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		fragSource	= getSimpleShaderSource(glu::SHADERTYPE_FRAGMENT);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint	vertShader	= glCreateShader(GL_VERTEX_SHADER);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint	fragShader	= glCreateShader(GL_FRAGMENT_SHADER);
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(vertShader != 0);
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(fragShader != 0);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glShaderSource(vertShader, 1, &vertSource, 0);
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glCompileShader(vertShader);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glShaderSource(fragShader, 1, &fragSource, 0);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glCompileShader(fragShader);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertShader = vertShader;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fragShader = fragShader;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void linkProgram (void)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLuint program = glCreateProgram();
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(program != 0);
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glAttachShader(program, m_vertShader);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glAttachShader(program, m_fragShader);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glLinkProgram(program);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = program;
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void cleanup (void)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(m_vertShader);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(m_fragShader);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteProgram(m_program);
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint	m_vertShader;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint	m_fragShader;
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint	m_program;
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// glDeleteShader() case
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DeleteShaderCase : public SimpleProgramCase
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DeleteShaderCase (Context& context, const char* name, const char* desc)
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: SimpleProgramCase (context, name, desc)
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool checkDeleteStatus(GLuint shader)
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint deleteStatus = -1;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetShaderiv(shader, GL_DELETE_STATUS, &deleteStatus);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (deleteStatus == GL_TRUE);
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void deleteShaders (void)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(m_vertShader);
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(m_fragShader);
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compileShaders();
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		linkProgram();
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deleteShaders();
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(checkDeleteStatus(m_vertShader) && checkDeleteStatus(m_fragShader));
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteProgram(m_program);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(!(glIsShader(m_vertShader) || glIsShader(m_fragShader)));
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Simple glLinkProgram() case
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LinkVertexFragmentCase : public SimpleProgramCase
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LinkVertexFragmentCase (Context& context, const char* name, const char* desc)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: SimpleProgramCase (context, name, desc)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool checkLinkStatus (const GLuint programObject)
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint linkStatus = -1;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetProgramiv(programObject, GL_LINK_STATUS, &linkStatus);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (linkStatus == GL_TRUE);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compileShaders();
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		linkProgram();
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_MSG("Linking failed.");
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(checkLinkStatus(m_program), "Fail, expected LINK_STATUS to be TRUE.");
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cleanup();
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderSourceReplaceCase : public ApiCase
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderSourceReplaceCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ApiCase		(context, name, desc)
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_shaderType	(shaderType)
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string generateFirstSource (void)
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getSimpleShaderSource(m_shaderType);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string generateSecondSource (void)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream out;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "#version 300 es\n";
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "precision mediump float;\n";
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_shaderType == glu::SHADERTYPE_FRAGMENT)
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			out << "layout(location = 0) out mediump vec4 o_fragColor;\n";
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "void main()\n";
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "{\n";
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "	float variable = 1.0f;\n";
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if		(m_shaderType == glu::SHADERTYPE_VERTEX)	out << "	gl_Position = vec4(variable);\n";
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if	(m_shaderType == glu::SHADERTYPE_FRAGMENT)	out << "	o_fragColor = vec4(variable);\n";
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "}\n";
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return out.str();
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint getSourceLength (glu::Shader& shader)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint sourceLength = 0;
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetShaderiv(shader.getShader(), GL_SHADER_SOURCE_LENGTH, &sourceLength);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sourceLength;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string readSource (glu::Shader& shader)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint			sourceLength	= getSourceLength(shader);
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<char>	sourceBuffer	(sourceLength + 1);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetShaderSource(shader.getShader(), (GLsizei)sourceBuffer.size(), 0, &sourceBuffer[0]);
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return std::string(&sourceBuffer[0]);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void verifyShaderSourceReplaced (glu::Shader& shader, const std::string& firstSource, const std::string& secondSource)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&			log		= m_testCtx.getLog();
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	result	= readSource(shader);
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result == firstSource)
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Fail, source was not replaced." << TestLog::EndMessage;
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader source nor replaced");
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (result != secondSource)
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Fail, invalid shader source." << TestLog::EndMessage;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid source");
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&			log				= m_testCtx.getLog();
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader			shader			(m_context.getRenderContext(), m_shaderType);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	firstSourceStr	= generateFirstSource();
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	secondSourceStr	= generateSecondSource();
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			firstSource		= firstSourceStr.c_str();
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			secondSource	= secondSourceStr.c_str();
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Setting shader source." << TestLog::EndMessage;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shader.setSources(1, &firstSource, 0);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Replacing shader source." << TestLog::EndMessage;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shader.setSources(1, &secondSource, 0);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyShaderSourceReplaced(shader, firstSourceStr, secondSourceStr);
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderType	m_shaderType;
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// glShaderSource() split source case
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderSourceSplitCase : public ApiCase
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderSourceSplitCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType, const int numSlices, const deUint32 flags = 0)
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ApiCase			(context, name, desc)
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_rnd				(deStringHash(getName()) ^ 0x4fb2337d)
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_shaderType		(shaderType)
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_numSlices		(numSlices)
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_explicitLengths	((flags & CASE_EXPLICIT_SOURCE_LENGTHS)	!= 0)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_randomNullTerm	((flags & CASE_RANDOM_NULL_TERMINATED)	!= 0)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ShaderSourceSplitCase (void)
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string generateFullSource (void)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream out;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "#version 300 es\n";
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "precision mediump float;\n";
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_shaderType == glu::SHADERTYPE_FRAGMENT)
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			out << "layout(location = 0) out mediump vec4 o_fragColor;\n";
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "void main()\n";
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "{\n";
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "	float variable = 1.0f;\n";
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if		(m_shaderType == glu::SHADERTYPE_VERTEX)	out << "	gl_Position = vec4(variable);\n";
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if	(m_shaderType == glu::SHADERTYPE_FRAGMENT)	out << "	o_fragColor = vec4(variable);\n";
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out << "}\n";
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return out.str();
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void insertRandomNullTermStrings (ShaderSources& sources)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			numInserts	= de::max(m_numSlices >> 2, 1);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<int>	indices		(sources.strings.size(), 0);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(sources.lengths.size() > 0);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(sources.lengths.size() == sources.strings.size());
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)sources.strings.size(); i++)
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			indices[i] = i;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_rnd.shuffle(indices.begin(), indices.end());
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numInserts; i++)
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			ndx				= indices[i];
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			unpaddedLength	= sources.lengths[ndx];
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string	unpaddedString	= sources.strings[ndx].substr(0, unpaddedLength);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sources.strings[ndx] = unpaddedString;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sources.lengths[ndx] = m_rnd.getInt(-10, -1);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void generateSources (ShaderSources& sources)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const size_t	paddingLength	= (m_explicitLengths ? 10 : 0);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string		str				= generateFullSource();
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sliceSourceString(str, sources, m_numSlices, paddingLength);
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_randomNullTerm)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			insertRandomNullTermStrings(sources);
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void buildProgram (glu::Shader& shader)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&				log					= m_testCtx.getLog();
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::RenderContext&		renderCtx			= m_context.getRenderContext();
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderType	supportShaderType	= (m_shaderType == glu::SHADERTYPE_FRAGMENT ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*				supportShaderSource	= getSimpleShaderSource(supportShaderType);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader				supportShader		(renderCtx, supportShaderType);
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Program			program				(renderCtx);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		supportShader.setSources(1, &supportShaderSource, 0);
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		supportShader.compile();
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(shader.getShader());
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(supportShader.getShader());
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.link();
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_shaderType == glu::SHADERTYPE_VERTEX)
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logVertexFragmentProgram(log, renderCtx, program, shader, supportShader);
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logVertexFragmentProgram(log, renderCtx, program, supportShader, shader);
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&			log			= m_testCtx.getLog();
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::RenderContext&	renderCtx	= m_context.getRenderContext();
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShaderSources		sources;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader			shader		(renderCtx, m_shaderType);
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		generateSources(sources);
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderSources(shader, sources);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shader.compile();
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildProgram(shader);
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!shader.getCompileStatus())
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Compilation failed." << TestLog::EndMessage;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				m_rnd;
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType	m_shaderType;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numSlices;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				m_explicitLengths;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				m_randomNullTerm;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class for program state persistence cases
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateCase : public ApiCase
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ProgramStateCase	(Context& context, const char* name, const char* desc, glu::ShaderType shaderType);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual			~ProgramStateCase	(void)	{}
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			buildProgram		(glu::Program& program, ShaderAllocator& shaders);
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			verify				(glu::Program& program, const glu::ProgramInfo& reference);
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			test				(void);
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void	executeForProgram	(glu::Program& program, ShaderAllocator& shaders)	= 0;
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random					m_rnd;
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType		m_shaderType;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramStateCase::ProgramStateCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ApiCase		(context, name, desc)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd			(deStringHash(name) ^ 0x713de0ca)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType	(shaderType)
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramStateCase::buildProgram (glu::Program& program, ShaderAllocator& shaders)
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	vertShader	= shaders.createShader(glu::SHADERTYPE_VERTEX);
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	fragShader	= shaders.createShader(glu::SHADERTYPE_FRAGMENT);
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertShader.compile();
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragShader.compile();
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.attachShader(vertShader.getShader());
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.attachShader(fragShader.getShader());
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.link();
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	logProgram(log, m_context.getRenderContext(), program, shaders);
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramStateCase::verify (glu::Program& program, const glu::ProgramInfo& reference)
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ProgramInfo&	programInfo	= program.getInfo();
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!programInfo.linkOk)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, link status may only change as a result of linking or loading a program binary." << TestLog::EndMessage;
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Link status changed");
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (programInfo.linkTimeUs != reference.linkTimeUs)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, reported link time changed." << TestLog::EndMessage;
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Link time changed");
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (programInfo.infoLog != reference.infoLog)
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, program infolog changed." << TestLog::EndMessage;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Infolog changed");
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramStateCase::test (void)
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&		renderCtx	= m_context.getRenderContext();
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstantShaderGenerator	sourceGen	(m_rnd);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderAllocator			shaders		(renderCtx, sourceGen);
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Program			program		(renderCtx);
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buildProgram(program, shaders);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (program.getLinkStatus())
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ProgramInfo programInfo = program.getInfo();
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		executeForProgram(program, shaders);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verify(program, programInfo);
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		logProgram(log, renderCtx, program, shaders);
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, couldn't link program." << TestLog::EndMessage;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Linking failed");
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Program state case utilities
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class T>
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addProgramStateCase (TestCaseGroup* group, Context& context, const std::string& name, const std::string& desc)
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderType	shaderType		= (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		shaderTypeName	= getShaderTypeName(shaderType);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		caseName		= name + "_" + shaderTypeName;
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		caseDesc		= "Build program, " + desc + ", for " + shaderTypeName + " shader.";
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new T(context, caseName.c_str(), caseDesc.c_str(), shaderType));
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Specialized program state cases
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateDetachShaderCase : public ProgramStateCase
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateDetachShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateDetachShaderCase (void)
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Detaching " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateReattachShaderCase : public ProgramStateCase
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateReattachShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateReattachShaderCase (void)
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Reattaching " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(caseShader.getShader());
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateDeleteShaderCase : public ProgramStateCase
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateDeleteShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateDeleteShaderCase (void)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Deleting " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.deleteShader(m_shaderType);
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateReplaceShaderCase : public ProgramStateCase
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateReplaceShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateReplaceShaderCase (void)
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Deleting and replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.deleteShader(m_shaderType);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(shaders.createShader(m_shaderType).getShader());
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateRecompileShaderCase : public ProgramStateCase
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateRecompileShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateRecompileShaderCase (void)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Recompiling " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		caseShader.compile();
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(program);
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramStateReplaceSourceCase : public ProgramStateCase
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramStateReplaceSourceCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramStateCase (context, name, desc, shaderType)
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramStateReplaceSourceCase (void)
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader source and recompiling" << TestLog::EndMessage;
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.setSource(m_shaderType);
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		caseShader.compile();
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(program);
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Program binary utilities
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ProgramBinary
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum					format;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint8>	data;
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool programBinariesEqual (const ProgramBinary& first, const ProgramBinary& second)
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((first.format != second.format) || (first.data.size() != second.data.size()))
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::equal(first.data.begin(), first.data.end(), second.data.begin());
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class for program binary cases
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryCase : public TestCase, protected glu::CallLogWrapper
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ProgramBinaryCase	(Context& context, const char* name, const char* desc);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~ProgramBinaryCase	(void);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					getBinaryFormats	(std::vector<GLenum>& out);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					isFormatSupported	(const glw::GLenum format) const;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					getProgramBinary	(ProgramBinary& out, GLuint program);
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					loadProgramBinary	(ProgramBinary& binary, GLuint program);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					verifyProgramBinary	(ProgramBinary& binary);
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init				(void);
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate				(void);
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			test				(void) = 0;
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<GLenum>		m_formats;
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramBinaryCase::ProgramBinaryCase (Context& context, const char* name, const char* desc)
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase			(context, name, desc)
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, CallLogWrapper	(context.getRenderContext().getFunctions(), context.getTestContext().getLog())
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramBinaryCase::~ProgramBinaryCase (void)
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryCase::getBinaryFormats (std::vector<GLenum>& out)
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint numFormats = -1;
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numFormats);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	out.clear();
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFormats > 0)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.resize(numFormats, 0);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, (GLint*)&out[0]);
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ProgramBinaryCase::isFormatSupported (const glw::GLenum format) const
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (std::find(m_formats.begin(), m_formats.end(), format) != m_formats.end());
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryCase::getProgramBinary (ProgramBinary& out, GLuint program)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint binaryLength = -1;
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (binaryLength > 0)
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLsizei	actualLength;
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum	format;
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.data.clear();
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.data.resize(binaryLength, 0);
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetProgramBinary(program, (GLsizei)out.data.size(), &actualLength, &format, &(out.data[0])));
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(actualLength == binaryLength);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		out.format = format;
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryCase::loadProgramBinary (ProgramBinary& binary, GLuint program)
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glProgramBinary(program, binary.format, &binary.data[0], (GLsizei)binary.data.size());
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("Failed to load program binary.");
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryCase::verifyProgramBinary (ProgramBinary& binary)
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isFormatSupported(binary.format))
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Program binary format " << binary.format << " is not among the supported formats reported by the platform." << TestLog::EndMessage;
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid format");
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryCase::init (void)
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getBinaryFormats(m_formats);
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TestNode::IterateResult ProgramBinaryCase::iterate (void)
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log	= m_testCtx.getLog();
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_formats.empty())
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "No program binary formats are supported." << TestLog::EndMessage;
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		enableLogging(true);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test();
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Simple program binary case
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinarySimpleCase : public ProgramBinaryCase
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinarySimpleCase (Context& context, const char* name, const char* desc)
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryCase(context, name, desc)
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinarySimpleCase (void)
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string			vertSrc	= getSimpleShaderSource(glu::SHADERTYPE_VERTEX);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string			fragSrc	= getSimpleShaderSource(glu::SHADERTYPE_FRAGMENT);
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ProgramSources	sources	= glu::makeVtxFragSources(vertSrc, fragSrc);
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ShaderProgram			program	(m_context.getRenderContext(), sources);
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (program.isOk())
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ProgramBinary binary;
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getProgramBinary(binary, program.getProgram());
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyProgramBinary(binary);
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Program binary uniform reset case
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryUniformResetCase : public ProgramBinaryCase
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryUniformResetCase (Context& context, const char* name, const char* desc)
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryCase	(context, name, desc)
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_rnd				(deStringHash(name) ^ 0xf2b48c6a)
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryUniformResetCase (void)
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string getShaderSource (const glu::ShaderType shaderType) const
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* vertSrc =
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform bool u_boolVar;\n"
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp int u_intVar;\n"
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp float u_floatVar;\n\n"
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n\n"
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* fragSrc =
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform bool u_boolVar;\n"
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp int u_intVar;\n"
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform highp float u_floatVar;\n\n"
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 o_fragColor;\n\n"
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump float refAll = float(u_boolVar) + float(u_intVar) + u_floatVar;\n"
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_fragColor = vec4(refAll);\n"
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(shaderType == glu::SHADERTYPE_VERTEX || shaderType == glu::SHADERTYPE_FRAGMENT);
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (shaderType == glu::SHADERTYPE_VERTEX) ? vertSrc : fragSrc;
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setUniformsRandom (glu::ShaderProgram& program)
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log		= m_testCtx.getLog();
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	glProg	= program.getProgram();
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Setting uniforms to random non-zero values." << TestLog::EndMessage;
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glUseProgram(glProg);
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLint		boolLoc		= glGetUniformLocation(glProg, "u_boolVar");
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLint		intLoc		= glGetUniformLocation(glProg, "u_intVar");
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLint		floatLoc	= glGetUniformLocation(glProg, "u_floatVar");
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	intVal		= m_rnd.getInt(1, 1000);
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		floatVal	= m_rnd.getFloat(1.0, 1000.0);
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(boolLoc,	GL_TRUE);
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1f(floatLoc,	floatVal);
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(intLoc,		intVal);
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void verifyUniformInt (glu::ShaderProgram& program, const std::string& name)
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint		intLoc	= glGetUniformLocation(program.getProgram(), name.c_str());
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint			intVar	= -1;
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetUniformiv(program.getProgram(), intLoc, &intVar);
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (intVar != 0)
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Fail, expected zero value for " << name << ", received: " << intVar << TestLog::EndMessage;
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Uniform value not reset");
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void verifyUniformFloat (glu::ShaderProgram& program, const std::string& name)
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLint	floatLoc	= glGetUniformLocation(program.getProgram(), name.c_str());
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLfloat		floatVar	= -1;
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetUniformfv(program.getProgram(), floatLoc, &floatVar);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (floatVar != 0.0f)
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Message << "Fail, expected zero value for " << name << ", received: " << de::toString(floatVar) << TestLog::EndMessage;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Uniform value not reset");
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void verifyUniformsReset (glu::ShaderProgram& program)
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Verifying uniform reset to 0/false." << TestLog::EndMessage;
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyUniformInt	(program,	"u_boolVar");
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyUniformInt	(program,	"u_intVar");
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyUniformFloat	(program,	"u_floatVar");
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void test (void)
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&					log		= m_testCtx.getLog();
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string			vertSrc	= getShaderSource(glu::SHADERTYPE_VERTEX);
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string			fragSrc	= getShaderSource(glu::SHADERTYPE_FRAGMENT);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ProgramSources	sources	= glu::makeVtxFragSources(vertSrc, fragSrc);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ShaderProgram			program	(m_context.getRenderContext(), sources);
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << program;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(program.isOk(), "Couldn't build program");
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ProgramBinary binary;
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getProgramBinary(binary, program.getProgram());
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyProgramBinary(binary);
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setUniformsRandom(program);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Rendering test image and reloading binary" << TestLog::EndMessage;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			drawWithProgram(m_context.getRenderContext(), program.getProgram());
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			loadProgramBinary(binary, program.getProgram());
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verifyUniformsReset(program);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	m_rnd;
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class for program state persistence cases
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceCase : public ProgramBinaryCase
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ProgramBinaryPersistenceCase	(Context& context, const char* name, const char* desc, glu::ShaderType shaderType);
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual			~ProgramBinaryPersistenceCase	(void) {}
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			buildProgram					(glu::Program& program, ShaderAllocator& shaders);
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			test							(void);
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void	executeForProgram				(glu::Program& program, ShaderAllocator& shaders)	= 0;
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void	verify							(glu::Program& program, const ProgramBinary& binary);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				m_rnd;
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType	m_shaderType;
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramBinaryPersistenceCase::ProgramBinaryPersistenceCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ProgramBinaryCase	(context, name, desc)
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rnd				(deStringHash(name) ^ 0x713de0ca)
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType		(shaderType)
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryPersistenceCase::buildProgram (glu::Program& program, ShaderAllocator& shaders)
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	vertShader	= shaders.createShader(glu::SHADERTYPE_VERTEX);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Shader&	fragShader	= shaders.createShader(glu::SHADERTYPE_FRAGMENT);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertShader.compile();
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragShader.compile();
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.attachShader(vertShader.getShader());
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.attachShader(fragShader.getShader());
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	program.link();
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	logProgram(log, m_context.getRenderContext(), program, shaders);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryPersistenceCase::verify (glu::Program& program, const ProgramBinary& binary)
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log				= m_testCtx.getLog();
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinary	currentBinary;
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getProgramBinary(currentBinary, program.getProgram());
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!programBinariesEqual(binary, currentBinary))
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, program binary may only change as a result of linking or loading." << TestLog::EndMessage;
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program binary changed");
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramBinaryPersistenceCase::test (void)
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::RenderContext&		renderCtx	= m_context.getRenderContext();
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstantShaderGenerator	sourceGen	(m_rnd);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderAllocator			shaders		(renderCtx, sourceGen);
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Program			program		(renderCtx);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buildProgram(program, shaders);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (program.getLinkStatus())
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramBinary binary;
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getProgramBinary(binary, program.getProgram());
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		executeForProgram(program, shaders);
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verify(program, binary);
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		logProgram(log, renderCtx, program, shaders);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Fail, couldn't link program." << TestLog::EndMessage;
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Linking failed");
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Program state case utilities
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class T>
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addProgramBinaryPersistenceCase (TestCaseGroup* group, Context& context, const std::string& name, const std::string& desc)
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::ShaderType	shaderType		= (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		shaderTypeName	= getShaderTypeName(shaderType);
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		caseName		= name + "_" + shaderTypeName;
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string		caseDesc		= "Build program, " + desc + ", for " + shaderTypeName + " shader.";
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(new T(context, caseName.c_str(), caseDesc.c_str(), shaderType));
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Specialized program state cases
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceDetachShaderCase : public ProgramBinaryPersistenceCase
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceDetachShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceDetachShaderCase (void)
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Detaching " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceReattachShaderCase : public ProgramBinaryPersistenceCase
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceReattachShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceReattachShaderCase (void)
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Reattaching " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(caseShader.getShader());
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceDeleteShaderCase : public ProgramBinaryPersistenceCase
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceDeleteShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceDeleteShaderCase (void)
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Deleting " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.deleteShader(m_shaderType);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceReplaceShaderCase : public ProgramBinaryPersistenceCase
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceReplaceShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceReplaceShaderCase (void)
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Deleting and replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.detachShader(caseShader.getShader());
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.deleteShader(m_shaderType);
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program.attachShader(shaders.createShader(m_shaderType).getShader());
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceRecompileShaderCase : public ProgramBinaryPersistenceCase
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceRecompileShaderCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceRecompileShaderCase (void)
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Recompiling " + std::string(getShaderTypeName(m_shaderType)) + " shader" << TestLog::EndMessage;
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		caseShader.compile();
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(program);
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ProgramBinaryPersistenceReplaceSourceCase : public ProgramBinaryPersistenceCase
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramBinaryPersistenceReplaceSourceCase (Context& context, const char* name, const char* desc, glu::ShaderType shaderType)
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ProgramBinaryPersistenceCase (context, name, desc, shaderType)
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ProgramBinaryPersistenceReplaceSourceCase (void)
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void executeForProgram (glu::Program& program, ShaderAllocator& shaders)
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog&		log			= m_testCtx.getLog();
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Shader&	caseShader	= shaders.get(m_shaderType);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Replacing " + std::string(getShaderTypeName(m_shaderType)) + " shader source and recompiling" << TestLog::EndMessage;
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaders.setSource(m_shaderType);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		caseShader.compile();
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(program);
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test group
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderApiTests::ShaderApiTests (Context& context)
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "shader_api", "Shader API Cases")
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderApiTests::~ShaderApiTests (void)
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderApiTests::init (void)
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// create and delete shaders
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* createDeleteGroup = new TestCaseGroup(m_context, "create_delete", "glCreateShader() tests");
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(createDeleteGroup);
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		createDeleteGroup->addChild(new CreateShaderCase(m_context,	"create_vertex_shader",		"Create vertex shader object",		glu::SHADERTYPE_VERTEX));
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		createDeleteGroup->addChild(new CreateShaderCase(m_context,	"create_fragment_shader",	"Create fragment shader object",	glu::SHADERTYPE_FRAGMENT));
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		createDeleteGroup->addChild(new DeleteShaderCase(m_context,	"delete_vertex_fragment",	"Delete vertex shader and fragment shader"));
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compile and link
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* compileLinkGroup = new TestCaseGroup(m_context, "compile_link", "Compile and link tests");
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(compileLinkGroup);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compileLinkGroup->addChild(new CompileShaderCase(m_context,	"compile_vertex_shader",	"Compile vertex shader",	glu::SHADERTYPE_VERTEX));
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compileLinkGroup->addChild(new CompileShaderCase(m_context,	"compile_fragment_shader",	"Compile fragment shader",	glu::SHADERTYPE_FRAGMENT));
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		compileLinkGroup->addChild(new LinkVertexFragmentCase(m_context,	"link_vertex_fragment",	"Link vertex and fragment shaders"));
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// shader source
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* shaderSourceGroup = new TestCaseGroup(m_context, "shader_source", "glShaderSource() tests");
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(shaderSourceGroup);
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::ShaderType	shaderType		= (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string		shaderTypeName	= getShaderTypeName(shaderType);
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string		caseName		= std::string("replace_source_") + shaderTypeName;
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string		caseDesc		= std::string("Replace source code of ") + shaderTypeName + " shader.";
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			shaderSourceGroup->addChild(new ShaderSourceReplaceCase(m_context, caseName.c_str(), caseDesc.c_str(), shaderType));
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int stringLengthsInt	= 0; stringLengthsInt < 3; stringLengthsInt++)
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 1; caseNdx <= 3; caseNdx++)
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numSlices		= 1 << caseNdx;
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::ShaderType	shaderType		= (shaderTypeInt == 1) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				explicitLengths	= (stringLengthsInt != 0);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool				randomNullTerm	= (stringLengthsInt == 2);
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32			flags			= (explicitLengths	? CASE_EXPLICIT_SOURCE_LENGTHS	: 0)
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													| (randomNullTerm	? CASE_RANDOM_NULL_TERMINATED	: 0);
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string		caseName		= "split_source_"
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ de::toString(numSlices)
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ (randomNullTerm ? "_random_negative_length" : (explicitLengths ? "_specify_lengths" : "_null_terminated"))
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ ((shaderType == glu::SHADERTYPE_FRAGMENT) ? "_fragment" : "_vertex");
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string		caseDesc		= std::string((shaderType == glu::SHADERTYPE_FRAGMENT) ? "Fragment" : "Vertex")
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ " shader source split into "
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ de::toString(numSlices)
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ " pieces"
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ (explicitLengths ? ", using explicitly specified string lengths" : "")
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													+ (randomNullTerm ? " with random negative length values" : "");
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			shaderSourceGroup->addChild(new ShaderSourceSplitCase(m_context, caseName.c_str(), caseDesc.c_str(), shaderType, numSlices, flags));
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// link status and infolog
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* linkStatusGroup = new TestCaseGroup(m_context, "program_state", "Program state persistence tests");
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(linkStatusGroup);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateDetachShaderCase>		(linkStatusGroup,	m_context,	"detach_shader",	"detach shader");
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateReattachShaderCase>		(linkStatusGroup,	m_context,	"reattach_shader",	"reattach shader");
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateDeleteShaderCase>		(linkStatusGroup,	m_context,	"delete_shader",	"delete shader");
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateReplaceShaderCase>		(linkStatusGroup,	m_context,	"replace_shader",	"replace shader object");
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateRecompileShaderCase>	(linkStatusGroup,	m_context,	"recompile_shader",	"recompile shader");
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addProgramStateCase<ProgramStateReplaceSourceCase>		(linkStatusGroup,	m_context,	"replace_source",	"replace shader source");
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// program binary
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* programBinaryGroup = new TestCaseGroup(m_context, "program_binary", "Program binary API tests");
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(programBinaryGroup);
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* simpleCaseGroup = new TestCaseGroup(m_context, "simple", "Simple API tests");
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			programBinaryGroup->addChild(simpleCaseGroup);
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			simpleCaseGroup->addChild(new ProgramBinarySimpleCase		(m_context,	"get_program_binary_vertex_fragment",	"Get vertex and fragment shader program binary"));
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			simpleCaseGroup->addChild(new ProgramBinaryUniformResetCase	(m_context,	"uniform_reset_on_binary_load",			"Verify uniform reset on successful load of program binary"));
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* binaryPersistenceGroup = new TestCaseGroup(m_context, "binary_persistence", "Program binary persistence tests");
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			programBinaryGroup->addChild(binaryPersistenceGroup);
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceDetachShaderCase>		(binaryPersistenceGroup,	m_context,	"detach_shader",	"detach shader");
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceReattachShaderCase>		(binaryPersistenceGroup,	m_context,	"reattach_shader",	"reattach shader");
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceDeleteShaderCase>		(binaryPersistenceGroup,	m_context,	"delete_shader",	"delete shader");
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceReplaceShaderCase>		(binaryPersistenceGroup,	m_context,	"replace_shader",	"replace shader object");
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceRecompileShaderCase>	(binaryPersistenceGroup,	m_context,	"recompile_shader",	"recompile shader");
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addProgramBinaryPersistenceCase<ProgramBinaryPersistenceReplaceSourceCase>		(binaryPersistenceGroup,	m_context,	"replace_source",	"replace shader source");
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1764