13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL (ES) 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 Random shader test case.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsRandomShaderCase.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
29162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry#include "gluStrUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
33162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
35162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry#include "deStringUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgProgramGenerator.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgProgramExecutor.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgUtils.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
45162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry#include "glwFunctions.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::pair;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gls
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_WIDTH			= 64,
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_HEIGHT			= 64,
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_2D_WIDTH		= 64,
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_2D_HEIGHT		= 64,
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_2D_FORMAT		= GL_RGBA,
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_2D_DATA_TYPE	= GL_UNSIGNED_BYTE,
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_CUBE_SIZE		= 16,
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_CUBE_FORMAT		= GL_RGBA,
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_CUBE_DATA_TYPE	= GL_UNSIGNED_BYTE,
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_WRAP_S			= GL_CLAMP_TO_EDGE,
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_WRAP_T			= GL_CLAMP_TO_EDGE,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_MIN_FILTER		= GL_LINEAR,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TEXTURE_MAG_FILTER		= GL_LINEAR
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexArray::VertexArray (const rsg::ShaderInput* input, int numVertices)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_input			(input)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertices		(input->getVariable()->getType().getNumElements() * numVertices)
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureManager::TextureManager (void)
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureManager::~TextureManager (void)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureManager::bindTexture (int unit, const glu::Texture2D* tex2D)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_tex2D[unit] = tex2D;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureManager::bindTexture (int unit, const glu::TextureCube* texCube)
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texCube[unit] = texCube;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline vector<pair<int, const glu::Texture2D*> > TextureManager::getBindings2D (void) const
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<pair<int, const glu::Texture2D*> > bindings;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (map<int, const glu::Texture2D*>::const_iterator i = m_tex2D.begin(); i != m_tex2D.end(); i++)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bindings.push_back(*i);
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return bindings;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline vector<pair<int, const glu::TextureCube*> > TextureManager::getBindingsCube (void) const
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<pair<int, const glu::TextureCube*> > bindings;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (map<int, const glu::TextureCube*>::const_iterator i = m_texCube.begin(); i != m_texCube.end(); i++)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bindings.push_back(*i);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return bindings;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomShaderCase::RandomShaderCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, const rsg::ProgramParameters& params)
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: tcu::TestCase		(testCtx, name, description)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderCtx		(renderCtx)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_parameters		(params)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridWidth		(1)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridHeight		(1)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertexShader	(rsg::Shader::TYPE_VERTEX)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fragmentShader	(rsg::Shader::TYPE_FRAGMENT)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_tex2D			(DE_NULL)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texCube			(DE_NULL)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomShaderCase::~RandomShaderCase (void)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_tex2D;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texCube;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RandomShaderCase::init (void)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate shaders
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rsg::ProgramGenerator programGenerator;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	programGenerator.generate(m_parameters, m_vertexShader, m_fragmentShader);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
143162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	checkShaderLimits(m_vertexShader);
144162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	checkShaderLimits(m_fragmentShader);
145162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	checkProgramLimits(m_vertexShader, m_fragmentShader);
146162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute uniform values
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<const rsg::ShaderInput*>	unifiedUniforms;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random								rnd(m_parameters.seed);
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rsg::computeUnifiedUniforms(m_vertexShader, m_fragmentShader, unifiedUniforms);
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rsg::computeUniformValues(rnd, m_uniforms, unifiedUniforms);
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate vertices
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<rsg::ShaderInput*>&	inputs		= m_vertexShader.getInputs();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int									numVertices	= (m_gridWidth+1)*(m_gridHeight+1);
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<rsg::ShaderInput*>::const_iterator i = inputs.begin(); i != inputs.end(); i++)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rsg::ShaderInput*			input			= *i;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rsg::ConstValueRangeAccess		valueRange		= input->getValueRange();
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								numComponents	= input->getVariable()->getType().getNumElements();
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VertexArray						vtxArray(input, numVertices);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool							isPosition		= string(input->getVariable()->getName()) == "dEQP_Position";
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(input->getVariable()->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		y	= vtxNdx / (m_gridWidth+1);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		x	= vtxNdx - y*(m_gridWidth+1);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	xf	= (float)x / (float)m_gridWidth;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	yf	= (float)y / (float)m_gridHeight;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float*	dst	= &vtxArray.getVertices()[vtxNdx*numComponents];
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isPosition)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Position attribute gets special interpolation handling.
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(numComponents == 4);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[0] = -1.0f + xf *  2.0f;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[1] =  1.0f + yf * -2.0f;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[2] = 0.0f;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst[3] = 1.0f;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int compNdx = 0; compNdx < numComponents; compNdx++)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	minVal	= valueRange.getMin().component(compNdx).asFloat();
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	maxVal	= valueRange.getMax().component(compNdx).asFloat();
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	xd, yd;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					rsg::getVertexInterpolationCoords(xd, yd, xf, yf, compNdx);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	f		= (xd+yd) / 2.0f;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst[compNdx] = minVal + f * (maxVal-minVal);
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.push_back(vtxArray);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate indices
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numQuads	= m_gridWidth*m_gridHeight;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numIndices	= numQuads*6;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_indices.resize(numIndices);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int quadNdx = 0; quadNdx < numQuads; quadNdx++)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int	quadY	= quadNdx / (m_gridWidth);
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int quadX	= quadNdx - quadY*m_gridWidth;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
213c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+0] = (deUint16)(quadX + quadY*(m_gridWidth+1));
214c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+1] = (deUint16)(quadX + (quadY+1)*(m_gridWidth+1));
215c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+2] = (deUint16)(quadX + quadY*(m_gridWidth+1) + 1);
216c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+3] = (deUint16)(m_indices[quadNdx*6+2]);
217c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+4] = (deUint16)(m_indices[quadNdx*6+1]);
218c8e526bfc2141e1cb7a269483fb55dc2a8e77c11Jarkko Pöyry		m_indices[quadNdx*6+5] = (deUint16)(quadX + (quadY+1)*(m_gridWidth+1) + 1);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create textures.
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<rsg::VariableValue>::const_iterator uniformIter = m_uniforms.begin(); uniformIter != m_uniforms.end(); uniformIter++)
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rsg::VariableType& type = uniformIter->getVariable()->getType();
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!type.isSampler())
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int unitNdx = uniformIter->getValue().asInt(0);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (type == rsg::VariableType(rsg::VariableType::TYPE_SAMPLER_2D, 1))
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texManager.bindTexture(unitNdx, getTex2D());
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (type == rsg::VariableType(rsg::VariableType::TYPE_SAMPLER_CUBE, 1))
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texManager.bindTexture(unitNdx, getTexCube());
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
240162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyrystatic int getNumSamplerUniforms (const std::vector<rsg::ShaderInput*>& uniforms)
241162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry{
242162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	int numSamplers = 0;
243162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
244162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	for (std::vector<rsg::ShaderInput*>::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
245162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	{
246162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		if ((*it)->getVariable()->getType().isSampler())
247162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry			++numSamplers;
248162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	}
249162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
250162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	return numSamplers;
251162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry}
252162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
253162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyryvoid RandomShaderCase::checkShaderLimits (const rsg::Shader& shader) const
254162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry{
255162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	const int numRequiredSamplers = getNumSamplerUniforms(shader.getUniforms());
256162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
257162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	if (numRequiredSamplers > 0)
258162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	{
259162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		const GLenum	pname			= (shader.getType() == rsg::Shader::TYPE_VERTEX) ? (GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) : (GL_MAX_TEXTURE_IMAGE_UNITS);
260162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		int				numSupported	= -1;
261162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		GLenum			error;
262162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
263162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		m_renderCtx.getFunctions().getIntegerv(pname, &numSupported);
264162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		error = m_renderCtx.getFunctions().getError();
265162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
266162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		if (error != GL_NO_ERROR)
267162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry			throw tcu::TestError("Limit query failed: " + de::toString(glu::getErrorStr(error)));
268162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
269162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		if (numSupported < numRequiredSamplers)
270162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry			throw tcu::NotSupportedError("Shader requires " + de::toString(numRequiredSamplers) + " sampler(s). Implementation supports " + de::toString(numSupported));
271162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	}
272162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry}
273162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
274162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyryvoid RandomShaderCase::checkProgramLimits (const rsg::Shader& vtxShader, const rsg::Shader& frgShader) const
275162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry{
276162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	const int numRequiredCombinedSamplers = getNumSamplerUniforms(vtxShader.getUniforms()) + getNumSamplerUniforms(frgShader.getUniforms());
277162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
278162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	if (numRequiredCombinedSamplers > 0)
279162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	{
280162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		int				numSupported	= -1;
281162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		GLenum			error;
282162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
283162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		m_renderCtx.getFunctions().getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numSupported);
284162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		error = m_renderCtx.getFunctions().getError();
285162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
286162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		if (error != GL_NO_ERROR)
287162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry			throw tcu::TestError("Limit query failed: " + de::toString(glu::getErrorStr(error)));
288162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
289162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry		if (numSupported < numRequiredCombinedSamplers)
290162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry			throw tcu::NotSupportedError("Program requires " + de::toString(numRequiredCombinedSamplers) + " sampler(s). Implementation supports " + de::toString(numSupported));
291162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry	}
292162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry}
293162d31979ebef81c4b49490d86e7f0ce579f4d0dJarkko Pöyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst glu::Texture2D* RandomShaderCase::getTex2D (void)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_tex2D)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_tex2D = new glu::Texture2D(m_renderCtx, TEXTURE_2D_FORMAT, TEXTURE_2D_DATA_TYPE, TEXTURE_2D_WIDTH, TEXTURE_2D_HEIGHT);
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_tex2D->getRefTexture().allocLevel(0);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::fillWithComponentGradients(m_tex2D->getRefTexture().getLevel(0), tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_tex2D->upload();
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Setup parameters.
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_2D, m_tex2D->getGLTexture());
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		TEXTURE_WRAP_S);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		TEXTURE_WRAP_T);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	TEXTURE_MIN_FILTER);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	TEXTURE_MAG_FILTER);
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_tex2D;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst glu::TextureCube* RandomShaderCase::getTexCube (void)
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_texCube)
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texCube = new glu::TextureCube(m_renderCtx, TEXTURE_CUBE_FORMAT, TEXTURE_CUBE_DATA_TYPE, TEXTURE_CUBE_SIZE);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill level 0.
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texCube->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_texCube->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), gradients[face][0], gradients[face][1]);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texCube->upload();
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Setup parameters.
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_CUBE_MAP, m_texCube->getGLTexture());
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		TEXTURE_WRAP_S);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		TEXTURE_WRAP_T);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	TEXTURE_MIN_FILTER);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	TEXTURE_MAG_FILTER);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK();
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_texCube;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RandomShaderCase::deinit (void)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_tex2D;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texCube;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_tex2D		= DE_NULL;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texCube	= DE_NULL;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Free up memory
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexArrays.clear();
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_indices.clear();
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setUniformValue (int location, rsg::ConstValueAccess value)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(float));
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(int));
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value.getType().getBaseType())
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_FLOAT:
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (value.getType().getNumElements())
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 1:		glUniform1fv(location, 1, (float*)value.value().getValuePtr());		break;
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 2:		glUniform2fv(location, 1, (float*)value.value().getValuePtr());		break;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 3:		glUniform3fv(location, 1, (float*)value.value().getValuePtr());		break;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 4:		glUniform4fv(location, 1, (float*)value.value().getValuePtr());		break;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:	TCU_FAIL("Unsupported type");										break;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_INT:
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_BOOL:
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_SAMPLER_2D:
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_SAMPLER_CUBE:
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (value.getType().getNumElements())
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 1:		glUniform1iv(location, 1, (int*)value.value().getValuePtr());		break;
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 2:		glUniform2iv(location, 1, (int*)value.value().getValuePtr());		break;
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 3:		glUniform3iv(location, 1, (int*)value.value().getValuePtr());		break;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 4:		glUniform4iv(location, 1, (int*)value.value().getValuePtr());		break;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:	TCU_FAIL("Unsupported type");										break;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Unsupported type");
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::MessageBuilder& operator<< (tcu::MessageBuilder& message, rsg::ConstValueAccess value)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*	scalarType	= DE_NULL;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* vecType		= DE_NULL;
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value.getType().getBaseType())
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_FLOAT:			scalarType = "float";	vecType	= "vec";	break;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_INT:			scalarType = "int";		vecType = "ivec";	break;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_BOOL:			scalarType = "bool";	vecType = "bvec";	break;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_SAMPLER_2D:	scalarType = "sampler2D";					break;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rsg::VariableType::TYPE_SAMPLER_CUBE:	scalarType = "samplerCube";					break;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Unsupported type.");
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numElements = value.getType().getNumElements();
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElements == 1)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		message << scalarType << "(";
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		message << vecType << numElements << "(";
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elementNdx = 0; elementNdx < numElements; elementNdx++)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (elementNdx > 0)
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			message << ", ";
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (value.getType().getBaseType())
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case rsg::VariableType::TYPE_FLOAT:			message << value.component(elementNdx).asFloat();						break;
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case rsg::VariableType::TYPE_INT:			message << value.component(elementNdx).asInt();							break;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case rsg::VariableType::TYPE_BOOL:			message << (value.component(elementNdx).asBool() ? "true" : "false");	break;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case rsg::VariableType::TYPE_SAMPLER_2D:	message << value.component(elementNdx).asInt();							break;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case rsg::VariableType::TYPE_SAMPLER_CUBE:	message << value.component(elementNdx).asInt();							break;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	message << ")";
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return message;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::MessageBuilder& operator<< (tcu::MessageBuilder& message, rsg::ConstValueRangeAccess valueRange)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return message << valueRange.getMin() << " -> " << valueRange.getMax();
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomShaderCase::IterateResult RandomShaderCase::iterate (void)
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog& log = m_testCtx.getLog();
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compile program
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram program(m_renderCtx, glu::makeVtxFragSources(m_vertexShader.getSource(), m_fragmentShader.getSource()));
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute random viewport
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd				(m_parameters.seed);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						viewportWidth	= de::min<int>(VIEWPORT_WIDTH,	m_renderCtx.getRenderTarget().getWidth());
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						viewportHeight	= de::min<int>(VIEWPORT_HEIGHT,	m_renderCtx.getRenderTarget().getHeight());
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						viewportX		= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth()	- viewportWidth);
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						viewportY		= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight()	- viewportHeight);
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					hasAlpha		= m_renderCtx.getRenderTarget().getPixelFormat().alphaBits > 0;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel		rendered		(tcu::TextureFormat(hasAlpha ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), viewportWidth, viewportHeight);
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel		reference		(tcu::TextureFormat(hasAlpha ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), viewportWidth, viewportHeight);
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference program executor.
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rsg::ProgramExecutor	executor		(reference.getAccess(), m_gridWidth, m_gridHeight);
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set up attributes
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<VertexArray>::const_iterator attribIter = m_vertexArrays.begin(); attribIter != m_vertexArrays.end(); attribIter++)
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint location = glGetAttribLocation(program.getProgram(), attribIter->getName());
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Print to log.
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << tcu::TestLog::Message << "attribute[" << location << "]: " << attribIter->getName() << " = " << attribIter->getValueRange() << tcu::TestLog::EndMessage;
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location >= 0)
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(location, attribIter->getNumComponents(), GL_FLOAT, GL_FALSE, 0, &attribIter->getVertices()[0]);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(location);
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("After attribute setup");
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Uniforms
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<rsg::VariableValue>::const_iterator uniformIter = m_uniforms.begin(); uniformIter != m_uniforms.end(); uniformIter++)
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint location = glGetUniformLocation(program.getProgram(), uniformIter->getVariable()->getName());
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << tcu::TestLog::Message << "uniform[" << location << "]: " << uniformIter->getVariable()->getName() << " = " << uniformIter->getValue() << tcu::TestLog::EndMessage;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location >= 0)
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setUniformValue(location, uniformIter->getValue());
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("After uniform setup");
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Textures
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<pair<int, const glu::Texture2D*> >	tex2DBindings		= m_texManager.getBindings2D();
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<pair<int, const glu::TextureCube*> >	texCubeBindings		= m_texManager.getBindingsCube();
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<pair<int, const glu::Texture2D*> >::const_iterator i = tex2DBindings.begin(); i != tex2DBindings.end(); i++)
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						unitNdx		= i->first;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Texture2D*	texture		= i->second;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glActiveTexture(GL_TEXTURE0 + unitNdx);
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_2D, texture->getGLTexture());
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		executor.setTexture(unitNdx, &texture->getRefTexture(), glu::mapGLSampler(TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE_MIN_FILTER, TEXTURE_MAG_FILTER));
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("After 2D texture setup");
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<pair<int, const glu::TextureCube*> >::const_iterator i = texCubeBindings.begin(); i != texCubeBindings.end(); i++)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						unitNdx		= i->first;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::TextureCube*	texture		= i->second;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glActiveTexture(GL_TEXTURE0 + unitNdx);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glBindTexture(GL_TEXTURE_CUBE_MAP, texture->getGLTexture());
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		executor.setTexture(unitNdx, &texture->getRefTexture(), glu::mapGLSampler(TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE_MIN_FILTER, TEXTURE_MAG_FILTER));
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("After cubemap setup");
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw and read
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, (GLsizei)m_indices.size(), GL_UNSIGNED_SHORT, &m_indices[0]);
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glFlush();
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_MSG("Draw");
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference while GPU is doing work
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	executor.execute(m_vertexShader, m_fragmentShader, m_uniforms);
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (rendered.getFormat().order != tcu::TextureFormat::RGBA || rendered.getFormat().type != tcu::TextureFormat::UNORM_INT8)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Read as GL_RGBA8
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureLevel readBuf(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), rendered.getWidth(), rendered.getHeight());
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_renderCtx, viewportX, viewportY, readBuf.getAccess());
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_MSG("Read pixels");
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::copy(rendered, readBuf);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_renderCtx, viewportX, viewportY, rendered.getAccess());
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float	threshold	= 0.02f;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	imagesOk	= tcu::fuzzyCompare(log, "Result", "Result images", reference.getAccess(), rendered.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (imagesOk)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gls
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
580